diff options
author | Nick Mathewson <nickm@torproject.org> | 2004-03-30 19:52:42 +0000 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2004-03-30 19:52:42 +0000 |
commit | 0ba9ab5fb05ceb064a24e2db91e7a2f72cea2722 (patch) | |
tree | 27a4a2cf5dd2def95fd2134a3a68ce8eb0ffbd38 /src/or | |
parent | 6ea95488d2e2b519a33bd7c2f391b520a6dc6b97 (diff) | |
download | tor-0ba9ab5fb05ceb064a24e2db91e7a2f72cea2722.tar tor-0ba9ab5fb05ceb064a24e2db91e7a2f72cea2722.tar.gz |
Add rendezvous-related metadata and code to circuits. Initially, we
thought that a complicated adjunct structure would be necessary, but
it doesn't look that way anymore.
Of course, I might have forgotten something.
svn:r1396
Diffstat (limited to 'src/or')
-rw-r--r-- | src/or/circuit.c | 41 | ||||
-rw-r--r-- | src/or/command.c | 1 | ||||
-rw-r--r-- | src/or/or.h | 43 |
3 files changed, 76 insertions, 9 deletions
diff --git a/src/or/circuit.c b/src/or/circuit.c index 6df8bc9a9..05ee82d3e 100644 --- a/src/or/circuit.c +++ b/src/or/circuit.c @@ -127,6 +127,10 @@ void circuit_free(circuit_t *circ) { tor_free(circ->build_state->chosen_exit); tor_free(circ->build_state); circuit_free_cpath(circ->cpath); + if (circ->rend_splice) { + circ->rend_splice->rend_splice = NULL; + } + memset(circ, 0xAA, sizeof(circuit_t)); /* poison memory */ free(circ); } @@ -290,6 +294,24 @@ circuit_t *circuit_get_newest(connection_t *conn, int must_be_open) { return NULL; } +/* Return the first circuit in global_circuitlist whose rend_service + * field is servid and whose purpose is purpose. Returns NULL if no circuit + * is found. + */ +circuit_t *circuit_get_by_service_and_purpose(const char *servid, int purpose) +{ + circuit_t *circ; + for(circ=global_circuitlist; circ; circ = circ->next) { + if (circ->marked_for_close) + continue; + if (circ->purpose != purpose) + continue; + if (!memcmp(circ->rend_service, servid, REND_COOKIE_LEN)) + return circ; + } + return NULL; +} + #define MIN_SECONDS_BEFORE_EXPIRING_CIRC 10 /* circuits that were born at the end of their second might be expired * after 10.1 seconds; circuits born at the beginning might be expired @@ -726,8 +748,13 @@ int _circuit_mark_for_close(circuit_t *circ) { * circuit-building failed immediately, it won't be set yet. */ circuit_increment_failure_count(); } - circ->marked_for_close = 1; + + if (circ->rend_splice && !circ->rend_splice->marked_for_close) { + /* do this after marking this circuit, to avoid infinite recursion. */ + circuit_mark_for_close(circ->rend_splice); + circ->rend_splice = NULL; + } return 0; } @@ -989,6 +1016,7 @@ int circuit_establish_circuit(void) { circ = circuit_new(0, NULL); /* sets circ->p_circ_id and circ->p_conn */ circ->state = CIRCUIT_STATE_OR_WAIT; circ->build_state = onion_new_cpath_build_state(); + circ->purpose = CIRCUIT_PURPOSE_C_GENERAL; if (! circ->build_state) { log_fn(LOG_INFO,"Generating cpath length failed."); @@ -1348,6 +1376,8 @@ void assert_circuit_ok(const circuit_t *c) assert(c); assert(c->magic == CIRCUIT_MAGIC); + assert(c->purpose >= _CIRCUIT_PURPOSE_MIN && + c->purpose <= _CIRCUIT_PURPOSE_MAX); if (c->n_conn) assert(c->n_conn->type == CONN_TYPE_OR); @@ -1376,6 +1406,15 @@ void assert_circuit_ok(const circuit_t *c) if (c->cpath) { //XXX assert_cpath_ok(c->cpath); } + if (c->purpose == CIRCUIT_PURPOSE_REND_ESTABLISHED) { + if (!c->marked_for_close) { + assert(c->rend_splice); + assert(c->rend_splice->rend_splice == c); + } + assert(c->rend_splice != c); + } else { + assert(!c->rend_splice); + } } /* diff --git a/src/or/command.c b/src/or/command.c index a55ad9c70..cf7dffc5e 100644 --- a/src/or/command.c +++ b/src/or/command.c @@ -103,6 +103,7 @@ static void command_process_create_cell(cell_t *cell, connection_t *conn) { circ = circuit_new(cell->circ_id, conn); circ->state = CIRCUIT_STATE_ONIONSKIN_PENDING; + circ->purpose = CIRCUIT_PURPOSE_INTERMEDIATE; memcpy(circ->onionskin, cell->payload, ONIONSKIN_CHALLENGE_LEN); diff --git a/src/or/or.h b/src/or/or.h index ed18b5036..4aaddafc4 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -188,19 +188,17 @@ #define _CIRCUIT_PURPOSE_MIN 1 /* these circuits were initiated elsewhere */ -#define CIRCUIT_PURPOSE_INTERMEDIATE 1 /* normal circuit */ -#define CIRCUIT_PURPOSE_INTRO_POINT 2 /* from Bob, waiting for intro from Alices */ -#define CIRCUIT_PURPOSE_REND_POINT_WAITING 3 /* from Alice, waiting for Bob */ -#define CIRCUIT_PURPOSE_REND_ESTABLISHED 4 /* both circuits have this purpose */ -/* these circuits were initiated at this node */ +#define CIRCUIT_PURPOSE_INTERMEDIATE 1 /* normal circuit, at OR. */ +#define CIRCUIT_PURPOSE_INTRO_POINT 2 /* At OR, from Bob, waiting for intro from Alices */ +#define CIRCUIT_PURPOSE_REND_POINT_WAITING 3 /* At OR, from Alice, waiting for Bob */ +#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_RENDEZVOUSING 9 /* at Bob, connecting to rend point */ -#define CIRCUIT_PURPOSE_S_UPLOAD_SERVICE_DESC 10 -#define CIRCUIT_PURPOSE_C_FETCH_SERVICE_DESC 11 -#define _CIRCUIT_PURPOSE_MAX 11 +#define _CIRCUIT_PURPOSE_MAX 9 #define RELAY_COMMAND_BEGIN 1 #define RELAY_COMMAND_DATA 2 @@ -473,6 +471,7 @@ struct crypt_path_t { #define DH_KEY_LEN CRYPTO_DH_SIZE #define ONIONSKIN_CHALLENGE_LEN (16+DH_KEY_LEN) #define ONIONSKIN_REPLY_LEN (DH_KEY_LEN+20) +#define REND_COOKIE_LEN CRYPTO_SHA1_DIGEST_LEN typedef struct crypt_path_t crypt_path_t; @@ -517,12 +516,35 @@ struct circuit_t { time_t timestamp_dirty; /* when the circuit was first used, or 0 if clean */ uint8_t state; + uint8_t purpose; + + /* + * holds hash of location-hidden service's PK if purpose is INTRO_POINT + * or S_ESTABLISH_INTRO or S_RENDEZVOUSING; + * holds y portion of y.onion (zero-padded) if purpose is C_INTRODUCING or + * C_ESTABLISH_REND, or is a C_GENERAL for a hidden service. + * filled with zeroes otherwise. + */ + char rend_service[CRYPTO_SHA1_DIGEST_LEN]; + /* Holds rendezvous cookie if purpose is REND_POINT_WAITING or + * S_RENDEZVOUSING. Filled with zeroes otherwise. + */ + char rend_cookie[REND_COOKIE_LEN]; + + /* Points to spliced circuit if purpose is REND_ESTABLISHED, and circuit + * is not marked for close. */ + struct circuit_t *rend_splice; struct circuit_t *next; }; typedef struct circuit_t circuit_t; +typedef struct circuit_data_rend_point_t { + /* for CIRCUIT_PURPOSE_INTRO_POINT (at OR, from Bob, waiting for intro) */ + char rend_cookie[20]; +} circuit_data_intro_point_t; + typedef struct { char *LogLevel; char *LogFile; @@ -630,6 +652,7 @@ int _circuit_mark_for_close(circuit_t *circ); circuit_t *circuit_get_by_circ_id_conn(uint16_t circ_id, connection_t *conn); circuit_t *circuit_get_by_conn(connection_t *conn); circuit_t *circuit_get_newest(connection_t *conn, int must_be_open); +circuit_t *circuit_get_by_service_and_purpose(const char *servid, int purpose); void circuit_expire_building(void); int circuit_count_building(void); @@ -938,6 +961,10 @@ void rep_hist_note_extend_succeeded(const char *from_name, void rep_hist_note_extend_failed(const char *from_name, const char *to_name); void rep_hist_dump_stats(time_t now, int severity); +/********************************* rendcommon.c ***************************/ + +/* length of 'y' portion of 'y.onion' URL. */ +#define REND_SERVICE_ID_LEN 16 #endif |