aboutsummaryrefslogtreecommitdiff
path: root/src/or
diff options
context:
space:
mode:
Diffstat (limited to 'src/or')
-rw-r--r--src/or/circuit.c17
-rw-r--r--src/or/connection_edge.c39
-rw-r--r--src/or/directory.c5
-rw-r--r--src/or/or.h23
-rw-r--r--src/or/rendclient.c47
-rw-r--r--src/or/routerlist.c3
6 files changed, 91 insertions, 43 deletions
diff --git a/src/or/circuit.c b/src/or/circuit.c
index f3f1c6f58..9c7b1a825 100644
--- a/src/or/circuit.c
+++ b/src/or/circuit.c
@@ -298,7 +298,7 @@ circuit_t *circuit_get_newest(connection_t *conn,
continue;
}
} else { /* not general */
- if(rend_cmp_service_ids(conn->socks_request->address, circ->rend_service)) {
+ if(rend_cmp_service_ids(conn->socks_request->address, circ->rend_query)) {
/* this circ is not for this conn */
continue;
}
@@ -1046,21 +1046,18 @@ static void circuit_is_ready(circuit_t *circ) {
switch(circ->purpose) {
case CIRCUIT_PURPOSE_C_GENERAL:
/* Tell any AP connections that have been waiting for a new
- * circuit that one is ready. */
+ * circuit that one is ready. */
+ case CIRCUIT_PURPOSE_C_INTRODUCING:
+ /* at Alice, connecting to intro point */
+ case CIRCUIT_PURPOSE_C_ESTABLISH_REND:
+ /* at Alice, waiting for Bob */
+
connection_ap_attach_pending();
break;
case CIRCUIT_PURPOSE_S_ESTABLISH_INTRO:
/* at Bob, waiting for introductions */
rend_service_intro_is_ready(circ);
break;
- case CIRCUIT_PURPOSE_C_INTRODUCING:
- /* at Alice, connecting to intro point */
- rend_client_intro_is_ready(circ);
- break;
- case CIRCUIT_PURPOSE_C_ESTABLISH_REND:
- /* at Alice, waiting for Bob */
- rend_client_rendezvous_is_ready(circ);
- break;
case CIRCUIT_PURPOSE_S_CONNECT_REND:
/* at Bob, connecting to rend point */
rend_service_rendezvous_is_ready(circ);
diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c
index 89d7dabae..83459e348 100644
--- a/src/or/connection_edge.c
+++ b/src/or/connection_edge.c
@@ -772,7 +772,6 @@ static int connection_ap_handshake_process_socks(connection_t *conn) {
static int connection_ap_handshake_attach_circuit(connection_t *conn) {
circuit_t *circ;
uint32_t addr;
- int must_be_clean;
uint8_t desired_circuit_purpose;
assert(conn);
@@ -780,9 +779,11 @@ static int connection_ap_handshake_attach_circuit(connection_t *conn) {
assert(conn->state == AP_CONN_STATE_CIRCUIT_WAIT);
assert(conn->socks_request);
+ if(conn->purpose == AP_PURPOSE_RENDDESC_WAIT)
+ return 0; /* these guys don't attach to circuits directly */
+
switch(conn->purpose) {
case AP_PURPOSE_GENERAL:
- case AP_PURPOSE_RENDDESC_WAIT:
desired_circuit_purpose = CIRCUIT_PURPOSE_C_GENERAL;
break;
case AP_PURPOSE_RENDPOINT_WAIT:
@@ -800,21 +801,34 @@ static int connection_ap_handshake_attach_circuit(connection_t *conn) {
circ = circuit_get_newest(conn, 1, desired_circuit_purpose);
if(!circ) {
-//XXX
- log_fn(LOG_INFO,"No safe circuit ready for edge connection; delaying.");
- addr = client_dns_lookup_entry(conn->socks_request->address);
- if(router_exit_policy_all_routers_reject(addr, conn->socks_request->port)) {
- log_fn(LOG_WARN,"No Tor server exists that allows exit to %s:%d. Rejecting.",
- conn->socks_request->address, conn->socks_request->port);
- return -1;
+
+ log_fn(LOG_INFO,"No safe circuit (purpose %d) ready for edge connection; delaying.",
+ desired_circuit_purpose);
+
+ if(conn->purpose == AP_PURPOSE_GENERAL) {
+ addr = client_dns_lookup_entry(conn->socks_request->address);
+ if(router_exit_policy_all_routers_reject(addr, conn->socks_request->port)) {
+ log_fn(LOG_WARN,"No Tor server exists that allows exit to %s:%d. Rejecting.",
+ conn->socks_request->address, conn->socks_request->port);
+ return -1;
+ }
}
if(!circuit_get_newest(conn, 0, desired_circuit_purpose)) {
/* is one already on the way? */
- circuit_launch_new(desired_circuit_purpose, NULL);
+ circ = circuit_launch_new(desired_circuit_purpose, NULL);
+ /* depending on purpose, store stuff into circ */
+ if (desired_circuit_purpose == CIRCUIT_PURPOSE_C_GENERAL ||
+ desired_circuit_purpose == CIRCUIT_PURPOSE_C_ESTABLISH_REND) {
+ /* then write the service_id into circ */
+ strncpy(circ->rend_query, conn->socks_request->address,
+ CRYPTO_SHA1_DIGEST_LEN); /* pad with nuls */
+ }
}
return 0;
}
+ /* We have found a suitable circuit for our conn. Hurray. */
+
/* here, print the circ's path. so people can figure out which circs are sucking. */
circuit_log_path(LOG_INFO,circ);
@@ -823,7 +837,6 @@ static int connection_ap_handshake_attach_circuit(connection_t *conn) {
switch(conn->purpose) {
case AP_PURPOSE_GENERAL:
- case AP_PURPOSE_RENDDESC_WAIT:
/* add it into the linked list of streams on this circuit */
log_fn(LOG_DEBUG,"attaching new conn to circ. n_circ_id %d.", circ->n_circ_id);
conn->next_stream = circ->p_streams;
@@ -837,7 +850,11 @@ static int connection_ap_handshake_attach_circuit(connection_t *conn) {
connection_ap_handshake_send_begin(conn, circ);
break;
case AP_PURPOSE_RENDPOINT_WAIT:
+ rend_client_rendcirc_is_ready(conn, circ);
+ break;
case AP_PURPOSE_INTROPOINT_WAIT:
+ rend_client_introcirc_is_ready(conn, circ);
+ break;
}
return 1;
diff --git a/src/or/directory.c b/src/or/directory.c
index d2a3126cd..29a8b153b 100644
--- a/src/or/directory.c
+++ b/src/or/directory.c
@@ -275,11 +275,12 @@ int connection_dir_process_inbuf(connection_t *conn) {
/* alice's ap_stream is just going to have to time out. */
} else {
/* success. notify pending connections about this. */
- rend_client_desc_fetched(conn->rend_query);
+ rend_client_desc_fetched(conn->rend_query, 1);
}
break;
case 404:
- rend_client_desc_not_fetched(conn->rend_query);
+ /* not there. also notify pending connections. */
+ rend_client_desc_fetched(conn->rend_query, 0);
break;
case 400:
log_fn(LOG_WARN,"http status 400 (bad request). Dirserver didn't like our rendezvous query?");
diff --git a/src/or/or.h b/src/or/or.h
index 7f1015d87..7b4383a46 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -553,14 +553,17 @@ struct circuit_t {
uint8_t state;
uint8_t purpose;
- /* The field rend_service:
- * 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.
- * is filled with zeroes otherwise.
+ /*
+ * rend_query holds y portion of y.onion (nul-terminated) if purpose
+ * is C_INTRODUCING or C_ESTABLISH_REND, or is a C_GENERAL for a
+ * hidden service.
*/
- char rend_service[CRYPTO_SHA1_DIGEST_LEN];
+ char rend_query[REND_SERVICE_ID_LEN+1];
+
+ /* rend_pk_digest 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[CRYPTO_SHA1_DIGEST_LEN];
/* Holds rendezvous cookie if purpose is REND_POINT_WAITING or
* C_ESTABLISH_REND. Filled with zeroes otherwise.
@@ -1028,8 +1031,10 @@ void rep_hist_dump_stats(time_t now, int severity);
/********************************* rendclient.c ***************************/
-void rend_client_desc_fetched(char *query);
-void rend_client_desc_not_fetched(char *query);
+void rend_client_introcirc_is_ready(connection_t *apconn, circuit_t *circ);
+void rend_client_rendcirc_is_ready(connection_t *apconn, circuit_t *circ);
+void rend_client_rendezvous(connection_t *apconn, circuit_t *circ);
+void rend_client_desc_fetched(char *query, int success);
/********************************* rendcommon.c ***************************/
diff --git a/src/or/rendclient.c b/src/or/rendclient.c
index a71dce9d0..1882d3f40 100644
--- a/src/or/rendclient.c
+++ b/src/or/rendclient.c
@@ -6,7 +6,7 @@
/* send the introduce cell */
void
-rend_client_intro_is_ready()
+rend_client_introcirc_is_ready(connection_t *apconn, circuit_t *circ)
{
@@ -14,7 +14,7 @@ rend_client_intro_is_ready()
/* send the rendezvous cell */
void
-rend_client_rendezvous_is_ready()
+rend_client_rendcirc_is_ready(connection_t *apconn, circuit_t *circ)
{
@@ -22,7 +22,7 @@ rend_client_rendezvous_is_ready()
/* bob sent us a rendezvous cell, join the circs. */
void
-rend_client_rendezvous()
+rend_client_rendezvous(connection_t *apconn, circuit_t *circ)
{
@@ -31,14 +31,39 @@ rend_client_rendezvous()
-void rend_client_desc_fetched(char *query) {
-
-
-}
-
-void rend_client_desc_not_fetched(char *query) {
-
-
+/* Find all the apconns in purpose AP_PURPOSE_RENDDESC_WAIT that
+ * are waiting on query. If success==1, move them to the next state.
+ * If success==0, fail them.
+ */
+void rend_client_desc_fetched(char *query, int success) {
+ connection_t **carray;
+ connection_t *conn;
+ int n, i;
+
+ get_connection_array(&carray, &n);
+
+ for (i = 0; i < n; ++i) {
+ conn = carray[i];
+ if (conn->type != CONN_TYPE_AP ||
+ conn->state != AP_CONN_STATE_CIRCUIT_WAIT)
+ continue;
+ if (conn->purpose != AP_PURPOSE_RENDDESC_WAIT)
+ continue;
+ if (rend_cmp_service_ids(conn->socks_request->address, query))
+ continue;
+ /* great, this guy was waiting */
+ if(success) {
+ conn->purpose = AP_PURPOSE_RENDPOINT_WAIT;
+ if (connection_ap_handshake_attach_circuit(conn) < 0) {
+ /* it will never work */
+ log_fn(LOG_WARN,"attaching to a rend circ failed. Closing conn.");
+ connection_mark_for_close(conn,0);
+ }
+ } else { /* 404 */
+ log_fn(LOG_WARN,"service id '%s' not found. Closing conn.", query);
+ connection_mark_for_close(conn,0);
+ }
+ }
}
/*
diff --git a/src/or/routerlist.c b/src/or/routerlist.c
index 048dc4947..711cf8d59 100644
--- a/src/or/routerlist.c
+++ b/src/or/routerlist.c
@@ -196,6 +196,9 @@ void add_nickname_list_to_smartlist(smartlist_t *sl, char *list) {
char nick[MAX_NICKNAME_LEN];
routerinfo_t *router;
+ assert(sl);
+ assert(list);
+
while(isspace((int)*list) || *list==',') list++;
start = list;