Parcourir la source

r14020@Kushana: nickm | 2007-08-14 16:07:37 -0400
return 404 properly when somebody requests a bunch of nonexistent statuses/servers


svn:r11110

Nick Mathewson il y a 17 ans
Parent
commit
486166f9a8
4 fichiers modifiés avec 56 ajouts et 9 suppressions
  1. 5 1
      ChangeLog
  2. 15 3
      src/or/directory.c
  3. 35 5
      src/or/dirserv.c
  4. 1 0
      src/or/or.h

+ 5 - 1
ChangeLog

@@ -11,6 +11,10 @@ Changes in version 0.2.0.5-alpha - 2007-??-??
     - Fix compile on platforms without getaddrinfo: bug found by Li-Hui
       Zhou.
 
+  o Minor features (directory servers):
+    - When somebody requests a list of statuses or servers, and we have
+      none of those, return a 404 rather than an empty 200.
+
   o Minor features (directory voting):
     - Store v3 consensus status consensuses on disk, and reload them
       on startup.
@@ -20,7 +24,7 @@ Changes in version 0.2.0.5-alpha - 2007-??-??
 
   o Minor bugfixes (directory voting):
     - Read v3 keys from the right location.
-
+    - Numerous bugfixes to directory voting code.
 
 Changes in version 0.2.0.4-alpha - 2007-08-01
   o Major security fixes:

+ 15 - 3
src/or/directory.c

@@ -1893,10 +1893,15 @@ directory_handle_command_get(dir_connection_t *conn, const char *headers,
       smartlist_free(dir_fps);
       return 0;
     }
-    if (dirserv_remove_old_statuses(dir_fps, if_modified_since)) {
+
+    if (!dirserv_remove_old_statuses(dir_fps, if_modified_since)) {
+      write_http_status_line(conn, 404, "Not found");
+      SMARTLIST_FOREACH(dir_fps, char *, cp, tor_free(cp));
+      smartlist_free(dir_fps);
+      return 0;
+    } else if (!smartlist_len(dir_fps)) {
       write_http_status_line(conn, 304, "Not modified");
-      /* no need to free dir_fps's elements, since
-       * dirserv_statuses_are_old() already did. */
+      SMARTLIST_FOREACH(dir_fps, char *, cp, tor_free(cp));
       smartlist_free(dir_fps);
       return 0;
     }
@@ -1972,6 +1977,13 @@ directory_handle_command_get(dir_connection_t *conn, const char *headers,
       conn->dir_spool_src =
         is_extra ? DIR_SPOOL_EXTRA_BY_FP : DIR_SPOOL_SERVER_BY_FP;
     tor_free(url_mem);
+
+    if (!dirserv_have_any_serverdesc(conn->fingerprint_stack,
+                                     conn->dir_spool_src)) {
+      res = -1;
+      msg = "Not found";
+    }
+
     if (res < 0)
       write_http_status_line(conn, 404, msg);
     else {

+ 35 - 5
src/or/dirserv.c

@@ -2713,11 +2713,12 @@ dirserv_test_reachability(int try_all)
  * a) we have a networkstatus document and
  * b) it is not newer than <b>cutoff</b>.
  *
- * Return 1 if no keys remain, else return 0.
+ * Return 1 if any items were present at all; else return 0.
  */
 int
 dirserv_remove_old_statuses(smartlist_t *fps, time_t cutoff)
 {
+  int found_any = 0;
   SMARTLIST_FOREACH(fps, char *, digest,
   {
     cached_dir_t *d;
@@ -2727,15 +2728,44 @@ dirserv_remove_old_statuses(smartlist_t *fps, time_t cutoff)
       d = cached_v3_networkstatus;
     else
       d = digestmap_get(cached_v2_networkstatus, digest);
-    if (d && d->published <= cutoff) {
+    if (!d)
+      continue;
+    found_any = 1;
+    if (d->published <= cutoff) {
       tor_free(digest);
       SMARTLIST_DEL_CURRENT(fps, digest);
     }
   });
 
-  if (smartlist_len(fps))
-    return 0; /* some items were not here or were not old */
-  return 1; /* all items were here and old */
+  return found_any;
+}
+
+/** DOCDOC */
+int
+dirserv_have_any_serverdesc(smartlist_t *fps, int spool_src)
+{
+  SMARTLIST_FOREACH(fps, const char *, fp, {
+      switch (spool_src)
+      {
+        case DIR_SPOOL_EXTRA_BY_DIGEST:
+          if (extrainfo_get_by_descriptor_digest(fp)) return 1;
+          break;
+        case DIR_SPOOL_EXTRA_BY_FP: {
+          routerinfo_t *ri = router_get_by_digest(fp);
+          if (ri && extrainfo_get_by_descriptor_digest(
+                                      ri->cache_info.extra_info_digest))
+            return 1;
+          }
+          break;
+        case DIR_SPOOL_SERVER_BY_DIGEST:
+          if (router_get_by_descriptor_digest(fp)) return 1;
+          break;
+        case DIR_SPOOL_SERVER_BY_FP:
+          if (router_get_by_digest(fp)) return 1;
+          break;
+      }
+  });
+  return 0;
 }
 
 /** Return an approximate estimate of the number of bytes that will

+ 1 - 0
src/or/or.h

@@ -2804,6 +2804,7 @@ int authdir_wants_to_reject_router(routerinfo_t *ri, const char **msg,
                                    int complain);
 int dirserv_would_reject_router(routerstatus_t *rs);
 int dirserv_remove_old_statuses(smartlist_t *fps, time_t cutoff);
+int dirserv_have_any_serverdesc(smartlist_t *fps, int spool_src);
 size_t dirserv_estimate_data_size(smartlist_t *fps, int is_serverdescs,
                                   int compressed);
 int routerstatus_format_entry(char *buf, size_t buf_len,