diff options
author | Nick Mathewson <nickm@torproject.org> | 2008-12-11 19:12:48 +0000 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2008-12-11 19:12:48 +0000 |
commit | 043b4fc59e635015dc7fc758d44ba298b8278f4a (patch) | |
tree | d139f6f67af83b9cc5866415e0e2d0795b474aaa | |
parent | 29f5a65a166cd06879ef55b7b5a38ae88c40482f (diff) | |
download | tor-043b4fc59e635015dc7fc758d44ba298b8278f4a.tar.gz tor-043b4fc59e635015dc7fc758d44ba298b8278f4a.zip |
Add a PDS_ flag to exclude authorities from which we are fetching descs.
Yes, this is maybe a little overspecific. Part of a bug 366 fix.
svn:r17593
-rw-r--r-- | src/or/directory.c | 16 | ||||
-rw-r--r-- | src/or/or.h | 17 | ||||
-rw-r--r-- | src/or/routerlist.c | 40 |
3 files changed, 66 insertions, 7 deletions
diff --git a/src/or/directory.c b/src/or/directory.c index fd609ea9a6..e74119c0e6 100644 --- a/src/or/directory.c +++ b/src/or/directory.c @@ -368,6 +368,22 @@ directory_get_from_dirserver(uint8_t dir_purpose, uint8_t router_purpose, if (prefer_authority || type == BRIDGE_AUTHORITY) { /* only ask authdirservers, and don't ask myself */ rs = router_pick_trusteddirserver(type, pds_flags); + if (rs == NULL && (pds_flags & PDS_NO_EXISTING_SERVERDESC_FETCH)) { + /* We don't want to fetch from any authorities that we're currently + * fetching server descriptors from, and we got no match. Did we + * get no match because all the authorities have connections + * fetching server descriptors (in which case we should just + * return,) or because all the authorities are down or on fire or + * unreachable or something (in which case we should go on with + * our fallback code)? */ + pds_flags &= ~PDS_NO_EXISTING_SERVERDESC_FETCH; + rs = router_pick_trusteddirserver(type, pds_flags); + if (rs) { + log_debug(LD_DIR, "Deferring serverdesc fetch: all authorities " + "are in use."); + return; + } + } } if (!rs && type != BRIDGE_AUTHORITY) { /* anybody with a non-zero dirport will do */ diff --git a/src/or/or.h b/src/or/or.h index 0335afef48..37eeaddc3e 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -4191,9 +4191,26 @@ int router_reload_router_list(void); smartlist_t *router_get_trusted_dir_servers(void); /* Flags for pick_directory_server and pick_trusteddirserver. */ +/** Flag to indicate that we should not automatically be willing to use + * ourself to answer a directory request. + * Passed to router_pick_directory_server (et al).*/ #define PDS_ALLOW_SELF (1<<0) +/** Flag to indicate that if no servers seem to be up, we should mark all + * directory servers as up and try again. + * Passed to router_pick_directory_server (et al).*/ #define PDS_RETRY_IF_NO_SERVERS (1<<1) +/** Flag to indicate that we should not exclude directory servers that + * our ReachableAddress settings would exclude. This usually means that + * we're going to connect to the server over Tor, and so we don't need to + * worry about our firewall telling us we can't. + * Passed to router_pick_directory_server (et al).*/ #define PDS_IGNORE_FASCISTFIREWALL (1<<2) +/** Flag to indicate that we should not use any directory authority to which + * we have an existing directory connection for downloading server descriptors + * or extrainfo documents. [NOTE: Only implemented for + * router_pick_trusteddirserver, not router_pick_directory_server.] + * Passed to router_pick_directory_server (et al).*/ +#define PDS_NO_EXISTING_SERVERDESC_FETCH (1<<3) #define _PDS_PREFER_TUNNELED_DIR_CONNS (1<<16) routerstatus_t *router_pick_directory_server(authority_type_t type, int flags); trusted_dir_server_t *router_get_trusteddirserver_by_digest(const char *d); diff --git a/src/or/routerlist.c b/src/or/routerlist.c index 032790cc6d..09e26cbcb2 100644 --- a/src/or/routerlist.c +++ b/src/or/routerlist.c @@ -24,7 +24,7 @@ const char routerlist_c_id[] = static routerstatus_t *router_pick_directory_server_impl( authority_type_t auth, int flags); static routerstatus_t *router_pick_trusteddirserver_impl( - authority_type_t auth, int flags); + authority_type_t auth, int flags, int *n_busy_out); static void mark_all_trusteddirservers_up(void); static int router_nickname_matches(routerinfo_t *router, const char *nickname); static void trusted_dir_server_free(trusted_dir_server_t *ds); @@ -979,17 +979,25 @@ routerstatus_t * router_pick_trusteddirserver(authority_type_t type, int flags) { routerstatus_t *choice; + int busy = 0; if (get_options()->PreferTunneledDirConns) flags |= _PDS_PREFER_TUNNELED_DIR_CONNS; - choice = router_pick_trusteddirserver_impl(type, flags); + choice = router_pick_trusteddirserver_impl(type, flags, &busy); if (choice || !(flags & PDS_RETRY_IF_NO_SERVERS)) return choice; + if (busy) { + /* If the reason that we got no server is that servers are "busy", + * we must be excluding good servers because we already have serverdesc + * fetches with them. Do not mark down servers up because of this. */ + tor_assert((flags & PDS_NO_EXISTING_SERVERDESC_FETCH)); + return NULL; + } log_info(LD_DIR, "No trusted dirservers are reachable. Trying them all again."); mark_all_trusteddirservers_up(); - return router_pick_trusteddirserver_impl(type, flags); + return router_pick_trusteddirserver_impl(type, flags, NULL); } /** How long do we avoid using a directory server after it's given us a 503? */ @@ -1095,16 +1103,19 @@ router_pick_directory_server_impl(authority_type_t type, int flags) * are as for router_pick_directory_server_impl(). */ static routerstatus_t * -router_pick_trusteddirserver_impl(authority_type_t type, int flags) +router_pick_trusteddirserver_impl(authority_type_t type, int flags, + int *n_busy_out) { smartlist_t *direct, *tunnel; smartlist_t *overloaded_direct, *overloaded_tunnel; routerinfo_t *me = router_get_my_routerinfo(); routerstatus_t *result; time_t now = time(NULL); - int requireother = ! (flags & PDS_ALLOW_SELF); - int fascistfirewall = ! (flags & PDS_IGNORE_FASCISTFIREWALL); - int prefer_tunnel = (flags & _PDS_PREFER_TUNNELED_DIR_CONNS); + const int requireother = ! (flags & PDS_ALLOW_SELF); + const int fascistfirewall = ! (flags & PDS_IGNORE_FASCISTFIREWALL); + const int prefer_tunnel = (flags & _PDS_PREFER_TUNNELED_DIR_CONNS); + const int no_serverdesc_fetching =(flags & PDS_NO_EXISTING_SERVERDESC_FETCH); + int n_busy = 0; if (!trusted_dir_servers) return NULL; @@ -1131,6 +1142,18 @@ router_pick_trusteddirserver_impl(authority_type_t type, int flags) /* XXXX021 IP6 proposal 118 */ tor_addr_from_ipv4h(&addr, d->addr); + if (no_serverdesc_fetching) { + if (connection_get_by_type_addr_port_purpose( + CONN_TYPE_DIR, &addr, d->dir_port, DIR_PURPOSE_FETCH_SERVERDESC) + || connection_get_by_type_addr_port_purpose( + CONN_TYPE_DIR, &addr, d->dir_port, DIR_PURPOSE_FETCH_EXTRAINFO)) { + //log_debug(LD_DIR, "We have an existing connection to fetch " + // "descriptor from %s; delaying",d->description); + ++n_busy; + continue; + } + } + if (prefer_tunnel && d->or_port && (!fascistfirewall || @@ -1154,6 +1177,9 @@ router_pick_trusteddirserver_impl(authority_type_t type, int flags) result = smartlist_choose(overloaded_direct); } + if (n_busy_out) + *n_busy_out = n_busy; + smartlist_free(direct); smartlist_free(tunnel); smartlist_free(overloaded_direct); |