aboutsummaryrefslogtreecommitdiff
path: root/src/or
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2004-03-30 19:52:42 +0000
committerNick Mathewson <nickm@torproject.org>2004-03-30 19:52:42 +0000
commit0ba9ab5fb05ceb064a24e2db91e7a2f72cea2722 (patch)
tree27a4a2cf5dd2def95fd2134a3a68ce8eb0ffbd38 /src/or
parent6ea95488d2e2b519a33bd7c2f391b520a6dc6b97 (diff)
downloadtor-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.c41
-rw-r--r--src/or/command.c1
-rw-r--r--src/or/or.h43
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