Преглед на файлове

r12850@catbus: nickm | 2007-05-21 22:20:42 -0400
Partial backport candidate: do not rely on finding a \0 after an mmaped() router/extrainfo file. Also, set journal length correctly when starting up.


svn:r10248

Nick Mathewson преди 17 години
родител
ревизия
4ec5e139c8
променени са 8 файла, в които са добавени 71 реда и са изтрити 22 реда
  1. 7 0
      src/common/compat.h
  2. 29 0
      src/common/util.c
  3. 1 0
      src/common/util.h
  4. 2 2
      src/or/directory.c
  5. 2 2
      src/or/dirserv.c
  6. 3 3
      src/or/or.h
  7. 12 9
      src/or/routerlist.c
  8. 15 6
      src/or/routerparse.c

+ 7 - 0
src/common/compat.h

@@ -161,6 +161,13 @@ int tor_vsnprintf(char *str, size_t size, const char *format, va_list args)
 
 const void *tor_memmem(const void *haystack, size_t hlen, const void *needle,
                        size_t nlen)  ATTR_PURE ATTR_NONNULL((1,3));
+static const void *tor_memstr(const void *haystack, size_t hlen,
+                           const char *needle) ATTR_PURE ATTR_NONNULL((1,3));
+static INLINE const void *
+tor_memstr(const void *haystack, size_t hlen, const char *needle)
+{
+  return tor_memmem(haystack, hlen, needle, strlen(needle));
+}
 
 #define TOR_ISALPHA(c)   isalpha((int)(unsigned char)(c))
 #define TOR_ISALNUM(c)   isalnum((int)(unsigned char)(c))

+ 29 - 0
src/common/util.c

@@ -418,6 +418,35 @@ eat_whitespace(const char *s)
   }
 }
 
+/** Return a pointer to the first char of s that is not whitespace and
+ * not a comment, or to the terminating NUL if no such character exists.
+ */
+const char *
+eat_whitespace_eos(const char *s, const char *eos)
+{
+  tor_assert(s);
+  tor_assert(eos && s <= eos);
+
+  while (s < eos) {
+    switch (*s) {
+    case '\0':
+    default:
+      return s;
+    case ' ':
+    case '\t':
+    case '\n':
+    case '\r':
+      ++s;
+      break;
+    case '#':
+      ++s;
+      while (s < eos && *s && *s != '\n')
+        ++s;
+    }
+  }
+  return s;
+}
+
 /** Return a pointer to the first char of s that is not a space or a tab,
  * or to the terminating NUL if no such character exists. */
 const char *

+ 1 - 0
src/common/util.h

@@ -167,6 +167,7 @@ uint64_t tor_parse_uint64(const char *s, int base, uint64_t min,
                          uint64_t max, int *ok, char **next);
 const char *hex_str(const char *from, size_t fromlen) ATTR_NONNULL((1));
 const char *eat_whitespace(const char *s) ATTR_PURE;
+const char *eat_whitespace_eos(const char *s, const char *eos) ATTR_PURE;
 const char *eat_whitespace_no_nl(const char *s) ATTR_PURE;
 const char *find_whitespace(const char *s) ATTR_PURE;
 int tor_mem_is_zero(const char *mem, size_t len) ATTR_PURE;

+ 2 - 2
src/or/directory.c

@@ -1248,9 +1248,9 @@ connection_dir_client_reached_eof(dir_connection_t *conn)
                   !strcmpstart(conn->requested_resource, "all"))) {
       /* as we learn from them, we remove them from 'which' */
       if (was_ei) {
-        router_load_extrainfo_from_string(body, SAVED_NOWHERE, which);
+        router_load_extrainfo_from_string(body, NULL, SAVED_NOWHERE, which);
       } else {
-        router_load_routers_from_string(body, SAVED_NOWHERE, which);
+        router_load_routers_from_string(body, NULL, SAVED_NOWHERE, which);
         directory_info_has_arrived(now, 0);
       }
     }

+ 2 - 2
src/or/dirserv.c

@@ -529,7 +529,7 @@ dirserv_add_multiple_descriptors(const char *desc, const char **msg)
 
   s = desc;
   list = smartlist_create();
