diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/or/circuit.c | 8 | ||||
-rw-r--r-- | src/or/command.c | 4 | ||||
-rw-r--r-- | src/or/connection_ap.c | 16 | ||||
-rw-r--r-- | src/or/main.c | 31 | ||||
-rw-r--r-- | src/or/onion.c | 6 | ||||
-rw-r--r-- | src/or/or.h | 1 |
6 files changed, 51 insertions, 15 deletions
diff --git a/src/or/circuit.c b/src/or/circuit.c index c2c91338c..2758c13d2 100644 --- a/src/or/circuit.c +++ b/src/or/circuit.c @@ -287,14 +287,14 @@ int circuit_crypt(circuit_t *circ, char *in, size_t inlen, char crypt_type) { return -1; if(crypt_type == 'e') { - log(LOG_DEBUG,"circuit_crypt(): Encrypting %d bytes.",inlen); +// log(LOG_DEBUG,"circuit_crypt(): Encrypting %d bytes.",inlen); if(circ->cpath) { /* we're at the beginning of the circuit. We'll want to do layered crypts. */ /* 'e' means we're preparing to send it out. */ for (i=0; i < circ->cpathlen; i++) /* moving from last to first hop * Remember : cpath is in reverse order, i.e. last hop first */ { - log(LOG_DEBUG,"circuit_crypt() : Encrypting via cpath: Processing hop %u",circ->cpathlen-i); +// log(LOG_DEBUG,"circuit_crypt() : Encrypting via cpath: Processing hop %u",circ->cpathlen-i); thishop = circ->cpath[i]; /* encrypt */ @@ -317,13 +317,13 @@ int circuit_crypt(circuit_t *circ, char *in, size_t inlen, char crypt_type) { memcpy(in,out,inlen); } } else if(crypt_type == 'd') { - log(LOG_DEBUG,"circuit_crypt(): Decrypting %d bytes.",inlen); +// log(LOG_DEBUG,"circuit_crypt(): Decrypting %d bytes.",inlen); if(circ->cpath) { /* we're at the beginning of the circuit. We'll want to do layered crypts. */ for (i=circ->cpathlen-1; i >= 0; i--) /* moving from first to last hop * Remember : cpath is in reverse order, i.e. last hop first */ { - log(LOG_DEBUG,"circuit_crypt() : Decrypting via cpath: Processing hop %u",circ->cpathlen-i); +// log(LOG_DEBUG,"circuit_crypt() : Decrypting via cpath: Processing hop %u",circ->cpathlen-i); thishop = circ->cpath[i]; /* encrypt */ diff --git a/src/or/command.c b/src/or/command.c index 5a1ad4155..31459ee24 100644 --- a/src/or/command.c +++ b/src/or/command.c @@ -111,6 +111,10 @@ void command_process_create_cell(cell_t *cell, connection_t *conn) { circuit_close(circ); return; } + + circ->n_addr = n_conn->addr; /* these are different if we found a twin instead */ + circ->n_port = n_conn->port; + circ->n_conn = n_conn; log(LOG_DEBUG,"command_process_create_cell(): n_conn is %s:%u",n_conn->address,ntohs(n_conn->port)); diff --git a/src/or/connection_ap.c b/src/or/connection_ap.c index ce4fdcd89..a25e3d7f4 100644 --- a/src/or/connection_ap.c +++ b/src/or/connection_ap.c @@ -195,8 +195,6 @@ int ap_handshake_establish_circuit(connection_t *conn, unsigned int *route, int free(route); /* we don't need it anymore */ circ = circuit_new(0, conn); /* sets circ->p_aci and circ->p_conn */ - circ->n_addr = firsthop->addr; - circ->n_port = firsthop->or_port; circ->state = CIRCUIT_STATE_OR_WAIT; circ->onion = onion; circ->onionlen = onionlen; @@ -207,6 +205,8 @@ int ap_handshake_establish_circuit(connection_t *conn, unsigned int *route, int firsthop->address,ntohs(firsthop->or_port)); n_conn = connection_twin_get_by_addr_port(firsthop->addr,firsthop->or_port); if(!n_conn) { /* not currently connected */ + circ->n_addr = firsthop->addr; + circ->n_port = firsthop->or_port; if(global_role & ROLE_OR_CONNECT_ALL) { /* we would be connected if he were up. but he's not. */ log(LOG_DEBUG,"ap_handshake_establish_circuit(): Route's firsthop isn't connected."); circuit_close(circ); @@ -221,11 +221,13 @@ int ap_handshake_establish_circuit(connection_t *conn, unsigned int *route, int return -1; } conn->state = AP_CONN_STATE_OR_WAIT; - connection_watch_events(conn, 0); /* Stop listening for input from the AP! */ + connection_stop_reading(conn); /* Stop listening for input from the AP! */ return 0; /* return success. The onion/circuit/etc will be taken care of automatically * (may already have been) whenever n_conn reaches OR_CONN_STATE_OPEN. */ - } else { /* it's already open. use it. */ + } else { /* it (or a twin) is already open. use it. */ + circ->n_addr = n_conn->addr; + circ->n_port = n_conn->port; return ap_handshake_send_onion(conn, n_conn, circ); } } @@ -237,12 +239,12 @@ int ap_handshake_n_conn_open(connection_t *or_conn) { log(LOG_DEBUG,"ap_handshake_n_conn_open(): Starting."); circ = circuit_get_by_naddr_nport(or_conn->addr, or_conn->port); if(!circ) - return 0; /* i'm ok with that */ + return 0; /* i'm ok with that. no need to close the connection or anything. */ if(circ->p_conn->state != AP_CONN_STATE_OR_WAIT) { log(LOG_DEBUG,"Bug: ap_handshake_n_conn_open() got an ap_conn not in OR_WAIT state."); } - connection_watch_events(or_conn, POLLIN); /* resume listening for reads */ + connection_start_reading(circ->p_conn); /* resume listening for reads */ log(LOG_DEBUG,"ap_handshake_n_conn_open(): Found circ, sending onion."); return ap_handshake_send_onion(circ->p_conn, or_conn, circ); } @@ -332,7 +334,7 @@ int ap_handshake_send_onion(connection_t *ap_conn, connection_t *n_conn, circuit /* now we want to give the AP a "0" byte, because it wants to hear * back from us */ - connection_write_to_buf(&zero, 1, ap_conn); + connection_write_to_buf(&zero, 1, ap_conn); /* this does connection_start_writing() too */ return 0; } diff --git a/src/or/main.c b/src/or/main.c index f5940c47d..c96cf3930 100644 --- a/src/or/main.c +++ b/src/or/main.c @@ -91,6 +91,22 @@ int connection_remove(connection_t *conn) { return 0; } +int pkey_cmp(RSA *a, RSA *b) { + /* return 0 if a and b are "the same key". Return non-0 otherwise. */ + + int result; + + if(!a || !b) + return -1; + + assert(a->n && a->e && b->n && b->e); + + result = BN_cmp(a->n, b->n); + if(result) + return result; + return BN_cmp(a->e, b->e); +} + connection_t *connection_twin_get_by_addr_port(uint32_t addr, uint16_t port) { /* Find a connection to the router described by addr and port, * or alternately any router which knows its key. @@ -99,16 +115,29 @@ connection_t *connection_twin_get_by_addr_port(uint32_t addr, uint16_t port) { */ int i; connection_t *conn; + routerinfo_t *router; /* first check if it's there exactly */ conn = connection_exact_get_by_addr_port(addr,port); if(conn && connection_state_is_open(conn)) { + log(LOG_DEBUG,"connection_twin_get_by_addr_port(): Found exact match."); return conn; } /* now check if any of the other open connections are a twin for this one */ - /* XXX */ + router = router_get_by_addr_port(addr,port); + if(!router) + return NULL; + + for(i=0;i<nfds;i++) { + conn = connection_array[i]; + assert(conn); + if(connection_state_is_open(conn) && !pkey_cmp(conn->pkey, router->pkey)) { + log(LOG_DEBUG,"connection_twin_get_by_addr_port(): Found twin (%s).",conn->address); + return conn; + } + } /* guess not */ return NULL; diff --git a/src/or/onion.c b/src/or/onion.c index 506eb25e9..52ef72f40 100644 --- a/src/or/onion.c +++ b/src/or/onion.c @@ -131,9 +131,9 @@ unsigned int *new_route(double cw, routerinfo_t **rarray, size_t rarray_len, siz choice = choice % (rarray_len); log(LOG_DEBUG,"new_route() : Chosen router %u.",choice); - if (choice == oldchoice) /* same router */ - { - /* try again */ + if (choice == oldchoice || + (oldchoice < rarray_len && !pkey_cmp(rarray[choice]->pkey, rarray[oldchoice]->pkey))) { + /* same router, or router twin. try again. */ i--; continue; } diff --git a/src/or/or.h b/src/or/or.h index a72f0d88b..c4fddbf35 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -509,6 +509,7 @@ int connection_add(connection_t *conn); int connection_remove(connection_t *conn); void connection_set_poll_socket(connection_t *conn); +int pkey_cmp(RSA *a, RSA *b); connection_t *connection_twin_get_by_addr_port(uint32_t addr, uint16_t port); connection_t *connection_exact_get_by_addr_port(uint32_t addr, uint16_t port); |