[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[or-cvs] Fix an assert in directory.c. Check received network-statu...



Update of /home/or/cvsroot/tor/src/or
In directory moria:/tmp/cvs-serv17620/src/or

Modified Files:
	directory.c dirserv.c or.h routerlist.c 
Log Message:
Fix an assert in directory.c.  Check received network-status objects against the list we expected to get.  Do not let anyone else update our network-status object.

Index: directory.c
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/directory.c,v
retrieving revision 1.262
retrieving revision 1.263
diff -u -d -r1.262 -r1.263
--- directory.c	8 Sep 2005 20:18:14 -0000	1.262
+++ directory.c	8 Sep 2005 20:36:40 -0000	1.263
@@ -401,7 +401,8 @@
   tor_assert(conn->type == CONN_TYPE_DIR);
 
   tor_free(conn->requested_resource);
-  conn->requested_resource = tor_strdup(resource);
+  if (resource)
+    conn->requested_resource = tor_strdup(resource);
 
   /* come up with a string for which Host: we want */
   if (conn->port == 80) {
@@ -450,13 +451,13 @@
       url = tor_strdup("/tor/running-routers");
       break;
     case DIR_PURPOSE_FETCH_NETWORKSTATUS:
-      httpcommand = "GET";//XXXX
+      httpcommand = "GET";
       len = strlen(resource)+32;
       url = tor_malloc(len);
       tor_snprintf(url, len, "/tor/status/%s", resource);
       break;
     case DIR_PURPOSE_FETCH_SERVERDESC:
-      httpcommand = "GET";//XXXX
+      httpcommand = "GET";
       len = strlen(resource)+32;
       url = tor_malloc(len);
       tor_snprintf(url, len, "/tor/server/%s", resource);
@@ -887,9 +888,7 @@
   }
 
   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. Also, never ask someone else for a status we
-     * generated! */
+    smartlist_t *which = NULL;
     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.",
@@ -897,17 +896,26 @@
       tor_free(body); tor_free(headers); tor_free(reason);
       return -1;
     }
+    if (conn->requested_resource &&
+        !strcmpstart(conn->requested_resource,"fp/")) {
+      which = smartlist_create();
+      smartlist_split_string(which, conn->requested_resource+3, "+", 0, -1);
+    }
     while (*body) {
       char *next = strstr(body, "\nnetwork-status-version");
       if (next)
         *next = '\0';
-      if (router_set_networkstatus(body, time(NULL), 0)<0)
+      if (router_set_networkstatus(body, time(NULL), NS_FROM_DIR, which)<0)
         break;
       if (next)
         body = next+1;
       else
         break;
     }
+    if (which) {
+      SMARTLIST_FOREACH(which, char *, cp, tor_free(cp));
+      smartlist_free(which);
+    }
   }
 
   if (conn->purpose == DIR_PURPOSE_FETCH_SERVERDESC) {

Index: dirserv.c
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/dirserv.c,v
retrieving revision 1.214
retrieving revision 1.215
diff -u -d -r1.214 -r1.215
--- dirserv.c	8 Sep 2005 20:18:14 -0000	1.214
+++ dirserv.c	8 Sep 2005 20:36:40 -0000	1.215
@@ -1134,7 +1134,8 @@
   set_cached_dir(&the_v2_networkstatus, status, time(NULL));
   status = NULL; /* So it doesn't get double-freed. */
   the_v2_networkstatus_is_dirty = 0;
-  router_set_networkstatus(the_v2_networkstatus.dir, time(NULL), 0);
+  router_set_networkstatus(the_v2_networkstatus.dir, time(NULL), NS_GENERATED,
+                           NULL);
 
   r = 0;
  done:

Index: or.h
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/or.h,v
retrieving revision 1.673
retrieving revision 1.674
diff -u -d -r1.673 -r1.674
--- or.h	8 Sep 2005 20:18:14 -0000	1.673
+++ or.h	8 Sep 2005 20:36:40 -0000	1.674
@@ -2072,7 +2072,10 @@
 int router_load_single_router(const char *s, const char **msg);
 int router_load_routerlist_from_directory(const char *s,crypto_pk_env_t *pkey,
                                         int dir_is_recent, int dir_is_cached);
-int router_set_networkstatus(const char *s, time_t arrived_at, int is_cached);
+typedef enum { NS_FROM_CACHE, NS_FROM_DIR, NS_GENERATED} networkstatus_source_t;
+int router_set_networkstatus(const char *s, time_t arrived_at,
+                             networkstatus_source_t source,
+                             smartlist_t *requested_fingerprints);
 addr_policy_result_t router_compare_addr_to_addr_policy(uint32_t addr,
                               uint16_t port, addr_policy_t *policy);
 

Index: routerlist.c
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/routerlist.c,v
retrieving revision 1.276
retrieving revision 1.277
diff -u -d -r1.276 -r1.277
--- routerlist.c	8 Sep 2005 20:18:15 -0000	1.276
+++ routerlist.c	8 Sep 2005 20:36:40 -0000	1.277
@@ -108,7 +108,7 @@
       s = read_file_to_str(filename, 0);
       if (s) {
         stat(filename, &st);
-        if (router_set_networkstatus(s, st.st_mtime, 1)<0) {
+        if (router_set_networkstatus(s, st.st_mtime, NS_FROM_CACHE, NULL)<0) {
           log_fn(LOG_WARN, "Couldn't load networkstatus from \"%s\"",filename);
         }
         tor_free(s);
@@ -1199,9 +1199,11 @@
 }
 
 /** DOCDOC returns 0 on no problems, -1 on problems.
+ * requested fingerprints must be upcased.
  */
 int
-router_set_networkstatus(const char *s, time_t arrived_at, int is_cached)
+router_set_networkstatus(const char *s, time_t arrived_at,
+            networkstatus_source_t source, smartlist_t *requested_fingerprints)
 {
   networkstatus_t *ns;
   int i, found;
@@ -1215,6 +1217,7 @@
   }
   if (!router_digest_is_trusted_dir(ns->identity_digest)) {
     log_fn(LOG_INFO, "Network status was signed, but not by an authoritative directory we recognize.");
+    networkstatus_free(ns);
     return -1;
   }
   now = time(NULL);
@@ -1228,6 +1231,20 @@
   if (!networkstatus_list)
     networkstatus_list = smartlist_create();
 
+  if (source == NS_FROM_DIR && router_digest_is_me(ns->identity_digest)) {
+    /* Drop our own networkstatus when we get it from somebody else. */
+    networkstatus_free(ns);
+    return 0;
+  }
+
+  base16_encode(fp, HEX_DIGEST_LEN+1, ns->identity_digest, DIGEST_LEN);
+
+  if (requested_fingerprints &&
+      !smartlist_string_isin(requested_fingerprints, fp)) {
+    log_fn(LOG_WARN, "We received a network status with a fingerprint (%s) that we never requested. Dropping.", fp);
+    return 0;
+  }
+
   found = 0;
   for (i=0; i < smartlist_len(networkstatus_list); ++i) {
     networkstatus_t *old_ns = smartlist_get(networkstatus_list, i);
@@ -1256,9 +1273,7 @@
   if (!found)
     smartlist_add(networkstatus_list, ns);
 
-  base16_encode(fp, HEX_DIGEST_LEN+1, ns->identity_digest, DIGEST_LEN);
-
-  if (!is_cached) {
+  if (source != NS_FROM_CACHE) {
     const char *datadir = get_options()->DataDirectory;
     size_t len = strlen(datadir)+64;
     char *fn = tor_malloc(len+1);