-  if (!router_parse_list_from_string(&s, list, SAVED_NOWHERE, 0)) {
+  if (!router_parse_list_from_string(&s, NULL, list, SAVED_NOWHERE, 0)) {
     SMARTLIST_FOREACH(list, routerinfo_t *, ri, {
         r_tmp = dirserv_add_descriptor(ri, &msg_out);
         if (r_tmp < r) {
@@ -542,7 +542,7 @@ dirserv_add_multiple_descriptors(const char *desc, const char **msg)
   smartlist_clear(list);
 
   s = desc;
-  if (!router_parse_list_from_string(&s, list, SAVED_NOWHERE, 1)) {
+  if (!router_parse_list_from_string(&s, NULL, list, SAVED_NOWHERE, 1)) {
     SMARTLIST_FOREACH(list, extrainfo_t *, ei, {
         r_tmp = dirserv_add_extrainfo(ei, &msg_out);
         if (r_tmp < r) {

+ 3 - 3
src/or/or.h

@@ -3143,10 +3143,10 @@ void router_add_extrainfo_to_routerlist(extrainfo_t *ei, const char **msg,
                                         int from_cache, int from_fetch);
 int router_load_single_router(const char *s, uint8_t purpose,
                               const char **msg);
-void router_load_routers_from_string(const char *s,
+void router_load_routers_from_string(const char *s, const char *eos,
                                      saved_location_t saved_location,
                                      smartlist_t *requested_fingerprints);
-void router_load_extrainfo_from_string(const char *s,
+void router_load_extrainfo_from_string(const char *s, const char *eos,
                                        saved_location_t saved_location,
                                        smartlist_t *requested_fps);
 
@@ -3246,7 +3246,7 @@ int router_get_extrainfo_hash(const char *s, char *digest);
 int router_append_dirobj_signature(char *buf, size_t buf_len,
                                    const char *digest,
                                    crypto_pk_env_t *private_key);
-int router_parse_list_from_string(const char **s,
+int router_parse_list_from_string(const char **s, const char *eos,
                                   smartlist_t *dest,
                                   saved_location_t saved_location,
                                   int is_extrainfo);

+ 12 - 9
src/or/routerlist.c

@@ -393,7 +393,6 @@ router_rebuild_store(int force, int extrainfo)
   write_str_to_file(fname, "", 1);
 
   r = 0;
-  tor_assert(offset >= 0);
   stats->store_len = (size_t) offset;
   stats->journal_len = 0;
   stats->bytes_dropped = 0;
@@ -420,6 +419,7 @@ router_reload_router_list_impl(int extrainfo)
   const char *fname_base =
     extrainfo ? "cached-extrainfo" : "cached-routers";
   tor_mmap_t **mmap_ptr;
+  struct stat st;
 
   routerlist_check_bug_417();
 
@@ -443,21 +443,24 @@ router_reload_router_list_impl(int extrainfo)
     stats->store_len = (*mmap_ptr)->size;
     if (extrainfo)
       router_load_extrainfo_from_string((*mmap_ptr)->data,
+                                        (*mmap_ptr)->data+(*mmap_ptr)->size,
                                         SAVED_IN_CACHE, NULL);
     else
       router_load_routers_from_string((*mmap_ptr)->data,
+                                      (*mmap_ptr)->data+(*mmap_ptr)->size,
                                       SAVED_IN_CACHE, NULL);
   }
 
   tor_snprintf(fname, fname_len, "%s"PATH_SEPARATOR"%s.new",
                options->DataDirectory, fname_base);
   if (file_status(fname) == FN_FILE)
-    contents = read_file_to_str(fname, RFTS_BIN|RFTS_IGNORE_MISSING, NULL);
+    contents = read_file_to_str(fname, RFTS_BIN|RFTS_IGNORE_MISSING, &st);
   if (contents) {
     if (extrainfo)
-      router_load_extrainfo_from_string(contents, SAVED_IN_JOURNAL, NULL);
+      router_load_extrainfo_from_string(contents, NULL,SAVED_IN_JOURNAL, NULL);
     else
-      router_load_routers_from_string(contents, SAVED_IN_JOURNAL, NULL);
+      router_load_routers_from_string(contents, NULL, SAVED_IN_JOURNAL, NULL);
+    stats->journal_len = st.st_size;
     tor_free(contents);
   }
 
@@ -823,7 +826,6 @@ routerlist_add_family(smartlist_t *sl, routerinfo_t *router)
   if (options->EnforceDistinctSubnets)
     routerlist_add_network_family(sl, router);
 
-
   if (router->declared_family) {
     /* Add every r such that router declares familyness with r, and r
      * declares familyhood with router. */
@@ -2655,7 +2657,8 @@ router_load_single_router(const char *s, uint8_t purpose, const char **msg)
  * fingerprint from the list.
  */
 void
-router_load_routers_from_string(const char *s, saved_location_t saved_location,
+router_load_routers_from_string(const char *s, const char *eos,
+                                saved_location_t saved_location,
                                 smartlist_t *requested_fingerprints)
 {
   smartlist_t *routers = smartlist_create(), *changed = smartlist_create();
@@ -2663,7 +2666,7 @@ router_load_routers_from_string(const char *s, saved_location_t saved_location,
   const char *msg;
   int from_cache = (saved_location != SAVED_NOWHERE);
 
-  router_parse_list_from_string(&s, routers, saved_location, 0);
+  router_parse_list_from_string(&s, eos, routers, saved_location, 0);
 
   routers_update_status_from_networkstatus(routers, !from_cache);
 
@@ -2705,7 +2708,7 @@ router_load_routers_from_string(const char *s, saved_location_t saved_location,
 
 /** DOCDOC */
 void
-router_load_extrainfo_from_string(const char *s,
+router_load_extrainfo_from_string(const char *s, const char *eos,
                                   saved_location_t saved_location,
                                   smartlist_t *requested_fingerprints)
 {
@@ -2713,7 +2716,7 @@ router_load_extrainfo_from_string(const char *s,
   const char *msg;
   int from_cache = (saved_location != SAVED_NOWHERE);
 
-  router_parse_list_from_string(&s, extrainfo_list, saved_location, 1);
+  router_parse_list_from_string(&s, eos, extrainfo_list, saved_location, 1);
 
   log_info(LD_DIR, "%d elements to add", smartlist_len(extrainfo_list));
 

+ 15 - 6
src/or/routerparse.c

@@ -831,7 +831,8 @@ check_signature_token(const char *digest,
  * Returns 0 on success and -1 on failure.
  */
 int
-router_parse_list_from_string(const char **s, smartlist_t *dest,
+router_parse_list_from_string(const char **s, const char *eos,
+                              smartlist_t *dest,
                               saved_location_t saved_location,
                               int want_extrainfo)
 {
@@ -847,8 +848,16 @@ router_parse_list_from_string(const char **s, smartlist_t *dest,
   tor_assert(dest);
 
   start = *s;
+  if (!eos)
+    eos = *s + strlen(*s);
+
+  tor_assert(eos >= *s);
+
   while (1) {
-    *s = eat_whitespace(*s);
+    *s = eat_whitespace_eos(*s, eos);
+    if ((eos - *s) < 32) /* make sure it's long enough. */
+      break;
+
     /* Don't start parsing the rest of *s unless it contains a router. */
     if (strcmpstart(*s, "extra-info ")==0) {
       have_extrainfo = 1;
@@ -856,8 +865,8 @@ router_parse_list_from_string(const char **s, smartlist_t *dest,
       have_extrainfo = 0;
     } else {
       /* skip junk. */
-      const char *ei = strstr(*s, "\nextra-info ");
-      const char *ri = strstr(*s, "\nrouter ");
+      const char *ei = tor_memstr(*s, eos-*s, "\nextra-info ");
+      const char *ri = tor_memstr(*s, eos-*s, "\nrouter ");
       if (ri && (!ei || ri < ei)) {
         have_extrainfo = 0;
         *s = ri + 1;
@@ -868,9 +877,9 @@ router_parse_list_from_string(const char **s, smartlist_t *dest,
         break;
       }
     }
-    end = strstr(*s, "\nrouter-signature");
+    end = tor_memstr(*s, eos-*s, "\nrouter-signature");
     if (end)
-      end = strstr(end, "\n-----END SIGNATURE-----\n");
+      end = tor_memstr(end, eos-*s, "\n-----END SIGNATURE-----\n");
     if (end)
       end += strlen("\n-----END SIGNATURE-----\n");