Ticket #874: patch874.txt

File patch874.txt, 3.7 KB (added by karsten, 11 years ago)

Patch

Line 
1Index: /home/karsten/tor/tor-trunk/ChangeLog
2===================================================================
3--- /home/karsten/tor/tor-trunk/ChangeLog       (revision 17396)
4+++ /home/karsten/tor/tor-trunk/ChangeLog       (working copy)
5@@ -23,6 +23,9 @@
6     - Do not mark smartlist_bsearch_idx() function as ATTR_PURE.  This bug
7       could make gcc generate non-functional binary search code. Bugfix
8       on 0.2.0.10-alpha.
9+    - Hidden services did not survive reloading the configuration: They
10+      discarded their introduction points but failed to build new ones.
11+      Spotted by John Brooks. Bugfix on 0.2.1.7-alpha. Fixes bug 874.
12 
13   o Minor features (controller):
14     - Return circuit purposes in response to GETINFO circuit-status.  Fixes
15Index: /home/karsten/tor/tor-trunk/src/or/rendservice.c
16===================================================================
17--- /home/karsten/tor/tor-trunk/src/or/rendservice.c    (revision 17396)
18+++ /home/karsten/tor/tor-trunk/src/or/rendservice.c    (working copy)
19@@ -513,6 +513,57 @@
20   }
21 }
22 
23+/** Check if there are any orphaned introduction points that have been
24+ * established or are about to be established for the given service; if
25+ * so, reassign them to the service. */
26+static void
27+reassign_intro_points_to_service(rend_service_t *service)
28+{
29+  circuit_t *circ;
30+  tor_assert(service);
31+  tor_assert(service->intro_nodes);
32+  log_debug(LD_REND, "Checking whether we already have introduction "
33+            "points for %s, version %d that we should reassign.",
34+            service->service_id, service->descriptor_version);
35+  for (circ = _circuit_get_global_list(); circ; circ = circ->next) {
36+    if (!circ->marked_for_close &&
37+        circ->state == CIRCUIT_STATE_OPEN &&
38+        (circ->purpose == CIRCUIT_PURPOSE_S_ESTABLISH_INTRO ||
39+         circ->purpose == CIRCUIT_PURPOSE_S_INTRO)) {
40+      origin_circuit_t *oc = TO_ORIGIN_CIRCUIT(circ);
41+      if (oc->rend_data &&
42+          oc->rend_data->rend_desc_version == service->descriptor_version &&
43+          !rend_cmp_service_ids(service->service_id,
44+                                oc->rend_data->onion_address)) {
45+        /* This one looks like we could reassign it. Check whether the
46+         * service already knows about it. */
47+        routerinfo_t *router =
48+          router_get_by_digest(oc->build_state->chosen_exit->identity_digest);
49+        extend_info_t *info = extend_info_from_router(router);
50+        rend_intro_point_t *intro;
51+        int orphaned = 1;
52+        SMARTLIST_FOREACH(service->intro_nodes, rend_intro_point_t *, _intro, {
53+          if (!memcmp(_intro->extend_info->identity_digest,
54+                      info->identity_digest, DIGEST_LEN))
55+            orphaned = 0;
56+        });
57+        if (!orphaned)
58+          continue;
59+        /* The service doesn't know, so we should reassign it. */
60+        intro = tor_malloc_zero(sizeof(rend_intro_point_t));
61+        intro->extend_info = info;
62+        if (oc->intro_key)
63+          intro->intro_key = crypto_pk_dup_key(oc->intro_key);
64+        smartlist_add(service->intro_nodes, intro);
65+        log_info(LD_REND, "Reassigned router %s as an intro point for %s, "
66+                 "version %d.",
67+                 router->nickname, service->service_id,
68+                 service->descriptor_version);
69+      }
70+    }
71+  }
72+}
73+
74 /** Load and/or generate private keys for all hidden services, possibly
75  * including keys for client authorization.  Return 0 on success, -1 on
76  * failure.
77@@ -568,6 +619,9 @@
78       return -1;
79     }
80 
81+    /* If configuration was reloaded, reassign intro points to service. */
82+    reassign_intro_points_to_service(s);
83+
84     /* If client authorization is configured, load or generate keys. */
85     if (s->auth_type != REND_NO_AUTH) {
86       char *client_keys_str = NULL;
87