[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[or-cvs] if an intro circ waiting for an ack dies before getting one...
- To: or-cvs@freehaven.net
- Subject: [or-cvs] if an intro circ waiting for an ack dies before getting one...
- From: arma@seul.org (Roger Dingledine)
- Date: Sun, 18 Apr 2004 03:37:18 -0400 (EDT)
- Delivered-to: archiver@seul.org
- Delivered-to: or-cvs-outgoing@seul.org
- Delivered-to: or-cvs@seul.org
- Delivery-date: Sun, 18 Apr 2004 03:37:56 -0400
- Reply-to: or-dev@freehaven.net
- Sender: owner-or-cvs@freehaven.net
Update of /home/or/cvsroot/src/or
In directory moria.mit.edu:/home2/arma/work/onion/cvs/src/or
Modified Files:
circuit.c connection_edge.c or.h rendclient.c
Log Message:
if an intro circ waiting for an ack dies before getting one, then
count it as a nack
Index: circuit.c
===================================================================
RCS file: /home/or/cvsroot/src/or/circuit.c,v
retrieving revision 1.215
retrieving revision 1.216
diff -u -d -r1.215 -r1.216
--- circuit.c 17 Apr 2004 10:25:38 -0000 1.215
+++ circuit.c 18 Apr 2004 07:37:15 -0000 1.216
@@ -997,6 +997,13 @@
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);
Index: connection_edge.c
===================================================================
RCS file: /home/or/cvsroot/src/or/connection_edge.c,v
retrieving revision 1.173
retrieving revision 1.174
diff -u -d -r1.173 -r1.174
--- connection_edge.c 18 Apr 2004 06:35:31 -0000 1.173
+++ connection_edge.c 18 Apr 2004 07:37:15 -0000 1.174
@@ -757,14 +757,7 @@
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;
}
}
Index: or.h
===================================================================
RCS file: /home/or/cvsroot/src/or/or.h,v
retrieving revision 1.320
retrieving revision 1.321
diff -u -d -r1.320 -r1.321
--- or.h 17 Apr 2004 06:35:18 -0000 1.320
+++ or.h 18 Apr 2004 07:37:15 -0000 1.321
@@ -1043,6 +1043,8 @@
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);
Index: rendclient.c
===================================================================
RCS file: /home/or/cvsroot/src/or/rendclient.c,v
retrieving revision 1.42
retrieving revision 1.43
diff -u -d -r1.42 -r1.43
--- rendclient.c 16 Apr 2004 14:35:28 -0000 1.42
+++ rendclient.c 18 Apr 2004 07:37:16 -0000 1.43
@@ -147,8 +147,6 @@
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;
@@ -177,71 +175,93 @@
} 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....
+ /* 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.
*/
- 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!)
- */
- 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);
- 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);
- 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;
+ 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)",
+ 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;
}
- }
- /* 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)) {
- /* 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;
}
+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,
+ 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.
*/