From a8d805e292142b2ba094c5066c59291953ae93ab Mon Sep 17 00:00:00 2001 From: Roger Dingledine Date: Fri, 2 Apr 2004 23:38:26 +0000 Subject: [PATCH] break out circ->rend_service (this breaks the compile; must fix things) let alice react when she learns a new rendezvous descriptor let alice launch intro and rend circuits and mark them with her query svn:r1446 --- src/or/circuit.c | 17 +++++++--------- src/or/connection_edge.c | 39 ++++++++++++++++++++++++++---------- src/or/directory.c | 5 +++-- src/or/or.h | 23 ++++++++++++--------- src/or/rendclient.c | 43 +++++++++++++++++++++++++++++++--------- src/or/routerlist.c | 3 +++ 6 files changed, 89 insertions(+), 41 deletions(-) diff --git a/src/or/circuit.c b/src/or/circuit.c index f3f1c6f586..9c7b1a825d 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 89d7dabae1..83459e3488 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 d2a3126cdc..29a8b153be 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 7f1015d875..7b4383a468 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 a71dce9d0f..1882d3f409 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 048dc49475..711cf8d594 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;