diff options
-rw-r--r-- | src/or/hs_circuitmap.c | 45 | ||||
-rw-r--r-- | src/or/hs_circuitmap.h | 8 | ||||
-rw-r--r-- | src/test/test_circuitlist.c | 11 |
3 files changed, 62 insertions, 2 deletions
diff --git a/src/or/hs_circuitmap.c b/src/or/hs_circuitmap.c index ea66fb5194..f235ecc82d 100644 --- a/src/or/hs_circuitmap.c +++ b/src/or/hs_circuitmap.c @@ -5,8 +5,10 @@ * \file hs_circuitmap.c * * \brief Hidden service circuitmap: A hash table that maps binary tokens to - * introduction and rendezvous circuits; it's used both by relays acting as - * intro points and rendezvous points, and also by hidden services themselves. + * introduction and rendezvous circuits; it's used: + * (a) by relays acting as intro points and rendezvous points + * (b) by hidden services to find intro and rend circuits and + * (c) by HS clients to find rendezvous circuits. **/ #define HS_CIRCUITMAP_PRIVATE @@ -404,6 +406,29 @@ hs_circuitmap_get_rend_circ_service_side(const uint8_t *cookie) return circ; } +/* Public function: Return client-side rendezvous circuit with rendezvous + * <b>cookie</b>. It will first lookup for the CIRCUIT_PURPOSE_C_REND_READY + * purpose and then try for CIRCUIT_PURPOSE_C_REND_READY_INTRO_ACKED. + * + * Return NULL if no such circuit is found in the circuitmap. */ +origin_circuit_t * +hs_circuitmap_get_rend_circ_client_side(const uint8_t *cookie) +{ + origin_circuit_t *circ = NULL; + + circ = hs_circuitmap_get_origin_circuit(HS_TOKEN_REND_CLIENT_SIDE, + REND_TOKEN_LEN, cookie, + CIRCUIT_PURPOSE_C_REND_READY); + if (circ) { + return circ; + } + + circ = hs_circuitmap_get_origin_circuit(HS_TOKEN_REND_CLIENT_SIDE, + REND_TOKEN_LEN, cookie, + CIRCUIT_PURPOSE_C_REND_READY_INTRO_ACKED); + return circ; +} + /**** Public servide-side setters: */ /* Public function: Register v2 intro circuit with key <b>digest</b> to the @@ -439,6 +464,22 @@ hs_circuitmap_register_rend_circ_service_side(origin_circuit_t *circ, REND_TOKEN_LEN, cookie); } +/* Public function: Register rendezvous circuit with key <b>cookie</b> to the + * client-side circuitmap. */ +void +hs_circuitmap_register_rend_circ_client_side(origin_circuit_t *or_circ, + const uint8_t *cookie) +{ + circuit_t *circ = TO_CIRCUIT(or_circ); + { /* Basic circ purpose sanity checking */ + tor_assert_nonfatal(circ->purpose == CIRCUIT_PURPOSE_C_REND_READY || + circ->purpose == CIRCUIT_PURPOSE_C_REND_READY_INTRO_ACKED); + } + + hs_circuitmap_register_circuit(circ, HS_TOKEN_REND_CLIENT_SIDE, + REND_TOKEN_LEN, cookie); +} + /**** Misc public functions: */ /** Public function: Remove this circuit from the HS circuitmap. Clear its HS diff --git a/src/or/hs_circuitmap.h b/src/or/hs_circuitmap.h index 33d5b64117..0903de2347 100644 --- a/src/or/hs_circuitmap.h +++ b/src/or/hs_circuitmap.h @@ -43,6 +43,8 @@ struct origin_circuit_t * hs_circuitmap_get_intro_circ_v2_service_side(const uint8_t *digest); struct origin_circuit_t * hs_circuitmap_get_rend_circ_service_side(const uint8_t *cookie); +struct origin_circuit_t * +hs_circuitmap_get_rend_circ_client_side(const uint8_t *cookie); void hs_circuitmap_register_intro_circ_v2_service_side( struct origin_circuit_t *circ, @@ -53,6 +55,9 @@ void hs_circuitmap_register_intro_circ_v3_service_side( void hs_circuitmap_register_rend_circ_service_side( struct origin_circuit_t *circ, const uint8_t *cookie); +void hs_circuitmap_register_rend_circ_client_side( + struct origin_circuit_t *circ, + const uint8_t *cookie); void hs_circuitmap_remove_circuit(struct circuit_t *circ); @@ -76,6 +81,9 @@ typedef enum { HS_TOKEN_INTRO_V2_SERVICE_SIDE, /** A v3 introduction point pubkey on a hidden service (256bit) */ HS_TOKEN_INTRO_V3_SERVICE_SIDE, + + /** A rendezvous cookie on the client side (128bit) */ + HS_TOKEN_REND_CLIENT_SIDE, } hs_token_type_t; /** Represents a token used in the HS protocol. Each such token maps to a diff --git a/src/test/test_circuitlist.c b/src/test/test_circuitlist.c index 344ab27921..6b8dae31f4 100644 --- a/src/test/test_circuitlist.c +++ b/src/test/test_circuitlist.c @@ -180,6 +180,7 @@ static void test_rend_token_maps(void *arg) { or_circuit_t *c1, *c2, *c3, *c4; + origin_circuit_t *c5; const uint8_t tok1[REND_TOKEN_LEN] = "The cat can't tell y"; const uint8_t tok2[REND_TOKEN_LEN] = "ou its name, and it "; const uint8_t tok3[REND_TOKEN_LEN] = "doesn't really care."; @@ -194,6 +195,7 @@ test_rend_token_maps(void *arg) c2 = or_circuit_new(0, NULL); c3 = or_circuit_new(0, NULL); c4 = or_circuit_new(0, NULL); + c5 = origin_circuit_new(); /* Make sure we really filled up the tok* variables */ tt_int_op(tok1[REND_TOKEN_LEN-1], OP_EQ, 'y'); @@ -264,6 +266,13 @@ test_rend_token_maps(void *arg) tt_ptr_op(TO_CIRCUIT(c4)->hs_token, OP_EQ, NULL); tt_ptr_op(NULL, OP_EQ, hs_circuitmap_get_intro_circ_v2_relay_side(tok3)); + /* Now let's do a check for the client-side rend circuitmap */ + c5->base_.purpose = CIRCUIT_PURPOSE_C_REND_READY; + hs_circuitmap_register_rend_circ_client_side(c5, tok1); + + tt_ptr_op(c5, OP_EQ, hs_circuitmap_get_rend_circ_client_side(tok1)); + tt_ptr_op(NULL, OP_EQ, hs_circuitmap_get_rend_circ_client_side(tok2)); + done: if (c1) circuit_free(TO_CIRCUIT(c1)); @@ -273,6 +282,8 @@ test_rend_token_maps(void *arg) circuit_free(TO_CIRCUIT(c3)); if (c4) circuit_free(TO_CIRCUIT(c4)); + if (c5) + circuit_free(TO_CIRCUIT(c5)); } static void |