From a9813f0210bbf723e19b24c73fb93ecc436efcfb Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Sat, 3 Apr 2004 04:55:22 +0000 Subject: [PATCH] Implement acks svn:r1470 --- src/or/connection_edge.c | 2 ++ src/or/or.h | 19 +++++++---- src/or/rendcommon.c | 7 ++++ src/or/rendmid.c | 16 ++++++++++ src/or/rendservice.c | 69 ++++++++++++++++++++++++++++------------ 5 files changed, 86 insertions(+), 27 deletions(-) diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c index 206f5dae7d..04bf1794f0 100644 --- a/src/or/connection_edge.c +++ b/src/or/connection_edge.c @@ -439,6 +439,8 @@ int connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ, case RELAY_COMMAND_INTRODUCE2: case RELAY_COMMAND_RENDEZVOUS1: case RELAY_COMMAND_RENDEZVOUS2: + case RELAY_COMMAND_INTRO_ESTABLISHED: + case RELAY_COMMAND_RENDEZVOUS_ESTABLISHED: rend_process_relay_cell(circ, rh.command, rh.length, cell->payload+RELAY_HEADER_SIZE); return 0; diff --git a/src/or/or.h b/src/or/or.h index ed82140344..11563475a1 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -201,12 +201,15 @@ #define CIRCUIT_PURPOSE_REND_ESTABLISHED 4 /* At OR, both circuits have this purpose */ /* these circuits originate at this node */ #define CIRCUIT_PURPOSE_C_GENERAL 5 /* normal circuit, with cpath */ -#define CIRCUIT_PURPOSE_S_ESTABLISH_INTRO 6 /* at Bob, waiting for introductions */ -#define CIRCUIT_PURPOSE_C_INTRODUCING 7 /* at Alice, connecting to intro point */ -#define CIRCUIT_PURPOSE_C_ESTABLISH_REND 8 /* at Alice, waiting for Bob */ -#define CIRCUIT_PURPOSE_S_CONNECT_REND 9 /* at Bob, connecting to rend point */ -#define CIRCUIT_PURPOSE_C_REND_JOINED 10 /* at Alice, rendezvous established.*/ -#define CIRCUIT_PURPOSE_S_REND_JOINED 11 /* at Bob, rendezvous established.*/ +#define CIRCUIT_PURPOSE_C_INTRODUCING 6 /* at Alice, connecting to intro point */ +#define CIRCUIT_PURPOSE_C_ESTABLISH_REND 7 /* at Alice, waiting for Bob */ +#define CIRCUIT_PURPOSE_C_REND_JOINED 8 /* at Alice, rendezvous established.*/ + +#define CIRCUIT_PURPOSE_S_ESTABLISH_INTRO 9 /* at Bob, waiting for introductions */ +#define CIRCUIT_PURPOSE_S_INTRO 10 /* at Bob, successfully established intro */ +#define CIRCUIT_PURPOSE_S_CONNECT_REND 11 /* at Bob, connecting to rend point */ + +#define CIRCUIT_PURPOSE_S_REND_JOINED 12 /* at Bob, rendezvous established.*/ #define _CIRCUIT_PURPOSE_MAX 11 #define RELAY_COMMAND_BEGIN 1 @@ -228,6 +231,9 @@ #define RELAY_COMMAND_INTRODUCE2 35 #define RELAY_COMMAND_RENDEZVOUS1 36 #define RELAY_COMMAND_RENDEZVOUS2 37 +/* DOCDOC Spec these next two. */ +#define RELAY_COMMAND_INTRO_ESTABLISHED 38 +#define RELAY_COMMAND_RENDEZVOUS_ESTABLISHED 39 #define _MIN_END_STREAM_REASON 1 #define END_STREAM_REASON_MISC 1 @@ -1062,6 +1068,7 @@ int rend_service_init_keys(void); int 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); void rend_service_rendezvous_is_ready(circuit_t *circuit); int rend_service_introduce(circuit_t *circuit, const char *request, int request_len); diff --git a/src/or/rendcommon.c b/src/or/rendcommon.c index f75a8182b7..878e83e3bd 100644 --- a/src/or/rendcommon.c +++ b/src/or/rendcommon.c @@ -278,6 +278,13 @@ void rend_process_relay_cell(circuit_t *circ, int command, int length, /* r = rend_client_rendezvous(circ,payload,length); */ log_fn(LOG_NOTICE, "Ignoring a rendezvous2 cell"); break; + case RELAY_COMMAND_INTRO_ESTABLISHED: + r = rend_service_intro_established(circ,payload,length); + break; + case RELAY_COMMAND_RENDEZVOUS_ESTABLISHED: + /* r = rend_client_rendezvous_established(circ,payload,length); */ + log_fn(LOG_NOTICE, "Ignoring a rendezvous_established cell"); + break; default: assert(0); } diff --git a/src/or/rendmid.c b/src/or/rendmid.c index 691af35878..fa24aed7ea 100644 --- a/src/or/rendmid.c +++ b/src/or/rendmid.c @@ -75,6 +75,14 @@ rend_mid_establish_intro(circuit_t *circ, const char *request, int request_len) circuit_mark_for_close(c); } + /* Acknlowedge the request. */ + if (connection_edge_send_command(NULL,circ, + RELAY_COMMAND_INTRO_ESTABLISHED, + "", 0, NULL)<0) { + log_fn(LOG_WARN, "Couldn't send INTRO_ESTABLISHED cell"); + goto err; + } + /* Now, set up this circuit. */ circ->purpose = CIRCUIT_PURPOSE_INTRO_POINT; memcpy(circ->rend_pk_digest, pk_digest, 20); @@ -168,6 +176,14 @@ rend_mid_establish_rendezvous(circuit_t *circ, const char *request, int request_ goto err; } + /* Acknlowedge the request. */ + if (connection_edge_send_command(NULL,circ, + RELAY_COMMAND_RENDEZVOUS_ESTABLISHED, + "", 0, NULL)<0) { + log_fn(LOG_WARN, "Couldn't send RENDEZVOUS_ESTABLISHED cell"); + goto err; + } + circ->purpose = CIRCUIT_PURPOSE_REND_POINT_WAITING; memcpy(circ->rend_cookie, request, REND_COOKIE_LEN); diff --git a/src/or/rendservice.c b/src/or/rendservice.c index e05998c71b..31f0c8c5dc 100644 --- a/src/or/rendservice.c +++ b/src/or/rendservice.c @@ -320,7 +320,7 @@ rend_service_introduce(circuit_t *circuit, const char *request, int request_len) log_fn(LOG_INFO, "Received INTRODUCE2 cell for service %s on circ %d", hexid, circuit->n_circ_id); - if (circuit->purpose != CIRCUIT_PURPOSE_S_ESTABLISH_INTRO) { + if (circuit->purpose != CIRCUIT_PURPOSE_S_INTRO) { log_fn(LOG_WARN, "Got an INTRODUCE2 over a non-introduction circuit %d", circuit->n_circ_id); return -1; @@ -504,6 +504,22 @@ rend_service_intro_is_ready(circuit_t *circuit) circuit_mark_for_close(circuit); } +/* Handle an intro_established cell. */ +int +rend_service_intro_established(circuit_t *circuit, const char *request, int request_len) +{ + if (circuit->purpose != CIRCUIT_PURPOSE_S_ESTABLISH_INTRO) { + log_fn(LOG_WARN, "received INTRO_ESTABLISHED cell on non-intro circuit"); + goto err; + } + circuit->purpose = CIRCUIT_PURPOSE_S_INTRO; + + return 0; + err: + circuit_mark_for_close(circuit); + return -1; +} + /* Called once a circuit to a rendezvous point is ready: sends a * RELAY_COMMAND_RENDEZVOUS1 cell. */ @@ -569,6 +585,33 @@ rend_service_rendezvous_is_ready(circuit_t *circuit) * Manage introduction points ******/ +static circuit_t * +find_intro_circuit(routerinfo_t *router, const char *pk_digest) +{ + circuit_t *circ = NULL; + + while ((circ = circuit_get_next_by_pk_and_purpose(circ,pk_digest, + CIRCUIT_PURPOSE_S_INTRO))) { + assert(circ->cpath); + if (circ->cpath->prev->addr == router->addr && + circ->cpath->prev->port == router->or_port) { + return circ; + } + } + + circ = NULL; + while ((circ = circuit_get_next_by_pk_and_purpose(circ,pk_digest, + CIRCUIT_PURPOSE_S_ESTABLISH_INTRO))) { + assert(circ->cpath); + if (circ->cpath->prev->addr == router->addr && + circ->cpath->prev->port == router->or_port) { + return circ; + } + } + return NULL; +} + + /* For every service, check how many intro points it currently has, and: * - Pick new intro points as necessary. * - Launch circuits to any new intro points. @@ -579,9 +622,8 @@ int rend_services_init(void) { routerinfo_t *router; routerlist_t *rl; rend_service_t *service; - circuit_t *circ; char *desc, *intro; - int changed, found, prev_intro_nodes, desc_len; + int changed, prev_intro_nodes, desc_len; router_get_routerlist(&rl); @@ -593,26 +635,11 @@ int rend_services_init(void) { /* Find out which introduction points we really have for this service. */ for (j=0;j< smartlist_len(service->intro_nodes); ++j) { - router = router_get_by_nickname(smartlist_get(service->intro_nodes,j)); - if (!router) - goto remove_point; - circ = NULL; - found = 1; - while ((circ = circuit_get_next_by_pk_and_purpose( - circ,service->pk_digest, - CIRCUIT_PURPOSE_S_ESTABLISH_INTRO))) { - assert(circ->cpath); - if (circ->cpath->prev->addr == router->addr && - circ->cpath->prev->port == router->or_port) { - found = 1; break; - } + if (!router || !find_intro_circuit(router,service->pk_digest)) { + smartlist_del(service->intro_nodes,j--); + changed = 1; } - if (found) continue; - - remove_point: - smartlist_del(service->intro_nodes,j--); - changed = 1; } /* We have enough intro points, and the intro points we thought we had were