mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-10 13:13:44 +01:00
recognize in-progress circs and don't start redundant ones
quickly notice streams that don't have a circ on the way, and start one svn:r819
This commit is contained in:
parent
5e81e4748e
commit
4aede010b9
@ -207,28 +207,37 @@ circuit_t *circuit_get_by_conn(connection_t *conn) {
|
||||
|
||||
/* Find the newest circ that conn can use, preferably one which is
|
||||
* dirty and not too old.
|
||||
* If !conn, return newest open.
|
||||
* If !conn, return newest.
|
||||
*
|
||||
* If must_be_open, ignore circs not in CIRCUIT_STATE_OPEN.
|
||||
*/
|
||||
circuit_t *circuit_get_newest_open(connection_t *conn) {
|
||||
circuit_t *circuit_get_newest(connection_t *conn, int must_be_open) {
|
||||
circuit_t *circ, *newest=NULL, *leastdirty=NULL;
|
||||
routerinfo_t *exitrouter;
|
||||
|
||||
for(circ=global_circuitlist;circ;circ = circ->next) {
|
||||
if(conn && connection_ap_can_use_exit(conn,
|
||||
router_get_by_addr_port(circ->cpath->prev->addr, circ->cpath->prev->port)) < 0) {
|
||||
log_fn(LOG_DEBUG,"Skipping %s:%d:%d because we couldn't exit there.",
|
||||
circ->n_conn->address, circ->n_port, circ->n_circ_id);
|
||||
continue;
|
||||
if(!circ->cpath)
|
||||
continue; /* this circ doesn't start at us */
|
||||
if(must_be_open && (circ->state != CIRCUIT_STATE_OPEN || !circ->n_conn))
|
||||
continue; /* ignore non-open circs */
|
||||
if(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 */
|
||||
exitrouter = router_get_by_nickname(circ->build_state->chosen_exit);
|
||||
if(!exitrouter || connection_ap_can_use_exit(conn, exitrouter) < 0) {
|
||||
/* can't exit from this router */
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if(circ->cpath && circ->state == CIRCUIT_STATE_OPEN && circ->n_conn) {
|
||||
if(!newest || newest->timestamp_created < circ->timestamp_created) {
|
||||
assert(circ->n_circ_id);
|
||||
newest = circ;
|
||||
}
|
||||
if(conn && circ->timestamp_dirty &&
|
||||
(!leastdirty || leastdirty->timestamp_dirty < circ->timestamp_dirty)) {
|
||||
assert(circ->n_circ_id);
|
||||
leastdirty = circ;
|
||||
}
|
||||
if(!newest || newest->timestamp_created < circ->timestamp_created) {
|
||||
assert(circ->n_circ_id);
|
||||
newest = circ;
|
||||
}
|
||||
if(conn && circ->timestamp_dirty &&
|
||||
(!leastdirty || leastdirty->timestamp_dirty < circ->timestamp_dirty)) {
|
||||
assert(circ->n_circ_id);
|
||||
leastdirty = circ;
|
||||
}
|
||||
}
|
||||
|
||||
@ -743,6 +752,7 @@ void circuit_n_conn_open(connection_t *or_conn) {
|
||||
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) {
|
||||
|
@ -481,7 +481,6 @@ void connection_ap_attach_pending(void)
|
||||
{
|
||||
connection_t **carray;
|
||||
int n, i;
|
||||
int need_new_circuit = 0;
|
||||
|
||||
get_connection_array(&carray, &n);
|
||||
|
||||
@ -490,11 +489,12 @@ void connection_ap_attach_pending(void)
|
||||
carray[i]->type != AP_CONN_STATE_CIRCUIT_WAIT)
|
||||
continue;
|
||||
if (connection_ap_handshake_attach_circuit(carray[i])<0) {
|
||||
need_new_circuit = 1;
|
||||
if(!circuit_get_newest(carray[i], 0)) {
|
||||
/* if there are no acceptable clean or not-very-dirty circs on the way */
|
||||
circuit_launch_new(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(need_new_circuit)
|
||||
circuit_launch_new(1);
|
||||
}
|
||||
|
||||
static void connection_edge_consider_sending_sendme(connection_t *conn) {
|
||||
@ -549,9 +549,8 @@ static int connection_ap_handshake_process_socks(connection_t *conn) {
|
||||
} /* else socks handshake is done, continue processing */
|
||||
|
||||
conn->state = AP_CONN_STATE_CIRCUIT_WAIT;
|
||||
if (connection_ap_handshake_attach_circuit(conn)<0) {
|
||||
circuit_launch_new(1);
|
||||
}
|
||||
if(connection_ap_handshake_attach_circuit(conn) < 0)
|
||||
circuit_launch_new(1); /* Build another circuit to handle this stream */
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -569,7 +568,7 @@ static int connection_ap_handshake_attach_circuit(connection_t *conn) {
|
||||
assert(conn->socks_request);
|
||||
|
||||
/* find the circuit that we should use, if there is one. */
|
||||
circ = circuit_get_newest_open(conn);
|
||||
circ = circuit_get_newest(conn, 1);
|
||||
|
||||
if(!circ) {
|
||||
log_fn(LOG_INFO,"No safe circuit ready for edge connection; delaying.");
|
||||
|
@ -341,7 +341,11 @@ static void run_scheduled_events(time_t now) {
|
||||
* and we make a new circ if there are no clean circuits.
|
||||
*/
|
||||
if(options.SocksPort) {
|
||||
circ = circuit_get_newest_open(NULL);
|
||||
|
||||
/* launch a new circ for any pending streams that need one */
|
||||
connection_ap_attach_pending();
|
||||
|
||||
circ = circuit_get_newest(NULL, 1);
|
||||
if(time_to_new_circuit < now) {
|
||||
client_dns_clean();
|
||||
circuit_expire_unused_circuits();
|
||||
@ -352,12 +356,8 @@ static void run_scheduled_events(time_t now) {
|
||||
}
|
||||
time_to_new_circuit = now + options.NewCircuitPeriod;
|
||||
}
|
||||
if(!circ) {
|
||||
if(!circ)
|
||||
circuit_launch_new(1);
|
||||
}
|
||||
/* XXX also check if we have any circuit_pending streams and we're not
|
||||
* currently building a circuit for them.
|
||||
*/
|
||||
}
|
||||
|
||||
/* 3. Every second, we check how much bandwidth we've consumed and
|
||||
|
@ -187,6 +187,7 @@
|
||||
#define RELAY_COMMAND_EXTENDED 7
|
||||
#define RELAY_COMMAND_TRUNCATE 8
|
||||
#define RELAY_COMMAND_TRUNCATED 9
|
||||
#define RELAY_COMMAND_DROP 10
|
||||
|
||||
#define RELAY_HEADER_SIZE 8
|
||||
|
||||
@ -515,7 +516,7 @@ 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_open(connection_t *conn);
|
||||
circuit_t *circuit_get_newest(connection_t *conn, int must_be_open);
|
||||
|
||||
int circuit_deliver_relay_cell(cell_t *cell, circuit_t *circ,
|
||||
int cell_direction, crypt_path_t *layer_hint);
|
||||
|
Loading…
Reference in New Issue
Block a user