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
This commit is contained in:
Roger Dingledine 2004-04-02 23:38:26 +00:00
parent e8345bfced
commit a8d805e292
6 changed files with 89 additions and 41 deletions

View File

@ -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;
}
@ -1047,20 +1047,17 @@ static void circuit_is_ready(circuit_t *circ) {
case CIRCUIT_PURPOSE_C_GENERAL:
/* Tell any AP connections that have been waiting for a new
* 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);

View File

@ -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.");
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;

View File

@ -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?");

View File

@ -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 ***************************/

View File

@ -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);
}
}
}
/*

View File

@ -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;