[tor-commits] [tor/master] Add bridge descriptor download status queries to GETINFO

nickm at torproject.org nickm at torproject.org
Thu Jun 30 17:43:09 UTC 2016


commit c69290072819d20e43bd0dd83fa8cefc1167b544
Author: Andrea Shepard <andrea at torproject.org>
Date:   Tue Jun 28 16:12:58 2016 +0000

    Add bridge descriptor download status queries to GETINFO
---
 src/or/control.c    | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/or/entrynodes.c | 38 +++++++++++++++++++++++++++++++++++
 src/or/entrynodes.h |  3 +++
 3 files changed, 98 insertions(+)

diff --git a/src/or/control.c b/src/or/control.c
index 7b8699d..77a09f0 100644
--- a/src/or/control.c
+++ b/src/or/control.c
@@ -2353,6 +2353,48 @@ getinfo_helper_downloads_desc(const char *desc_req,
   }
 }
 
+/** Handle the bridge download cases for getinfo_helper_downloads() */
+static void
+getinfo_helper_downloads_bridge(const char *bridge_req,
+                                download_status_t **dl_to_emit,
+                                smartlist_t **digest_list,
+                                const char **errmsg)
+{
+  char bridge_digest[DIGEST_LEN];
+  /*
+   * Two cases to handle here:
+   *
+   * Case 1: bridge_req = "bridges"
+   *   - Emit a list of all bridge identity digests, which we get by
+   *     calling list_bridge_identities(); this can return NULL if we are
+   *     not using bridges.
+   *
+   * Case 2: bridge_req = <fp>
+   *   - Check on the specified fingerprint and emit its download_status_t
+   *     using get_bridge_dl_status_by_id().
+   */
+
+  if (strcmp(bridge_req, "bridges") == 0) {
+    *digest_list = list_bridge_identities();
+    if (!(*digest_list)) {
+      *errmsg = "We don't seem to be using bridges";
+    }
+  } else if (strlen(bridge_req) == HEX_DIGEST_LEN) {
+    if (base16_decode(bridge_digest, DIGEST_LEN,
+                      bridge_req, strlen(bridge_req)) == DIGEST_LEN) {
+      /* Okay we got a digest-shaped thing; try asking for it */
+      *dl_to_emit = get_bridge_dl_status_by_id(bridge_digest);
+      if (!(*dl_to_emit)) {
+        *errmsg = "No such bridge identity digest found";
+      }
+    } else {
+      *errmsg = "That didn't look like a digest";
+    }
+  } else {
+    *errmsg = "Unknown bridge descriptor download status query";
+  }
+}
+
 /** Implementation helper for GETINFO: knows the answers for questions about
  * download status information. */
 static int
@@ -2377,14 +2419,21 @@ getinfo_helper_downloads(control_connection_t *control_conn,
     getinfo_helper_downloads_networkstatus(
         question + strlen("downloads/networkstatus/"),
         &dl_to_emit, errmsg);
+  /* Certificates? */
   } else if (!strcmpstart(question, "downloads/cert/")) {
     getinfo_helper_downloads_cert(
         question + strlen("downloads/cert/"),
         &dl_to_emit, &digest_list, errmsg);
+  /* Router descriptors? */
   } else if (!strcmpstart(question, "downloads/desc/")) {
     getinfo_helper_downloads_desc(
         question + strlen("downloads/desc/"),
         &dl_to_emit, &digest_list, errmsg);
+  /* Bridge descriptors? */
+  } else if (!strcmpstart(question, "downloads/bridge/")) {
+    getinfo_helper_downloads_bridge(
+        question + strlen("downloads/bridge/"),
+        &dl_to_emit, &digest_list, errmsg);
   } else {
     *errmsg = "Unknown download status query";
   }
@@ -2882,6 +2931,14 @@ static const getinfo_item_t getinfo_items[] = {
       "Return a list of known router descriptor digests"),
   DOC("downloads/desc/<desc>",
       "Return a download status for a given descriptor digest"),
+  PREFIX("downloads/bridge/", downloads,
+         "Download statuses for bridge descriptors, by bridge identity "
+         "digest"),
+  DOC("downloads/bridge/bridges",
+      "Return a list of configured bridge identity digests with download "
+      "statuses"),
+  DOC("downloads/bridge/<desc>",
+      "Return a download status for a given bridge identity digest"),
   ITEM("info/names", misc,
        "List of GETINFO options, types, and documentation."),
   ITEM("events/names", misc,
diff --git a/src/or/entrynodes.c b/src/or/entrynodes.c
index 68241af..72ac6e7 100644
--- a/src/or/entrynodes.c
+++ b/src/or/entrynodes.c
@@ -2424,6 +2424,44 @@ num_bridges_usable(void)
   return n_options;
 }
 
+/** Return a smartlist containing all bridge identity digests */
+smartlist_t *
+list_bridge_identities(void)
+{
+  smartlist_t *result = NULL;
+  char *digest_tmp;
+
+  if (get_options()->UseBridges && bridge_list) {
+    result = smartlist_new();
+
+    SMARTLIST_FOREACH_BEGIN(bridge_list, bridge_info_t *, b) {
+      digest_tmp = tor_malloc(DIGEST_LEN);
+      memcpy(digest_tmp, b->identity, DIGEST_LEN);
+      smartlist_add(result, digest_tmp);
+    } SMARTLIST_FOREACH_END(b);
+  }
+
+  return result;
+}
+
+/** Get the download status for a bridge descriptor given its identity */
+download_status_t *
+get_bridge_dl_status_by_id(const char *digest)
+{
+  download_status_t *dl = NULL;
+
+  if (digest && get_options()->UseBridges && bridge_list) {
+    SMARTLIST_FOREACH_BEGIN(bridge_list, bridge_info_t *, b) {
+      if (memcmp(digest, b->identity, DIGEST_LEN) == 0) {
+        dl = &(b->fetch_status);
+        break;
+      }
+    } SMARTLIST_FOREACH_END(b);
+  }
+
+  return dl;
+}
+
 /** Return 1 if we have at least one descriptor for an entry guard
  * (bridge or member of EntryNodes) and all descriptors we know are
  * down. Else return 0. If <b>act</b> is 1, then mark the down guards
diff --git a/src/or/entrynodes.h b/src/or/entrynodes.h
index 247c809..285367d 100644
--- a/src/or/entrynodes.h
+++ b/src/or/entrynodes.h
@@ -179,5 +179,8 @@ guard_get_guardfraction_bandwidth(guardfraction_bandwidth_t *guardfraction_bw,
                                   int orig_bandwidth,
                                   uint32_t guardfraction_percentage);
 
+smartlist_t * list_bridge_identities(void);
+download_status_t * get_bridge_dl_status_by_id(const char *digest);
+
 #endif
 





More information about the tor-commits mailing list