Browse Source

patch from karsten for bug 814. whew.

svn:r16915
Roger Dingledine 15 years ago
parent
commit
38f2272d5d
5 changed files with 33 additions and 11 deletions
  1. 6 0
      ChangeLog
  2. 7 2
      src/or/connection.c
  3. 2 2
      src/or/directory.c
  4. 1 1
      src/or/or.h
  5. 17 6
      src/or/rendclient.c

+ 6 - 0
ChangeLog

@@ -24,6 +24,12 @@ Changes in version 0.2.1.6-alpha - 2008-09-xx
       for bug 811.
     - Catch and report a few more bootstrapping failure cases when Tor
       fails to establish a TCP connection. Cleanup on 0.2.1.x.
+    - When fetching v0 and v2 rendezvous service descriptors in parallel,
+      do not fail the whole hidden service request only because the v0
+      descriptor fetch request fails; the v2 request might still succeed.
+      The other way round, when the last v2 request fails and no v0 request
+      is going on, do fail the hidden service request. Fixes bug 814.
+      Bugfix on 0.2.0.10-alpha.
 
   o Minor features:
     - Allow ports 465 and 587 in the default exit policy again. We had

+ 7 - 2
src/or/connection.c

@@ -523,8 +523,13 @@ connection_about_to_close_connection(connection_t *conn)
          * failed: forget about this router, and maybe try again. */
         connection_dir_request_failed(dir_conn);
       }
-      if (conn->purpose == DIR_PURPOSE_FETCH_RENDDESC)
-        rend_client_desc_here(dir_conn->rend_query); /* give it a try */
+      if (conn->purpose == DIR_PURPOSE_FETCH_RENDDESC) {
+        /* Give it a try. However, there is no re-fetching for v0 rend
+         * descriptors; if the response is empty or the descriptor is
+         * unusable, close pending connections (unless a v2 request is
+         * still in progress). */
+        rend_client_desc_here(dir_conn->rend_query, 0);
+      }
       /* If we were trying to fetch a v2 rend desc and did not succeed,
        * retry as needed. (If a fetch is successful, the connection state
        * is changed to DIR_PURPOSE_HAS_FETCHED_RENDDESC to mark that

+ 2 - 2
src/or/directory.c

@@ -1892,7 +1892,7 @@ connection_dir_client_reached_eof(dir_connection_t *conn)
         } else {
           /* success. notify pending connections about this. */
           conn->_base.purpose = DIR_PURPOSE_HAS_FETCHED_RENDDESC;
-          rend_client_desc_here(conn->rend_query);
+          rend_client_desc_here(conn->rend_query, -1);
         }
         break;
       case 404:
@@ -1938,7 +1938,7 @@ connection_dir_client_reached_eof(dir_connection_t *conn)
             log_info(LD_REND, "Successfully fetched v2 rendezvous "
                      "descriptor.");
             conn->_base.purpose = DIR_PURPOSE_HAS_FETCHED_RENDDESC;
-            rend_client_desc_here(conn->rend_query);
+            rend_client_desc_here(conn->rend_query, -1);
             break;
         }
         break;

+ 1 - 1
src/or/or.h

@@ -3842,7 +3842,7 @@ int rend_client_rendezvous_acked(origin_circuit_t *circ, const char *request,
                                  size_t request_len);
 int rend_client_receive_rendezvous(origin_circuit_t *circ, const char *request,
                                    size_t request_len);
-void rend_client_desc_here(const char *query);
+void rend_client_desc_here(const char *query, int rend_version);
 
 extend_info_t *rend_client_get_random_intro(const char *query);
 

+ 17 - 6
src/or/rendclient.c

@@ -462,6 +462,8 @@ rend_client_refetch_v2_renddesc(const char *query)
   log_info(LD_REND, "Could not pick one of the responsible hidden "
                     "service directories to fetch descriptors, because "
                     "we already tried them all unsuccessfully.");
+  /* Close pending connections (unless a v0 request is still going on). */
+  rend_client_desc_here(query, 2);
   return;
 }
 
@@ -625,11 +627,14 @@ rend_client_receive_rendezvous(origin_circuit_t *circ, const char *request,
 
 /** Find all the apconns in state AP_CONN_STATE_RENDDESC_WAIT that
  * are waiting on query. If there's a working cache entry here
- * with at least one intro point, move them to the next state;
- * else fail them.
+ * with at least one intro point, move them to the next state. If
+ * <b>rend_version</b> is non-negative, fail connections that have
+ * requested <b>query</b> unless there are still descriptor fetch
+ * requests in progress for other descriptor versions than
+ * <b>rend_version</b>.
  */
 void
-rend_client_desc_here(const char *query)
+rend_client_desc_here(const char *query, int rend_version)
 {
   edge_connection_t *conn;
   rend_cache_entry_t *entry;
@@ -666,9 +671,15 @@ rend_client_desc_here(const char *query)
           connection_mark_unattached_ap(conn, END_STREAM_REASON_CANT_ATTACH);
       }
     } else { /* 404, or fetch didn't get that far */
-      log_notice(LD_REND,"Closing stream for '%s.onion': hidden service is "
-                 "unavailable (try again later).", safe_str(query));
-      connection_mark_unattached_ap(conn, END_STREAM_REASON_RESOLVEFAILED);
+      /* Unless there are requests for another descriptor version pending,
+       * close the connection. */
+      if (rend_version >= 0 &&
+          !connection_get_by_type_state_rendquery(CONN_TYPE_DIR, 0, query,
+                                                  rend_version == 0 ? 2 : 0)) {
+        log_notice(LD_REND,"Closing stream for '%s.onion': hidden service is "
+                   "unavailable (try again later).", safe_str(query));
+        connection_mark_unattached_ap(conn, END_STREAM_REASON_RESOLVEFAILED);
+      }
     }
   });
 }