diff options
author | Nick Mathewson <nickm@torproject.org> | 2004-04-13 02:31:52 +0000 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2004-04-13 02:31:52 +0000 |
commit | e53ba59250834f9d5ae8f17adc585446a8b2e2d6 (patch) | |
tree | 6742b47a0d4bf659534e563a70c54cb6f923b8ba /src/or/rendclient.c | |
parent | 8483bace6591836d289e55d42f6c2fd94e806aa5 (diff) | |
download | tor-e53ba59250834f9d5ae8f17adc585446a8b2e2d6.tar.gz tor-e53ba59250834f9d5ae8f17adc585446a8b2e2d6.zip |
Handle introduce naks. Arma: Is this right?
svn:r1602
Diffstat (limited to 'src/or/rendclient.c')
-rw-r--r-- | src/or/rendclient.c | 61 |
1 files changed, 59 insertions, 2 deletions
diff --git a/src/or/rendclient.c b/src/or/rendclient.c index 5fba33006f..fb4543aedd 100644 --- a/src/or/rendclient.c +++ b/src/or/rendclient.c @@ -143,6 +143,10 @@ int rend_client_introduction_acked(circuit_t *circ, const char *request, int request_len) { + int i; + rend_cache_entry_t *ent; + char *nickname; + if (circ->purpose != CIRCUIT_PURPOSE_C_INTRODUCE_ACK_WAIT) { log_fn(LOG_WARN, "Recieved REND_INTRODUCE_ACK on unexpected circuit %d", circ->n_circ_id); @@ -150,6 +154,8 @@ rend_client_introduction_acked(circuit_t *circ, return -1; } + assert(circ->build_state->chosen_exit); + if (request_len == 0) { /* It's an ACK; the introduction point relayed our introduction request. */ /* So close the circuit; we won't need it any more. */ @@ -163,9 +169,60 @@ rend_client_introduction_acked(circuit_t *circ, * non-functional at the first intro point somehow? * * Or re-fetch the service descriptor? Hm.... - * - * XXXX writeme */ + i = rend_cache_lookup_entry(circ->rend_query, &ent); + if (i<0) { + log_fn(LOG_WARN, "Malformed service ID '%s'", circ->rend_query); + return -1; + } + if (i>0) { + /* Okay, we found the right service desc. First, remove this intro point + * from the parsed descriptor (if it's still there!) + */ + for (i=0; i < ent->parsed->n_intro_points; ++i) { + if (!strcasecmp(ent->parsed->intro_points[i], + circ->build_state->chosen_exit)) { + tor_free(ent->parsed->intro_points[i]); + ent->parsed->intro_points[i] = + ent->parsed->intro_points[--ent->parsed->n_intro_points]; + break; + } + } + /* If there are any introduction points left, re-extend the circuit to + * another intro point and try again. */ + if (ent->parsed->n_intro_points) { + nickname = rend_client_get_random_intro(circ->rend_query); + assert(nickname); + if (!router_get_by_nickname(nickname)) { + log_fn(LOG_WARN, "Advertised intro point '%s' is not known. Closing.", + nickname); + circuit_mark_for_close(circ); + return -1; + } + log_fn(LOG_INFO, "Chose new intro point %s for %s (circ %d)", + nickname, circ->rend_query, circ->n_circ_id); + circ->state = CIRCUIT_STATE_BUILDING; + tor_free(circ->build_state->chosen_exit); + circ->build_state->chosen_exit = tor_strdup(nickname); + ++circ->build_state->desired_path_len; + if (circuit_send_next_onion_skin(circ)<0) { + log_fn(LOG_WARN, "Couldn't extend circuit to new intro point."); + circuit_mark_for_close(circ); + return -1; + } + return 0; + } + } + /* Either we have no service desc, or all the intro points in that + * descriptor failed. So re-fetch the descriptor and try again. */ + /* XXXX What do we do to this circ in the meantime? */ + /* Refetch descriptor */ + if(!connection_get_by_type_rendquery(CONN_TYPE_DIR, circ->rend_query)) { + /* not one already; initiate a dir rend desc lookup */ + directory_initiate_command(router_pick_directory_server(), + DIR_PURPOSE_FETCH_RENDDESC, + circ->rend_query, strlen(circ->rend_query)); + } } return 0; } |