[or-cvs] When requesting or serving resources via fingerprint/digest...

Nick Mathewson nickm at seul.org
Wed Jun 21 04:57:14 UTC 2006


Update of /home/or/cvsroot/tor/src/or
In directory moria:/home/nickm/src/tor/src/or

Modified Files:
	directory.c dirserv.c or.h routerlist.c 
Log Message:
When requesting or serving resources via fingerprint/digest, request and respond in-order, removing duplicates.

Index: directory.c
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/directory.c,v
retrieving revision 1.381
retrieving revision 1.382
diff -u -p -d -r1.381 -r1.382
--- directory.c	20 Jun 2006 00:48:23 -0000	1.381
+++ directory.c	21 Jun 2006 04:57:12 -0000	1.382
@@ -306,7 +306,7 @@ connection_dir_download_networkstatus_fa
      * failed, and possibly retry them later.*/
     smartlist_t *failed = smartlist_create();
     dir_split_resource_into_fingerprints(conn->requested_resource+3,
-                                         failed, NULL, 0);
+                                         failed, NULL, 0, 0);
     if (smartlist_len(failed)) {
       dir_networkstatus_download_failed(failed);
       SMARTLIST_FOREACH(failed, char *, cp, tor_free(cp));
@@ -997,7 +997,7 @@ connection_dir_client_reached_eof(connec
         !strcmpstart(conn->requested_resource,"fp/")) {
       which = smartlist_create();
       dir_split_resource_into_fingerprints(conn->requested_resource+3,
-                                           which, NULL, 0);
+                                           which, NULL, 0, 0);
     } else if (conn->requested_resource &&
                !strcmpstart(conn->requested_resource, "all")) {
       which = smartlist_create();
@@ -1045,7 +1045,7 @@ connection_dir_client_reached_eof(connec
         !strcmpstart(conn->requested_resource,"d/")) {
       which = smartlist_create();
       dir_split_resource_into_fingerprints(conn->requested_resource+2,
-                                           which, NULL, 0);
+                                           which, NULL, 0, 0);
       n_asked_for = smartlist_len(which);
     }
     if (status_code != 200) {
@@ -1906,21 +1906,21 @@ dir_routerdesc_download_failed(smartlist
  * the strings, in order, into <b>fp_out</b>.  If <b>compressed_out</b> is
  * non-NULL, set it to 1 if the resource ends in ".z", else set it to 0.  If
  * decode_hex is true, then delete all elements that aren't hex digests, and
- * decode the rest.
+ * decode the rest.  If sort_uniq is true, then sort the list and remove
+ * all duplicates.
  */
 int
 dir_split_resource_into_fingerprints(const char *resource,
                                      smartlist_t *fp_out, int *compressed_out,
-                                     int decode_hex)
+                                     int decode_hex, int sort_uniq)
 {
-  int old_len;
+  smartlist_t *fp_tmp = smartlist_create();
   tor_assert(fp_out);
-  old_len = smartlist_len(fp_out);
-  smartlist_split_string(fp_out, resource, "+", 0, 0);
+  smartlist_split_string(fp_tmp, resource, "+", 0, 0);
   if (compressed_out)
     *compressed_out = 0;
-  if (smartlist_len(fp_out) > old_len) {
-    char *last = smartlist_get(fp_out,smartlist_len(fp_out)-1);
+  if (smartlist_len(fp_tmp)) {
+    char *last = smartlist_get(fp_tmp,smartlist_len(fp_tmp)-1);
     size_t last_len = strlen(last);
     if (last_len > 2 && !strcmp(last+last_len-2, ".z")) {
       last[last_len-2] = '\0';
@@ -1931,27 +1931,51 @@ dir_split_resource_into_fingerprints(con
   if (decode_hex) {
     int i;
     char *cp, *d = NULL;
-    for (i = old_len; i < smartlist_len(fp_out); ++i) {
-      cp = smartlist_get(fp_out, i);
+    for (i = 0; i < smartlist_len(fp_tmp); ++i) {
+      cp = smartlist_get(fp_tmp, i);
       if (strlen(cp) != HEX_DIGEST_LEN) {
         log_info(LD_DIR,
                  "Skipping digest %s with non-standard length.", escaped(cp));
-        smartlist_del(fp_out, i--);
+        smartlist_del_keeporder(fp_tmp, i--);
         goto again;
       }
       d = tor_malloc_zero(DIGEST_LEN);
       if (base16_decode(d, DIGEST_LEN, cp, HEX_DIGEST_LEN)<0) {
         log_info(LD_DIR, "Skipping non-decodable digest %s", escaped(cp));
-        smartlist_del(fp_out, i--);
+        smartlist_del_keeporder(fp_tmp, i--);
         goto again;
       }
-      smartlist_set(fp_out, i, d);
+      smartlist_set(fp_tmp, i, d);
       d = NULL;
     again:
       tor_free(cp);
       tor_free(d);
     }
   }
+  if (sort_uniq) {
+    smartlist_t *fp_tmp2 = smartlist_create();
+    int i;
+    if (decode_hex)
+      smartlist_sort_digests(fp_tmp);
+    else
+      smartlist_sort_strings(fp_tmp);
+    if (smartlist_len(fp_tmp))
+      smartlist_add(fp_tmp2, smartlist_get(fp_tmp, 0));
+    for (i = 1; i < smartlist_len(fp_tmp); ++i) {
+      char *cp = smartlist_get(fp_tmp, i);
+      char *last = smartlist_get(fp_tmp2, smartlist_len(fp_tmp2)-1);
+      
+      if ((decode_hex && memcmp(cp, last, DIGEST_LEN))
+	  || (!decode_hex && strcasecmp(cp, last)))
+	smartlist_add(fp_tmp2, cp);
+      else
+	tor_free(cp);
+    }
+    smartlist_free(fp_tmp);
+    fp_tmp = fp_tmp2;
+  }
+  smartlist_add_all(fp_out, fp_tmp);
+  smartlist_free(fp_tmp);
   return 0;
 }
 

Index: dirserv.c
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/dirserv.c,v
retrieving revision 1.347
retrieving revision 1.348
diff -u -p -d -r1.347 -r1.348
--- dirserv.c	20 Jun 2006 23:11:15 -0000	1.347
+++ dirserv.c	21 Jun 2006 04:57:12 -0000	1.348
@@ -1533,11 +1533,12 @@ dirserv_get_networkstatus_v2_fingerprint
       smartlist_add(result, tor_memdup(ident, DIGEST_LEN));
       iter = digestmap_iter_next(cached_v2_networkstatus, iter);
     }
+    smartlist_sort_digests(result);
     if (smartlist_len(result) == 0)
       log_warn(LD_DIRSERV,
                "Client requested 'all' network status objects; we have none.");
   } else if (!strcmpstart(key, "fp/")) {
-    dir_split_resource_into_fingerprints(key+3, result, NULL, 1);
+    dir_split_resource_into_fingerprints(key+3, result, NULL, 1, 1);
   }
 }
 
@@ -1586,7 +1587,7 @@ dirserv_get_networkstatus_v2(smartlist_t
                "Client requested 'all' network status objects; we have none.");
   } else if (!strcmpstart(key, "fp/")) {
     smartlist_t *digests = smartlist_create();
-    dir_split_resource_into_fingerprints(key+3, digests, NULL, 1);
+    dir_split_resource_into_fingerprints(key+3, digests, NULL, 1, 1);
     SMARTLIST_FOREACH(digests, char *, cp,
         {
           cached_dir_t *cached;
@@ -1629,10 +1630,10 @@ dirserv_get_routerdesc_fingerprints(smar
                     tor_memdup(ri->cache_info.identity_digest, DIGEST_LEN));
   } else if (!strcmpstart(key, "/tor/server/d/")) {
     key += strlen("/tor/server/d/");
-    dir_split_resource_into_fingerprints(key, fps_out, NULL, 1);
+    dir_split_resource_into_fingerprints(key, fps_out, NULL, 1, 1);
   } else if (!strcmpstart(key, "/tor/server/fp/")) {
     key += strlen("/tor/server/fp/");
-    dir_split_resource_into_fingerprints(key, fps_out, NULL, 1);
+    dir_split_resource_into_fingerprints(key, fps_out, NULL, 1, 1);
   } else {
     *msg = "Key not recognized";
     return -1;
@@ -1680,7 +1681,7 @@ dirserv_get_routerdescs(smartlist_t *des
   } else if (!strcmpstart(key, "/tor/server/d/")) {
     smartlist_t *digests = smartlist_create();
     key += strlen("/tor/server/d/");
-    dir_split_resource_into_fingerprints(key, digests, NULL, 1);
+    dir_split_resource_into_fingerprints(key, digests, NULL, 1, 1);
     SMARTLIST_FOREACH(digests, const char *, d,
        {
          signed_descriptor_t *sd = router_get_by_descriptor_digest(d);
@@ -1693,7 +1694,7 @@ dirserv_get_routerdescs(smartlist_t *des
     smartlist_t *digests = smartlist_create();
     time_t cutoff = time(NULL) - ROUTER_MAX_AGE_TO_PUBLISH;
     key += strlen("/tor/server/fp/");
-    dir_split_resource_into_fingerprints(key, digests, NULL, 1);
+    dir_split_resource_into_fingerprints(key, digests, NULL, 1, 1);
     SMARTLIST_FOREACH(digests, const char *, d,
        {
          if (router_digest_is_me(d)) {

Index: or.h
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/or.h,v
retrieving revision 1.844
retrieving revision 1.845
diff -u -p -d -r1.844 -r1.845
--- or.h	20 Jun 2006 00:48:23 -0000	1.844
+++ or.h	21 Jun 2006 04:57:12 -0000	1.845
@@ -1910,7 +1910,7 @@ int connection_dir_finished_connecting(c
 void connection_dir_request_failed(connection_t *conn);
 int dir_split_resource_into_fingerprints(const char *resource,
                                     smartlist_t *fp_out, int *compresseed_out,
-                                    int decode_hex);
+                                    int decode_hex, int sort_uniq);
 char *directory_dump_request_log(void);
 
 /********************************* dirserv.c ***************************/

Index: routerlist.c
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/routerlist.c,v
retrieving revision 1.520
retrieving revision 1.521
diff -u -p -d -r1.520 -r1.521
--- routerlist.c	18 Jun 2006 16:05:54 -0000	1.520
+++ routerlist.c	21 Jun 2006 04:57:12 -0000	1.521
@@ -2507,6 +2507,7 @@ update_networkstatus_client_downloads(ti
   resource = tor_malloc(resource_len);
   memcpy(resource, "fp/", 3);
   cp = resource+3;
+  smartlist_sort_digests(missing);
   needed = smartlist_len(missing);
   SMARTLIST_FOREACH(missing, const char *, d,
     {
@@ -3252,7 +3253,7 @@ list_pending_descriptor_downloads(digest
         !conn->marked_for_close) {
       if (!strcmpstart(conn->requested_resource, prefix))
         dir_split_resource_into_fingerprints(conn->requested_resource+p_len,
-                                             tmp, NULL, 1);
+                                             tmp, NULL, 1, 0);
     }
   }
   SMARTLIST_FOREACH(tmp, char *, d,
@@ -3487,6 +3488,7 @@ update_router_descriptor_client_download
              (n_downloadable+n_per_request-1)/n_per_request,
              n_downloadable>n_per_request?"s":"",
              n_downloadable, n_downloadable>1?"s":"", n_per_request);
+    smartlist_sort_digests(downloadable);
     for (i=0; i < n_downloadable; i += n_per_request) {
       initiate_descriptor_downloads(NULL, downloadable, i, i+n_per_request);
     }



More information about the tor-commits mailing list