Forráskód Böngészése

Merge remote-tracking branch 'sebastian/bug14784'

Nick Mathewson 9 éve
szülő
commit
b98cc79477
4 módosított fájl, 92 hozzáadás és 15 törlés
  1. 4 0
      changes/bug14784
  2. 43 0
      src/or/control.c
  3. 44 15
      src/or/router.c
  4. 1 0
      src/or/router.h

+ 4 - 0
changes/bug14784

@@ -0,0 +1,4 @@
+  o Minor features:
+    - Implement a new controller command "status/fresh-relay-descs" to
+      fetch a descriptor/extrainfo pair that was generated on demand
+      just for the controller's use. Implements ticket 14784.

+ 43 - 0
src/or/control.c

@@ -2100,6 +2100,47 @@ getinfo_helper_events(control_connection_t *control_conn,
         return -1;
       }
       *answer = bridge_stats;
+    } else if (!strcmp(question, "status/fresh-relay-descs")) {
+        if (!server_mode(get_options())) {
+          *errmsg = "Only relays have descriptors";
+          return -1;
+        }
+        routerinfo_t *r;
+        extrainfo_t *e;
+        if (router_build_fresh_descriptor(&r, &e) < 0) {
+          *errmsg = "Error generating descriptor";
+          return -1;
+        }
+        size_t size = r->cache_info.signed_descriptor_len + 1;
+        if (e) {
+          size += e->cache_info.signed_descriptor_len + 1;
+        }
+        tor_assert(r->cache_info.signed_descriptor_len);
+        char *descs = tor_malloc(size);
+        char *cp = descs;
+        memcpy(cp, signed_descriptor_get_body(&r->cache_info),
+               r->cache_info.signed_descriptor_len);
+        cp += r->cache_info.signed_descriptor_len - 1;
+        if (e) {
+          if (cp[0] == '\0') {
+            cp[0] = '\n';
+          } else if (cp[0] != '\n') {
+            cp[1] = '\n';
+            cp++;
+          }
+          memcpy(cp, signed_descriptor_get_body(&e->cache_info),
+                 e->cache_info.signed_descriptor_len);
+          cp += e->cache_info.signed_descriptor_len - 1;
+        }
+        if (cp[0] == '\n') {
+          cp[0] = '\0';
+        } else if (cp[0] != '\0') {
+          cp[1] = '\0';
+        }
+        log_warn(LD_CONFIG, "%s", descs);
+        *answer = descs;
+        routerinfo_free(r);
+        extrainfo_free(e);
     } else {
       return 0;
     }
@@ -2210,6 +2251,8 @@ static const getinfo_item_t getinfo_items[] = {
       "The last bootstrap phase status event that Tor sent."),
   DOC("status/clients-seen",
       "Breakdown of client countries seen by a bridge."),
+  DOC("status/fresh-relay-descs",
+      "A fresh relay/ei descriptor pair for Tor's current state. Not stored."),
   DOC("status/version/recommended", "List of currently recommended versions."),
   DOC("status/version/current", "Status of the current version."),
   DOC("status/version/num-versioning", "Number of versioning authorities."),

+ 44 - 15
src/or/router.c

@@ -1802,12 +1802,15 @@ router_pick_published_address(const or_options_t *options, uint32_t *addr)
   return 0;
 }
 
-/** If <b>force</b> is true, or our descriptor is out-of-date, rebuild a fresh
- * routerinfo, signed server descriptor, and extra-info document for this OR.
- * Return 0 on success, -1 on temporary error.
+/** Build a fresh routerinfo, signed server descriptor, and extra-info document
+ * for this OR. Set r to the generated routerinfo, e to the generated
+ * extra-info document. Return 0 on success, -1 on temporary error. Failure to
+ * generate an extra-info document is not an error and is indicated by setting
+ * e to NULL. Caller is responsible for freeing generated documents if 0 is
+ * returned.
  */
 int
-router_rebuild_descriptor(int force)
+router_build_fresh_descriptor(routerinfo_t **r, extrainfo_t **e)
 {
   routerinfo_t *ri;
   extrainfo_t *ei;
@@ -1816,20 +1819,11 @@ router_rebuild_descriptor(int force)
   int hibernating = we_are_hibernating();
   const or_options_t *options = get_options();
 
-  if (desc_clean_since && !force)
-    return 0;
-
-  if (router_pick_published_address(options, &addr) < 0 ||
-      router_get_advertised_or_port(options) == 0) {
-    /* Stop trying to rebuild our descriptor every second. We'll
-     * learn that it's time to try again when ip_address_changed()
-     * marks it dirty. */
-    desc_clean_since = time(NULL);
+  if (router_pick_published_address(options, &addr) < 0) {
+    log_warn(LD_CONFIG, "Don't know my address while generating descriptor");
     return -1;
   }
 
-  log_info(LD_OR, "Rebuilding relay descriptor%s", force ? " (forced)" : "");
-
   ri = tor_malloc_zero(sizeof(routerinfo_t));
   ri->cache_info.routerlist_index = -1;
   ri->nickname = tor_strdup(options->Nickname);
@@ -2024,6 +2018,41 @@ router_rebuild_descriptor(int force)
     tor_assert(! routerinfo_incompatible_with_extrainfo(ri, ei, NULL, NULL));
   }
 
+  *r = ri;
+  *e = ei;
+  return 0;
+}
+
+/** If <b>force</b> is true, or our descriptor is out-of-date, rebuild a fresh
+ * routerinfo, signed server descriptor, and extra-info document for this OR.
+ * Return 0 on success, -1 on temporary error.
+ */
+int
+router_rebuild_descriptor(int force)
+{
+  routerinfo_t *ri;
+  extrainfo_t *ei;
+  uint32_t addr;
+  const or_options_t *options = get_options();
+
+  if (desc_clean_since && !force)
+    return 0;
+
+  if (router_pick_published_address(options, &addr) < 0 ||
+      router_get_advertised_or_port(options) == 0) {
+    /* Stop trying to rebuild our descriptor every second. We'll
+     * learn that it's time to try again when ip_address_changed()
+     * marks it dirty. */
+    desc_clean_since = time(NULL);
+    return -1;
+  }
+
+  log_info(LD_OR, "Rebuilding relay descriptor%s", force ? " (forced)" : "");
+
+  if (router_build_fresh_descriptor(&ri, &ei) < 0) {
+    return -1;
+  }
+
   routerinfo_free(desc_routerinfo);
   desc_routerinfo = ri;
   extrainfo_free(desc_extrainfo);

+ 1 - 0
src/or/router.h

@@ -89,6 +89,7 @@ const uint8_t *router_get_my_id_digest(void);
 int router_extrainfo_digest_is_me(const char *digest);
 int router_is_me(const routerinfo_t *router);
 int router_pick_published_address(const or_options_t *options, uint32_t *addr);
+int router_build_fresh_descriptor(routerinfo_t **r, extrainfo_t **e);
 int router_rebuild_descriptor(int force);
 char *router_dump_router_to_string(routerinfo_t *router,
                                    crypto_pk_t *ident_key);