diff options
-rw-r--r-- | src/or/circuit.c | 83 | ||||
-rw-r--r-- | src/or/main.c | 13 | ||||
-rw-r--r-- | src/or/or.h | 43 | ||||
-rw-r--r-- | src/or/rendclient.c | 2 | ||||
-rw-r--r-- | src/or/rendservice.c | 4 |
5 files changed, 65 insertions, 80 deletions
diff --git a/src/or/circuit.c b/src/or/circuit.c index ca9c503aa1..7b51905329 100644 --- a/src/or/circuit.c +++ b/src/or/circuit.c @@ -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; diff --git a/src/or/main.c b/src/or/main.c index 88faede1fa..ee7070acd9 100644 --- a/src/or/main.c +++ b/src/or/main.c @@ -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(), diff --git a/src/or/or.h b/src/or/or.h index d5390022fb..9f85af996a 100644 --- a/src/or/or.h +++ b/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); diff --git a/src/or/rendclient.c b/src/or/rendclient.c index 0f2dfa15c9..27d6fd5f1b 100644 --- a/src/or/rendclient.c +++ b/src/or/rendclient.c @@ -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; diff --git a/src/or/rendservice.c b/src/or/rendservice.c index 793d6d44cb..608a19773b 100644 --- a/src/or/rendservice.c +++ b/src/or/rendservice.c @@ -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 |