[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[or-cvs] r17883: {tor} Backport r17562: Do not litter the circuit list with introdu (in tor/branches/tor-0_2_0-patches: . src/or)



Author: nickm
Date: 2009-01-04 13:52:54 -0500 (Sun, 04 Jan 2009)
New Revision: 17883

Modified:
   tor/branches/tor-0_2_0-patches/ChangeLog
   tor/branches/tor-0_2_0-patches/src/or/rendservice.c
Log:
Backport r17562: Do not litter the circuit list with introductino points on sighup.  Reuse the ones we can, and dump the rest.  Fixes bug 879.  Patch by Karsten.

Modified: tor/branches/tor-0_2_0-patches/ChangeLog
===================================================================
--- tor/branches/tor-0_2_0-patches/ChangeLog	2009-01-04 18:52:32 UTC (rev 17882)
+++ tor/branches/tor-0_2_0-patches/ChangeLog	2009-01-04 18:52:54 UTC (rev 17883)
@@ -60,6 +60,10 @@
       do not even do the DNS lookup before rejecting the connection.
       Fixes another case of bug 619.  Patch from rovv.
 
+  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.
 
   o Minor features:
     - Report the case where all signatures in a detached set are rejected

Modified: tor/branches/tor-0_2_0-patches/src/or/rendservice.c
===================================================================
--- tor/branches/tor-0_2_0-patches/src/or/rendservice.c	2009-01-04 18:52:32 UTC (rev 17882)
+++ tor/branches/tor-0_2_0-patches/src/or/rendservice.c	2009-01-04 18:52:54 UTC (rev 17883)
@@ -251,9 +251,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();
   }
 
@@ -342,6 +343,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;
+        SMARTLIST_FOREACH(surviving_services, rend_service_t *, ptr, {
+          if (!memcmp(ptr->pk_digest, oc->rend_pk_digest,
+                      DIGEST_LEN) &&
+              ptr->descriptor_version == oc->rend_desc_version) {
+            keep_it = 1;
+            break;
+          }
+        });
+        if (keep_it)
+          continue;
+        log_info(LD_REND, "Closing intro point %s for service %s.onion "
+                 "version %d.",
+                 safe_str(oc->build_state->chosen_exit->nickname),
+                 oc->rend_query,
+                 oc->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;
 }