mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-11 05:33:47 +01:00
clean up circuit rebuilding some; fix some bugs we hadn't hit yet
svn:r1606
This commit is contained in:
parent
a3c072e579
commit
e0ce205a76
@ -16,6 +16,7 @@ static void circuit_free_cpath_node(crypt_path_t *victim);
|
||||
static uint16_t get_unique_circ_id_by_conn(connection_t *conn, int circ_id_type);
|
||||
static void circuit_rep_hist_note_result(circuit_t *circ);
|
||||
|
||||
void circuit_expire_old_circuits(void);
|
||||
static void circuit_is_open(circuit_t *circ);
|
||||
static void circuit_build_failed(circuit_t *circ);
|
||||
static circuit_t *circuit_establish_circuit(uint8_t purpose, const char *exit_nickname);
|
||||
@ -293,10 +294,6 @@ static int circuit_is_acceptable(circuit_t *circ,
|
||||
if(conn) {
|
||||
/* decide if this circ is suitable for this conn */
|
||||
|
||||
// if(circ->state == CIRCUIT_STATE_OPEN && circ->n_conn) /* open */
|
||||
// exitrouter = router_get_by_addr_port(circ->cpath->prev->addr,
|
||||
// circ->cpath->prev->port);
|
||||
// else /* not open */
|
||||
/* for rend circs, circ->cpath->prev is not the last router in the
|
||||
* circuit, it's the magical extra bob hop. so just check the nickname
|
||||
* of the one we meant to finish at.
|
||||
@ -442,8 +439,7 @@ circuit_t *circuit_get_rendezvous(const char *cookie)
|
||||
|
||||
/* close all circuits that start at us, aren't open, and were born
|
||||
* at least MIN_SECONDS_BEFORE_EXPIRING_CIRC seconds ago */
|
||||
void circuit_expire_building(void) {
|
||||
int now = time(NULL);
|
||||
void circuit_expire_building(time_t now) {
|
||||
circuit_t *victim, *circ = global_circuitlist;
|
||||
|
||||
while(circ) {
|
||||
@ -480,14 +476,15 @@ void circuit_expire_building(void) {
|
||||
}
|
||||
|
||||
/* count the number of circs starting at us that aren't open */
|
||||
int circuit_count_building(void) {
|
||||
int circuit_count_building(uint8_t purpose) {
|
||||
circuit_t *circ;
|
||||
int num=0;
|
||||
|
||||
for(circ=global_circuitlist;circ;circ = circ->next) {
|
||||
if(CIRCUIT_IS_ORIGIN(circ)
|
||||
&& circ->state != CIRCUIT_STATE_OPEN
|
||||
&& !circ->marked_for_close)
|
||||
if(CIRCUIT_IS_ORIGIN(circ) &&
|
||||
circ->state != CIRCUIT_STATE_OPEN &&
|
||||
circ->purpose == purpose &&
|
||||
!circ->marked_for_close)
|
||||
num++;
|
||||
}
|
||||
return num;
|
||||
@ -518,41 +515,65 @@ int circuit_stream_is_being_handled(connection_t *conn) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void circuit_build_needed_circs(time_t now) {
|
||||
static long time_to_new_circuit = 0;
|
||||
static circuit_t *
|
||||
circuit_get_youngest_clean_open(uint8_t purpose) {
|
||||
circuit_t *circ;
|
||||
circuit_t *youngest=NULL;
|
||||
|
||||
if (options.SocksPort)
|
||||
/* launch a new circ for any pending streams that need one */
|
||||
connection_ap_attach_pending();
|
||||
for(circ=global_circuitlist;circ;circ = circ->next) {
|
||||
if(CIRCUIT_IS_ORIGIN(circ) && circ->state == CIRCUIT_STATE_OPEN &&
|
||||
!circ->marked_for_close && circ->purpose == purpose &&
|
||||
!circ->timestamp_dirty &&
|
||||
(!youngest || youngest->timestamp_created < circ->timestamp_created))
|
||||
youngest = circ;
|
||||
}
|
||||
return youngest;
|
||||
}
|
||||
|
||||
/* Build a new test circuit every 5 minutes */
|
||||
#define TESTING_CIRCUIT_INTERVAL 300
|
||||
|
||||
circ = circuit_get_best(NULL, 1, CIRCUIT_PURPOSE_C_GENERAL);
|
||||
/* this function is called once a second. its job is to make sure
|
||||
* all services we offer have enough circuits available. Some
|
||||
* services just want enough circuits for current tasks, whereas
|
||||
* others want a minimum set of idle circuits hanging around.
|
||||
*/
|
||||
void circuit_build_needed_circs(time_t now) {
|
||||
static long time_to_new_circuit = 0;
|
||||
circuit_t *circ;
|
||||
|
||||
/* launch a new circ for any pending streams that need one */
|
||||
connection_ap_attach_pending();
|
||||
|
||||
/* make sure any hidden services have enough intro points */
|
||||
rend_services_init();
|
||||
|
||||
circ = circuit_get_youngest_clean_open(CIRCUIT_PURPOSE_C_GENERAL);
|
||||
|
||||
if(time_to_new_circuit < now) {
|
||||
client_dns_clean();
|
||||
circuit_expire_unused_circuits();
|
||||
circuit_reset_failure_count();
|
||||
if(circ && circ->timestamp_dirty) {
|
||||
log_fn(LOG_INFO,"Youngest circuit dirty; launching replacement.");
|
||||
/* make a new circuit */
|
||||
circuit_launch_new(CIRCUIT_PURPOSE_C_GENERAL, NULL);
|
||||
} else if (options.RunTesting && circ &&
|
||||
time_to_new_circuit = now + options.NewCircuitPeriod;
|
||||
if(options.SocksPort)
|
||||
client_dns_clean();
|
||||
circuit_expire_old_circuits();
|
||||
|
||||
if(options.RunTesting && circ &&
|
||||
circ->timestamp_created + TESTING_CIRCUIT_INTERVAL < now) {
|
||||
log_fn(LOG_INFO,"Creating a new testing circuit.");
|
||||
circuit_launch_new(CIRCUIT_PURPOSE_C_GENERAL, NULL);
|
||||
}
|
||||
time_to_new_circuit = now + options.NewCircuitPeriod;
|
||||
time_to_new_circuit = now + options.NewCircuitPeriod;
|
||||
}
|
||||
#define CIRCUIT_MIN_BUILDING 3
|
||||
if(!circ && circuit_count_building() < CIRCUIT_MIN_BUILDING) {
|
||||
/* if there's no open circ, and less than 3 are on the way,
|
||||
* go ahead and try another.
|
||||
*/
|
||||
|
||||
#define CIRCUIT_MIN_BUILDING_GENERAL 3
|
||||
/* if there's no open circ, and less than 3 are on the way,
|
||||
* go ahead and try another. */
|
||||
if(!circ && circuit_count_building(CIRCUIT_PURPOSE_C_GENERAL)
|
||||
< CIRCUIT_MIN_BUILDING_GENERAL) {
|
||||
circuit_launch_new(CIRCUIT_PURPOSE_C_GENERAL, NULL);
|
||||
}
|
||||
|
||||
/* XXX count idle rendezvous circs and build more */
|
||||
|
||||
}
|
||||
|
||||
/* update digest from the payload of cell. assign integrity part to cell. */
|
||||
@ -1142,7 +1163,7 @@ void circuit_dump_by_conn(connection_t *conn, int severity) {
|
||||
/* Don't keep more than 10 unused open circuits around. */
|
||||
#define MAX_UNUSED_OPEN_CIRCUITS 10
|
||||
|
||||
void circuit_expire_unused_circuits(void) {
|
||||
void circuit_expire_old_circuits(void) {
|
||||
circuit_t *circ;
|
||||
time_t now = time(NULL);
|
||||
smartlist_t *unused_open_circs;
|
||||
|
@ -297,9 +297,6 @@ void directory_has_arrived(void) {
|
||||
if(options.ORPort) { /* connect to them all */
|
||||
router_retry_connections();
|
||||
}
|
||||
|
||||
rend_services_init(); /* get bob to initialize all his hidden services */
|
||||
|
||||
}
|
||||
|
||||
/* Perform regular maintenance tasks for a single connection. This
|
||||
@ -366,7 +363,7 @@ static void run_scheduled_events(time_t now) {
|
||||
* We do this before step 3, so it can try building more if
|
||||
* it's not comfortable with the number of available circuits.
|
||||
*/
|
||||
circuit_expire_building();
|
||||
circuit_expire_building(now);
|
||||
|
||||
/* 2b. Also look at pending streams and prune the ones that 'began'
|
||||
* a long time ago but haven't gotten a 'connected' yet.
|
||||
@ -385,8 +382,7 @@ static void run_scheduled_events(time_t now) {
|
||||
* that became dirty more than NewCircuitPeriod seconds ago,
|
||||
* and we make a new circ if there are no clean circuits.
|
||||
*/
|
||||
if(has_fetched_directory &&
|
||||
(options.SocksPort || options.RunTesting))
|
||||
if(has_fetched_directory)
|
||||
circuit_build_needed_circs(now);
|
||||
|
||||
/* 4. We do housekeeping for each connection... */
|
||||
@ -522,10 +518,7 @@ static int do_hup(void) {
|
||||
}
|
||||
/* Since we aren't fetching a directory, we won't retry rendezvous points
|
||||
* when it gets in. Try again now. */
|
||||
if (rend_services_init()<0) {
|
||||
log_fn(LOG_ERR,"Error updating rendezvous services");
|
||||
return -1;
|
||||
}
|
||||
rend_services_init();
|
||||
} else {
|
||||
/* fetch a new directory */
|
||||
directory_initiate_command(router_pick_directory_server(),
|
||||
|
43
src/or/or.h
43
src/or/or.h
@ -202,8 +202,10 @@
|
||||
/* here's how circ client-side purposes work:
|
||||
* normal circuits are C_GENERAL.
|
||||
* circuits that are c_introducing are either on their way to
|
||||
* becoming open, or they are open but haven't been used yet.
|
||||
* (as soon as they are used, they are destroyed.)
|
||||
* becoming open, or they are open and waiting for a
|
||||
* suitable rendcirc before they send the intro.
|
||||
* circuits that are c_introduce_ack_wait have sent the intro,
|
||||
* but haven't gotten a response yet.
|
||||
* circuits that are c_establish_rend are either on their way
|
||||
* to becoming open, or they are open and have sent the
|
||||
* establish_rendezvous cell but haven't received an ack.
|
||||
@ -216,7 +218,7 @@
|
||||
*/
|
||||
#define CIRCUIT_PURPOSE_C_GENERAL 5 /* normal circuit, with cpath */
|
||||
#define CIRCUIT_PURPOSE_C_INTRODUCING 6 /* at Alice, connecting to intro point */
|
||||
#define CIRCUIT_PURPOSE_C_INTRODUCE_ACK_WAIT 7 /* at alice, sent INTRODUCE1 to intro point, waiting for ACK/NAK */
|
||||
#define CIRCUIT_PURPOSE_C_INTRODUCE_ACK_WAIT 7 /* at Alice, sent INTRODUCE1 to intro point, waiting for ACK/NAK */
|
||||
|
||||
#define CIRCUIT_PURPOSE_C_ESTABLISH_REND 8 /* at Alice, waiting for ack */
|
||||
#define CIRCUIT_PURPOSE_C_REND_READY 9 /* at Alice, waiting for Bob */
|
||||
@ -274,9 +276,6 @@
|
||||
|
||||
#define CELL_DIRECTION_IN 1
|
||||
#define CELL_DIRECTION_OUT 2
|
||||
//#define EDGE_EXIT CONN_TYPE_EXIT
|
||||
//#define EDGE_AP CONN_TYPE_AP
|
||||
//#define CELL_DIRECTION(x) ((x) == EDGE_EXIT ? CELL_DIRECTION_IN : CELL_DIRECTION_OUT)
|
||||
|
||||
#ifdef TOR_PERF
|
||||
#define CIRCWINDOW_START 10000
|
||||
@ -312,32 +311,6 @@
|
||||
* Relay payload [498 bytes]
|
||||
*/
|
||||
|
||||
#if 0
|
||||
#define CELL_RELAY_COMMAND(c) (*(uint8_t*)((c).payload))
|
||||
#define SET_CELL_RELAY_COMMAND(c,cmd) (*(uint8_t*)((c).payload) = (cmd))
|
||||
|
||||
#define CELL_RELAY_RECOGNIZED(c) (ntohs(*(uint16_t*)((c).payload+1)))
|
||||
#define SET_CELL_RELAY_RECOGNIZED(c,r) (*(uint16_t*)((c).payload+1) = htons(r))
|
||||
|
||||
#define STREAM_ID_SIZE 2
|
||||
//#define SET_CELL_STREAM_ID(c,id) memcpy((c).payload+1,(id),STREAM_ID_SIZE)
|
||||
#define CELL_RELAY_STREAM_ID(c) (ntohs(*(uint16_t*)((c).payload+3)))
|
||||
#define SET_CELL_RELAY_STREAM_ID(c,id) (*(uint16_t*)((c).payload+3) = htons(id))
|
||||
#define ZERO_STREAM 0
|
||||
|
||||
/* integrity is the first 32 bits (in network order) of a sha-1 of all
|
||||
* cell payloads that are relay cells that have been sent / delivered
|
||||
* to the hop on the * circuit (the integrity is zeroed while doing
|
||||
* each calculation)
|
||||
*/
|
||||
#define CELL_RELAY_INTEGRITY(c) (ntohl(*(uint32_t*)((c).payload+5)))
|
||||
#define SET_CELL_RELAY_INTEGRITY(c,i) (*(uint32_t*)((c).payload+5) = htonl(i))
|
||||
|
||||
/* relay length is how many bytes are used in the cell payload past relay_header_size */
|
||||
#define CELL_RELAY_LENGTH(c) (ntohs(*(uint16_t*)((c).payload+9)))
|
||||
#define SET_CELL_RELAY_LENGTH(c,len) (*(uint16_t*)((c).payload+9) = htons(len))
|
||||
#endif
|
||||
|
||||
#define CELL_PAYLOAD_SIZE 509
|
||||
#define CELL_NETWORK_SIZE 512
|
||||
|
||||
@ -716,8 +689,8 @@ circuit_t *circuit_get_next_by_pk_and_purpose(circuit_t *circuit,
|
||||
const char *servid, uint8_t purpose);
|
||||
circuit_t *circuit_get_rendezvous(const char *cookie);
|
||||
|
||||
void circuit_expire_building(void);
|
||||
int circuit_count_building(void);
|
||||
void circuit_expire_building(time_t now);
|
||||
int circuit_count_building(uint8_t purpose);
|
||||
int circuit_stream_is_being_handled(connection_t *conn);
|
||||
void circuit_build_needed_circs(time_t now);
|
||||
|
||||
@ -1110,7 +1083,7 @@ int rend_cache_store(char *desc, int desc_len);
|
||||
|
||||
int rend_config_services(or_options_t *options);
|
||||
int rend_service_init_keys(void);
|
||||
int rend_services_init(void);
|
||||
void rend_services_init(void);
|
||||
|
||||
void rend_service_intro_is_ready(circuit_t *circuit);
|
||||
int rend_service_intro_established(circuit_t *circuit, const char *request, int request_len);
|
||||
|
@ -156,7 +156,7 @@ rend_client_introduction_acked(circuit_t *circ,
|
||||
char *nickname;
|
||||
|
||||
if (circ->purpose != CIRCUIT_PURPOSE_C_INTRODUCE_ACK_WAIT) {
|
||||
log_fn(LOG_WARN, "Recieved REND_INTRODUCE_ACK on unexpected circuit %d",
|
||||
log_fn(LOG_WARN, "Received REND_INTRODUCE_ACK on unexpected circuit %d",
|
||||
circ->n_circ_id);
|
||||
circuit_mark_for_close(circ);
|
||||
return -1;
|
||||
|
@ -662,7 +662,7 @@ find_intro_circuit(routerinfo_t *router, const char *pk_digest)
|
||||
* - Launch circuits to any new intro points.
|
||||
* - Upload a fresh service descriptor if anything has changed.
|
||||
*/
|
||||
int rend_services_init(void) {
|
||||
void rend_services_init(void) {
|
||||
int i,j,r;
|
||||
routerinfo_t *router;
|
||||
routerlist_t *rl;
|
||||
@ -759,8 +759,6 @@ int rend_services_init(void) {
|
||||
}
|
||||
smartlist_free(intro_routers);
|
||||
smartlist_free(exclude_routers);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
|
Loading…
Reference in New Issue
Block a user