Browse Source

patch4 from proposal 155:
Hidden services start out building five intro circuits rather
than three, and when the first three finish they publish a service
descriptor using those. Now we publish our service descriptor much
faster after restart.


svn:r17110

Roger Dingledine 17 years ago
parent
commit
a5769eefa4
2 changed files with 49 additions and 6 deletions
  1. 9 3
      ChangeLog
  2. 40 3
      src/or/rendservice.c

+ 9 - 3
ChangeLog

@@ -3,18 +3,24 @@ Changes in version 0.2.1.7-alpha - 2008-10-xx
     - Now NodeFamily and MyFamily config options allow spaces in
     - Now NodeFamily and MyFamily config options allow spaces in
       identity fingerprints, so it's easier to paste them in.
       identity fingerprints, so it's easier to paste them in.
       Suggested by Lucky Green.
       Suggested by Lucky Green.
+
+  o Hidden service performance improvements:
     - Reduce extension timeout for introduction circuits on the hidden
     - Reduce extension timeout for introduction circuits on the hidden
       service side from 60 to 30 seconds.
       service side from 60 to 30 seconds.
     - Launch a second client-side introduction circuit in parallel
     - Launch a second client-side introduction circuit in parallel
       after a delay of 15 seconds (based on work by Christian Wilms).
       after a delay of 15 seconds (based on work by Christian Wilms).
+    - Hidden services start out building five intro circuits rather
+      than three, and when the first three finish they publish a service
+      descriptor using those. Now we publish our service descriptor much
+      faster after restart.
 
 
   o Minor bugfixes:
   o Minor bugfixes:
     - Minor fix in the warning messages when you're having problems
     - Minor fix in the warning messages when you're having problems
       bootstrapping; also, be more forgiving of bootstrap problems when
       bootstrapping; also, be more forgiving of bootstrap problems when
       we're still making incremental progress on a given bootstrap phase.
       we're still making incremental progress on a given bootstrap phase.
-    - When we're choosing an exit node for a circuit, and we have no pending
-      streams, choose a good general exit rather than one that supports "all
-      the pending streams".  Bugfix on 0.1.1.x. (Fix by rovv.)
+    - When we're choosing an exit node for a circuit, and we have
+      no pending streams, choose a good general exit rather than one that
+      supports "all the pending streams". Bugfix on 0.1.1.x. Fix by rovv.
 
 
 
 
 Changes in version 0.2.1.6-alpha - 2008-09-30
 Changes in version 0.2.1.6-alpha - 2008-09-30

+ 40 - 3
src/or/rendservice.c

@@ -1275,6 +1275,28 @@ rend_service_launch_establish_intro(rend_service_t *service,
   return 0;
   return 0;
 }
 }
 
 
+/** Return the number of introduction points that are or have been
+ * established for the given service address and rendezvous version. */
+static int
+count_established_intro_points(const char *query, int rend_version)
+{
+  int num_ipos = 0;
+  circuit_t *circ;
+  for (circ = _circuit_get_global_list(); circ; circ = circ->next) {
+    if (!circ->marked_for_close &&
+        circ->state == CIRCUIT_STATE_OPEN &&
+        (circ->purpose == CIRCUIT_PURPOSE_S_ESTABLISH_INTRO ||
+         circ->purpose == CIRCUIT_PURPOSE_S_INTRO)) {
+      origin_circuit_t *oc = TO_ORIGIN_CIRCUIT(circ);
+      if (oc->rend_data &&
+          oc->rend_data->rend_desc_version == rend_version &&
+          !rend_cmp_service_ids(query, oc->rend_data->onion_address))
+        num_ipos++;
+    }
+  }
+  return num_ipos;
+}
+
 /** Called when we're done building a circuit to an introduction point:
 /** Called when we're done building a circuit to an introduction point:
  *  sends a RELAY_ESTABLISH_INTRO cell.
  *  sends a RELAY_ESTABLISH_INTRO cell.
  */
  */
@@ -1307,6 +1329,18 @@ rend_service_intro_has_opened(origin_circuit_t *circuit)
     goto err;
     goto err;
   }
   }
 
 
+  /* If we already have enough introduction circuits for this service,
+   * redefine this one as a general circuit. */
+  if (count_established_intro_points(serviceid,
+          circuit->rend_data->rend_desc_version) > NUM_INTRO_POINTS) {
+    log_info(LD_CIRC|LD_REND, "We have just finished an introduction "
+             "circuit, but we already have enough. Redefining purpose to "
+             "general.");
+    TO_CIRCUIT(circuit)->purpose = CIRCUIT_PURPOSE_C_GENERAL;
+    circuit_has_opened(circuit);
+    return;
+  }
+
   log_info(LD_REND,
   log_info(LD_REND,
            "Established circuit %d as introduction point for service %s",
            "Established circuit %d as introduction point for service %s",
            circuit->_base.n_circ_id, serviceid);
            circuit->_base.n_circ_id, serviceid);
@@ -1823,9 +1857,12 @@ rend_services_introduce(void)
 
 
     /* Remember how many introduction circuits we started with. */
     /* Remember how many introduction circuits we started with. */
     prev_intro_nodes = smartlist_len(service->intro_nodes);
     prev_intro_nodes = smartlist_len(service->intro_nodes);
-
-    /* The directory is now here. Pick three ORs as intro points. */
-    for (j=prev_intro_nodes; j < NUM_INTRO_POINTS; ++j) {
+    /* The directory is now here. Pick three ORs as intro points (plus, if
+     * we currently have none at all, two more so that we can pick the first
+     * three that complete). */
+#define NUM_INTRO_POINTS_INIT (NUM_INTRO_POINTS + 2)
+    for (j=prev_intro_nodes; j < (prev_intro_nodes == 0 ?
+             NUM_INTRO_POINTS_INIT : NUM_INTRO_POINTS); ++j) {
       router_crn_flags_t flags = CRN_NEED_UPTIME;
       router_crn_flags_t flags = CRN_NEED_UPTIME;
       if (get_options()->_AllowInvalid & ALLOW_INVALID_INTRODUCTION)
       if (get_options()->_AllowInvalid & ALLOW_INVALID_INTRODUCTION)
         flags |= CRN_ALLOW_INVALID;
         flags |= CRN_ALLOW_INVALID;