summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2009-01-04 18:52:54 +0000
committerNick Mathewson <nickm@torproject.org>2009-01-04 18:52:54 +0000
commitd2a2da8de802931b82181e461b203e6ad56f160a (patch)
tree287eb069de4599b0bb71527e1fb58be8b5324222
parent39117bb422e1f13c689dae62036c815a7171019c (diff)
downloadtor-d2a2da8de802931b82181e461b203e6ad56f160a.tar.gz
tor-d2a2da8de802931b82181e461b203e6ad56f160a.zip
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.
svn:r17883
-rw-r--r--ChangeLog4
-rw-r--r--src/or/rendservice.c61
2 files changed, 64 insertions, 1 deletions
diff --git a/ChangeLog b/ChangeLog
index 42e4b7cc12..6d334ebd5c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -60,6 +60,10 @@ Changes in version 0.2.0.33 - 2009-??-??
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
diff --git a/src/or/rendservice.c b/src/or/rendservice.c
index a9796f02af..3dfe2cb7ad 100644
--- a/src/or/rendservice.c
+++ b/src/or/rendservice.c
@@ -251,9 +251,10 @@ rend_config_services(or_options_t *options, int validate_only)
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_config_services(or_options_t *options, int validate_only)
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;
}