mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-12-06 19:41:15 +01:00
bugfix: don't ask for ->next of an expired circuit
bugfix: keep going when a circ fails in circuit_n_conn_open
(make circuit_enumerate_by_naddr_nport obsolete)
bugfix: make circuit_n_conn_open only look at circ's that start at us
bugfix: only try circuit_n_conn_open if we're an OP. Otherwise we
expect connections to always already be up.
bugfix: when choosing path length, pay attention to whether the directory
says a router is down.
bugfix: when picking good exit, skip routers which are known to be down
(more work needs to be done on this one)
svn:r838
This commit is contained in:
+24
-39
@@ -141,20 +141,6 @@ static circ_id_t get_unique_circ_id_by_conn(connection_t *conn, int circ_id_type
|
||||
return test_circ_id;
|
||||
}
|
||||
|
||||
circuit_t *circuit_enumerate_by_naddr_nport(circuit_t *circ, uint32_t naddr, uint16_t nport) {
|
||||
|
||||
if(!circ) /* use circ if it's defined, else start from the beginning */
|
||||
circ = global_circuitlist;
|
||||
else
|
||||
circ = circ->next;
|
||||
|
||||
for( ; circ; circ = circ->next) {
|
||||
if(circ->n_addr == naddr && circ->n_port == nport)
|
||||
return circ;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
circuit_t *circuit_get_by_circ_id_conn(circ_id_t circ_id, connection_t *conn) {
|
||||
circuit_t *circ;
|
||||
connection_t *tmpconn;
|
||||
@@ -258,21 +244,23 @@ circuit_t *circuit_get_newest(connection_t *conn, int must_be_open) {
|
||||
/* 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) {
|
||||
circuit_t *circ;
|
||||
int now = time(NULL);
|
||||
circuit_t *victim, *circ = global_circuitlist;
|
||||
|
||||
for(circ=global_circuitlist;circ;circ = circ->next) {
|
||||
if(circ->cpath &&
|
||||
circ->state != CIRCUIT_STATE_OPEN &&
|
||||
circ->timestamp_created + MIN_SECONDS_BEFORE_EXPIRING_CIRC+1 < now) {
|
||||
if(circ->n_conn)
|
||||
while(circ) {
|
||||
victim = circ;
|
||||
circ = circ->next;
|
||||
if(victim->cpath &&
|
||||
victim->state != CIRCUIT_STATE_OPEN &&
|
||||
victim->timestamp_created + MIN_SECONDS_BEFORE_EXPIRING_CIRC+1 < now) {
|
||||
if(victim->n_conn)
|
||||
log_fn(LOG_INFO,"Abandoning circ %s:%d:%d (state %d:%s)",
|
||||
circ->n_conn->address, circ->n_port, circ->n_circ_id,
|
||||
circ->state, circuit_state_to_string[circ->state]);
|
||||
victim->n_conn->address, victim->n_port, victim->n_circ_id,
|
||||
victim->state, circuit_state_to_string[victim->state]);
|
||||
else
|
||||
log_fn(LOG_INFO,"Abandoning circ %d (state %d:%s)", circ->n_circ_id,
|
||||
circ->state, circuit_state_to_string[circ->state]);
|
||||
circuit_close(circ);
|
||||
log_fn(LOG_INFO,"Abandoning circ %d (state %d:%s)", victim->n_circ_id,
|
||||
victim->state, circuit_state_to_string[victim->state]);
|
||||
circuit_close(victim);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -793,21 +781,18 @@ int circuit_establish_circuit(void) {
|
||||
void circuit_n_conn_open(connection_t *or_conn) {
|
||||
circuit_t *circ;
|
||||
|
||||
log_fn(LOG_DEBUG,"Starting.");
|
||||
circ = circuit_enumerate_by_naddr_nport(NULL, or_conn->addr, or_conn->port);
|
||||
for(;;) {
|
||||
if(!circ)
|
||||
return;
|
||||
|
||||
assert(circ->state == CIRCUIT_STATE_OR_WAIT);
|
||||
log_fn(LOG_DEBUG,"Found circ, sending onion skin.");
|
||||
circ->n_conn = or_conn;
|
||||
if(circuit_send_next_onion_skin(circ) < 0) {
|
||||
log_fn(LOG_INFO,"send_next_onion_skin failed; circuit marked for closing.");
|
||||
circuit_close(circ);
|
||||
return; /* FIXME will want to try the other circuits too? */
|
||||
for(circ=global_circuitlist;circ;circ = circ->next) {
|
||||
if(circ->cpath && circ->n_addr == or_conn->addr && circ->n_port == or_conn->port) {
|
||||
assert(circ->state == CIRCUIT_STATE_OR_WAIT);
|
||||
log_fn(LOG_DEBUG,"Found circ %d, sending onion skin.", circ->n_circ_id);
|
||||
circ->n_conn = or_conn;
|
||||
if(circuit_send_next_onion_skin(circ) < 0) {
|
||||
log_fn(LOG_INFO,"send_next_onion_skin failed; circuit marked for closing.");
|
||||
circuit_close(circ);
|
||||
continue;
|
||||
/* XXX could this be bad, eg if next_onion_skin failed because conn died? */
|
||||
}
|
||||
}
|
||||
circ = circuit_enumerate_by_naddr_nport(circ, or_conn->addr, or_conn->port);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -203,8 +203,8 @@ static int connection_tls_finish_handshake(connection_t *conn) {
|
||||
log_fn(LOG_DEBUG, "Other side claims to be '%s'", nickname);
|
||||
pk = tor_tls_verify(conn->tls);
|
||||
if(!pk) {
|
||||
log_fn(LOG_WARN,"Other side (%s:%d) has a cert but it's invalid. Closing.",
|
||||
conn->address, conn->port);
|
||||
log_fn(LOG_WARN,"Other side '%s' (%s:%d) has a cert but it's invalid. Closing.",
|
||||
nickname, conn->address, conn->port);
|
||||
return -1;
|
||||
}
|
||||
router = router_get_by_link_pk(pk);
|
||||
@@ -230,7 +230,7 @@ static int connection_tls_finish_handshake(connection_t *conn) {
|
||||
}
|
||||
connection_or_init_conn_from_router(conn, router);
|
||||
crypto_free_pk_env(pk);
|
||||
}
|
||||
}
|
||||
if (strcmp(conn->nickname, nickname)) {
|
||||
log_fn(LOG_WARN,"Other side claims to be '%s', but we wanted '%s'",
|
||||
nickname, conn->nickname);
|
||||
@@ -239,8 +239,8 @@ static int connection_tls_finish_handshake(connection_t *conn) {
|
||||
if (!options.OnionRouter) {
|
||||
/* If I'm an OP... */
|
||||
conn->receiver_bucket = conn->bandwidth = DEFAULT_BANDWIDTH_OP;
|
||||
circuit_n_conn_open(conn); /* send the pending creates, if any. */
|
||||
}
|
||||
circuit_n_conn_open(conn); /* send the pending creates, if any. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -363,9 +363,9 @@ static void run_scheduled_events(time_t now) {
|
||||
}
|
||||
time_to_new_circuit = now + options.NewCircuitPeriod;
|
||||
}
|
||||
#define CIRCUIT_MIN_BUILDING 3
|
||||
#define CIRCUIT_MIN_BUILDING 2
|
||||
if(!circ && circuit_count_building() < CIRCUIT_MIN_BUILDING)
|
||||
/* if there's no open circ, and less than 3 are on the way,
|
||||
/* if there's no open circ, and less than 2 are on the way,
|
||||
* go ahead and try another.
|
||||
*/
|
||||
circuit_launch_new(1);
|
||||
|
||||
+11
-2
@@ -254,15 +254,17 @@ static routerinfo_t *choose_good_exit_server(directory_t *dir)
|
||||
n_maybe_supported = tor_malloc(sizeof(int)*dir->n_routers);
|
||||
for (i = 0; i < dir->n_routers; ++i) { /* iterate over routers */
|
||||
n_supported[i] = n_maybe_supported[i] = 0;
|
||||
if(!dir->routers[i]->is_running)
|
||||
continue; /* skip routers which are known to be down */
|
||||
for (j = 0; j < n_connections; ++j) { /* iterate over connections */
|
||||
if (carray[j]->type != CONN_TYPE_AP ||
|
||||
carray[j]->state == AP_CONN_STATE_CIRCUIT_WAIT ||
|
||||
carray[j]->marked_for_close)
|
||||
continue; /* Skip everything by open APs in CIRCUIT_WAIT */
|
||||
continue; /* Skip everything but APs in CIRCUIT_WAIT */
|
||||
switch (connection_ap_can_use_exit(carray[j], dir->routers[i]))
|
||||
{
|
||||
case -1:
|
||||
break;
|
||||
break; /* would be rejected; try next connection */
|
||||
case 0:
|
||||
++n_supported[i];
|
||||
; /* Fall through: If it is supported, it is also maybe supported. */
|
||||
@@ -308,6 +310,7 @@ static routerinfo_t *choose_good_exit_server(directory_t *dir)
|
||||
}
|
||||
}
|
||||
/* This point should never be reached. */
|
||||
assert(0);
|
||||
}
|
||||
/* If any routers _maybe_ support pending connections, choose one at
|
||||
* random, as above. */
|
||||
@@ -324,9 +327,11 @@ static routerinfo_t *choose_good_exit_server(directory_t *dir)
|
||||
}
|
||||
}
|
||||
/* This point should never be reached. */
|
||||
assert(0);
|
||||
}
|
||||
/* Either there are no pending connections, or no routers even seem to
|
||||
* possibly support any of them. Choose a router at random. */
|
||||
/* XXX should change to not choose non-running routers */
|
||||
tor_free(n_supported); tor_free(n_maybe_supported);
|
||||
i = crypto_pseudo_rand_int(dir->n_routers);
|
||||
log_fn(LOG_DEBUG, "Chose exit server '%s'", dir->routers[i]->nickname);
|
||||
@@ -355,6 +360,10 @@ static int count_acceptable_routers(routerinfo_t **rarray, int rarray_len) {
|
||||
|
||||
for(i=0;i<rarray_len;i++) {
|
||||
log_fn(LOG_DEBUG,"Contemplating whether router %d is a new option...",i);
|
||||
if(rarray[i]->is_running == 0) {
|
||||
log_fn(LOG_DEBUG,"Nope, the directory says %d is not running.",i);
|
||||
goto next_i_loop;
|
||||
}
|
||||
if(options.OnionRouter) {
|
||||
conn = connection_exact_get_by_addr_port(rarray[i]->addr, rarray[i]->or_port);
|
||||
if(!conn || conn->type != CONN_TYPE_OR || conn->state != OR_CONN_STATE_OPEN) {
|
||||
|
||||
@@ -512,7 +512,6 @@ circuit_t *circuit_new(circ_id_t p_circ_id, connection_t *p_conn);
|
||||
void circuit_free(circuit_t *circ);
|
||||
void circuit_free_cpath(crypt_path_t *cpath);
|
||||
|
||||
circuit_t *circuit_enumerate_by_naddr_nport(circuit_t *start, uint32_t naddr, uint16_t nport);
|
||||
circuit_t *circuit_get_by_circ_id_conn(circ_id_t circ_id, connection_t *conn);
|
||||
circuit_t *circuit_get_by_conn(connection_t *conn);
|
||||
circuit_t *circuit_get_newest(connection_t *conn, int must_be_open);
|
||||
|
||||
Reference in New Issue
Block a user