diff options
author | Nick Mathewson <nickm@torproject.org> | 2006-07-26 19:05:41 +0000 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2006-07-26 19:05:41 +0000 |
commit | e61d28dfb8f2936b8024f1cb4d3ad8ecf1cd25b5 (patch) | |
tree | e5e1a34aa6f63717ddcb75087bd1ec8f93939ce5 | |
parent | a88ec48a39e5531fa80a0b5d5ec42dd31f268b67 (diff) | |
download | tor-e61d28dfb8f2936b8024f1cb4d3ad8ecf1cd25b5.tar tor-e61d28dfb8f2936b8024f1cb4d3ad8ecf1cd25b5.tar.gz |
r6903@Kushana: nickm | 2006-07-25 18:22:48 -0400
No circuit can be both an intro point and a rend point, so we can merge both the cookie and the pk digest into one "rend_token" field for or circuits. This saves another 20 bytes per or circuit.
svn:r6904
-rw-r--r-- | src/or/circuitlist.c | 47 | ||||
-rw-r--r-- | src/or/or.h | 35 | ||||
-rw-r--r-- | src/or/rendclient.c | 8 | ||||
-rw-r--r-- | src/or/rendmid.c | 25 | ||||
-rw-r--r-- | src/or/rendservice.c | 47 |
5 files changed, 96 insertions, 66 deletions
diff --git a/src/or/circuitlist.c b/src/or/circuitlist.c index 2751dde6b..db8b7577f 100644 --- a/src/or/circuitlist.c +++ b/src/or/circuitlist.c @@ -652,44 +652,67 @@ circuit_get_by_rend_query_and_purpose(const char *rend_query, uint8_t purpose) * whose rend_pk_digest field is <b>digest</b> and whose purpose is * <b>purpose</b>. Returns NULL if no circuit is found. * If <b>start</b> is NULL, begin at the start of the list. + * DOCDOC origin. */ -circuit_t * -circuit_get_next_by_pk_and_purpose(circuit_t *start, +origin_circuit_t * +circuit_get_next_by_pk_and_purpose(origin_circuit_t *start, const char *digest, uint8_t purpose) { circuit_t *circ; + tor_assert(CIRCUIT_PURPOSE_IS_ORIGIN(purpose)); if (start == NULL) circ = global_circuitlist; else - circ = start->next; + circ = TO_CIRCUIT(start)->next; for ( ; circ; circ = circ->next) { if (circ->marked_for_close) continue; if (circ->purpose != purpose) continue; - if (!memcmp(circ->rend_pk_digest, digest, DIGEST_LEN)) - return circ; + if (!memcmp(TO_ORIGIN_CIRCUIT(circ)->rend_pk_digest, digest, DIGEST_LEN)) + return TO_ORIGIN_CIRCUIT(circ); } return NULL; } -/** Return the circuit waiting for a rendezvous with the provided cookie. - * Return NULL if no such circuit is found. - */ -or_circuit_t * -circuit_get_rendezvous(const char *cookie) +/* DOCDOC */ +static or_circuit_t * +circuit_get_by_rend_token_and_purpose(uint8_t purpose, const char *token, + size_t len) { circuit_t *circ; for (circ = global_circuitlist; circ; circ = circ->next) { if (! circ->marked_for_close && - circ->purpose == CIRCUIT_PURPOSE_REND_POINT_WAITING && - ! memcmp(circ->rend_cookie, cookie, REND_COOKIE_LEN) ) + circ->purpose == purpose && + ! memcmp(TO_OR_CIRCUIT(circ)->rend_token, token, len)) return TO_OR_CIRCUIT(circ); } return NULL; } +/** Return the circuit waiting for a rendezvous with the provided cookie. + * Return NULL if no such circuit is found. + */ +or_circuit_t * +circuit_get_rendezvous(const char *cookie) +{ + return circuit_get_by_rend_token_and_purpose( + CIRCUIT_PURPOSE_REND_POINT_WAITING, + cookie, REND_COOKIE_LEN); +} + +/** Return the circuit waiting for intro cells of the given digest. + * Return NULL if no such circuit is found. + */ +or_circuit_t * +circuit_get_intro_point(const char *digest) +{ + return circuit_get_by_rend_token_and_purpose( + CIRCUIT_PURPOSE_INTRO_POINT, digest, + DIGEST_LEN); +} + /** Return a circuit that is open, has specified <b>purpose</b>, * has a timestamp_dirty value of 0, is uptime/capacity/internal * if required, and if info is defined, does not already use info diff --git a/src/or/or.h b/src/or/or.h index d70039eea..2f49e8c1f 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -1110,16 +1110,6 @@ typedef struct circuit_t { const char *marked_for_close_file; /**< For debugging: in which file was this * circuit marked for close? */ - /** The rend_pk_digest field holds a hash of location-hidden service's - * PK if purpose is INTRO_POINT or S_ESTABLISH_INTRO or S_RENDEZVOUSING. - */ - char rend_pk_digest[DIGEST_LEN]; - - /** Holds rendezvous cookie if purpose is REND_POINT_WAITING or - * C_ESTABLISH_REND. Filled with zeroes otherwise. - */ - char rend_cookie[REND_COOKIE_LEN]; - /** Quasi-global identifier for this circuit; used for control.c */ /* XXXX NM This can get re-used after 2**32 circuits. */ uint32_t global_identifier; @@ -1148,6 +1138,16 @@ typedef struct origin_circuit_t { */ crypt_path_t *cpath; + /** The rend_pk_digest field holds a hash of location-hidden service's + * PK if purpose is S_ESTABLISH_INTRO or S_RENDEZVOUSING. + */ + char rend_pk_digest[DIGEST_LEN]; + + /** Holds rendezvous cookie if purpose is C_ESTABLISH_REND. Filled with + * zeroes otherwise. + */ + char rend_cookie[REND_COOKIE_LEN]; + /** * The rend_query field holds the y portion of y.onion (nul-terminated) * if purpose is C_INTRODUCING or C_ESTABLISH_REND, or is a C_GENERAL @@ -1189,6 +1189,18 @@ typedef struct or_circuit_t { * is not marked for close. */ struct or_circuit_t *rend_splice; +#if REND_COOKIE_LEN >= DIGEST_LEN +#define REND_TOKEN_LEN REND_COOKIE_LEN +#else +#define REND_TOKEN_LEN DIGEST_LEN +#endif + + /** A hash of location-hidden service's PK if purpose is INTRO_POINT, or a + * rendezvous cookie if purpose is REND_POINT_WAITING or + * C_ESTABLISH_REND. Filled with zeroes otherwise. + */ + char rend_token[REND_TOKEN_LEN]; + char handshake_digest[DIGEST_LEN]; /**< Stores KH for intermediate hops. */ } or_circuit_t; @@ -1594,9 +1606,10 @@ void circuit_unlink_all_from_or_conn(connection_t *conn, int reason); circuit_t *circuit_get_by_global_id(uint32_t id); origin_circuit_t *circuit_get_by_rend_query_and_purpose(const char *rend_query, uint8_t purpose); -circuit_t *circuit_get_next_by_pk_and_purpose(circuit_t *start, +origin_circuit_t *circuit_get_next_by_pk_and_purpose(origin_circuit_t *start, const char *digest, uint8_t purpose); or_circuit_t *circuit_get_rendezvous(const char *cookie); +or_circuit_t *circuit_get_intro_point(const char *digest); origin_circuit_t *circuit_find_to_cannibalize(uint8_t purpose, extend_info_t *info, int need_uptime, diff --git a/src/or/rendclient.c b/src/or/rendclient.c index e635f36f2..3445bd5c8 100644 --- a/src/or/rendclient.c +++ b/src/or/rendclient.c @@ -32,14 +32,14 @@ rend_client_send_establish_rendezvous(origin_circuit_t *circ) tor_assert(circ->_base.purpose == CIRCUIT_PURPOSE_C_ESTABLISH_REND); log_info(LD_REND, "Sending an ESTABLISH_RENDEZVOUS cell"); - if (crypto_rand(circ->_base.rend_cookie, REND_COOKIE_LEN) < 0) { + if (crypto_rand(circ->rend_cookie, REND_COOKIE_LEN) < 0) { log_warn(LD_BUG, "Internal error: Couldn't produce random cookie."); circuit_mark_for_close(TO_CIRCUIT(circ), END_CIRC_AT_ORIGIN); return -1; } if (connection_edge_send_command(NULL,TO_CIRCUIT(circ), RELAY_COMMAND_ESTABLISH_RENDEZVOUS, - circ->_base.rend_cookie, REND_COOKIE_LEN, + circ->rend_cookie, REND_COOKIE_LEN, circ->cpath->prev)<0) { /* circ is already marked for close */ log_warn(LD_GENERAL, "Couldn't send ESTABLISH_RENDEZVOUS cell"); @@ -111,14 +111,14 @@ rend_client_send_introduction(origin_circuit_t *introcirc, klen = crypto_pk_asn1_encode(extend_info->onion_key, tmp+7+DIGEST_LEN+2, sizeof(tmp)-(7+DIGEST_LEN+2)); set_uint16(tmp+7+DIGEST_LEN, htons(klen)); - memcpy(tmp+7+DIGEST_LEN+2+klen, rendcirc->_base.rend_cookie, + memcpy(tmp+7+DIGEST_LEN+2+klen, rendcirc->rend_cookie, REND_COOKIE_LEN); dh_offset = 7+DIGEST_LEN+2+klen+REND_COOKIE_LEN; } else { /* Version 0. */ strncpy(tmp, rendcirc->build_state->chosen_exit->nickname, (MAX_NICKNAME_LEN+1)); /* nul pads */ - memcpy(tmp+MAX_NICKNAME_LEN+1, rendcirc->_base.rend_cookie, + memcpy(tmp+MAX_NICKNAME_LEN+1, rendcirc->rend_cookie, REND_COOKIE_LEN); dh_offset = MAX_NICKNAME_LEN+1+REND_COOKIE_LEN; } diff --git a/src/or/rendmid.c b/src/or/rendmid.c index 21189eb2c..5ecd2af93 100644 --- a/src/or/rendmid.c +++ b/src/or/rendmid.c @@ -23,7 +23,7 @@ rend_mid_establish_intro(or_circuit_t *circ, const char *request, char expected_digest[DIGEST_LEN]; char pk_digest[DIGEST_LEN]; size_t asn1len; - circuit_t *c; + or_circuit_t *c; char serviceid[REND_SERVICE_ID_LEN+1]; int reason = END_CIRC_REASON_INTERNAL; @@ -87,11 +87,11 @@ rend_mid_establish_intro(or_circuit_t *circ, const char *request, /* Close any other intro circuits with the same pk. */ c = NULL; - while ((c = circuit_get_next_by_pk_and_purpose( - c,pk_digest,CIRCUIT_PURPOSE_INTRO_POINT))) { + while ((c = circuit_get_intro_point(pk_digest))) { log_info(LD_REND, "Replacing old circuit for service %s", safe_str(serviceid)); - circuit_mark_for_close(c, END_CIRC_REASON_REQUESTED); + circuit_mark_for_close(TO_CIRCUIT(c), END_CIRC_REASON_REQUESTED); + /* Now it's marked, and it won't be returned next time. */ } /* Acknowledge the request. */ @@ -104,7 +104,7 @@ rend_mid_establish_intro(or_circuit_t *circ, const char *request, /* Now, set up this circuit. */ circ->_base.purpose = CIRCUIT_PURPOSE_INTRO_POINT; - memcpy(circ->_base.rend_pk_digest, pk_digest, DIGEST_LEN); + memcpy(circ->rend_token, pk_digest, DIGEST_LEN); log_info(LD_REND, "Established introduction point on circuit %d for service %s", @@ -127,7 +127,7 @@ rend_mid_establish_intro(or_circuit_t *circ, const char *request, int rend_mid_introduce(or_circuit_t *circ, const char *request, size_t request_len) { - circuit_t *intro_circ; + or_circuit_t *intro_circ; char serviceid[REND_SERVICE_ID_LEN+1]; char nak_body[1]; @@ -153,9 +153,8 @@ rend_mid_introduce(or_circuit_t *circ, const char *request, size_t request_len) base32_encode(serviceid, REND_SERVICE_ID_LEN+1, request,10); /* The first 20 bytes are all we look at: they have a hash of Bob's PK. */ - intro_circ = circuit_get_next_by_pk_and_purpose( - NULL, request, CIRCUIT_PURPOSE_INTRO_POINT); - if (!intro_circ || CIRCUIT_IS_ORIGIN(intro_circ)) { + intro_circ = circuit_get_intro_point(request); + if (!intro_circ) { log_info(LD_REND, "No intro circ found for INTRODUCE1 cell (%s) from circuit %d; " "responding with nack.", @@ -167,10 +166,10 @@ rend_mid_introduce(or_circuit_t *circ, const char *request, size_t request_len) "Sending introduction request for service %s " "from circ %d to circ %d", safe_str(serviceid), circ->p_circ_id, - TO_OR_CIRCUIT(intro_circ)->p_circ_id); + intro_circ->p_circ_id); /* Great. Now we just relay the cell down the circuit. */ - if (connection_edge_send_command(NULL, intro_circ, + if (connection_edge_send_command(NULL, TO_CIRCUIT(intro_circ), RELAY_COMMAND_INTRODUCE2, request, request_len, NULL)) { log_warn(LD_GENERAL, @@ -237,7 +236,7 @@ rend_mid_establish_rendezvous(or_circuit_t *circ, const char *request, } circ->_base.purpose = CIRCUIT_PURPOSE_REND_POINT_WAITING; - memcpy(circ->_base.rend_cookie, request, REND_COOKIE_LEN); + memcpy(circ->rend_token, request, REND_COOKIE_LEN); base16_encode(hexid,9,request,4); @@ -313,7 +312,7 @@ rend_mid_rendezvous(or_circuit_t *circ, const char *request, circ->_base.purpose = CIRCUIT_PURPOSE_REND_ESTABLISHED; rend_circ->_base.purpose = CIRCUIT_PURPOSE_REND_ESTABLISHED; - memset(circ->_base.rend_cookie, 0, REND_COOKIE_LEN); + memset(circ->rend_token, 0, REND_COOKIE_LEN); rend_circ->rend_splice = circ; circ->rend_splice = rend_circ; diff --git a/src/or/rendservice.c b/src/or/rendservice.c index 619dbf270..d0bb33d13 100644 --- a/src/or/rendservice.c +++ b/src/or/rendservice.c @@ -428,7 +428,7 @@ rend_service_introduce(origin_circuit_t *circuit, const char *request, int circ_needs_uptime; base32_encode(serviceid, REND_SERVICE_ID_LEN+1, - circuit->_base.rend_pk_digest,10); + circuit->rend_pk_digest,10); log_info(LD_REND, "Received INTRODUCE2 cell for service %s on circ %d.", escaped(serviceid), circuit->_base.n_circ_id); @@ -454,7 +454,7 @@ rend_service_introduce(origin_circuit_t *circuit, const char *request, escaped(serviceid)); return -1; } - if (memcmp(circuit->_base.rend_pk_digest, request, DIGEST_LEN)) { + if (memcmp(circuit->rend_pk_digest, request, DIGEST_LEN)) { base32_encode(serviceid, REND_SERVICE_ID_LEN+1, request, 10); log_warn(LD_REND, "Got an INTRODUCE2 cell for the wrong service (%s).", escaped(serviceid)); @@ -589,9 +589,9 @@ rend_service_introduce(origin_circuit_t *circuit, const char *request, extend_info->nickname, hexcookie, serviceid); tor_assert(launched->build_state); /* Fill in the circuit's state. */ - memcpy(launched->_base.rend_pk_digest, circuit->_base.rend_pk_digest, + memcpy(launched->rend_pk_digest, circuit->rend_pk_digest, DIGEST_LEN); - memcpy(launched->_base.rend_cookie, r_cookie, REND_COOKIE_LEN); + memcpy(launched->rend_cookie, r_cookie, REND_COOKIE_LEN); strlcpy(launched->rend_query, service->service_id, sizeof(launched->rend_query)); launched->build_state->pending_final_cpath = cpath = @@ -664,9 +664,9 @@ rend_service_relaunch_rendezvous(origin_circuit_t *oldcirc) oldstate->pending_final_cpath = NULL; memcpy(newcirc->rend_query, oldcirc->rend_query, REND_SERVICE_ID_LEN+1); - memcpy(newcirc->_base.rend_pk_digest, oldcirc->_base.rend_pk_digest, + memcpy(newcirc->rend_pk_digest, oldcirc->rend_pk_digest, DIGEST_LEN); - memcpy(newcirc->_base.rend_cookie, oldcirc->_base.rend_cookie, + memcpy(newcirc->rend_cookie, oldcirc->rend_cookie, REND_COOKIE_LEN); } @@ -696,7 +696,7 @@ rend_service_launch_establish_intro(rend_service_t *service, } strlcpy(launched->rend_query, service->service_id, sizeof(launched->rend_query)); - memcpy(launched->_base.rend_pk_digest, service->pk_digest, DIGEST_LEN); + memcpy(launched->rend_pk_digest, service->pk_digest, DIGEST_LEN); if (launched->_base.state == CIRCUIT_STATE_OPEN) rend_service_intro_has_opened(launched); @@ -720,9 +720,9 @@ rend_service_intro_has_opened(origin_circuit_t *circuit) tor_assert(circuit->cpath); base32_encode(serviceid, REND_SERVICE_ID_LEN+1, - circuit->_base.rend_pk_digest,10); + circuit->rend_pk_digest,10); - service = rend_service_get_by_pk_digest(circuit->_base.rend_pk_digest); + service = rend_service_get_by_pk_digest(circuit->rend_pk_digest); if (!service) { log_warn(LD_REND, "Unrecognized service ID %s on introduction circuit %d.", serviceid, circuit->_base.n_circ_id); @@ -780,7 +780,7 @@ rend_service_intro_established(origin_circuit_t *circuit, const char *request, "received INTRO_ESTABLISHED cell on non-intro circuit."); goto err; } - service = rend_service_get_by_pk_digest(circuit->_base.rend_pk_digest); + service = rend_service_get_by_pk_digest(circuit->rend_pk_digest); if (!service) { log_warn(LD_REND, "Unknown service on introduction circuit %d.", circuit->_base.n_circ_id); @@ -813,16 +813,16 @@ rend_service_rendezvous_has_opened(origin_circuit_t *circuit) hop = circuit->build_state->pending_final_cpath; tor_assert(hop); - base16_encode(hexcookie,9,circuit->_base.rend_cookie,4); + base16_encode(hexcookie,9,circuit->rend_cookie,4); base32_encode(serviceid, REND_SERVICE_ID_LEN+1, - circuit->_base.rend_pk_digest,10); + circuit->rend_pk_digest,10); log_info(LD_REND, "Done building circuit %d to rendezvous with " "cookie %s for service %s", circuit->_base.n_circ_id, hexcookie, serviceid); - service = rend_service_get_by_pk_digest(circuit->_base.rend_pk_digest); + service = rend_service_get_by_pk_digest(circuit->rend_pk_digest); if (!service) { log_warn(LD_GENERAL, "Internal error: unrecognized service ID on " "introduction circuit."); @@ -830,7 +830,7 @@ rend_service_rendezvous_has_opened(origin_circuit_t *circuit) } /* All we need to do is send a RELAY_RENDEZVOUS1 cell... */ - memcpy(buf, circuit->_base.rend_cookie, REND_COOKIE_LEN); + memcpy(buf, circuit->rend_cookie, REND_COOKIE_LEN); if (crypto_dh_get_public(hop->dh_handshake_state, buf+REND_COOKIE_LEN, DH_KEY_LEN)<0) { log_warn(LD_GENERAL,"Couldn't get DH public key."); @@ -881,28 +881,23 @@ rend_service_rendezvous_has_opened(origin_circuit_t *circuit) static origin_circuit_t * find_intro_circuit(routerinfo_t *router, const char *pk_digest) { - circuit_t *circ = NULL; - cpath_build_state_t *build_state = NULL; + origin_circuit_t *circ = NULL; tor_assert(router); while ((circ = circuit_get_next_by_pk_and_purpose(circ,pk_digest, CIRCUIT_PURPOSE_S_INTRO))) { - tor_assert(CIRCUIT_IS_ORIGIN(circ)); - build_state = TO_ORIGIN_CIRCUIT(circ)->build_state; - if (!strcasecmp(build_state->chosen_exit->nickname, + if (!strcasecmp(circ->build_state->chosen_exit->nickname, router->nickname)) { - return TO_ORIGIN_CIRCUIT(circ); + return circ; } } circ = NULL; while ((circ = circuit_get_next_by_pk_and_purpose(circ,pk_digest, CIRCUIT_PURPOSE_S_ESTABLISH_INTRO))) { - tor_assert(CIRCUIT_IS_ORIGIN(circ)); - build_state = TO_ORIGIN_CIRCUIT(circ)->build_state; - if (!strcasecmp(build_state->chosen_exit->nickname, + if (!strcasecmp(circ->build_state->chosen_exit->nickname, router->nickname)) { - return TO_ORIGIN_CIRCUIT(circ); + return circ; } } return NULL; @@ -1137,8 +1132,8 @@ rend_service_set_connection_addr_port(connection_t *conn, tor_assert(circ->_base.purpose == CIRCUIT_PURPOSE_S_REND_JOINED); log_debug(LD_REND,"beginning to hunt for addr/port"); base32_encode(serviceid, REND_SERVICE_ID_LEN+1, - circ->_base.rend_pk_digest,10); - service = rend_service_get_by_pk_digest(circ->_base.rend_pk_digest); + circ->rend_pk_digest,10); + service = rend_service_get_by_pk_digest(circ->rend_pk_digest); if (!service) { log_warn(LD_REND, "Couldn't find any service associated with pk %s on " "rendezvous circuit %d; closing.", |