Commit 9482b1b9 authored by Nick Mathewson's avatar Nick Mathewson 🐘
Browse files

Choose directory servers from routerstatus list, not from routerinfo list. ...

Choose directory servers from routerstatus list, not from routerinfo list.  This way, as soon was we have a networkstatus, we can ask a cache to give us routers, rather than needing to ask the directories.


svn:r5586
parent 7e6a41af
Loading
Loading
Loading
Loading
+2 −2
Changes for doc/TODO: 2 added lines, 2 removed lines.
Original line number Diff line number Diff line
@@ -194,8 +194,8 @@ N - Clients use Stable and Fast instead of uptime and bandwidth to
      servers?
      - Is this still necessary?
    o All versions of Tor should get cosmetic changes rate-limited.
    - Pick directories from networkstatus objects, not from routerlist.
      - But! We can't do this easily, since we want to know about platform,
    o Pick directories from networkstatus objects, not from routerlist.
      o But! We can't do this easily, since we want to know about platform,
        and networkstatus doesn't tell us Tor version.  Can we solve this?
        Should we do it by adding flags to networkstatus or what?

+1 −1
Changes for src/common/ht.h: 1 added line, 1 removed line.
Original line number Diff line number Diff line
@@ -24,7 +24,7 @@
  }

#define HT_INITIALIZER()                        \
  { 0, NULL, 0, 0, -1 }
  { NULL, 0, 0, 0, -1 }

#define HT_INIT(root) do {                      \
    (root)->hth_table_length = 0;               \
+58 −35
Changes for src/or/directory.c: 58 added lines, 35 removed lines.
Original line number Diff line number Diff line
@@ -31,11 +31,6 @@ const char directory_c_id[] =
 *   connection_finished_connecting() in connection.c
 */
static void
directory_initiate_command_trusted_dir(trusted_dir_server_t *dirserv,
                                      uint8_t purpose, int private_connection,
                                      const char *resource,
                                      const char *payload, size_t payload_len);
