diff options
author | Nick Mathewson <nickm@torproject.org> | 2005-09-08 20:18:15 +0000 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2005-09-08 20:18:15 +0000 |
commit | 059148f5880de62e29ec63f5ca17cecc5767dfa1 (patch) | |
tree | 9964583eafd2d621646971ed2823491e0f2ee3a6 | |
parent | 6c4d43c724ff44bc68e52a7bfcd5b79cbbec42d7 (diff) | |
download | tor-059148f5880de62e29ec63f5ca17cecc5767dfa1.tar.gz tor-059148f5880de62e29ec63f5ca17cecc5767dfa1.zip |
Only caches download network-status for now, and they use a different strategy. Add an element to connection_t to remember what we are downloading, and a function to recognize our own fingerprint.
svn:r4944
-rw-r--r-- | src/or/connection.c | 1 | ||||
-rw-r--r-- | src/or/directory.c | 10 | ||||
-rw-r--r-- | src/or/dirserv.c | 4 | ||||
-rw-r--r-- | src/or/main.c | 7 | ||||
-rw-r--r-- | src/or/or.h | 9 | ||||
-rw-r--r-- | src/or/router.c | 12 | ||||
-rw-r--r-- | src/or/routerlist.c | 48 |
7 files changed, 73 insertions, 18 deletions
diff --git a/src/or/connection.c b/src/or/connection.c index 1adfc08a69..3b8c0347fd 100644 --- a/src/or/connection.c +++ b/src/or/connection.c @@ -231,6 +231,7 @@ _connection_free(connection_t *conn) tor_free(conn->incoming_cmd); tor_free(conn->read_event); /* Probably already freed by connection_free. */ tor_free(conn->write_event); /* Probably already freed by connection_free. */ + tor_free(conn->requested_resource); if (conn->s >= 0) { log_fn(LOG_INFO,"closing fd %d.",conn->s); diff --git a/src/or/directory.c b/src/or/directory.c index a91ab64b92..2b13cbae86 100644 --- a/src/or/directory.c +++ b/src/or/directory.c @@ -180,9 +180,6 @@ directory_get_from_dirserver(uint8_t purpose, const char *resource, char digest[DIGEST_LEN]; base16_decode(digest, DIGEST_LEN, resource+3, HEX_DIGEST_LEN); ds = router_get_trusteddirserver_by_digest(digest); - // XXXXX NM remove this. - log_fn(LOG_NOTICE, "Going straight to the authority for %s? %s",resource, - ds? "Ok.":"Oops. I can't."); } if (!ds && fetch_fresh_first) { /* only ask authdirservers, and don't ask myself */ @@ -403,6 +400,9 @@ directory_send_command(connection_t *conn, const char *platform, tor_assert(conn); tor_assert(conn->type == CONN_TYPE_DIR); + tor_free(conn->requested_resource); + conn->requested_resource = tor_strdup(resource); + /* come up with a string for which Host: we want */ if (conn->port == 80) { strlcpy(hoststring, conn->address, sizeof(hoststring)); @@ -453,7 +453,6 @@ directory_send_command(connection_t *conn, const char *platform, httpcommand = "GET";//XXXX len = strlen(resource)+32; url = tor_malloc(len); - log_fn(LOG_NOTICE, "Asking for %s", resource); tor_snprintf(url, len, "/tor/status/%s", resource); break; case DIR_PURPOSE_FETCH_SERVERDESC: @@ -889,7 +888,8 @@ connection_dir_client_reached_eof(connection_t *conn) if (conn->purpose == DIR_PURPOSE_FETCH_NETWORKSTATUS) { /* XXXX NM We *must* make certain we get the one(s) we asked for or we - * could be partitioned. */ + * could be partitioned. Also, never ask someone else for a status we + * generated! */ log_fn(LOG_INFO,"Received networkstatus objects (size %d) from server '%s:%d'",(int) body_len, conn->address, conn->port); if (status_code != 200) { log_fn(LOG_WARN,"Received http status code %d (\"%s\") from server '%s:%d'. Failing.", diff --git a/src/or/dirserv.c b/src/or/dirserv.c index 654cc19889..66204dbaf9 100644 --- a/src/or/dirserv.c +++ b/src/or/dirserv.c @@ -1183,15 +1183,13 @@ dirserv_get_networkstatus_v2(smartlist_t *result, smartlist_add(result, val); } } else if (!strcmpstart(key, "fp/")) { - char own_fp[HEX_DIGEST_LEN+1]; - crypto_pk_get_fingerprint(get_identity_key(), own_fp, 0); smartlist_t *hexdigests = smartlist_create(); smartlist_split_string(hexdigests, key+3, "+", 0, 0); SMARTLIST_FOREACH(hexdigests, char *, cp, { cached_dir_t *cached; tor_strupper(cp); - if (!strcmp(cp, own_fp) && + if (router_fingerprint_is_me(cp) && get_options()->AuthoritativeDir && the_v2_networkstatus_is_dirty && the_v2_networkstatus_is_dirty + DIR_REGEN_SLACK_TIME < time(NULL)) diff --git a/src/or/main.c b/src/or/main.c index 08f8d26a1d..8cbf2d7e60 100644 --- a/src/or/main.c +++ b/src/or/main.c @@ -732,7 +732,12 @@ run_scheduled_events(time_t now) !we_are_hibernating()) consider_testing_reachability(); - update_networkstatus_downloads(); + if (server_mode(options) && options->DirPort) + update_networkstatus_cache_downloads(now); + /* XXXX Disabled until 0.1.1.6 is out: only servers need networkstatus. + else + update_networkstatus_client_downloads(now); + */ } /** 3a. Every second, we examine pending circuits and prune the diff --git a/src/or/or.h b/src/or/or.h index 531e88993b..9bdca92bc0 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -673,7 +673,10 @@ struct connection_t { struct circuit_t *on_circuit; /**< The circuit (if any) that this edge * connection is using. */ - /* Used only by AP connections */ +/* Used only by Dir connections */ + char *requested_resource; /**< Which 'resource' did we ask the directory for?*/ + +/* Used only by AP connections */ socks_request_t *socks_request; /**< SOCKS structure describing request (AP * only.) */ @@ -1997,6 +2000,7 @@ routerinfo_t *router_get_my_routerinfo(void); const char *router_get_my_descriptor(void); int router_digest_is_me(const char *digest); int router_is_me(routerinfo_t *router); +int router_fingerprint_is_me(const char *fp); int router_rebuild_descriptor(int force); int router_dump_router_to_string(char *s, size_t maxlen, routerinfo_t *router, crypto_pk_env_t *ident_key); @@ -2088,7 +2092,8 @@ void add_trusted_dir_server(const char *addr, uint16_t port, const char *digest, int supports_v1); void clear_trusted_dir_servers(void); networkstatus_t *networkstatus_get_by_digest(const char *digest); -void update_networkstatus_downloads(void); +void update_networkstatus_cache_downloads(time_t now); +void update_networkstatus_client_downloads(time_t now); /********************************* routerparse.c ************************/ diff --git a/src/or/router.c b/src/or/router.c index 286b02f95d..d75b6bbcc4 100644 --- a/src/or/router.c +++ b/src/or/router.c @@ -676,6 +676,18 @@ router_is_me(routerinfo_t *router) return router_digest_is_me(router->identity_digest); } +/** Return true iff <b>fp</b> is a hex fingerprint of my identity digest. */ +int +router_fingerprint_is_me(const char *fp) +{ + char digest[DIGEST_LEN]; + if (strlen(fp) == HEX_DIGEST_LEN && + base16_decode(digest, sizeof(digest), fp, HEX_DIGEST_LEN) == 0) + return router_digest_is_me(digest); + + return 0; +} + /** Return a routerinfo for this OR, rebuilding a fresh one if * necessary. Return NULL on error, or if called on an OP. */ routerinfo_t * diff --git a/src/or/routerlist.c b/src/or/routerlist.c index 0b540fafdd..ccbb5b0b23 100644 --- a/src/or/routerlist.c +++ b/src/or/routerlist.c @@ -1208,8 +1208,6 @@ router_set_networkstatus(const char *s, time_t arrived_at, int is_cached) time_t now; char fp[HEX_DIGEST_LEN+1]; - log_fn(LOG_NOTICE, "setting status (%d)", is_cached); - ns = networkstatus_parse_from_string(s); if (!ns) { log_fn(LOG_WARN, "Couldn't parse network status."); @@ -1277,19 +1275,54 @@ router_set_networkstatus(const char *s, time_t arrived_at, int is_cached) return 0; } +/* These should be configurable, perhaps. */ +#define AUTHORITY_NS_CACHE_INTERVAL 10*60 +#define NONAUTHORITY_NS_CACHE_INTERVAL 15*60 +void +update_networkstatus_cache_downloads(time_t now) +{ + static time_t last_downloaded = 0; + int authority = authdir_mode(get_options()); + int interval = + authority ? AUTHORITY_NS_CACHE_INTERVAL : NONAUTHORITY_NS_CACHE_INTERVAL; + + if (last_downloaded + interval >= now) + return; + if (!trusted_dir_servers) + return; + + last_downloaded = now; + + if (authority) { + /* An authority launches a separate connection for everybody. */ + SMARTLIST_FOREACH(trusted_dir_servers, trusted_dir_server_t *, ds, + { + char resource[HEX_DIGEST_LEN+6]; + if (router_digest_is_me(ds->digest)) + continue; + strlcpy(resource, "fp/", sizeof(resource)); + base16_encode(resource+3, sizeof(resource)-3, ds->digest, DIGEST_LEN); + strlcat(resource, ".z", sizeof(resource)); + directory_get_from_dirserver(DIR_PURPOSE_FETCH_NETWORKSTATUS,resource,1); + }); + } else { + /* A non-authority cache launches one connection to a random authority. */ + directory_get_from_dirserver(DIR_PURPOSE_FETCH_NETWORKSTATUS,"all.z",1); + } +} + +#define ABOUT_TWO_DAYS (48*60*60) +#define ABOUT_HALF_AN_HOUR (30*60) /** DOCDOC */ void -update_networkstatus_downloads(void) +update_networkstatus_client_downloads(time_t now) { /* XXX Yes, these constants are supposed to be dumb, so we can choose better * values. */ -#define ABOUT_TWO_DAYS (48*60*60) -#define ABOUT_HALF_AN_HOUR (30*60) int n_live = 0, needed = 0, n_dirservers, i; int most_recent_idx = -1; trusted_dir_server_t *most_recent = NULL; time_t most_recent_received = 0; - time_t now = time(NULL); /* This is a little tricky. We want to download enough network-status * objects so that we have at least half of them under ABOUT_TWO_DAYS @@ -1332,13 +1365,14 @@ update_networkstatus_downloads(void) /* XXXX NM This could compress multiple downloads into a single request. * It could also be smarter on failures. */ for (i = most_recent_idx+1; needed; ++i) { - char resource[HEX_DIGEST_LEN+4]; + char resource[HEX_DIGEST_LEN+6]; trusted_dir_server_t *ds; if (i >= n_dirservers) i = 0; ds = smartlist_get(trusted_dir_servers, i); strlcpy(resource, "fp/", sizeof(resource)); base16_encode(resource+3, sizeof(resource)-3, ds->digest, DIGEST_LEN); + strlcat(resource, ".z", sizeof(resource)); directory_get_from_dirserver(DIR_PURPOSE_FETCH_NETWORKSTATUS, resource, 1); --needed; } |