[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...



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