From ce147a2a9a0e399943362062b1fbccecac36aa99 Mon Sep 17 00:00:00 2001 From: Andrea Shepard Date: Fri, 31 May 2013 15:35:51 -0700 Subject: [PATCH 01/14] When launching a resolve request on behalf of an AF_UNIX control, omit the address field of the new entry connection. Fixes bug 8639. --- changes/bug8639 | 5 +++++ src/or/control.c | 17 +++++++++++++++-- src/or/dnsserv.c | 15 +++++++++++++++ 3 files changed, 35 insertions(+), 2 deletions(-) create mode 100644 changes/bug8639 diff --git a/changes/bug8639 b/changes/bug8639 new file mode 100644 index 000000000..0db5c9142 --- /dev/null +++ b/changes/bug8639 @@ -0,0 +1,5 @@ + o Normal bugfixes: + - When launching a resolve request on behalf of an AF_UNIX control + socket, omit the address field of the new entry connection, used in + subsequent controller events, rather than letting tor_dup_addr() set + it to "". Fixes bug 8639. diff --git a/src/or/control.c b/src/or/control.c index 48782682c..88bd00b5e 100644 --- a/src/or/control.c +++ b/src/or/control.c @@ -3743,8 +3743,21 @@ control_event_stream_status(entry_connection_t *conn, stream_status_event_t tp, } if (tp == STREAM_EVENT_NEW || tp == STREAM_EVENT_NEW_RESOLVE) { - tor_snprintf(addrport_buf,sizeof(addrport_buf), " SOURCE_ADDR=%s:%d", - ENTRY_TO_CONN(conn)->address, ENTRY_TO_CONN(conn)->port); + /* + * When the control conn is an AF_UNIX socket and we have no address, + * it gets set to "(Tor_internal)"; see dnsserv_launch_request() in + * dnsserv.c. + */ + if (strcmp(ENTRY_TO_CONN(conn)->address, "(Tor_internal)") != 0) { + tor_snprintf(addrport_buf,sizeof(addrport_buf), " SOURCE_ADDR=%s:%d", + ENTRY_TO_CONN(conn)->address, ENTRY_TO_CONN(conn)->port); + } else { + /* + * else leave it blank so control on AF_UNIX doesn't need to make + * something up. + */ + addrport_buf[0] = '\0'; + } } else { addrport_buf[0] = '\0'; } diff --git a/src/or/dnsserv.c b/src/or/dnsserv.c index a1275cf2b..ebff7b524 100644 --- a/src/or/dnsserv.c +++ b/src/or/dnsserv.c @@ -183,8 +183,23 @@ dnsserv_launch_request(const char *name, int reverse, conn->base_.state = AP_CONN_STATE_RESOLVE_WAIT; tor_addr_copy(&TO_CONN(conn)->addr, &control_conn->base_.addr); +#ifdef AF_UNIX + /* + * The control connection can be AF_UNIX and if so tor_dup_addr will + * unhelpfully say ""; say "(Tor_internal)" + * instead. + */ + if (control_conn->base_.socket_family == AF_UNIX) { + TO_CONN(conn)->port = 0; + TO_CONN(conn)->address = tor_strdup("(Tor_internal)"); + } else { + TO_CONN(conn)->port = control_conn->base_.port; + TO_CONN(conn)->address = tor_dup_addr(&control_conn->base_.addr); + } +#else TO_CONN(conn)->port = control_conn->base_.port; TO_CONN(conn)->address = tor_dup_addr(&control_conn->base_.addr); +#endif if (reverse) entry_conn->socks_request->command = SOCKS_COMMAND_RESOLVE_PTR; From 4f4fc63fea0589a4fa03f3859dc27860cdde75af Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Wed, 12 Jun 2013 09:30:09 -0400 Subject: [PATCH 02/14] Expand microdesc cache tests Is it possible that *every* attempt to replace the microdesc cache on windows 7 is going to fail because of our lack of FILE_SHARE_DELETE while opening the file? If so, this test will catch #2077 and let us know when it's fixed. --- src/test/test_microdesc.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/test/test_microdesc.c b/src/test/test_microdesc.c index 4bc9fa726..a8171a325 100644 --- a/src/test/test_microdesc.c +++ b/src/test/test_microdesc.c @@ -208,11 +208,25 @@ test_md_cache(void *data) md3 = NULL; /* it's history now! */ /* rebuild again, make sure it stays gone. */ - microdesc_cache_rebuild(mc, 1); + tt_int_op(microdesc_cache_rebuild(mc, 1), ==, 0); tt_ptr_op(md1, ==, microdesc_cache_lookup_by_digest256(mc, d1)); tt_ptr_op(md2, ==, microdesc_cache_lookup_by_digest256(mc, d2)); tt_ptr_op(NULL, ==, microdesc_cache_lookup_by_digest256(mc, d3)); + /* Re-add md3, and make sure we can rebuild the cache. */ + added = microdescs_add_to_cache(mc, test_md3_noannotation, NULL, + SAVED_NOWHERE, 0, time3, NULL); + tt_int_op(1, ==, smartlist_len(added)); + md3 = smartlist_get(added, 0); + smartlist_free(added); + added = NULL; + tt_int_op(md1->saved_location, ==, SAVED_IN_CACHE); + tt_int_op(md2->saved_location, ==, SAVED_IN_CACHE); + tt_int_op(md3->saved_location, ==, SAVED_IN_JOURNAL); + + tt_int_op(microdesc_cache_rebuild(mc, 1), ==, 0); + tt_int_op(md3->saved_location, ==, SAVED_IN_CACHE); + done: if (options) tor_free(options->DataDirectory); From 884a0e269c382f9e927d8c8b1ef4ef9d2d48379d Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Wed, 12 Jun 2013 09:53:46 -0400 Subject: [PATCH 03/14] Use the FILE_SHARE_DELETE flag for CreateFile on a mapping A comment by rransom on #8795 taken together with a comment by doorss recorded on #2077 suggest that *every* attempt to replace the md cache will fail on Vista/Win7 if we don't have the FILE_SHARE_DELETE flag passed to CreateFile, and if we try to replace the file ourselves before unmapping it. I'm adding the FILE_SHARE_DELETE, since that's this simplest fix. Broken indexers (the favored #2077 hypothesis) could still cause trouble here, but at least this patch should make us stop stepping on our own feet. Likely fix for #2077 and its numerous duplicates. Bugfix on 0.2.2.6-alpha, which first had a microdescriptor cache that would get replaced before remapping it. --- changes/bug2077_share_delete | 7 +++++++ src/common/compat.c | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 changes/bug2077_share_delete diff --git a/changes/bug2077_share_delete b/changes/bug2077_share_delete new file mode 100644 index 000000000..71e916053 --- /dev/null +++ b/changes/bug2077_share_delete @@ -0,0 +1,7 @@ + o Major bugfixes (windows): + - Open files to be mapped with FILE_SHARE_DELETE so that we can + replace them before closing the mapping. This is a likely cause of + warnings and crashes when replacing the microdescriptor cache + file. Diagnosed based on comments by "doorss" and by Robert + Ransom. Possible fix for bug 2077; bugfix on 0.2.2.6-alpha. + diff --git a/src/common/compat.c b/src/common/compat.c index 59e3898de..7f7405f6f 100644 --- a/src/common/compat.c +++ b/src/common/compat.c @@ -238,7 +238,7 @@ tor_mmap_file(const char *filename) strlcpy(tfilename,filename,MAX_PATH); #endif file_handle = CreateFile(tfilename, - GENERIC_READ, FILE_SHARE_READ, + GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, From fff9386af87bd0f54cda1ef4fe0bf131de7c3d8e Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Wed, 12 Jun 2013 10:45:48 -0400 Subject: [PATCH 04/14] Revert "Use the FILE_SHARE_DELETE flag for CreateFile on a mapping" This reverts commit 884a0e269c382f9e927d8c8b1ef4ef9d2d48379d. I'm reverting this because it doesn't actually make the problem go away. It appears that instead we need to do unmap-then-replace. --- changes/bug2077_share_delete | 7 ------- src/common/compat.c | 2 +- 2 files changed, 1 insertion(+), 8 deletions(-) delete mode 100644 changes/bug2077_share_delete diff --git a/changes/bug2077_share_delete b/changes/bug2077_share_delete deleted file mode 100644 index 71e916053..000000000 --- a/changes/bug2077_share_delete +++ /dev/null @@ -1,7 +0,0 @@ - o Major bugfixes (windows): - - Open files to be mapped with FILE_SHARE_DELETE so that we can - replace them before closing the mapping. This is a likely cause of - warnings and crashes when replacing the microdescriptor cache - file. Diagnosed based on comments by "doorss" and by Robert - Ransom. Possible fix for bug 2077; bugfix on 0.2.2.6-alpha. - diff --git a/src/common/compat.c b/src/common/compat.c index cb1dd787a..c97a4545c 100644 --- a/src/common/compat.c +++ b/src/common/compat.c @@ -248,7 +248,7 @@ tor_mmap_file(const char *filename) strlcpy(tfilename,filename,MAX_PATH); #endif file_handle = CreateFile(tfilename, - GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_DELETE, + GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, From f455686b77e4ac686251c6edf1f4a506a369866c Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Wed, 12 Jun 2013 12:04:33 -0400 Subject: [PATCH 05/14] Unmap the microdescriptor cache before replacing it. This is a reprise of the fix in bdff7e3299d78; 6905c1f6 reintroduced that bug. Briefly: windows doesn't seem to like deleting a mapped file. I tried adding the PROT_SHARED_DELETE flag to the createfile all, but that didn't actually fix this issue. Fortunately, the unit test I added in 4f4fc63fea0589a4fa03f3859dc27860cdde75af should prevent us from making this particular screw-up again. This patch also tries to limit the crash potential of a failure to write by a little bit, although it could do a better job of retaining microdescriptor bodies. Fix for bug 8822, bugfix on 0.2.4.12-alpha. --- changes/bug8822 | 5 +++++ src/or/microdesc.c | 20 +++++++++++++++++--- 2 files changed, 22 insertions(+), 3 deletions(-) create mode 100644 changes/bug8822 diff --git a/changes/bug8822 b/changes/bug8822 new file mode 100644 index 000000000..c6787afe0 --- /dev/null +++ b/changes/bug8822 @@ -0,0 +1,5 @@ + o Major bugfixes (windows): + - Prevent failures on Windows Vista and later when rebuilding the + microdescriptor cache. Diagnosed by Robert Ransom. Fixes bug 8822; + bugfix on 0.2.4.12-alpha. + diff --git a/src/or/microdesc.c b/src/or/microdesc.c index d9955c7b4..f99e1c88a 100644 --- a/src/or/microdesc.c +++ b/src/or/microdesc.c @@ -474,15 +474,29 @@ microdesc_cache_rebuild(microdesc_cache_t *cache, int force) smartlist_add(wrote, md); } + /* We must do this unmap _before_ we call finish_writing_to_file(), or + * windows will not actually replace the file. */ + if (cache->cache_content) + tor_munmap_file(cache->cache_content); + if (finish_writing_to_file(open_file) < 0) { log_warn(LD_DIR, "Error rebuilding microdescriptor cache: %s", strerror(errno)); + /* Okay. Let's prevent from making things worse elsewhere. */ + cache->cache_content = NULL; + HT_FOREACH(mdp, microdesc_map, &cache->map) { + microdesc_t *md = *mdp; + if (md->saved_location == SAVED_IN_CACHE) { + md->off = 0; + md->saved_location = SAVED_NOWHERE; + md->body = NULL; + md->bodylen = 0; + md->no_save = 1; + } + } return -1; } - if (cache->cache_content) - tor_munmap_file(cache->cache_content); - cache->cache_content = tor_mmap_file(cache->cache_fname); if (!cache->cache_content && smartlist_len(wrote)) { From e602c4031b57f0780661ce0473a5e30d187d385c Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Wed, 12 Jun 2013 12:12:11 -0400 Subject: [PATCH 06/14] Make all consumers of microdesc_t.body tolerate NULL This is another fix to try to mitigate recurrences of 8031/8822. --- src/or/control.c | 6 ++---- src/or/dirserv.c | 2 +- src/or/microdesc.c | 6 +++++- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/or/control.c b/src/or/control.c index 48782682c..5ae7b71b5 100644 --- a/src/or/control.c +++ b/src/or/control.c @@ -1711,8 +1711,7 @@ getinfo_helper_dir(control_connection_t *control_conn, const node_t *node = node_get_by_hex_id(question+strlen("md/id/")); const microdesc_t *md = NULL; if (node) md = node->md; - if (md) { - tor_assert(md->body); + if (md && md->body) { *answer = tor_strndup(md->body, md->bodylen); } } else if (!strcmpstart(question, "md/name/")) { @@ -1722,8 +1721,7 @@ getinfo_helper_dir(control_connection_t *control_conn, /* XXXX duplicated code */ const microdesc_t *md = NULL; if (node) md = node->md; - if (md) { - tor_assert(md->body); + if (md && md->body) { *answer = tor_strndup(md->body, md->bodylen); } } else if (!strcmpstart(question, "desc-annotations/id/")) { diff --git a/src/or/dirserv.c b/src/or/dirserv.c index 8f6d9ec43..3e46153a5 100644 --- a/src/or/dirserv.c +++ b/src/or/dirserv.c @@ -3981,7 +3981,7 @@ connection_dirserv_add_microdescs_to_outbuf(dir_connection_t *conn) char *fp256 = smartlist_pop_last(conn->fingerprint_stack); microdesc_t *md = microdesc_cache_lookup_by_digest256(cache, fp256); tor_free(fp256); - if (!md) + if (!md || !md->body) continue; if (conn->zlib_state) { /* XXXX024 This 'last' business should actually happen on the last diff --git a/src/or/microdesc.c b/src/or/microdesc.c index f99e1c88a..05e3b4181 100644 --- a/src/or/microdesc.c +++ b/src/or/microdesc.c @@ -75,6 +75,10 @@ dump_microdescriptor(int fd, microdesc_t *md, size_t *annotation_len_out) { ssize_t r = 0; size_t written; + if (md->body == NULL) { + *annotation_len_out = 0; + return 0; + } /* XXXX drops unknown annotations. */ if (md->last_listed) { char buf[ISO_TIME_LEN+1]; @@ -447,7 +451,7 @@ microdesc_cache_rebuild(microdesc_cache_t *cache, int force) HT_FOREACH(mdp, microdesc_map, &cache->map) { microdesc_t *md = *mdp; size_t annotation_len; - if (md->no_save) + if (md->no_save || !md->body) continue; size = dump_microdescriptor(fd, md, &annotation_len); From a3f6f3316a8037e723f225021186a772cb6707fe Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Wed, 12 Jun 2013 21:07:27 -0400 Subject: [PATCH 07/14] Remove various outdated documents. doc/TODO and doc/spec/README were placeholders to tell people where to look for the real TODO and README stuff -- we replaced them years ago, though. authority-policy, v3-authority-howto, and torel-design.txt belong in torspec. I'm putting them in attic there since I think they may be in large part obsolete, but someone can rescue them if they're not. translations.txt is outdated, and refers to lots of programs other than Tor. We have much better translation resources on the website now. tor-win32-mingw-creation.txt is pending review of a revised version for 0.2.5 (see ticket #4520), but there's no reason to ship this one while we're waiting for an accurate version. the tor-rpm-creation.txt isn't obsolete AFAIK, but it belongs in doc/contrib if anywhere. Resolves bug #8965. --- changes/bug8965 | 3 + doc/TODO | 3 - doc/contrib/authority-policy.txt | 89 ------------ doc/{ => contrib}/tor-rpm-creation.txt | 0 doc/contrib/torel-design.txt | 181 ------------------------ doc/include.am | 2 - doc/spec/README | 11 -- doc/tor-win32-mingw-creation.txt | 119 ---------------- doc/translations.txt | 182 ------------------------- doc/v3-authority-howto.txt | 84 ------------ 10 files changed, 3 insertions(+), 671 deletions(-) create mode 100644 changes/bug8965 delete mode 100644 doc/TODO delete mode 100644 doc/contrib/authority-policy.txt rename doc/{ => contrib}/tor-rpm-creation.txt (100%) delete mode 100644 doc/contrib/torel-design.txt delete mode 100644 doc/spec/README delete mode 100644 doc/tor-win32-mingw-creation.txt delete mode 100644 doc/translations.txt delete mode 100644 doc/v3-authority-howto.txt diff --git a/changes/bug8965 b/changes/bug8965 new file mode 100644 index 000000000..b5af27963 --- /dev/null +++ b/changes/bug8965 @@ -0,0 +1,3 @@ + o Removed documentation: + - Remove some of the older contents of doc/ as obsolete; move others + to torspec.git. Fixes bug 8965. diff --git a/doc/TODO b/doc/TODO deleted file mode 100644 index 7e547496e..000000000 --- a/doc/TODO +++ /dev/null @@ -1,3 +0,0 @@ - -We no longer track our TODO lists in git. To see open Tor tasks, visit -our bugtracker and wiki at trac.torproject.org. diff --git a/doc/contrib/authority-policy.txt b/doc/contrib/authority-policy.txt deleted file mode 100644 index 7072082d1..000000000 --- a/doc/contrib/authority-policy.txt +++ /dev/null @@ -1,89 +0,0 @@ - -0. Overview. - - This document contains various informal policies for how to operate - a directory authority, how to choose new ones, etc. - -1. How to pick a new directory authority. - - Here's our current guidelines for how to pick new directory - authorities. - - (These won't ever be formal criteria -- we need to keep this flexible - so we can adapt to new situations.) - - o Stability: - - Must be a low-downtime Tor server (computer as well as network). - - Must have a static IP. - - The operator must have been running a stable Tor server for at least - 3 months. - - Must intend for this server to stick around for the next 12 months - or more. - - Must not hibernate. - - Should not be an exit node (as this increases the risk both of - downtime and of key compromise). - - o Performance: - - Must have sufficient bandwidth: at least 10mbit/s symmetric, - though in practice the inbound traffic can be considerably less. - - o Availability: - - Must be available to upgrade within a few days in most cases. - (While we're still developing Tor, we periodically find bugs that - impact the whole network and require authority upgrades.) - - Should have a well-known way to contact the administrator - via PGP-encrypted message. - - o Integrity: - - Must promise not to censor or attack the network and users. - - Should be run by somebody that Tor (i.e. Roger) knows. - - Should be widely regarded as fair/trustworthy, or at least - known, by many people. - - If somebody asks you to backdoor or change your server, legally or - otherwise, you will fight it to the extent of your abilities. If - you fail to fight it, you must shut down the Tor server and notify - us that you have. - - o Diversity - - We should avoid situations that make it likelier for multiple - authority failures to happen at the same time. Therefore... - - It's good when authorities are not all in the same country. - - It's good when authorities are not all in the same jurisdictions. - - It's good when authorities are not all running the same OS. - - It's good when authorities are not all using the same ISP. - - It's good when authorities are not all running the same - version of Tor. - - No two authorities should have the same operator. - - Maximal diversity, however, is not always practical. Sometimes, - for example, there is only one version of Tor that provides a - given consensus generation algorithm. - - A small group of authorities with the same country/jurisdiction/OS is - not a problem, until that group's size approaches quorum (half the - authorities). - -2. How to choose the recommended versions - - The policy, in a nutshell, is to not remove versions without a good - reason. So this means we should recommend all versions except: - - - Versions that no longer conform to the spec. That is, if they wouldn't - actually interact correctly with the current Tor network. - - Versions that have known security problems. - - Versions that have frequent crash or assert problems. - - Versions that harm the performance or stability of the current Tor - network or the anonymity of other users. For example, a version - that load balances wrong, or a version that hammers the authorities - too much. - - -> some use the slight variant of requiring a *good* reason. -> excellent reasons include "there's a security flaw" -> good reasons include "that crashes every time you start it. you would think -+tor is dumb if you tried to use that version and think of it as tor." -> good reasons include "those old clients do their load balancing wrong, and -+they're screwing up the whole network" -> reasons include "the old one is really slow, clients should prefer the new -+one" -> i try to draw the line at 'good reasons and above' - - diff --git a/doc/tor-rpm-creation.txt b/doc/contrib/tor-rpm-creation.txt similarity index 100% rename from doc/tor-rpm-creation.txt rename to doc/contrib/tor-rpm-creation.txt diff --git a/doc/contrib/torel-design.txt b/doc/contrib/torel-design.txt deleted file mode 100644 index 610cbe21f..000000000 --- a/doc/contrib/torel-design.txt +++ /dev/null @@ -1,181 +0,0 @@ -Design For A Tor DNS-based Exit List - -Status: - - This is a suggested design for a DNS Exit List (DNSEL) for Tor exit nodes. - See http://exitlist.torproject.org/ for an implementation. - -Why? - - It's useful for third parties to be able to tell when a given connection - is coming from a Tor exit node. Potential applications range from - "anonymous user" cloaks on IRC networks like oftc, to networks like - Freenode that apply special authentication rules to users from these - IPs, to systems like Wikipedia that may want to make a priority of - _unblocking_ shared IPs more liberally than non-shared IPs, since shared - IPs presumably have non-abusive users as well as abusive ones. - - Since Tor provides exit policies, not every Tor server will connect to - every address:port combination on the Internet. Unless you're trying to - penalize hosts for supporting anonymity, it makes more sense to answer - the fine-grained question "which Tor servers will connect to _me_?" than - the coarse-grained question "which Tor servers exist?" The fine-grained - approach also helps Tor server ops who share an IP with their Tor - server: if they want to access a site that blocks Tor users, they - can exclude that site from their exit policy, and the site can learn - that they won't send it anonymous connections. - - Tor already ships with a tool (the "contrib/exitlist" script) to - identify which Tor nodes might open anonymous connections to any given - exit address. But this is a bit tricky to set up, so only sites like - Freenode and OFTC that are dedicated to privacy use it. - Conversely, providers of some DNSEL implementations are providing - coarse-grained lists of Tor hosts -- sometimes even listing servers that - permit no exit connections at all. This is rather a problem, since - support for DNSEL is pretty ubiquitous. - - -How? - - Keep a running Tor instance, and parse the cached-routers and - cached-routers.new files as new routers arrive. To tell whether a given - server allows connections to a certain address:port combo, look at the - definitions in dir-spec.txt or follow the logic of the current exitlist - script. If bug 405 is still open when you work on this - (https://bugs.torproject.org/flyspray/index.php?do=details&id=405), you'll - probably want to extend it to look at only the newest descriptor for - each server, so you don't use obsolete exit policy data. - - FetchUselessDescriptors would probably be a good torrc option to enable. - - If you're also running a directory cache, you get extra-fresh - information. - - -The DNS interface - - Standard DNSEL, if I understand right, looks like this: There's some - authoritative name server for foo.example.com. You want to know if - 1.2.3.4 is in the list, so you query for an A record for - 4.3.2.1.foo.example.com. If the record exists and has the value - 127.0.0.2[DNSBL-EMAIL], 1.2.3.4 is in the list. If you get an NXDOMAIN - error, 1.2.3.4 is not in the list. If you ask for a domain name outside - of the foo.example.com zone, you get a Server Failure error[RFC 1035]. - - Assume that the DNSEL answers queries authoritatively for some zone, - torhosts.example.com. Below are some queries that could be supported, - though some of them are possibly a bad idea. - - - Query type 1: "General IP:Port" - - Format: - {IP1}.{port}.{IP2}.ip-port.torhosts.example.com - - Rule: - Iff {IP1} is a Tor server that permits connections to {port} on - {IP2}, then there should be an A record with the value 127.0.0.2. - - Example: - "1.0.0.10.80.4.3.2.1.ip-port.torhosts.example.com" should have the - value 127.0.0.2 if and only if there is a Tor server at 10.0.0.1 - that allows connections to port 80 on 1.2.3.4. - - Example use: - I'm running an IRC server at w.x.y.z:9999, and I want to tell - whether an incoming connection is from a Tor server. I set - up my IRC server to give a special mask to any user coming from - an IP listed in 9999.z.y.x.w.ip-port.torhosts.example.com. - - Later, when I get a connection from a.b.c.d, my ircd looks up - "d.c.b.a.9999.z.y.x.w.ip-port.torhosts.example.com" to see - if it's a Tor server that allows connections to my ircd. - - - Query type 2: "IP-port group" - - Format: - {IP}.{listname}.list.torhosts.example.com - - Rule: - Iff this Tor server is configured with an IP:Port list named - {listname}, and {IP} is a Tor server that permits connections to - any member of {listname}, then there exists an A record. - - Example: - Suppose torhosts.example.com has a list of IP:Port called "foo". - There is an A record for 4.3.2.1.foo.list.torhosts.example.com - if and only if 1.2.3.4 is a Tor server that permits connections - to one of the addresses in list "foo". - - Example use: - Suppose torhosts.example.com has a list of hosts in "examplenet", - a popular IRC network. Rather than having them each set up to - query the appropriate "ip-port" list, they could instead all be - set to query a central examplenet.list.torhosts.example.com. - - Problems: - We'd be better off if each individual server queried about hosts - that allowed connections to itself. That way, if I wanted to - allow anonymous connections to foonet, but I wanted to be able to - connect to foonet from my own IP without being marked, I could add - just a few foonet addresses to my exit policy. - - - Query type 3: "My IP, with port" - - Format: - {IP}.{port}.me.torhosts.example.com - - Rule: - An A record exists iff there is a tor server at {IP} that permits - connections to {port} on the host that requested the lookup. - - Example: - "4.3.2.1.80.me.torhosts.example.com" should have an A record if - and only if there is a Tor server at 1.2.3.4 that allows - connections to port 80 of the querying host. - - Example use: - Somebody wants to set up a quick-and-dirty Tor detector for a - single webserver: just point them at 80.me.torhosts.example.com. - - Problem: - This would be easiest to use, but DNS gets in the way. If you - create DNS records that give different results depending on who is - asking, you mess up caching. There could be a fix here, but might - not. - - - RECOMMENDATION: Just build ip-port for now, and see what demand is - like. There's no point in building mechanisms nobody wants. - -Web interface: - - Should provide the same data as the dns interface. - -Other issues: - - After a Tor server op turns off their server, it stops publishing server - descriptors. We should consider that server's IP address to still - represent a Tor node until 48 hours after its last descriptor was - published. - - 30-60 minutes is not an unreasonable TTL. - - There could be some demand for address masks and port lists. Address - masks wider than /8 make me nervous here, as do port ranges. - - We need an answer for what to do about hosts which exit from different - IPs than their advertised IP. One approach would be for the DNSEL - to launch periodic requests to itself through all exit servers whose - policies allow it -- and then see where the requests actually come from. - -References: - - [DNSBL-EMAIL] Levine, J., "DNS Based Blacklists and Whitelists for - E-Mail", http://tools.ietf.org/html/draft-irtf-asrg-dnsbl-02, November - 2005. - - [RFC 1035] Mockapetris, P., "Domain Names - Implementation and - Specification", RFC 1035, November 1987. diff --git a/doc/include.am b/doc/include.am index 9eb919b9e..9695292bd 100644 --- a/doc/include.am +++ b/doc/include.am @@ -36,8 +36,6 @@ endif EXTRA_DIST+= doc/HACKING doc/asciidoc-helper.sh \ $(html_in) $(man_in) $(txt_in) \ - doc/tor-rpm-creation.txt \ - doc/tor-win32-mingw-creation.txt doc/spec/README \ doc/state-contents.txt docdir = @docdir@ diff --git a/doc/spec/README b/doc/spec/README deleted file mode 100644 index ccd33a421..000000000 --- a/doc/spec/README +++ /dev/null @@ -1,11 +0,0 @@ -The Tor specifications and proposals have moved to a new repository. - -To browse the specifications, go to - https://gitweb.torproject.org/torspec.git/tree - -To check out the specification repository, run - git clone git://git.torproject.org/torspec.git - -For other information on the repository, see - https://gitweb.torproject.org/torspec.git - diff --git a/doc/tor-win32-mingw-creation.txt b/doc/tor-win32-mingw-creation.txt deleted file mode 100644 index 4a25e47a8..000000000 --- a/doc/tor-win32-mingw-creation.txt +++ /dev/null @@ -1,119 +0,0 @@ -## -## Instructions for building Tor with MinGW (http://www.mingw.org/) -## - -Stage One: Download and Install MinGW. ---------------------------------------- - -Download mingw: -http://prdownloads.sf.net/mingw/MinGW-5.1.6.exe?download - -Download msys: -http://prdownloads.sf.net/ming/MSYS-1.0.11.exe?download - -Download msysDTK: -http://sourceforge.net/projects/mingw/files/MSYS%20Supplementary%20Tools/msysDTK-1.0.1/msysDTK-1.0.1.exe/download - -Install MinGW, msysDTK, and MSYS in that order. - -Make sure your PATH includes C:\MinGW\bin. You can verify this by right -clicking on "My Computer", choose "Properties", choose "Advanced", -choose "Environment Variables", select PATH. - -Start MSYS(rxvt). - -Create a directory called "tor-mingw". - -Stage Two: Download, extract, compile openssl ----------------------------------------------- - -Download openssl: -http://www.openssl.org/source/openssl-0.9.8l.tar.gz - -Extract openssl: -Copy the openssl tarball into the "tor-mingw" directory. -Type "cd tor-mingw/" -Type "tar zxf openssl-0.9.8l.tar.gz" -(Note: There are many symlink errors because Windows doesn't support -symlinks. You can ignore these errors.) - -Make openssl libraries: -Type "cd tor-mingw/openssl-0.9.8l/" -Type "./Configure -no-idea -no-rc5 -no-mdc2 mingw" -Edit Makefile and remove the "test:" and "tests:" sections. -Type "rm -rf ./test" -Type "cd crypto/" -Type "find ./ -name "*.h" -exec cp {} ../include/openssl/ \;" -Type "cd ../ssl/" -Type "find ./ -name "*.h" -exec cp {} ../include/openssl/ \;" -Type "cd .." -Type "cp *.h include/openssl/" -Type "find ./fips -type f -name "*.h" -exec cp {} include/openssl/ \;" -# The next steps can take up to 30 minutes to complete. -Type "make" -Type "make install" - - -Stage Three: Download, extract, compile zlib ---------------------------------------------- - -Download zlib source: -http://www.zlib.net/zlib-1.2.3.tar.gz - -Extract zlib: -Copy the zlib tarball into the "tor-mingw" directory -Type "cd tor-mingw/" -Type "tar zxf zlib-1.2.3.tar.gz" - -CHOICE: - -Make zlib.a: -Type "cd tor-mingw/zlib-1.2.3/" -Type "./configure" -Type "make" -Type "make install" - -Done. - - -Stage Four: Download, extract, and compile libevent ------------------------------------------------------- - -Download the latest libevent release: -http://www.monkey.org/~provos/libevent/ - -Copy the libevent tarball into the "tor-mingw" directory. -Type "cd tor-mingw" - -Extract libevent. - -Type "./configure --enable-static --disable-shared" -Type "make" -Type "make install" - -Stage Five: Build Tor ----------------------- - -Download the current Tor alpha release source code from https://torproject.org/download.html. -Copy the Tor tarball into the "tor-mingw" directory. -Extract Tor: -Type "tar zxf latest-tor-alpha.tar.gz" - -cd tor- -Type "./configure" -Type "make" - -You now have a tor.exe in src/or/. This is Tor. -You now have a tor-resolve.exe in src/tools/. - -Stage Six: Build the installer -------------------------------- - -Install the latest NSIS: -http://nsis.sourceforge.net/Download - -Run the package script in contrib: -From the Tor build directory above, run: -"./contrib/package_nsis-mingw.sh" - -The resulting Tor installer executable is in ./win_tmp/. diff --git a/doc/translations.txt b/doc/translations.txt deleted file mode 100644 index 06d16f446..000000000 --- a/doc/translations.txt +++ /dev/null @@ -1,182 +0,0 @@ -## Instructions for helping translate text for Vidalia, TorButton -## and TorCheck -## ( More translation information for Tor related apps will accumulate here ) - -Our translations are handled in one of two places. The Tor Translation Portal -handles all of the translations for Vidalia, Torbutton and TorCheck. The Tor -website itself is currently handled by hand translations using subversion. - -------------------------------------------------------------------------- - -For the Tor website, you'll need a Tor SVN account. -If you do not have one and you need one, please run this command with your -desired username in place of 'USERNAME': - htdigest -c passwd.tmp "Tor subversion repository" USERNAME -and send us the contents of passwd.tmp. - -------------------------------------------------------------------------- - -For the Portal-based projects, all three check in their respective .po -files into the following subversion urls: - - https://tor-svn.freehaven.net/svn/translation/trunk/projects/torbutton - https://tor-svn.freehaven.net/svn/translation/trunk/projects/torcheck - https://svn.vidalia-project.net/svn/vidalia/trunk/src/vidalia/i18n/ - -The current pootle configuration is checked into subversion as well: - - https://tor-svn.freehaven.net/svn/translation/trunk/pootle - ----------------------------- TorCheck ------------------------------- - -TorCheck uses our translation portal to accept translations. Users use -the portal to check in their changes. To make use of the translations -that users have committed to the translations/ subversion module, you'll -need to ensure that you have a current checked out copy of TorCheck: - - cd check/trunk/i18n/ - check/trunk/i18n$ svn up - -You should see something like the following: - - Fetching external item into 'pootle' - External at revision 15300. - - At revision 15300. - -Now if you had changes, you'd simply want to move the newly updated .po files -into the current stable directory. Moving the .po files from -'check/trunk/i18n/pootle/' into 'check/trunk/i18n' properly naming the files -for their respective locale. - -Here's an example of how to move all of the current pootle translations into -the svn trunk area of TorCheck: - - cd check/trunk/i18n/ - for locale in `ls -1 pootle/|grep -v template`; - do - mv -v pootle/$locale/TorCheck_$locale.po TorCheck_$locale.po; - done - -Now check the differences (ensure the output looks reasonable): - - svn diff - -Ensure that msgfmt has no errors: - - msgfmt -C *.po - -And finally check in the changes: - - svn commit - ----------------------------- Torbutton ------------------------------- - -Torbutton uses our translation portal to accept translations. Users use -the portal to check in their changes. - -To make use of the translations that users have committed to the translations/ -subversion module, you'll need to ensure that you have a current checked out -copy of them in your torbutton git checkout: - - cd torbutton.git/trans_tools - torbutton.git/trans_tools$ svn co https://tor-svn.freehaven.net/svn/translation/trunk/projects/torbutton pootle - -You should see something like the following: - - Checked out revision 21092. - -If you made changes to strings in Torbutton, you need to rebuild the -templates in torbutton.git/trans_tools/pootle/templates. This is done with -the following command from within the torbutton.git checkout directory: - - moz2po -P -i src/chrome/locale/en/ -o trans_tools/pootle/templates/ - -You now have two options: - -Option 1 (The [shitty] Pootle Web UI Way): - -View then commit the changes to the template with: - - cd trans_tools/pootle - svn diff templates - svn commit templates - -Then poke Jake to 'svn up' on the Pootle side. If you do this enough -times, he may give you a button to click to update templates in Pootle, -or maybe even an account on the Pootle server. Persistence is a virtue. - -You then need to go to the Pootle website and click the checkbox next to -every language on: -https://translation.torproject.org/projects/torbutton/admin.html -and then click "Update Languages" at the bottom. - -You then need to go to each language and go to "Editing Options" and click -"Commit" for each one. - -You then need to 'svn up' locally, and follow the procedure above for -rebuilding your .dtd and .properties files. - -Yes, this sucks. :/ - -Option 2 (Use your own msgmerge: YMMV, may change .po flags and formatting): - -Run msgmerge yourself for each language: - - cd trans_tools - for i in `ls -1 pootle` - do - msgmerge -U ./pootle/$i/torbutton.dtd.po ./pootle/templates/torbutton.dtd.pot - msgmerge -U ./pootle/$i/torbutton.properties.po ./pootle/templates/torbutton.properties.pot - done - svn diff pootle - svn commit pootle - -Then poke Jake to 'svn up' on the Pootle side. If you do this enough times, -he may give you a button on Pootle, or maybe even an account on the Pootle -server. Persistence is a virtue. - -You may notice that some .po file flags and string formatting have changed -with this method, depending on your gettext version. It is unclear if this -is a problem. Please update this doc if you hit a landmine and everything -breaks :) - -After this process is done, you then need to regenerate the mozilla -.dtd and .properties files as specified above. - - -Regardless of whether or not you had changes in the torbutton strings, if there -were updated strings in pootle that you checked out from svn you now need to -convert from .po and move the newly updated mozilla files into the current -stable locale directory. First convert them with the 'mkmoz.sh' script and -then move the proper mozilla files from 'torbutton.git/trans_tools/moz/' into -'torbutton.git/src/chrome/locale/' directory while properly naming the files -for their respective locale. - -Here's an example of how to move all of the current pootle translations into -the svn trunk area of Torbutton: - - cd trans_tools - ./mkmoz.sh - for locale in `ls -1 moz/`; - do - mv -v moz/$locale/*.{dtd,properties} ../src/chrome/locale/$locale/ - done - -Now check the differences to your git branch to ensure the output looks -reasonable: - - cd .. - git diff - -And finally check in the changes: - - cd src/chrome/locale - git commit . - ----------------------------- Vidalia ------------------------------- - -Vidalia uses our translation portal to accept translations. Users use the -portal to check in their changes. No conversion or moving is required other -than normal pootle usage. - diff --git a/doc/v3-authority-howto.txt b/doc/v3-authority-howto.txt deleted file mode 100644 index e4470e8c8..000000000 --- a/doc/v3-authority-howto.txt +++ /dev/null @@ -1,84 +0,0 @@ - - How to add a v3 directory authority. - -What we'll be doing: - - We'll be configuring your Tor server as a v3 directory authority, - generating a v3 identity key plus certificates, and adding your v3 - identity fingerprint to the list of default directory authorities. - -The steps: - -0) Make sure you're running ntp, and that your time is correct. - - Make sure you have Tor version at least r12724. In the short term, - running a working authority may mean running the latest version of - Tor from SVN trunk. Later on, we hope that it will become easier - and you can just run a recent development release (and later still, - a recent stable release). - -1) First, you'll need a certificate. Run ./src/tools/tor-gencert to - generate one. - - Run tor-gencert in a separate, very secure directory. Maybe even on - a more secure computer. The first time you run it, you will need to - run it with the --create-identity-key option to make a v3 authority - identity key. Subsequent times, you can just run it as-is. - - tor-gencert will make 3 files: - - authority_identity_key -- THIS IS VERY SECRET AND VERY SENSITIVE. - DO NOT LEAK IT. DO NOT LOSE IT. - - authority_signing_key -- A key for signing votes and v3 conensuses. - - authority_certificate -- A document authenticating your signing key - with your identity-key. - - You will need to rotate your signing key periodically. The current - default lifetime is 1 year. We'll probably take this down to a month or - two some time soon. To rotate your key, run tor-gencert as before, - but without the --create-identity-key option. - -2) Copy authority_signing_key and authority_certificate to your Tor keys - directory. - - For example if your data directory is /var/lib/tor/, you should run - cp authority_signing_key authority_certificate /var/lib/tor/keys/ - - You will need to repeat this every time you rotate your certificate. - -3) Tell your Tor to be a v3 authority by adding these lines to your torrc: - - AuthoritativeDirectory 1 - V3AuthoritativeDirectory 1 - -4) Now your authority is generating a networkstatus opinion (called a - "vote") every period, but none of the other authorities care yet. The - next step is to get a Tor developer (likely Roger or Nick) to add - your v3 identity fingerprint to the default list of dirservers. - - First, you need to learn your authority's v3 identity fingerprint. - It should be in your authority_certificate file in a line like: - - fingerprint 3041632465FA8847A98B2C5742108C72325532D9 - - One of the Tor developers then needs to add this fingerprint to - the add_default_trusted_dirservers() function in config.c, using - the syntax "v3ident=". For example, if moria1's new v3 - identity fingerprint is FOO, the moria1 dirserver line should now be: - - DirServer moria1 v1 orport=9001 v3ident=FOO 128.31.0.34:9031 FFCB 46DB 1339 DA84 674C 70D7 CB58 6434 C437 0441 - - The v3ident item must appear after the nickname and before the IP. - -5) Once your fingerprint has been added to config.c, we will try to - get a majority of v3 authorities to upgrade, so they know about you - too. At that point your vote will automatically be included in the - networkstatus consensus, and you'll be a fully-functioning contributing - v3 authority. - - Note also that a majority of the configured v3 authorities need to - agree in order to generate a consensus: so this is also the point - where extended downtime on your server means missing votes. - From 74a534be15a26cddb8b134757416a7550072f44b Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Wed, 12 Jun 2013 21:27:30 -0400 Subject: [PATCH 08/14] Fix the biggest errors in doc/HACKING We can wait for 0.2.5 for a full rewrite. #8964 --- doc/HACKING | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/doc/HACKING b/doc/HACKING index c06a68268..b7cd8952d 100644 --- a/doc/HACKING +++ b/doc/HACKING @@ -12,7 +12,7 @@ https://gitweb.torproject.org/torspec.git/blob_plain/HEAD:/proposals/001-process For the latest version of the code, get a copy of git, and - git clone git://git.torproject.org/git/tor . + git clone https://git.torproject.org/git/tor We talk about Tor on the tor-talk mailing list. Design proposals and discussion belong on the tor-dev mailing list. We hang around on @@ -38,9 +38,9 @@ release. Occasionally, we'll merge an urgent bugfix into the release branch before it gets merged into maint, but that's rare. If you're working on a bugfix for a bug that occurs in a particular version, -base your bugfix branch on the "maint" branch for the first _actively -developed_ series that has that bug. (Right now, that's 0.2.1.) If you're -working on a new feature, base it on the master branch. +base your bugfix branch on the "maint" branch for the first supported series +that has that bug. (As of June 2013, we're supporting 0.2.3 and later.) If +you're working on a new feature, base it on the master branch. How we log changes @@ -51,7 +51,7 @@ the "changes" toplevel subdirectory. It should have the format of a one-entry changelog section from the current ChangeLog file, as in o Major bugfixes: - - Fix a potential buffer overflow. Fixes bug 9999; bugfix on + - Fix a potential buffer overflow. Fixes bug 99999; bugfix on 0.3.1.4-beta. To write a changes file, first categorize the change. Some common categories @@ -90,10 +90,10 @@ Useful tools These aren't strictly necessary for hacking on Tor, but they can help track down bugs. -The buildbot -~~~~~~~~~~~~ +Jenkins +~~~~~~~ -https://buildbot.vidalia-project.net/one_line_per_build +http://jenkins.torproject.org Dmalloc ~~~~~~~ @@ -182,6 +182,8 @@ Did you remember... - To build your code while configured with --enable-gcc-warnings? - To run "make check-spaces" on your code? + - To run "make check-docs" to see whether all new options are on + the manpage? - To write unit tests, as possible? - To base your code on the appropriate branch? - To include a file in the "changes" directory as appropriate? @@ -312,7 +314,7 @@ do your own profiling to determine otherwise. Log conventions ~~~~~~~~~~~~~~~ -https://wiki.torproject.org/noreply/TheOnionRouter/TorFAQ#LogLevels +https://trac.torproject.org/projects/tor/wiki/doc/TorFAQ#loglevel No error or warning messages should be expected during normal OR or OP operation. From caa0d15c4902a8d376a2a79bfbfdb21bf047366a Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Thu, 13 Jun 2013 12:29:01 -0400 Subject: [PATCH 09/14] If we write the annotation but not the microdescriptor, rewind. This fixes bug 9047 (and some parts of 9031, 8922, 8883 that weren't fixed in 8822). Bugfix on 0.2.2.6-alpha. --- changes/bug9047 | 6 ++++++ src/common/compat.c | 12 ++++++++++++ src/common/compat.h | 1 + src/or/microdesc.c | 19 +++++++++++++------ 4 files changed, 32 insertions(+), 6 deletions(-) create mode 100644 changes/bug9047 diff --git a/changes/bug9047 b/changes/bug9047 new file mode 100644 index 000000000..497f0d337 --- /dev/null +++ b/changes/bug9047 @@ -0,0 +1,6 @@ + o Minor bugfixes: + - If for some reason we fail to write a microdescriptor while + rebuilding the cache, do not let the annotations from that + microdescriptor linger in the cache file, and do not let the + microdescriptor stay recorded as present in its old location. + Fixes bug 9047; bugfix on 0.2.2.6-alpha. diff --git a/src/common/compat.c b/src/common/compat.c index c97a4545c..24b44fb05 100644 --- a/src/common/compat.c +++ b/src/common/compat.c @@ -900,6 +900,18 @@ tor_fd_seekend(int fd) #endif } +/** Move fd to position pos in the file. Return -1 on error, 0 + * on success. */ +int +tor_fd_setpos(int fd, off_t pos) +{ +#ifdef _WIN32 + return _lseek(fd, pos, SEEK_SET) < 0 ? -1 : 0; +#else + return lseek(fd, pos, SEEK_SET) < 0 ? -1 : 0; +#endif +} + #undef DEBUG_SOCKET_COUNTING #ifdef DEBUG_SOCKET_COUNTING /** A bitarray of all fds that should be passed to tor_socket_close(). Only diff --git a/src/common/compat.h b/src/common/compat.h index f0a34aae4..8ab719052 100644 --- a/src/common/compat.h +++ b/src/common/compat.h @@ -411,6 +411,7 @@ tor_lockfile_t *tor_lockfile_lock(const char *filename, int blocking, void tor_lockfile_unlock(tor_lockfile_t *lockfile); off_t tor_fd_getpos(int fd); +int tor_fd_setpos(int fd, off_t pos); int tor_fd_seekend(int fd); #ifdef _WIN32 diff --git a/src/or/microdesc.c b/src/or/microdesc.c index 05e3b4181..b93bd83af 100644 --- a/src/or/microdesc.c +++ b/src/or/microdesc.c @@ -74,7 +74,7 @@ static ssize_t dump_microdescriptor(int fd, microdesc_t *md, size_t *annotation_len_out) { ssize_t r = 0; - size_t written; + ssize_t written; if (md->body == NULL) { *annotation_len_out = 0; return 0; @@ -99,10 +99,10 @@ dump_microdescriptor(int fd, microdesc_t *md, size_t *annotation_len_out) md->off = tor_fd_getpos(fd); written = write_all(fd, md->body, md->bodylen, 0); - if (written != md->bodylen) { + if (written != (ssize_t)md->bodylen) { log_warn(LD_DIR, - "Couldn't dump microdescriptor (wrote %lu out of %lu): %s", - (unsigned long)written, (unsigned long)md->bodylen, + "Couldn't dump microdescriptor (wrote %ld out of %lu): %s", + (long)written, (unsigned long)md->bodylen, strerror(errno)); return -1; } @@ -456,8 +456,15 @@ microdesc_cache_rebuild(microdesc_cache_t *cache, int force) size = dump_microdescriptor(fd, md, &annotation_len); if (size < 0) { - /* XXX handle errors from dump_microdescriptor() */ - /* log? return -1? die? coredump the universe? */ + if (md->saved_location != SAVED_IN_CACHE) + tor_free(md->body); + md->saved_location = SAVED_NOWHERE; + md->off = 0; + md->bodylen = 0; + md->no_save = 1; + + /* rewind, in case it was a partial write. */ + tor_fd_setpos(fd, off); continue; } tor_assert(((size_t)size) == annotation_len + md->bodylen); From 2338681efbdc8070c0cdfd0b9226fcdeb37f0538 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Thu, 13 Jun 2013 21:56:35 -0400 Subject: [PATCH 10/14] Define SEEK_SET for platforms that lack it. --- src/common/compat.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/common/compat.c b/src/common/compat.c index 24b44fb05..69eb0643d 100644 --- a/src/common/compat.c +++ b/src/common/compat.c @@ -870,6 +870,9 @@ tor_lockfile_unlock(tor_lockfile_t *lockfile) /** @{ */ /** Some old versions of Unix didn't define constants for these values, * and instead expect you to say 0, 1, or 2. */ +#ifndef SEEK_SET +#define SEEK_SET 0 +#endif #ifndef SEEK_CUR #define SEEK_CUR 1 #endif From 4cce58d3c22c65350fffb3c4bc4dccd73e0193d7 Mon Sep 17 00:00:00 2001 From: Andrea Shepard Date: Thu, 13 Jun 2013 20:41:00 -0700 Subject: [PATCH 11/14] Don't queue more cells as a middle relay than the spec allows to be in flight --- changes/bug9063 | 3 +++ src/or/or.h | 8 ++++++++ src/or/relay.c | 23 ++++++++++++++++++++++- 3 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 changes/bug9063 diff --git a/changes/bug9063 b/changes/bug9063 new file mode 100644 index 000000000..af3b1a87f --- /dev/null +++ b/changes/bug9063 @@ -0,0 +1,3 @@ + o Normal bugfixes: + - Close any circuit that has more cells queued than the spec permits. + Fixes bug #9063; bugfix on 0.2.3.25. diff --git a/src/or/or.h b/src/or/or.h index 6728b862b..2565777c7 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -539,6 +539,8 @@ typedef enum { #define CIRCUIT_PURPOSE_IS_ESTABLISHED_REND(p) \ ((p) == CIRCUIT_PURPOSE_C_REND_JOINED || \ (p) == CIRCUIT_PURPOSE_S_REND_JOINED) +/** True iff the circuit_t c is actually an or_circuit_t */ +#define CIRCUIT_IS_ORCIRC(c) (((circuit_t *)(c))->magic == OR_CIRCUIT_MAGIC) /** How many circuits do we want simultaneously in-progress to handle * a given stream? */ @@ -814,6 +816,12 @@ typedef enum { /** Amount to increment a stream window when we get a stream SENDME. */ #define STREAMWINDOW_INCREMENT 50 +/** Maximum number of queued cells on a circuit for which we are the + * midpoint before we give up and kill it. This must be >= circwindow + * to avoid killing innocent circuits. + */ +#define ORCIRC_MAX_MIDDLE_CELLS (11*(CIRCWINDOW_START_MAX)/10) + /* Cell commands. These values are defined in tor-spec.txt. */ #define CELL_PADDING 0 #define CELL_CREATE 1 diff --git a/src/or/relay.c b/src/or/relay.c index a17c33331..087459c5c 100644 --- a/src/or/relay.c +++ b/src/or/relay.c @@ -2532,8 +2532,10 @@ append_cell_to_circuit_queue(circuit_t *circ, or_connection_t *orconn, cell_t *cell, cell_direction_t direction, streamid_t fromstream) { + or_circuit_t *orcirc = NULL; cell_queue_t *queue; int streams_blocked; + if (circ->marked_for_close) return; @@ -2541,11 +2543,30 @@ append_cell_to_circuit_queue(circuit_t *circ, or_connection_t *orconn, queue = &circ->n_conn_cells; streams_blocked = circ->streams_blocked_on_n_conn; } else { - or_circuit_t *orcirc = TO_OR_CIRCUIT(circ); + orcirc = TO_OR_CIRCUIT(circ); queue = &orcirc->p_conn_cells; streams_blocked = circ->streams_blocked_on_p_conn; } + /* Are we a middle circuit about to exceed ORCIRC_MAX_MIDDLE_CELLS? */ + if ((circ->n_conn != NULL) && CIRCUIT_IS_ORCIRC(circ)) { + orcirc = TO_OR_CIRCUIT(circ); + if (orcirc->p_conn) { + if (queue->n + 1 >= ORCIRC_MAX_MIDDLE_CELLS) { + /* Queueing this cell would put queue over the cap */ + log_warn(LD_CIRC, + "Got a cell exceeding the cap of %u in the %s direction " + "on middle circ ID %u; killing the circuit.", + ORCIRC_MAX_MIDDLE_CELLS, + (direction == CELL_DIRECTION_OUT) ? "n" : "p", + (direction == CELL_DIRECTION_OUT) ? + circ->n_circ_id : orcirc->p_circ_id); + circuit_mark_for_close(circ, END_CIRC_REASON_RESOURCELIMIT); + return; + } + } + } + cell_queue_append_packed_copy(queue, cell); /* If we have too many cells on the circuit, we should stop reading from From 418c2845d03bf425ac2a0a9758b89e151dc3b9aa Mon Sep 17 00:00:00 2001 From: Andrea Shepard Date: Thu, 13 Jun 2013 20:49:01 -0700 Subject: [PATCH 12/14] Don't queue more cells as a middle relay than the spec allows to be in flight --- changes/bug9063 | 3 +++ src/or/or.h | 8 ++++++++ src/or/relay.c | 28 +++++++++++++++++++++++++++- 3 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 changes/bug9063 diff --git a/changes/bug9063 b/changes/bug9063 new file mode 100644 index 000000000..dcbecf617 --- /dev/null +++ b/changes/bug9063 @@ -0,0 +1,3 @@ + o Normal bugfixes: + - Close any circuit that has more cells queued than the spec permits. + Fixes bug #9063; bugfix on 0.2.4.12. diff --git a/src/or/or.h b/src/or/or.h index ab5e3aaad..36b67789e 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -541,6 +541,8 @@ typedef enum { #define CIRCUIT_PURPOSE_IS_ESTABLISHED_REND(p) \ ((p) == CIRCUIT_PURPOSE_C_REND_JOINED || \ (p) == CIRCUIT_PURPOSE_S_REND_JOINED) +/** True iff the circuit_t c is actually an or_circuit_t */ +#define CIRCUIT_IS_ORCIRC(c) (((circuit_t *)(c))->magic == OR_CIRCUIT_MAGIC) /** How many circuits do we want simultaneously in-progress to handle * a given stream? */ @@ -818,6 +820,12 @@ typedef enum { /** Amount to increment a stream window when we get a stream SENDME. */ #define STREAMWINDOW_INCREMENT 50 +/** Maximum number of queued cells on a circuit for which we are the + * midpoint before we give up and kill it. This must be >= circwindow + * to avoid killing innocent circuits. + */ +#define ORCIRC_MAX_MIDDLE_CELLS (11*(CIRCWINDOW_START_MAX)/10) + /* Cell commands. These values are defined in tor-spec.txt. */ #define CELL_PADDING 0 #define CELL_CREATE 1 diff --git a/src/or/relay.c b/src/or/relay.c index d57ceaacf..a26d4186d 100644 --- a/src/or/relay.c +++ b/src/or/relay.c @@ -2466,8 +2466,10 @@ append_cell_to_circuit_queue(circuit_t *circ, channel_t *chan, cell_t *cell, cell_direction_t direction, streamid_t fromstream) { + or_circuit_t *orcirc = NULL; cell_queue_t *queue; int streams_blocked; + if (circ->marked_for_close) return; @@ -2475,11 +2477,35 @@ append_cell_to_circuit_queue(circuit_t *circ, channel_t *chan, queue = &circ->n_chan_cells; streams_blocked = circ->streams_blocked_on_n_chan; } else { - or_circuit_t *orcirc = TO_OR_CIRCUIT(circ); + orcirc = TO_OR_CIRCUIT(circ); queue = &orcirc->p_chan_cells; streams_blocked = circ->streams_blocked_on_p_chan; } + /* Are we a middle circuit about to exceed ORCIRC_MAX_MIDDLE_CELLS? */ + if ((circ->n_chan != NULL) && CIRCUIT_IS_ORCIRC(circ)) { + orcirc = TO_OR_CIRCUIT(circ); + if (orcirc->p_chan) { + if (queue->n + 1 >= ORCIRC_MAX_MIDDLE_CELLS) { + /* Queueing this cell would put queue over the cap */ + log_warn(LD_CIRC, + "Got a cell exceeding the cap of %u in the %s direction " + "on middle circ ID %u on chan ID " U64_FORMAT + "; killing the circuit.", + ORCIRC_MAX_MIDDLE_CELLS, + (direction == CELL_DIRECTION_OUT) ? "n" : "p", + (direction == CELL_DIRECTION_OUT) ? + circ->n_circ_id : orcirc->p_circ_id, + U64_PRINTF_ARG( + (direction == CELL_DIRECTION_OUT) ? + circ->n_chan->global_identifier : + orcirc->p_chan->global_identifier)); + circuit_mark_for_close(circ, END_CIRC_REASON_RESOURCELIMIT); + return; + } + } + } + cell_queue_append_packed_copy(queue, cell, chan->wide_circ_ids); /* If we have too many cells on the circuit, we should stop reading from From 9e8c104ab879f979d313d1f1cef4c1480f431ceb Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Fri, 14 Jun 2013 01:35:21 -0400 Subject: [PATCH 13/14] Increase the limit so leaky pipe might work --- src/or/or.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/or/or.h b/src/or/or.h index 2565777c7..83bf8c890 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -818,9 +818,10 @@ typedef enum { /** Maximum number of queued cells on a circuit for which we are the * midpoint before we give up and kill it. This must be >= circwindow - * to avoid killing innocent circuits. + * to avoid killing innocent circuits, and >= circwindow*2 to give + * leaky-pipe a chance for being useful someday. */ -#define ORCIRC_MAX_MIDDLE_CELLS (11*(CIRCWINDOW_START_MAX)/10) +#define ORCIRC_MAX_MIDDLE_CELLS (21*(CIRCWINDOW_START_MAX)/10) /* Cell commands. These values are defined in tor-spec.txt. */ #define CELL_PADDING 0 From 79cdf81ec12c4f692db7c88e5f94a8419dfcea62 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Fri, 14 Jun 2013 01:37:22 -0400 Subject: [PATCH 14/14] Increase the limit so leaky pipe might work --- src/or/or.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/or/or.h b/src/or/or.h index 36b67789e..935da538a 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -822,9 +822,10 @@ typedef enum { /** Maximum number of queued cells on a circuit for which we are the * midpoint before we give up and kill it. This must be >= circwindow - * to avoid killing innocent circuits. + * to avoid killing innocent circuits, and >= circwindow*2 to give + * leaky-pipe a chance for being useful someday. */ -#define ORCIRC_MAX_MIDDLE_CELLS (11*(CIRCWINDOW_START_MAX)/10) +#define ORCIRC_MAX_MIDDLE_CELLS (21*(CIRCWINDOW_START_MAX)/10) /* Cell commands. These values are defined in tor-spec.txt. */ #define CELL_PADDING 0