[or-cvs] r17562: {tor} Apply patch from Karsten to fix bug 879. Backport candidate. (in tor/trunk: . src/or)

nickm at seul.org nickm at seul.org
Wed Dec 10 18:16:59 UTC 2008


Author: nickm
Date: 2008-12-10 13:16:58 -0500 (Wed, 10 Dec 2008)
New Revision: 17562

Modified:
   tor/trunk/ChangeLog
   tor/trunk/src/or/rendservice.c
Log:
Apply patch from Karsten to fix bug 879.  Backport candidate.

Modified: tor/trunk/ChangeLog
===================================================================
--- tor/trunk/ChangeLog	2008-12-10 17:25:17 UTC (rev 17561)
+++ tor/trunk/ChangeLog	2008-12-10 18:16:58 UTC (rev 17562)
@@ -20,7 +20,12 @@
     - Resume using the correct "REASON=" stream when telling the
       controller why we closed a stream. Bugfix in 0.2.1.1-alpha.
 
+  o Minor bugfixes (hidden services):
+    - Do not throw away existing introduction points on SIGHUP; do not
+      stall hidden services because of introduction points thrown away.
+      Patch by Karsten.  Fixes bug 879.
 
+
 Changes in version 0.2.1.8-alpha - 2008-12-08
   o Major features:
     - New DirPortFrontPage option that takes an html file and publishes

Modified: tor/trunk/src/or/rendservice.c
===================================================================
--- tor/trunk/src/or/rendservice.c	2008-12-10 17:25:17 UTC (rev 17561)
+++ tor/trunk/src/or/rendservice.c	2008-12-10 18:16:58 UTC (rev 17562)
@@ -291,9 +291,10 @@
   config_line_t *line;
   rend_service_t *service = NULL;
   rend_service_port_config_t *portcfg;
+  smartlist_t *old_service_list = NULL;
 
   if (!validate_only) {
-    rend_service_free_all();
+    old_service_list = rend_service_list;
     rend_service_list = smartlist_create();
   }
 
@@ -473,6 +474,64 @@
       rend_add_service(service);
   }
 
+  /* If this is a reload and there were hidden services configured before,
+   * keep the introduction points that are still needed and close the
+   * other ones. */
+  if (old_service_list && !validate_only) {
+    smartlist_t *surviving_services = smartlist_create();
+    circuit_t *circ;
+
+    /* Copy introduction points to new services. */
+    /* XXXX This is O(n^2), but it's only called on reconfigure, so it's
+     * probably ok? */
+    SMARTLIST_FOREACH(rend_service_list, rend_service_t *, new, {
+      SMARTLIST_FOREACH(old_service_list, rend_service_t *, old, {
+        if (!strcmp(old->directory, new->directory) &&
+            old->descriptor_version == new->descriptor_version) {
+          smartlist_add_all(new->intro_nodes, old->intro_nodes);
+          smartlist_clear(old->intro_nodes);
+          smartlist_add(surviving_services, old);
+          break;
+        }
+      });
+    });
+
+    /* Close introduction circuits of services we don't serve anymore. */
+    /* XXXX it would be nicer if we had a nicer abstraction to use here,
+     * so we could just iterate over the list of services to close, but
+     * once again, this isn't critical-path code. */
+    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);
+        int keep_it = 0;
+        tor_assert(oc->rend_data);
+        SMARTLIST_FOREACH(surviving_services, rend_service_t *, ptr, {
+          if (!memcmp(ptr->pk_digest, oc->rend_data->rend_pk_digest,
+                      DIGEST_LEN) &&
+              ptr->descriptor_version == oc->rend_data->rend_desc_version) {
+            keep_it = 1;
+            break;
+          }
+        });
+        if (keep_it)
+          continue;
+        log_info(LD_REND, "Closing intro point %s for service %s version %d.",
+                 safe_str(oc->build_state->chosen_exit->nickname),
+                 oc->rend_data->onion_address,
+                 oc->rend_data->rend_desc_version);
+        circuit_mark_for_close(circ, END_CIRC_REASON_FINISHED);
+        /* XXXX Is there another reason we should use here? */
+      }
+    }
+    smartlist_free(surviving_services);
+    SMARTLIST_FOREACH(old_service_list, rend_service_t *, ptr,
+                      rend_service_free(ptr));
+    smartlist_free(old_service_list);
+  }
+
   return 0;
 }
 



More information about the tor-commits mailing list