static void
directory_initiate_command(const char *address, uint32_t addr, uint16_t port,
                           const char *platform,
                           const char *digest, uint8_t purpose,
@@ -143,9 +138,10 @@ directory_post_to_dirservers(uint8_t purpose, const char *payload,
   */
  SMARTLIST_FOREACH(dirservers, trusted_dir_server_t *, ds,
    {
      routerstatus_t *rs = &(ds->fake_status);
      post_via_tor = purpose_is_private(purpose) ||
                     !fascist_firewall_allows_address(ds->addr,ds->dir_port);
      directory_initiate_command_trusted_dir(ds, purpose, post_via_tor,
      directory_initiate_command_routerstatus(rs, purpose, post_via_tor,
                                              NULL, payload, payload_len);
    });
}
@@ -159,8 +155,7 @@ void
directory_get_from_dirserver(uint8_t purpose, const char *resource,
                             int retry_if_no_servers)
{
  routerinfo_t *r = NULL;
  trusted_dir_server_t *ds = NULL;
  routerstatus_t *rs = NULL;
  or_options_t *options = get_options();
  int fetch_fresh_first = server_mode(options) && options->DirPort != 0;
  int directconn = !purpose_is_private(purpose);
@@ -175,19 +170,21 @@ directory_get_from_dirserver(uint8_t purpose, const char *resource,
        !strcmpstart(resource,"fp/") && strlen(resource) == HEX_DIGEST_LEN+3) {
      /* Try to ask the actual dirserver its opinion. */
      char digest[DIGEST_LEN];
      trusted_dir_server_t *ds;
      base16_decode(digest, DIGEST_LEN, resource+3, HEX_DIGEST_LEN);
      ds = router_get_trusteddirserver_by_digest(digest);
      rs = &(ds->fake_status);
    }
    if (!ds && fetch_fresh_first) {
    if (!rs && fetch_fresh_first) {
      /* only ask authdirservers, and don't ask myself */
      ds = router_pick_trusteddirserver(need_v1_support, 1, 1,
      rs = router_pick_trusteddirserver(need_v1_support, 1, 1,
                                        retry_if_no_servers);
    }
    if (!ds) {
    if (!rs) {
      /* anybody with a non-zero dirport will do */
      r = router_pick_directory_server(1, 1, need_v2_support,
      rs = router_pick_directory_server(1, 1, need_v2_support,
                                        retry_if_no_servers);
      if (!r) {
      if (!rs) {
        const char *which;
        if (purpose == DIR_PURPOSE_FETCH_DIR)
          which = "directory";
@@ -199,9 +196,9 @@ directory_get_from_dirserver(uint8_t purpose, const char *resource,
          which = "server descriptors";
        info(LD_DIR,
             "No router found for %s; falling back to dirserver list", which);
        ds = router_pick_trusteddirserver(1, 1, 1,
        rs = router_pick_trusteddirserver(1, 1, 1,
                                          retry_if_no_servers);
        if (!ds)
        if (!rs)
          directconn = 0; /* last resort: try routing it via Tor */
      }
    }
@@ -210,19 +207,17 @@ directory_get_from_dirserver(uint8_t purpose, const char *resource,
    /* Never use fascistfirewall; we're going via Tor. */
    if (purpose == DIR_PURPOSE_FETCH_RENDDESC) {
      /* only ask authdirservers, any of them will do */
      ds = router_pick_trusteddirserver(0, 0, 0, retry_if_no_servers);
      rs = router_pick_trusteddirserver(0, 0, 0, retry_if_no_servers);
    } else {
      /* anybody with a non-zero dirport will do. Disregard firewalls. */
      r = router_pick_directory_server(1, 0, need_v2_support,
      rs = router_pick_directory_server(1, 0, need_v2_support,
                                        retry_if_no_servers);
      /* XXXX If no rs, fall back to trusted dir servers? -NM */
    }
  }

  if (r)
    directory_initiate_command_router(r, purpose, !directconn,
                                      resource, NULL, 0);
  else if (ds)
    directory_initiate_command_trusted_dir(ds, purpose, !directconn,
  if (rs)
    directory_initiate_command_routerstatus(rs, purpose, !directconn,
                                            resource, NULL, 0);
  else {
    notice(LD_DIR,
@@ -247,27 +242,55 @@ directory_get_from_dirserver(uint8_t purpose, const char *resource,
 * want to fetch.
 */
void
directory_initiate_command_router(routerinfo_t *router, uint8_t purpose,
                                  int private_connection, const char *resource,
                                  const char *payload, size_t payload_len)
directory_initiate_command_router(routerinfo_t *router,
                                  uint8_t purpose,
                                  int private_connection,
                                  const char *resource,
                                  const char *payload,
                                  size_t payload_len)
{
  directory_initiate_command(router->address, router->addr, router->dir_port,
                         router->platform, router->cache_info.identity_digest,
                             router->platform,
                             router->cache_info.identity_digest,
                             purpose, private_connection, resource,
                             payload, payload_len);
}

/** As directory_initiate_command_router, but send the command to a trusted
 * directory server <b>dirserv</b>. **/
static void
directory_initiate_command_trusted_dir(trusted_dir_server_t *dirserv,
                                       uint8_t purpose, int private_connection,
/** Launch a new connection to the directory server <b>status</b> to upload or
 * download a service or rendezvous descriptor. <b>purpose</b> determines what
 * kind of directory connection we're launching, and must be one of
 * DIR_PURPOSE_{FETCH|UPLOAD}_{DIR|RENDDESC}.
 *
 * When uploading, <b>payload</b> and <b>payload_len</b> determine the content
 * of the HTTP post.  Otherwise, <b>payload</b> should be NULL.
 *
 * When fetching a rendezvous descriptor, <b>resource</b> is the service ID we
 * want to fetch.
 */
void
directory_initiate_command_routerstatus(routerstatus_t *status,
                                        uint8_t purpose,
                                        int private_connection,
                                        const char *resource,
                                       const char *payload, size_t payload_len)
                                        const char *payload,
                                        size_t payload_len)
{
  directory_initiate_command(dirserv->address, dirserv->addr,
               dirserv->dir_port, NULL, dirserv->digest, purpose,
               private_connection, resource,
  const char *platform = NULL;
  routerinfo_t *router;
  char address_buf[INET_NTOA_BUF_LEN];
  struct in_addr in;
  const char *address;
  if ((router = router_get_by_digest(status->identity_digest))) {
    platform = router->platform;
    address = router->address;
  } else {
    in.s_addr = htonl(status->addr);
    tor_inet_ntoa(&in, address_buf, sizeof(address_buf));
    address = address_buf;
  }
  directory_initiate_command(address, status->addr, status->dir_port,
                             platform, status->identity_digest,
                             purpose, private_connection, resource,
                             payload, payload_len);
}

+11 −3
Changes for src/or/or.h: 11 added lines, 3 removed lines.
Original line number Diff line number Diff line
@@ -1822,6 +1822,12 @@ void directory_initiate_command_router(routerinfo_t *router, uint8_t purpose,
                                       const char *resource,
                                       const char *payload,
                                       size_t payload_len);
void directory_initiate_command_routerstatus(routerstatus_t *status,
                                             uint8_t purpose,
                                             int private_connection,
                                             const char *resource,
                                             const char *payload,
                                             size_t payload_len);

int parse_http_response(const char *headers, int *code, time_t *date,
                        int *compression, char **response);
@@ -2183,21 +2189,23 @@ typedef struct trusted_dir_server_t {
  uint16_t dir_port; /**< Directory port */
  char digest[DIGEST_LEN]; /**< Digest of identity key */
  unsigned int is_running:1; /**< True iff we think this server is running. */
  unsigned int supports_v1_protocol:1; /**< True iff this server is an
  unsigned int is_v1_authority:1; /**< True iff this server is an
                                   * authority for the older ("v1")
                                   * directory protocol.*/
  int n_networkstatus_failures; /**< How many times have we asked for this
                                 * server's network-status unsuccessfully? */
  routerstatus_t fake_status; /**< Used when we need to pass this trusted
                               * dir_server_t as a routerstatus_t. */
} trusted_dir_server_t;

int router_reload_router_list(void);
int router_reload_networkstatus(void);
void router_get_trusted_dir_servers(smartlist_t **outp);
routerinfo_t *router_pick_directory_server(int requireother,
routerstatus_t *router_pick_directory_server(int requireother,
                                             int fascistfirewall,
                                             int for_v2_directory,
                                             int retry_if_no_servers);
trusted_dir_server_t *router_pick_trusteddirserver(int need_v1_support,
routerstatus_t *router_pick_trusteddirserver(int need_v1_authority,
                                             int requireother,
                                             int fascistfirewall,
                                             int retry_if_no_servers);
+2 −1
Changes for src/or/relay.c: 2 added lines, 1 removed line.
Original line number Diff line number Diff line
@@ -3,7 +3,8 @@
 * Copyright 2004-2005 Roger Dingledine, Nick Mathewson. */
/* See LICENSE for licensing information */
/* $Id$ */
const char relay_c_id[] = "$Id$";
const char relay_c_id[] =
  "$Id$";

/**
 * \file relay.c
Loading