summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2005-09-08 20:18:15 +0000
committerNick Mathewson <nickm@torproject.org>2005-09-08 20:18:15 +0000
commit059148f5880de62e29ec63f5ca17cecc5767dfa1 (patch)
tree9964583eafd2d621646971ed2823491e0f2ee3a6
parent6c4d43c724ff44bc68e52a7bfcd5b79cbbec42d7 (diff)
downloadtor-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.c1
-rw-r--r--src/or/directory.c10
-rw-r--r--src/or/dirserv.c4
-rw-r--r--src/or/main.c7
-rw-r--r--src/or/or.h9
-rw-r--r--src/or/router.c12
-rw-r--r--src/or/routerlist.c48
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;
}