mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-14 07:03:44 +01:00
Implemented router twins
I modified new_route so we don't pick twins back-to-back in the path. I also had to patch my previous uses of connection_twin_get_by_addr_port() because they assumed that "addr" and "port" would be the same for a twin as for the original router. svn:r56
This commit is contained in:
parent
0a8d58138d
commit
2147898577
@ -287,14 +287,14 @@ int circuit_crypt(circuit_t *circ, char *in, size_t inlen, char crypt_type) {
|
|||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if(crypt_type == 'e') {
|
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. */
|
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. */
|
/* 'e' means we're preparing to send it out. */
|
||||||
for (i=0; i < circ->cpathlen; i++) /* moving from last to first hop
|
for (i=0; i < circ->cpathlen; i++) /* moving from last to first hop
|
||||||
* Remember : cpath is in reverse order, i.e. last hop first
|
* 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];
|
thishop = circ->cpath[i];
|
||||||
|
|
||||||
/* encrypt */
|
/* encrypt */
|
||||||
@ -317,13 +317,13 @@ int circuit_crypt(circuit_t *circ, char *in, size_t inlen, char crypt_type) {
|
|||||||
memcpy(in,out,inlen);
|
memcpy(in,out,inlen);
|
||||||
}
|
}
|
||||||
} else if(crypt_type == 'd') {
|
} 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. */
|
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
|
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
|
* 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];
|
thishop = circ->cpath[i];
|
||||||
|
|
||||||
/* encrypt */
|
/* encrypt */
|
||||||
|
@ -111,6 +111,10 @@ void command_process_create_cell(cell_t *cell, connection_t *conn) {
|
|||||||
circuit_close(circ);
|
circuit_close(circ);
|
||||||
return;
|
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;
|
circ->n_conn = n_conn;
|
||||||
log(LOG_DEBUG,"command_process_create_cell(): n_conn is %s:%u",n_conn->address,ntohs(n_conn->port));
|
log(LOG_DEBUG,"command_process_create_cell(): n_conn is %s:%u",n_conn->address,ntohs(n_conn->port));
|
||||||
|
|
||||||
|
@ -195,8 +195,6 @@ int ap_handshake_establish_circuit(connection_t *conn, unsigned int *route, int
|
|||||||
free(route); /* we don't need it anymore */
|
free(route); /* we don't need it anymore */
|
||||||
|
|
||||||
circ = circuit_new(0, conn); /* sets circ->p_aci and circ->p_conn */
|
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->state = CIRCUIT_STATE_OR_WAIT;
|
||||||
circ->onion = onion;
|
circ->onion = onion;
|
||||||
circ->onionlen = onionlen;
|
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));
|
firsthop->address,ntohs(firsthop->or_port));
|
||||||
n_conn = connection_twin_get_by_addr_port(firsthop->addr,firsthop->or_port);
|
n_conn = connection_twin_get_by_addr_port(firsthop->addr,firsthop->or_port);
|
||||||
if(!n_conn) { /* not currently connected */
|
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. */
|
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.");
|
log(LOG_DEBUG,"ap_handshake_establish_circuit(): Route's firsthop isn't connected.");
|
||||||
circuit_close(circ);
|
circuit_close(circ);
|
||||||
@ -221,11 +221,13 @@ int ap_handshake_establish_circuit(connection_t *conn, unsigned int *route, int
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
conn->state = AP_CONN_STATE_OR_WAIT;
|
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
|
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.
|
* (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);
|
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.");
|
log(LOG_DEBUG,"ap_handshake_n_conn_open(): Starting.");
|
||||||
circ = circuit_get_by_naddr_nport(or_conn->addr, or_conn->port);
|
circ = circuit_get_by_naddr_nport(or_conn->addr, or_conn->port);
|
||||||
if(!circ)
|
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) {
|
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.");
|
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.");
|
log(LOG_DEBUG,"ap_handshake_n_conn_open(): Found circ, sending onion.");
|
||||||
return ap_handshake_send_onion(circ->p_conn, or_conn, circ);
|
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
|
/* now we want to give the AP a "0" byte, because it wants to hear
|
||||||
* back from us */
|
* 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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -91,6 +91,22 @@ int connection_remove(connection_t *conn) {
|
|||||||
return 0;
|
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) {
|
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,
|
/* Find a connection to the router described by addr and port,
|
||||||
* or alternately any router which knows its key.
|
* 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;
|
int i;
|
||||||
connection_t *conn;
|
connection_t *conn;
|
||||||
|
routerinfo_t *router;
|
||||||
|
|
||||||
/* first check if it's there exactly */
|
/* first check if it's there exactly */
|
||||||
conn = connection_exact_get_by_addr_port(addr,port);
|
conn = connection_exact_get_by_addr_port(addr,port);
|
||||||
if(conn && connection_state_is_open(conn)) {
|
if(conn && connection_state_is_open(conn)) {
|
||||||
|
log(LOG_DEBUG,"connection_twin_get_by_addr_port(): Found exact match.");
|
||||||
return conn;
|
return conn;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* now check if any of the other open connections are a twin for this one */
|
/* 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 */
|
/* guess not */
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -131,9 +131,9 @@ unsigned int *new_route(double cw, routerinfo_t **rarray, size_t rarray_len, siz
|
|||||||
|
|
||||||
choice = choice % (rarray_len);
|
choice = choice % (rarray_len);
|
||||||
log(LOG_DEBUG,"new_route() : Chosen router %u.",choice);
|
log(LOG_DEBUG,"new_route() : Chosen router %u.",choice);
|
||||||
if (choice == oldchoice) /* same router */
|
if (choice == oldchoice ||
|
||||||
{
|
(oldchoice < rarray_len && !pkey_cmp(rarray[choice]->pkey, rarray[oldchoice]->pkey))) {
|
||||||
/* try again */
|
/* same router, or router twin. try again. */
|
||||||
i--;
|
i--;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -509,6 +509,7 @@ int connection_add(connection_t *conn);
|
|||||||
int connection_remove(connection_t *conn);
|
int connection_remove(connection_t *conn);
|
||||||
void connection_set_poll_socket(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_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);
|
connection_t *connection_exact_get_by_addr_port(uint32_t addr, uint16_t port);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user