Loading src/or/circuit.c +7 −0 Changes for src/or/circuit.c: 7 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -997,6 +997,13 @@ int _circuit_mark_for_close(circuit_t *circ) { circuit_build_failed(circ); /* take actions if necessary */ circuit_rep_hist_note_result(circ); } if (circ->purpose == CIRCUIT_PURPOSE_C_INTRODUCE_ACK_WAIT) { assert(circ->state == CIRCUIT_STATE_OPEN); /* treat this like getting a nack from it */ log_fn(LOG_INFO,"Failed intro circ %s to %s (awaiting ack). Removing from descriptor.", circ->rend_query, circ->build_state->chosen_exit); rend_client_remove_intro_point(circ->build_state->chosen_exit, circ->rend_query); } if(circ->n_conn) connection_send_destroy(circ->n_circ_id, circ->n_conn); Loading src/or/connection_edge.c +1 −8 Changes for src/or/connection_edge.c: 1 added line, 8 removed lines. Original line number Diff line number Diff line Loading @@ -757,14 +757,7 @@ static int connection_ap_handshake_process_socks(connection_t *conn) { return connection_ap_handshake_attach_circuit(conn); } else { conn->state = AP_CONN_STATE_RENDDESC_WAIT; if(connection_get_by_type_rendquery(CONN_TYPE_DIR, conn->rend_query)) { log_fn(LOG_INFO,"Would fetch a new renddesc here (for %s), but one is already in progress.", conn->rend_query); } else { /* not one already; initiate a dir rend desc lookup */ directory_initiate_command(router_pick_directory_server(), DIR_PURPOSE_FETCH_RENDDESC, conn->rend_query, strlen(conn->rend_query)); } rend_client_refetch_renddesc(conn->rend_query); return 0; } } Loading src/or/or.h +2 −0 Changes for src/or/or.h: 2 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -1043,6 +1043,8 @@ void rep_hist_dump_stats(time_t now, int severity); void rend_client_introcirc_is_open(circuit_t *circ); void rend_client_rendcirc_is_open(circuit_t *circ); int rend_client_introduction_acked(circuit_t *circ, const char *request, int request_len); void rend_client_refetch_renddesc(char *query); int rend_client_remove_intro_point(char *failed_intro, char *query); int rend_client_rendezvous_acked(circuit_t *circ, const char *request, int request_len); int rend_client_receive_rendezvous(circuit_t *circ, const char *request, int request_len); void rend_client_desc_fetched(char *query, int success); Loading src/or/rendclient.c +58 −38 Changes for src/or/rendclient.c: 58 added lines, 38 removed lines. Original line number Diff line number Diff line Loading @@ -147,8 +147,6 @@ int rend_client_introduction_acked(circuit_t *circ, const char *request, int request_len) { int i, r; rend_cache_entry_t *ent; char *nickname; circuit_t *rendcirc; Loading Loading @@ -177,44 +175,25 @@ rend_client_introduction_acked(circuit_t *circ, } else { /* It's a NAK; the introduction point didn't relay our request. */ circ->purpose = CIRCUIT_PURPOSE_C_INTRODUCING; /* XXXX * Now become non-open, extend to another one of Bob's * introduction points, and try again. Maybe mark the service as * non-functional at the first intro point somehow? * * Or re-fetch the service descriptor? Hm.... */ r = rend_cache_lookup_entry(circ->rend_query, &ent); if (r<0) { log_fn(LOG_WARN, "Malformed service ID '%s'", circ->rend_query); return -1; } if (r>0) { /* Okay, we found the right service desc. First, remove this intro point * from the parsed descriptor (if it's still there!) /* Remove this intro point from the set of viable introduction * points. If any remain, extend to a new one and try again. * If none remain, refetch the service descriptor. */ 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 if(rend_client_remove_intro_point(circ->build_state->chosen_exit, circ->rend_query) > 0) { /* There are 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); log_fn(LOG_INFO,"Got nack for %s from %s, extending to %s.", circ->rend_query, circ->build_state->chosen_exit, nickname); if (!router_get_by_nickname(nickname)) { log_fn(LOG_WARN, "Advertised intro point '%s' for %s is not known. Closing.", nickname, circ->rend_query); circuit_mark_for_close(circ); return -1; } log_fn(LOG_INFO, "Chose new intro point %s for %s (circ %d, %d choices left)", nickname, circ->rend_query, circ->n_circ_id, ent->parsed->n_intro_points); 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); Loading @@ -224,23 +203,64 @@ rend_client_introduction_acked(circuit_t *circ, 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. */ circ->purpose = CIRCUIT_PURPOSE_C_INTRODUCING; /* XXX anything else we need to do to circ? */ /* Refetch descriptor */ if(!connection_get_by_type_rendquery(CONN_TYPE_DIR, circ->rend_query)) { return 0; } void rend_client_refetch_renddesc(char *query) { if(connection_get_by_type_rendquery(CONN_TYPE_DIR, query)) { log_fn(LOG_INFO,"Would fetch a new renddesc here (for %s), but one is already in progress.", query); } else { /* 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)); query, strlen(query)); } } /* remove failed_intro from ent. if ent now has no intro points, or * service is unrecognized, then launch a new renddesc fetch. * * Return -1 if error, 0 if no intro points remain or service * unrecognized, 1 if recognized and some intro points remain. */ int rend_client_remove_intro_point(char *failed_intro, char *query) { int i, r; rend_cache_entry_t *ent; r = rend_cache_lookup_entry(query, &ent); if (r<0) { log_fn(LOG_WARN, "Malformed service ID '%s'", query); return -1; } if (r==0) { log_fn(LOG_INFO, "Unknown service %s. Re-fetching descriptor.", query); rend_client_refetch_renddesc(query); return 0; } for (i=0; i < ent->parsed->n_intro_points; ++i) { if (!strcasecmp(ent->parsed->intro_points[i], failed_intro)) { tor_free(ent->parsed->intro_points[i]); ent->parsed->intro_points[i] = ent->parsed->intro_points[--ent->parsed->n_intro_points]; break; } } if(!ent->parsed->n_intro_points) { log_fn(LOG_INFO,"No more intro points remain for %s. Re-fetching descriptor.", query); rend_client_refetch_renddesc(query); return 0; } log_fn(LOG_INFO,"%d options left for %s.", ent->parsed->n_intro_points, query); return 1; } /* Called when we receive a RENDEZVOUS_ESTABLISHED cell; changes the state of * the circuit to C_REND_READY. Loading Loading
src/or/circuit.c +7 −0 Changes for src/or/circuit.c: 7 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -997,6 +997,13 @@ int _circuit_mark_for_close(circuit_t *circ) { circuit_build_failed(circ); /* take actions if necessary */ circuit_rep_hist_note_result(circ); } if (circ->purpose == CIRCUIT_PURPOSE_C_INTRODUCE_ACK_WAIT) { assert(circ->state == CIRCUIT_STATE_OPEN); /* treat this like getting a nack from it */ log_fn(LOG_INFO,"Failed intro circ %s to %s (awaiting ack). Removing from descriptor.", circ->rend_query, circ->build_state->chosen_exit); rend_client_remove_intro_point(circ->build_state->chosen_exit, circ->rend_query); } if(circ->n_conn) connection_send_destroy(circ->n_circ_id, circ->n_conn); Loading
src/or/connection_edge.c +1 −8 Changes for src/or/connection_edge.c: 1 added line, 8 removed lines. Original line number Diff line number Diff line Loading @@ -757,14 +757,7 @@ static int connection_ap_handshake_process_socks(connection_t *conn) { return connection_ap_handshake_attach_circuit(conn); } else { conn->state = AP_CONN_STATE_RENDDESC_WAIT; if(connection_get_by_type_rendquery(CONN_TYPE_DIR, conn->rend_query)) { log_fn(LOG_INFO,"Would fetch a new renddesc here (for %s), but one is already in progress.", conn->rend_query); } else { /* not one already; initiate a dir rend desc lookup */ directory_initiate_command(router_pick_directory_server(), DIR_PURPOSE_FETCH_RENDDESC, conn->rend_query, strlen(conn->rend_query)); } rend_client_refetch_renddesc(conn->rend_query); return 0; } } Loading
src/or/or.h +2 −0 Changes for src/or/or.h: 2 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -1043,6 +1043,8 @@ void rep_hist_dump_stats(time_t now, int severity); void rend_client_introcirc_is_open(circuit_t *circ); void rend_client_rendcirc_is_open(circuit_t *circ); int rend_client_introduction_acked(circuit_t *circ, const char *request, int request_len); void rend_client_refetch_renddesc(char *query); int rend_client_remove_intro_point(char *failed_intro, char *query); int rend_client_rendezvous_acked(circuit_t *circ, const char *request, int request_len); int rend_client_receive_rendezvous(circuit_t *circ, const char *request, int request_len); void rend_client_desc_fetched(char *query, int success); Loading
src/or/rendclient.c +58 −38 Changes for src/or/rendclient.c: 58 added lines, 38 removed lines. Original line number Diff line number Diff line Loading @@ -147,8 +147,6 @@ int rend_client_introduction_acked(circuit_t *circ, const char *request, int request_len) { int i, r; rend_cache_entry_t *ent; char *nickname; circuit_t *rendcirc; Loading Loading @@ -177,44 +175,25 @@ rend_client_introduction_acked(circuit_t *circ, } else { /* It's a NAK; the introduction point didn't relay our request. */ circ->purpose = CIRCUIT_PURPOSE_C_INTRODUCING; /* XXXX * Now become non-open, extend to another one of Bob's * introduction points, and try again. Maybe mark the service as * non-functional at the first intro point somehow? * * Or re-fetch the service descriptor? Hm.... */ r = rend_cache_lookup_entry(circ->rend_query, &ent); if (r<0) { log_fn(LOG_WARN, "Malformed service ID '%s'", circ->rend_query); return -1; } if (r>0) { /* Okay, we found the right service desc. First, remove this intro point * from the parsed descriptor (if it's still there!) /* Remove this intro point from the set of viable introduction * points. If any remain, extend to a new one and try again. * If none remain, refetch the service descriptor. */ 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 if(rend_client_remove_intro_point(circ->build_state->chosen_exit, circ->rend_query) > 0) { /* There are 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); log_fn(LOG_INFO,"Got nack for %s from %s, extending to %s.", circ->rend_query, circ->build_state->chosen_exit, nickname); if (!router_get_by_nickname(nickname)) { log_fn(LOG_WARN, "Advertised intro point '%s' for %s is not known. Closing.", nickname, circ->rend_query); circuit_mark_for_close(circ); return -1; } log_fn(LOG_INFO, "Chose new intro point %s for %s (circ %d, %d choices left)", nickname, circ->rend_query, circ->n_circ_id, ent->parsed->n_intro_points); 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); Loading @@ -224,23 +203,64 @@ rend_client_introduction_acked(circuit_t *circ, 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. */ circ->purpose = CIRCUIT_PURPOSE_C_INTRODUCING; /* XXX anything else we need to do to circ? */ /* Refetch descriptor */ if(!connection_get_by_type_rendquery(CONN_TYPE_DIR, circ->rend_query)) { return 0; } void rend_client_refetch_renddesc(char *query) { if(connection_get_by_type_rendquery(CONN_TYPE_DIR, query)) { log_fn(LOG_INFO,"Would fetch a new renddesc here (for %s), but one is already in progress.", query); } else { /* 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)); query, strlen(query)); } } /* remove failed_intro from ent. if ent now has no intro points, or * service is unrecognized, then launch a new renddesc fetch. * * Return -1 if error, 0 if no intro points remain or service * unrecognized, 1 if recognized and some intro points remain. */ int rend_client_remove_intro_point(char *failed_intro, char *query) { int i, r; rend_cache_entry_t *ent; r = rend_cache_lookup_entry(query, &ent); if (r<0) { log_fn(LOG_WARN, "Malformed service ID '%s'", query); return -1; } if (r==0) { log_fn(LOG_INFO, "Unknown service %s. Re-fetching descriptor.", query); rend_client_refetch_renddesc(query); return 0; } for (i=0; i < ent->parsed->n_intro_points; ++i) { if (!strcasecmp(ent->parsed->intro_points[i], failed_intro)) { tor_free(ent->parsed->intro_points[i]); ent->parsed->intro_points[i] = ent->parsed->intro_points[--ent->parsed->n_intro_points]; break; } } if(!ent->parsed->n_intro_points) { log_fn(LOG_INFO,"No more intro points remain for %s. Re-fetching descriptor.", query); rend_client_refetch_renddesc(query); return 0; } log_fn(LOG_INFO,"%d options left for %s.", ent->parsed->n_intro_points, query); return 1; } /* Called when we receive a RENDEZVOUS_ESTABLISHED cell; changes the state of * the circuit to C_REND_READY. Loading