Bladeren bron

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

Roger Dingledine 21 jaren geleden
bovenliggende
commit
a8d805e292
6 gewijzigde bestanden met toevoegingen van 91 en 43 verwijderingen
  1. 7 10
      src/or/circuit.c
  2. 28 11
      src/or/connection_edge.c
  3. 3 2
      src/or/directory.c
  4. 14 9
      src/or/or.h
  5. 36 11
      src/or/rendclient.c
  6. 3 0
      src/or/routerlist.c

+ 7 - 10
src/or/circuit.c

@@ -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;
         }
@@ -1046,21 +1046,18 @@ static void circuit_is_ready(circuit_t *circ) {
   switch(circ->purpose) {
     case CIRCUIT_PURPOSE_C_GENERAL:
       /* Tell any AP connections that have been waiting for a new
-      * circuit that one is ready. */
+       * 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);

+ 28 - 11
src/or/connection_edge.c

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

+ 3 - 2
src/or/directory.c

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

+ 14 - 9
src/or/or.h

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

+ 36 - 11
src/or/rendclient.c

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

+ 3 - 0
src/or/routerlist.c

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