[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[or-cvs] r17260: {tor} Backport bugfix for #767 (r16808, r16810, r16817, r16818, an (in tor/branches/tor-0_2_0-patches: . doc src/or)
Author: kloesing
Date: 2008-11-12 09:26:38 -0500 (Wed, 12 Nov 2008)
New Revision: 17260
Modified:
tor/branches/tor-0_2_0-patches/ChangeLog
tor/branches/tor-0_2_0-patches/doc/TODO.020
tor/branches/tor-0_2_0-patches/src/or/directory.c
tor/branches/tor-0_2_0-patches/src/or/main.c
tor/branches/tor-0_2_0-patches/src/or/or.h
tor/branches/tor-0_2_0-patches/src/or/rendclient.c
tor/branches/tor-0_2_0-patches/src/or/rendcommon.c
tor/branches/tor-0_2_0-patches/src/or/rendservice.c
tor/branches/tor-0_2_0-patches/src/or/routerlist.c
Log:
Backport bugfix for #767 (r16808, r16810, r16817, r16818, and r16939).
Modified: tor/branches/tor-0_2_0-patches/ChangeLog
===================================================================
--- tor/branches/tor-0_2_0-patches/ChangeLog 2008-11-12 11:47:49 UTC (rev 17259)
+++ tor/branches/tor-0_2_0-patches/ChangeLog 2008-11-12 14:26:38 UTC (rev 17260)
@@ -19,6 +19,15 @@
might succeed. Similarly, if the last v2 fetch fails, we were
failing the whole hidden service request even if a v0 fetch is
still pending. Fixes bug 814. Bugfix on 0.2.0.10-alpha.
+ - When extending a circuit to a hidden service directory to upload a
+ rendezvous descriptor using a BEGIN_DIR cell, almost 1/6 of all
+ requests failed, because the router descriptor has not been
+ downloaded yet. In these cases, do not attempt to upload the
+ rendezvous descriptor, but wait until the router descriptor is
+ downloaded and retry. Likewise, do not attempt to fetch a rendezvous
+ descriptor from a hidden service directory for which the router
+ descriptor has not yet been downloaded. Fixes bug 767. Bugfix
+ on 0.2.0.10-alpha.
o Minor bugfixes:
- Fix several infrequent memory leaks spotted by Coverity.
Modified: tor/branches/tor-0_2_0-patches/doc/TODO.020
===================================================================
--- tor/branches/tor-0_2_0-patches/doc/TODO.020 2008-11-12 11:47:49 UTC (rev 17259)
+++ tor/branches/tor-0_2_0-patches/doc/TODO.020 2008-11-12 14:26:38 UTC (rev 17260)
@@ -3,13 +3,6 @@
description of the patch.)
Backport for 0.2.0:
- - r16915,r16916: Don't fail hidden service request if the descriptor
- fetch fails for one descriptor version, when the other might
- still succeed. (Will be more problematic if not backported
- as soon as services stop publishing version 0 descriptors.)
- - r16808,r16810,r16817,r16818,r16939: Don't send tunneled hidden service
- directory requests to routers for which we don't have a
- router descriptor. (Will significantly improve reliability.)
- r17135: ClientDNSRejectInternalAddresses not consistently obeyed.
Backport for 0.2.0 once better tested:
Modified: tor/branches/tor-0_2_0-patches/src/or/directory.c
===================================================================
--- tor/branches/tor-0_2_0-patches/src/or/directory.c 2008-11-12 11:47:49 UTC (rev 17259)
+++ tor/branches/tor-0_2_0-patches/src/or/directory.c 2008-11-12 14:26:38 UTC (rev 17260)
@@ -454,7 +454,12 @@
char address_buf[INET_NTOA_BUF_LEN+1];
struct in_addr in;
const char *address;
- if ((router = router_get_by_digest(status->identity_digest))) {
+ router = router_get_by_digest(status->identity_digest);
+ if (!router && anonymized_connection) {
+ log_info(LD_DIR, "Not sending anonymized request to directory '%s'; we "
+ "don't have its router descriptor.", status->nickname);
+ return;
+ } else if (router) {
address = router->address;
} else {
in.s_addr = htonl(status->addr);
Modified: tor/branches/tor-0_2_0-patches/src/or/main.c
===================================================================
--- tor/branches/tor-0_2_0-patches/src/or/main.c 2008-11-12 11:47:49 UTC (rev 17259)
+++ tor/branches/tor-0_2_0-patches/src/or/main.c 2008-11-12 14:26:38 UTC (rev 17260)
@@ -1113,8 +1113,10 @@
circuit_close_all_marked();
/** 7. And upload service descriptors if necessary. */
- if (has_completed_circuit && !we_are_hibernating())
+ if (has_completed_circuit && !we_are_hibernating()) {
rend_consider_services_upload(now);
+ rend_consider_descriptor_republication();
+ }
/** 8. and blow away any connections that need to die. have to do this now,
* because if we marked a conn for close and left its socket -1, then
Modified: tor/branches/tor-0_2_0-patches/src/or/or.h
===================================================================
--- tor/branches/tor-0_2_0-patches/src/or/or.h 2008-11-12 11:47:49 UTC (rev 17259)
+++ tor/branches/tor-0_2_0-patches/src/or/or.h 2008-11-12 14:26:38 UTC (rev 17260)
@@ -3677,6 +3677,13 @@
/** List of the service's introduction points. Elements are removed if
* introduction attempts fail. */
smartlist_t *intro_nodes;
+ /** Has descriptor been uploaded to all hidden service directories? */
+ int all_uploads_performed;
+ /** List of hidden service directories to which an upload request for
+ * this descriptor could be sent. Smartlist exists only when at least one
+ * of the previous upload requests failed (otherwise it's not important
+ * to know which uploads succeeded and which not). */
+ smartlist_t *successful_uploads;
} rend_service_descriptor_t;
int rend_cmp_service_ids(const char *one, const char *two);
@@ -3738,6 +3745,8 @@
void rend_services_init(void);
void rend_services_introduce(void);
void rend_consider_services_upload(time_t now);
+void rend_hsdir_routers_changed(void);
+void rend_consider_descriptor_republication(void);
void rend_service_intro_has_opened(origin_circuit_t *circuit);
int rend_service_intro_established(origin_circuit_t *circuit,
Modified: tor/branches/tor-0_2_0-patches/src/or/rendclient.c
===================================================================
--- tor/branches/tor-0_2_0-patches/src/or/rendclient.c 2008-11-12 11:47:49 UTC (rev 17259)
+++ tor/branches/tor-0_2_0-patches/src/or/rendclient.c 2008-11-12 14:26:38 UTC (rev 17260)
@@ -354,12 +354,13 @@
desc_id, DIGEST_LEN);
/* Only select those hidden service directories to which we did not send
- * a request recently. */
+ * a request recently and for which we have a router descriptor here. */
directory_clean_last_hid_serv_requests(); /* Clean request history first. */
SMARTLIST_FOREACH(responsible_dirs, routerstatus_t *, dir, {
if (lookup_last_hid_serv_request(dir, desc_id_base32, 0, 0) +
- REND_HID_SERV_DIR_REQUERY_PERIOD >= now)
+ REND_HID_SERV_DIR_REQUERY_PERIOD >= now ||
+ !router_get_by_digest(dir->identity_digest))
SMARTLIST_DEL_CURRENT(responsible_dirs, dir);
});
Modified: tor/branches/tor-0_2_0-patches/src/or/rendcommon.c
===================================================================
--- tor/branches/tor-0_2_0-patches/src/or/rendcommon.c 2008-11-12 11:47:49 UTC (rev 17259)
+++ tor/branches/tor-0_2_0-patches/src/or/rendcommon.c 2008-11-12 14:26:38 UTC (rev 17260)
@@ -32,6 +32,10 @@
rend_intro_point_free(intro););
smartlist_free(desc->intro_nodes);
}
+ if (desc->successful_uploads) {
+ SMARTLIST_FOREACH(desc->successful_uploads, char *, c, tor_free(c););
+ smartlist_free(desc->successful_uploads);
+ }
tor_free(desc);
}
Modified: tor/branches/tor-0_2_0-patches/src/or/rendservice.c
===================================================================
--- tor/branches/tor-0_2_0-patches/src/or/rendservice.c 2008-11-12 11:47:49 UTC (rev 17259)
+++ tor/branches/tor-0_2_0-patches/src/or/rendservice.c 2008-11-12 14:26:38 UTC (rev 17260)
@@ -1066,11 +1066,13 @@
* <b>service_id</b> and <b>seconds_valid</b> are only passed for logging
* purposes. */
static void
-directory_post_to_hs_dir(smartlist_t *descs, const char *service_id,
+directory_post_to_hs_dir(rend_service_descriptor_t *renddesc,
+ smartlist_t *descs, const char *service_id,
int seconds_valid)
{
- int i, j;
+ int i, j, failed_upload = 0;
smartlist_t *responsible_dirs = smartlist_create();
+ smartlist_t *successful_uploads = smartlist_create();
routerstatus_t *hs_dir;
for (i = 0; i < smartlist_len(descs); i++) {
rend_encoded_v2_service_descriptor_t *desc = smartlist_get(descs, i);
@@ -1080,11 +1082,24 @@
log_warn(LD_REND, "Could not determine the responsible hidden service "
"directories to post descriptors to.");
smartlist_free(responsible_dirs);
+ smartlist_free(successful_uploads);
return;
}
for (j = 0; j < smartlist_len(responsible_dirs); j++) {
char desc_id_base32[REND_DESC_ID_V2_LEN_BASE32 + 1];
hs_dir = smartlist_get(responsible_dirs, j);
+ if (smartlist_digest_isin(renddesc->successful_uploads,
+ hs_dir->identity_digest))
+ /* Don't upload descriptor if we succeeded in doing so last time. */
+ continue;
+ if (!router_get_by_digest(hs_dir->identity_digest)) {
+ log_info(LD_REND, "Not sending publish request for v2 descriptor to "
+ "hidden service directory '%s'; we don't have its "
+ "router descriptor. Queueing for later upload.",
+ hs_dir->nickname);
+ failed_upload = -1;
+ continue;
+ }
/* Send publish request. */
directory_initiate_command_routerstatus(hs_dir,
DIR_PURPOSE_UPLOAD_RENDDESC_V2,
@@ -1102,10 +1117,33 @@
seconds_valid,
hs_dir->nickname,
hs_dir->dir_port);
+ /* Remember successful upload to this router for next time. */
+ if (!smartlist_digest_isin(successful_uploads, hs_dir->identity_digest))
+ smartlist_add(successful_uploads, hs_dir->identity_digest);
}
smartlist_clear(responsible_dirs);
}
+ if (!failed_upload) {
+ if (renddesc->successful_uploads) {
+ SMARTLIST_FOREACH(renddesc->successful_uploads, char *, c, tor_free(c););
+ smartlist_free(renddesc->successful_uploads);
+ }
+ renddesc->all_uploads_performed = 1;
+ } else {
+ /* Remember which routers worked this time, so that we don't upload the
+ * descriptor to them again. */
+ if (!renddesc->successful_uploads)
+ renddesc->successful_uploads = smartlist_create();
+ SMARTLIST_FOREACH(successful_uploads, char *, c, {
+ if (!smartlist_digest_isin(renddesc->successful_uploads, c)) {
+ char *hsdir_id = tor_malloc_zero(DIGEST_LEN);
+ memcpy(hsdir_id, c, DIGEST_LEN);
+ smartlist_add(renddesc->successful_uploads, hsdir_id);
+ }
+ });
+ }
smartlist_free(responsible_dirs);
+ smartlist_free(successful_uploads);
}
/** Encode and sign up-to-date v0 and/or v2 service descriptors for
@@ -1120,9 +1158,6 @@
char serviceid[REND_SERVICE_ID_LEN_BASE32+1];
int uploaded = 0;
- /* Update the descriptor. */
- rend_service_update_descriptor(service);
-
rendpostperiod = get_options()->RendPostPeriod;
/* Upload unversioned (v0) descriptor? */
@@ -1172,7 +1207,8 @@
rend_get_service_id(service->desc->pk, serviceid);
log_info(LD_REND, "Sending publish request for hidden service %s",
serviceid);
- directory_post_to_hs_dir(descs, serviceid, seconds_valid);
+ directory_post_to_hs_dir(service->desc, descs, serviceid,
+ seconds_valid);
/* Free memory for descriptors. */
for (i = 0; i < smartlist_len(descs); i++)
rend_encoded_v2_service_descriptor_free(smartlist_get(descs, i));
@@ -1196,7 +1232,8 @@
smartlist_free(descs);
return;
}
- directory_post_to_hs_dir(descs, serviceid, seconds_valid);
+ directory_post_to_hs_dir(service->desc, descs, serviceid,
+ seconds_valid);
/* Free memory for descriptors. */
for (i = 0; i < smartlist_len(descs); i++)
rend_encoded_v2_service_descriptor_free(smartlist_get(descs, i));
@@ -1360,11 +1397,53 @@
/* if it's time, or if the directory servers have a wrong service
* descriptor and ours has been stable for 30 seconds, upload a
* new one of each format. */
+ rend_service_update_descriptor(service);
upload_service_descriptor(service);
}
}
}
+/** True if the list of available router descriptors might have changed so
+ * that we should have a look whether we can republish previously failed
+ * rendezvous service descriptors. */
+static int consider_republishing_rend_descriptors = 1;
+
+/** Called when our internal view of the directory has changed, so that we
+ * might have router descriptors of hidden service directories available that
+ * we did not have before. */
+void
+rend_hsdir_routers_changed(void)
+{
+ consider_republishing_rend_descriptors = 1;
+}
+
+/** Consider republication of v2 rendezvous service descriptors that failed
+ * previously, but without regenerating descriptor contents.
+ */
+void
+rend_consider_descriptor_republication(void)
+{
+ int i;
+ rend_service_t *service;
+
+ if (!consider_republishing_rend_descriptors)
+ return;
+ consider_republishing_rend_descriptors = 0;
+
+ if (!get_options()->PublishHidServDescriptors)
+ return;
+
+ for (i=0; i < smartlist_len(rend_service_list); ++i) {
+ service = smartlist_get(rend_service_list, i);
+ if (service->descriptor_version && service->desc &&
+ !service->desc->all_uploads_performed) {
+ /* If we failed in uploading a descriptor last time, try again *without*
+ * updating the descriptor's contents. */
+ upload_service_descriptor(service);
+ }
+ }
+}
+
/** Log the status of introduction points for all rendezvous services
* at log severity <b>severity</b>.
*/
Modified: tor/branches/tor-0_2_0-patches/src/or/routerlist.c
===================================================================
--- tor/branches/tor-0_2_0-patches/src/or/routerlist.c 2008-11-12 11:47:49 UTC (rev 17259)
+++ tor/branches/tor-0_2_0-patches/src/or/routerlist.c 2008-11-12 14:26:38 UTC (rev 17260)
@@ -4116,6 +4116,7 @@
router_dir_info_changed(void)
{
need_to_update_have_min_dir_info = 1;
+ rend_hsdir_routers_changed();
}
/** Return a string describing what we're missing before we have enough