tor

The Tor anonymity network
git clone https://git.dasho.dev/tor.git
Log | Files | Refs | README | LICENSE

directory.c (26541B)


      1 /* Copyright (c) 2001-2004, Roger Dingledine.
      2 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
      3 * Copyright (c) 2007-2021, The Tor Project, Inc. */
      4 /* See LICENSE for licensing information */
      5 
      6 #include "core/or/or.h"
      7 
      8 #include "app/config/config.h"
      9 #include "core/mainloop/connection.h"
     10 #include "core/or/circuitlist.h"
     11 #include "core/or/connection_edge.h"
     12 #include "core/or/connection_or.h"
     13 #include "core/or/channeltls.h"
     14 #include "feature/dircache/dircache.h"
     15 #include "feature/dircache/dirserv.h"
     16 #include "feature/dirclient/dirclient.h"
     17 #include "feature/dircommon/directory.h"
     18 #include "feature/dircommon/fp_pair.h"
     19 #include "feature/hs/hs_cache.h"
     20 #include "feature/stats/geoip_stats.h"
     21 #include "lib/compress/compress.h"
     22 
     23 #include "core/or/circuit_st.h"
     24 #include "core/or/or_circuit_st.h"
     25 #include "core/or/edge_connection_st.h"
     26 #include "core/or/or_connection_st.h"
     27 #include "feature/dircommon/dir_connection_st.h"
     28 #include "feature/nodelist/routerinfo_st.h"
     29 
     30 /**
     31 * \file directory.c
     32 * \brief Code to send and fetch information from directory authorities and
     33 * caches via HTTP.
     34 *
     35 * Directory caches and authorities use dirserv.c to generate the results of a
     36 * query and stream them to the connection; clients use routerparse.c to parse
     37 * them.
     38 *
     39 * Every directory request has a dir_connection_t on the client side and on
     40 * the server side.  In most cases, the dir_connection_t object is a linked
     41 * connection, tunneled through an edge_connection_t so that it can be a
     42 * stream on the Tor network.  The only non-tunneled connections are those
     43 * that are used to upload material (descriptors and votes) to authorities.
     44 * Among tunneled connections, some use one-hop circuits, and others use
     45 * multi-hop circuits for anonymity.
     46 *
     47 * Directory requests are launched by calling
     48 * directory_initiate_request(). This
     49 * launch the connection, will construct an HTTP request with
     50 * directory_send_command(), send the and wait for a response.  The client
     51 * later handles the response with connection_dir_client_reached_eof(),
     52 * which passes the information received to another part of Tor.
     53 *
     54 * On the server side, requests are read in directory_handle_command(),
     55 * which dispatches first on the request type (GET or POST), and then on
     56 * the URL requested. GET requests are processed with a table-based
     57 * dispatcher in url_table[].  The process of handling larger GET requests
     58 * is complicated because we need to avoid allocating a copy of all the
     59 * data to be sent to the client in one huge buffer.  Instead, we spool the
     60 * data into the buffer using logic in connection_dirserv_flushed_some() in
     61 * dirserv.c.  (TODO: If we extended buf.c to have a zero-copy
     62 * reference-based buffer type, we could remove most of that code, at the
     63 * cost of a bit more reference counting.)
     64 **/
     65 
     66 /* In-points to directory.c:
     67 *
     68 * - directory_post_to_dirservers(), called from
     69 *   router_upload_dir_desc_to_dirservers() in router.c
     70 *   upload_service_descriptor() in rendservice.c
     71 * - directory_get_from_dirserver(), called from
     72 *   run_scheduled_events() in main.c
     73 *   do_hup() in main.c
     74 * - connection_dir_process_inbuf(), called from
     75 *   connection_process_inbuf() in connection.c
     76 * - connection_dir_finished_flushing(), called from
     77 *   connection_finished_flushing() in connection.c
     78 * - connection_dir_finished_connecting(), called from
     79 *   connection_finished_connecting() in connection.c
     80 */
     81 
     82 /**
     83 * Cast a `connection_t *` to a `dir_connection_t *`.
     84 *
     85 * Exit with an assertion failure if the input is not a
     86 * `dir_connection_t`.
     87 **/
     88 dir_connection_t *
     89 TO_DIR_CONN(connection_t *c)
     90 {
     91  tor_assert(c->magic == DIR_CONNECTION_MAGIC);
     92  return DOWNCAST(dir_connection_t, c);
     93 }
     94 
     95 /**
     96 * Cast a `const connection_t *` to a `const dir_connection_t *`.
     97 *
     98 * Exit with an assertion failure if the input is not a
     99 * `dir_connection_t`.
    100 **/
    101 const dir_connection_t *
    102 CONST_TO_DIR_CONN(const connection_t *c)
    103 {
    104  return TO_DIR_CONN((connection_t *)c);
    105 }
    106 
    107 /** Return false if the directory purpose <b>dir_purpose</b>
    108 * does not require an anonymous (three-hop) connection.
    109 *
    110 * Return true 1) by default, 2) if all directory actions have
    111 * specifically been configured to be over an anonymous connection,
    112 * or 3) if the router is a bridge */
    113 int
    114 purpose_needs_anonymity(uint8_t dir_purpose, uint8_t router_purpose,
    115                        const char *resource)
    116 {
    117  if (get_options()->AllDirActionsPrivate)
    118    return 1;
    119 
    120  if (router_purpose == ROUTER_PURPOSE_BRIDGE) {
    121    if (dir_purpose == DIR_PURPOSE_FETCH_SERVERDESC
    122        && resource && !strcmp(resource, "authority.z")) {
    123      /* We are asking a bridge for its own descriptor. That doesn't need
    124         anonymity. */
    125      return 0;
    126    }
    127    /* Assume all other bridge stuff needs anonymity. */
    128    return 1; /* if no circuits yet, this might break bootstrapping, but it's
    129               * needed to be safe. */
    130  }
    131 
    132  switch (dir_purpose)
    133  {
    134    case DIR_PURPOSE_UPLOAD_DIR:
    135    case DIR_PURPOSE_UPLOAD_VOTE:
    136    case DIR_PURPOSE_UPLOAD_SIGNATURES:
    137    case DIR_PURPOSE_FETCH_STATUS_VOTE:
    138    case DIR_PURPOSE_FETCH_DETACHED_SIGNATURES:
    139    case DIR_PURPOSE_FETCH_CONSENSUS:
    140    case DIR_PURPOSE_FETCH_CERTIFICATE:
    141    case DIR_PURPOSE_FETCH_SERVERDESC:
    142    case DIR_PURPOSE_FETCH_EXTRAINFO:
    143    case DIR_PURPOSE_FETCH_MICRODESC:
    144      return 0;
    145    case DIR_PURPOSE_HAS_FETCHED_HSDESC:
    146    case DIR_PURPOSE_FETCH_HSDESC:
    147    case DIR_PURPOSE_UPLOAD_HSDESC:
    148      return 1;
    149    case DIR_PURPOSE_SERVER:
    150    default:
    151      log_warn(LD_BUG, "Called with dir_purpose=%d, router_purpose=%d",
    152               dir_purpose, router_purpose);
    153      tor_assert_nonfatal_unreached();
    154      return 1; /* Assume it needs anonymity; better safe than sorry. */
    155  }
    156 }
    157 
    158 /** Return a newly allocated string describing <b>auth</b>. Only describes
    159 * authority features. */
    160 char *
    161 authdir_type_to_string(dirinfo_type_t auth)
    162 {
    163  char *result;
    164  smartlist_t *lst = smartlist_new();
    165  if (auth & V3_DIRINFO)
    166    smartlist_add(lst, (void*)"V3");
    167  if (auth & BRIDGE_DIRINFO)
    168    smartlist_add(lst, (void*)"Bridge");
    169  if (smartlist_len(lst)) {
    170    result = smartlist_join_strings(lst, ", ", 0, NULL);
    171  } else {
    172    result = tor_strdup("[Not an authority]");
    173  }
    174  smartlist_free(lst);
    175  return result;
    176 }
    177 
    178 /** Return true iff anything we say on <b>conn</b> is being encrypted before
    179 * we send it to the client/server. */
    180 int
    181 connection_dir_is_encrypted(const dir_connection_t *conn)
    182 {
    183  /* Right now it's sufficient to see if conn is or has been linked, since
    184   * the only thing it could be linked to is an edge connection on a
    185   * circuit, and the only way it could have been unlinked is at the edge
    186   * connection getting closed.
    187   */
    188  return TO_CONN(conn)->linked;
    189 }
    190 
    191 /** Return true iff the given directory connection <b>dir_conn</b> is
    192 * anonymous, that is, it is on a circuit via a public relay and not directly
    193 * from a client or bridge.
    194 *
    195 * For client circuits via relays: true for 2-hop+ paths.
    196 * For client circuits via bridges: true for 3-hop+ paths.
    197 *
    198 * This first test if the connection is encrypted since it is a strong
    199 * requirement for anonymity. */
    200 bool
    201 connection_dir_is_anonymous(const dir_connection_t *dir_conn)
    202 {
    203  const connection_t *conn, *linked_conn;
    204  const edge_connection_t *edge_conn;
    205  const circuit_t *circ;
    206 
    207  tor_assert(dir_conn);
    208 
    209  if (!connection_dir_is_encrypted(dir_conn)) {
    210    return false;
    211  }
    212 
    213  /*
    214   * Buckle up, we'll do a deep dive into the connection in order to get the
    215   * final connection channel of that connection in order to figure out if
    216   * this is a client or relay link.
    217   *
    218   * We go: dir_conn -> linked_conn -> edge_conn -> on_circuit -> p_chan.
    219   */
    220 
    221  conn = TO_CONN(dir_conn);
    222  linked_conn = conn->linked_conn;
    223 
    224  /* The dir connection should be connected to an edge connection. It can not
    225   * be closed or marked for close. */
    226  if (linked_conn == NULL || linked_conn->magic != EDGE_CONNECTION_MAGIC ||
    227      conn->linked_conn_is_closed || conn->linked_conn->marked_for_close) {
    228    log_debug(LD_DIR, "Directory connection is not anonymous: "
    229                      "not linked to edge");
    230    return false;
    231  }
    232 
    233  edge_conn = CONST_TO_EDGE_CONN(linked_conn);
    234  circ = edge_conn->on_circuit;
    235 
    236  /* Can't be a circuit we initiated and without a circuit, no channel. */
    237  if (circ == NULL || CIRCUIT_IS_ORIGIN(circ)) {
    238    log_debug(LD_DIR, "Directory connection is not anonymous: "
    239                      "not on OR circuit");
    240    return false;
    241  }
    242 
    243  /* It is possible that the circuit was closed because one of the channel was
    244   * closed or a DESTROY cell was received. Either way, this connection can
    245   * not continue so return that it is not anonymous since we can not know for
    246   * sure if it is. */
    247  if (circ->marked_for_close) {
    248    log_debug(LD_DIR, "Directory connection is not anonymous: "
    249                      "circuit marked for close");
    250    return false;
    251  }
    252 
    253  /* Get the previous channel to learn if it is a client or relay link. We
    254   * BUG() because if the circuit is not mark for close, we ought to have a
    255   * p_chan else we have a code flow issue. */
    256  if (BUG(CONST_TO_OR_CIRCUIT(circ)->p_chan == NULL)) {
    257    log_debug(LD_DIR, "Directory connection is not anonymous: "
    258                      "no p_chan on circuit");
    259    return false;
    260  }
    261 
    262  /* Will be true if the channel is an unauthenticated peer which is only true
    263   * for clients and bridges. */
    264  return !channel_is_client(CONST_TO_OR_CIRCUIT(circ)->p_chan);
    265 }
    266 
    267 /** Did <b>conn</b> ever send us a version 0 sendme cell and we allowed
    268 * it? Used to decide whether to count consensus fetches from it in our
    269 * geoip stats.
    270 *
    271 * Note that this function might have false negatives in some cases, i.e.
    272 * it could tell us that the conn never sent a v0 sendme when actually it
    273 * did but its linked edge connection or OR connection got broken before
    274 * we called this function. For our geoip stats these false negatives
    275 * would mean overcounting users by including some of the v0-using
    276 * clients.
    277 *
    278 * We think these false positives should be unlikely or maybe even
    279 * impossible when called from connection_dirserv_flushed_some(), but
    280 * be careful calling it from elsewhere.
    281 * */
    282 bool
    283 connection_dir_used_obsolete_sendme(const dir_connection_t *conn)
    284 {
    285  const edge_connection_t *edge_conn = NULL;
    286  const circuit_t *circ = NULL;
    287  bool used_obsolete_sendme = 0;
    288  const connection_t *linked_conn = TO_CONN(conn)->linked_conn;
    289  if (linked_conn)
    290    edge_conn = CONST_TO_EDGE_CONN(linked_conn);
    291  if (edge_conn)
    292    circ = edge_conn->on_circuit;
    293  if (circ && CIRCUIT_IS_ORCIRC(circ))
    294    used_obsolete_sendme = CONST_TO_OR_CIRCUIT(circ)->used_obsolete_sendme;
    295 
    296  return used_obsolete_sendme;
    297 }
    298 
    299 /** Parse an HTTP request line at the start of a headers string.  On failure,
    300 * return -1.  On success, set *<b>command_out</b> to a copy of the HTTP
    301 * command ("get", "post", etc), set *<b>url_out</b> to a copy of the URL, and
    302 * return 0. */
    303 int
    304 parse_http_command(const char *headers, char **command_out, char **url_out)
    305 {
    306  const char *command, *end_of_command;
    307  char *s, *start, *tmp;
    308 
    309  s = (char *)eat_whitespace_no_nl(headers);
    310  if (!*s) return -1;
    311  command = s;
    312  s = (char *)find_whitespace(s); /* get past GET/POST */
    313  if (!*s) return -1;
    314  end_of_command = s;
    315  s = (char *)eat_whitespace_no_nl(s);
    316  if (!*s) return -1;
    317  start = s; /* this is the URL, assuming it's valid */
    318  s = (char *)find_whitespace(start);
    319  if (!*s) return -1;
    320 
    321  /* tolerate the http[s] proxy style of putting the hostname in the url */
    322  if (s-start >= 4 && !strcmpstart(start,"http")) {
    323    tmp = start + 4;
    324    if (*tmp == 's')
    325      tmp++;
    326    if (s-tmp >= 3 && !strcmpstart(tmp,"://")) {
    327      tmp = strchr(tmp+3, '/');
    328      if (tmp && tmp < s) {
    329        log_debug(LD_DIR,"Skipping over 'http[s]://hostname/' string");
    330        start = tmp;
    331      }
    332    }
    333  }
    334 
    335  /* Check if the header is well formed (next sequence
    336   * should be HTTP/1.X\r\n). Assumes we're supporting 1.0? */
    337  {
    338    unsigned minor_ver;
    339    char ch;
    340    char *e = (char *)eat_whitespace_no_nl(s);
    341    if (2 != tor_sscanf(e, "HTTP/1.%u%c", &minor_ver, &ch)) {
    342      return -1;
    343    }
    344    if (ch != '\r')
    345      return -1;
    346  }
    347 
    348  *url_out = tor_memdup_nulterm(start, s-start);
    349  *command_out = tor_memdup_nulterm(command, end_of_command - command);
    350  return 0;
    351 }
    352 
    353 /** Return a copy of the first HTTP header in <b>headers</b> whose key is
    354 * <b>which</b>.  The key should be given with a terminating colon and space;
    355 * this function copies everything after, up to but not including the
    356 * following \\r\\n. */
    357 char *
    358 http_get_header(const char *headers, const char *which)
    359 {
    360  const char *cp = headers;
    361  while (cp) {
    362    if (!strcasecmpstart(cp, which)) {
    363      const char *eos;
    364      cp += strlen(which);
    365      if ((eos = strchr(cp,'\r')))
    366        return tor_strndup(cp, eos-cp);
    367      else
    368        return tor_strdup(cp);
    369    }
    370    cp = strchr(cp, '\n');
    371    if (cp)
    372      ++cp;
    373  }
    374  return NULL;
    375 }
    376 /** Parse an HTTP response string <b>headers</b> of the form
    377 * \verbatim
    378 * "HTTP/1.\%d \%d\%s\r\n...".
    379 * \endverbatim
    380 *
    381 * If it's well-formed, assign the status code to *<b>code</b> and
    382 * return 0.  Otherwise, return -1.
    383 *
    384 * On success: If <b>date</b> is provided, set *date to the Date
    385 * header in the http headers, or 0 if no such header is found.  If
    386 * <b>compression</b> is provided, set *<b>compression</b> to the
    387 * compression method given in the Content-Encoding header, or 0 if no
    388 * such header is found, or -1 if the value of the header is not
    389 * recognized.  If <b>reason</b> is provided, strdup the reason string
    390 * into it.
    391 */
    392 int
    393 parse_http_response(const char *headers, int *code, time_t *date,
    394                    compress_method_t *compression, char **reason)
    395 {
    396  unsigned n1, n2;
    397  char datestr[RFC1123_TIME_LEN+1];
    398  smartlist_t *parsed_headers;
    399  tor_assert(headers);
    400  tor_assert(code);
    401 
    402  while (TOR_ISSPACE(*headers)) headers++; /* tolerate leading whitespace */
    403 
    404  if (tor_sscanf(headers, "HTTP/1.%u %u", &n1, &n2) < 2 ||
    405      (n1 != 0 && n1 != 1) ||
    406      (n2 < 100 || n2 >= 600)) {
    407    log_warn(LD_HTTP,"Failed to parse header %s",escaped(headers));
    408    return -1;
    409  }
    410  *code = n2;
    411 
    412  parsed_headers = smartlist_new();
    413  smartlist_split_string(parsed_headers, headers, "\n",
    414                         SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, -1);
    415  if (reason) {
    416    smartlist_t *status_line_elements = smartlist_new();
    417    tor_assert(smartlist_len(parsed_headers));
    418    smartlist_split_string(status_line_elements,
    419                           smartlist_get(parsed_headers, 0),
    420                           " ", SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 3);
    421    tor_assert(smartlist_len(status_line_elements) <= 3);
    422    if (smartlist_len(status_line_elements) == 3) {
    423      *reason = smartlist_get(status_line_elements, 2);
    424      smartlist_set(status_line_elements, 2, NULL); /* Prevent free */
    425    }
    426    SMARTLIST_FOREACH(status_line_elements, char *, cp, tor_free(cp));
    427    smartlist_free(status_line_elements);
    428  }
    429  if (date) {
    430    *date = 0;
    431    SMARTLIST_FOREACH(parsed_headers, const char *, s,
    432      if (!strcmpstart(s, "Date: ")) {
    433        strlcpy(datestr, s+6, sizeof(datestr));
    434        /* This will do nothing on failure, so we don't need to check
    435           the result.   We shouldn't warn, since there are many other valid
    436           date formats besides the one we use. */
    437        parse_rfc1123_time(datestr, date);
    438        break;
    439      });
    440  }
    441  if (compression) {
    442    const char *enc = NULL;
    443    SMARTLIST_FOREACH(parsed_headers, const char *, s,
    444      if (!strcmpstart(s, "Content-Encoding: ")) {
    445        enc = s+18; break;
    446      });
    447 
    448    if (enc == NULL)
    449      *compression = NO_METHOD;
    450    else {
    451      *compression = compression_method_get_by_name(enc);
    452 
    453      if (*compression == UNKNOWN_METHOD)
    454        log_info(LD_HTTP, "Unrecognized content encoding: %s. Trying to deal.",
    455                 escaped(enc));
    456    }
    457  }
    458  SMARTLIST_FOREACH(parsed_headers, char *, s, tor_free(s));
    459  smartlist_free(parsed_headers);
    460 
    461  return 0;
    462 }
    463 
    464 /** If any directory object is arriving, and it's over 10MB large, we're
    465 * getting DoS'd.  (As of 0.1.2.x, raw directories are about 1MB, and we never
    466 * ask for more than 96 router descriptors at a time.)
    467 */
    468 #define MAX_DIRECTORY_OBJECT_SIZE (10*(1<<20))
    469 
    470 #define MAX_VOTE_DL_SIZE (MAX_DIRECTORY_OBJECT_SIZE * 5)
    471 
    472 /** Read handler for directory connections.  (That's connections <em>to</em>
    473 * directory servers and connections <em>at</em> directory servers.)
    474 */
    475 int
    476 connection_dir_process_inbuf(dir_connection_t *conn)
    477 {
    478  size_t max_size;
    479  tor_assert(conn);
    480  tor_assert(conn->base_.type == CONN_TYPE_DIR);
    481 
    482  /* Directory clients write, then read data until they receive EOF;
    483   * directory servers read data until they get an HTTP command, then
    484   * write their response (when it's finished flushing, they mark for
    485   * close).
    486   */
    487 
    488  /* If we're on the dirserver side, look for a command. */
    489  if (conn->base_.state == DIR_CONN_STATE_SERVER_COMMAND_WAIT) {
    490    if (directory_handle_command(conn) < 0) {
    491      connection_mark_for_close(TO_CONN(conn));
    492      return -1;
    493    }
    494    return 0;
    495  }
    496 
    497  max_size =
    498    (TO_CONN(conn)->purpose == DIR_PURPOSE_FETCH_STATUS_VOTE) ?
    499    MAX_VOTE_DL_SIZE : MAX_DIRECTORY_OBJECT_SIZE;
    500 
    501  if (connection_get_inbuf_len(TO_CONN(conn)) > max_size) {
    502    log_warn(LD_HTTP,
    503             "Too much data received from %s: "
    504             "denial of service attempt, or you need to upgrade?",
    505             connection_describe(TO_CONN(conn)));
    506    connection_mark_for_close(TO_CONN(conn));
    507    return -1;
    508  }
    509 
    510  if (!conn->base_.inbuf_reached_eof)
    511    log_debug(LD_HTTP,"Got data, not eof. Leaving on inbuf.");
    512  return 0;
    513 }
    514 
    515 /** Called when we're about to finally unlink and free a directory connection:
    516 * perform necessary accounting and cleanup */
    517 void
    518 connection_dir_about_to_close(dir_connection_t *dir_conn)
    519 {
    520  connection_t *conn = TO_CONN(dir_conn);
    521 
    522  if (conn->state < DIR_CONN_STATE_CLIENT_FINISHED) {
    523    /* It's a directory connection and connecting or fetching
    524     * failed: forget about this router, and maybe try again. */
    525    connection_dir_client_request_failed(dir_conn);
    526  }
    527 
    528  /* If we are an HSDir, mark the corresponding descriptor as downloaded. This
    529   * is needed for the OOM cache cleanup.
    530   *
    531   * This is done when the direction connection is closed in order to raise the
    532   * attack cost of filling the cache with bogus descriptors. That attacker
    533   * would need to increase that downloaded counter for the attack to be
    534   * successful which is expensive. */
    535  if (conn->purpose == DIR_PURPOSE_SERVER && dir_conn->hs_ident) {
    536    hs_cache_mark_dowloaded_as_dir(dir_conn->hs_ident);
    537  }
    538 
    539  connection_dir_client_refetch_hsdesc_if_needed(dir_conn);
    540 }
    541 
    542 /** Write handler for directory connections; called when all data has
    543 * been flushed.  Close the connection or wait for a response as
    544 * appropriate.
    545 */
    546 int
    547 connection_dir_finished_flushing(dir_connection_t *conn)
    548 {
    549  tor_assert(conn);
    550  tor_assert(conn->base_.type == CONN_TYPE_DIR);
    551 
    552  if (conn->base_.marked_for_close)
    553    return 0;
    554 
    555  /* Note that we have finished writing the directory response. For direct
    556   * connections this means we're done; for tunneled connections it's only
    557   * an intermediate step. */
    558  if (conn->dirreq_id)
    559    geoip_change_dirreq_state(conn->dirreq_id, DIRREQ_TUNNELED,
    560                              DIRREQ_FLUSHING_DIR_CONN_FINISHED);
    561  else
    562    geoip_change_dirreq_state(TO_CONN(conn)->global_identifier,
    563                              DIRREQ_DIRECT,
    564                              DIRREQ_FLUSHING_DIR_CONN_FINISHED);
    565  switch (conn->base_.state) {
    566    case DIR_CONN_STATE_CONNECTING:
    567    case DIR_CONN_STATE_CLIENT_SENDING:
    568      log_debug(LD_DIR,"client finished sending command.");
    569      conn->base_.state = DIR_CONN_STATE_CLIENT_READING;
    570      return 0;
    571    case DIR_CONN_STATE_SERVER_WRITING:
    572      if (conn->spool) {
    573        log_warn(LD_BUG, "Emptied a dirserv buffer, but it's still spooling!");
    574        connection_mark_for_close(TO_CONN(conn));
    575      } else {
    576        log_debug(LD_DIRSERV, "Finished writing server response. Closing.");
    577        connection_mark_for_close(TO_CONN(conn));
    578      }
    579      return 0;
    580    default:
    581      log_warn(LD_BUG,"called in unexpected state %d.",
    582               conn->base_.state);
    583      tor_fragile_assert();
    584      return -1;
    585  }
    586  return 0;
    587 }
    588 
    589 /** Connected handler for directory connections: begin sending data to the
    590 * server, and return 0.
    591 * Only used when connections don't immediately connect. */
    592 int
    593 connection_dir_finished_connecting(dir_connection_t *conn)
    594 {
    595  tor_assert(conn);
    596  tor_assert(conn->base_.type == CONN_TYPE_DIR);
    597  tor_assert(conn->base_.state == DIR_CONN_STATE_CONNECTING);
    598 
    599  log_debug(LD_HTTP,"Dir connection to %s established.",
    600            connection_describe_peer(TO_CONN(conn)));
    601 
    602  /* start flushing conn */
    603  conn->base_.state = DIR_CONN_STATE_CLIENT_SENDING;
    604  return 0;
    605 }
    606 
    607 /** Helper.  Compare two fp_pair_t objects, and return negative, 0, or
    608 * positive as appropriate. */
    609 static int
    610 compare_pairs_(const void **a, const void **b)
    611 {
    612  const fp_pair_t *fp1 = *a, *fp2 = *b;
    613  int r;
    614  if ((r = fast_memcmp(fp1->first, fp2->first, DIGEST_LEN)))
    615    return r;
    616  else
    617    return fast_memcmp(fp1->second, fp2->second, DIGEST_LEN);
    618 }
    619 
    620 /** Divide a string <b>res</b> of the form FP1-FP2+FP3-FP4...[.z], where each
    621 * FP is a hex-encoded fingerprint, into a sequence of distinct sorted
    622 * fp_pair_t. Skip malformed pairs. On success, return 0 and add those
    623 * fp_pair_t into <b>pairs_out</b>.  On failure, return -1. */
    624 int
    625 dir_split_resource_into_fingerprint_pairs(const char *res,
    626                                          smartlist_t *pairs_out)
    627 {
    628  smartlist_t *pairs_tmp = smartlist_new();
    629  smartlist_t *pairs_result = smartlist_new();
    630 
    631  smartlist_split_string(pairs_tmp, res, "+", 0, 0);
    632  if (smartlist_len(pairs_tmp)) {
    633    char *last = smartlist_get(pairs_tmp,smartlist_len(pairs_tmp)-1);
    634    size_t last_len = strlen(last);
    635    if (last_len > 2 && !strcmp(last+last_len-2, ".z")) {
    636      last[last_len-2] = '\0';
    637    }
    638  }
    639  SMARTLIST_FOREACH_BEGIN(pairs_tmp, char *, cp) {
    640    if (strlen(cp) != HEX_DIGEST_LEN*2+1) {
    641      log_info(LD_DIR,
    642             "Skipping digest pair %s with non-standard length.", escaped(cp));
    643    } else if (cp[HEX_DIGEST_LEN] != '-') {
    644      log_info(LD_DIR,
    645             "Skipping digest pair %s with missing dash.", escaped(cp));
    646    } else {
    647      fp_pair_t pair;
    648      if (base16_decode(pair.first, DIGEST_LEN,
    649                        cp, HEX_DIGEST_LEN) != DIGEST_LEN ||
    650          base16_decode(pair.second,DIGEST_LEN,
    651                        cp+HEX_DIGEST_LEN+1, HEX_DIGEST_LEN) != DIGEST_LEN) {
    652        log_info(LD_DIR, "Skipping non-decodable digest pair %s", escaped(cp));
    653      } else {
    654        smartlist_add(pairs_result, tor_memdup(&pair, sizeof(pair)));
    655      }
    656    }
    657    tor_free(cp);
    658  } SMARTLIST_FOREACH_END(cp);
    659  smartlist_free(pairs_tmp);
    660 
    661  /* Uniq-and-sort */
    662  smartlist_sort(pairs_result, compare_pairs_);
    663  smartlist_uniq(pairs_result, compare_pairs_, tor_free_);
    664 
    665  smartlist_add_all(pairs_out, pairs_result);
    666  smartlist_free(pairs_result);
    667  return 0;
    668 }
    669 
    670 /** Given a directory <b>resource</b> request, containing zero
    671 * or more strings separated by plus signs, followed optionally by ".z", store
    672 * the strings, in order, into <b>fp_out</b>.  If <b>compressed_out</b> is
    673 * non-NULL, set it to 1 if the resource ends in ".z", else set it to 0.
    674 *
    675 * If (flags & DSR_HEX), then delete all elements that aren't hex digests, and
    676 * decode the rest.  If (flags & DSR_BASE64), then use "-" rather than "+" as
    677 * a separator, delete all the elements that aren't base64-encoded digests,
    678 * and decode the rest.  If (flags & DSR_DIGEST256), these digests should be
    679 * 256 bits long; else they should be 160.
    680 *
    681 * If (flags & DSR_SORT_UNIQ), then sort the list and remove all duplicates.
    682 */
    683 int
    684 dir_split_resource_into_fingerprints(const char *resource,
    685                                     smartlist_t *fp_out, int *compressed_out,
    686                                     int flags)
    687 {
    688  const int decode_hex = flags & DSR_HEX;
    689  const int decode_base64 = flags & DSR_BASE64;
    690  const int digests_are_256 = flags & DSR_DIGEST256;
    691  const int sort_uniq = flags & DSR_SORT_UNIQ;
    692 
    693  const int digest_len = digests_are_256 ? DIGEST256_LEN : DIGEST_LEN;
    694  const int hex_digest_len = digests_are_256 ?
    695    HEX_DIGEST256_LEN : HEX_DIGEST_LEN;
    696  const int base64_digest_len = digests_are_256 ?
    697    BASE64_DIGEST256_LEN : BASE64_DIGEST_LEN;
    698  smartlist_t *fp_tmp = smartlist_new();
    699 
    700  tor_assert(!(decode_hex && decode_base64));
    701  tor_assert(fp_out);
    702 
    703  smartlist_split_string(fp_tmp, resource, decode_base64?"-":"+", 0, 0);
    704  if (compressed_out)
    705    *compressed_out = 0;
    706  if (smartlist_len(fp_tmp)) {
    707    char *last = smartlist_get(fp_tmp,smartlist_len(fp_tmp)-1);
    708    size_t last_len = strlen(last);
    709    if (last_len > 2 && !strcmp(last+last_len-2, ".z")) {
    710      last[last_len-2] = '\0';
    711      if (compressed_out)
    712        *compressed_out = 1;
    713    }
    714  }
    715  if (decode_hex || decode_base64) {
    716    const size_t encoded_len = decode_hex ? hex_digest_len : base64_digest_len;
    717    int i;
    718    char *cp, *d = NULL;
    719    for (i = 0; i < smartlist_len(fp_tmp); ++i) {
    720      cp = smartlist_get(fp_tmp, i);
    721      if (strlen(cp) != encoded_len) {
    722        log_info(LD_DIR,
    723                 "Skipping digest %s with non-standard length.", escaped(cp));
    724        smartlist_del_keeporder(fp_tmp, i--);
    725        goto again;
    726      }
    727      d = tor_malloc_zero(digest_len);
    728      if (decode_hex ?
    729          (base16_decode(d, digest_len, cp, hex_digest_len) != digest_len) :
    730          (base64_decode(d, digest_len, cp, base64_digest_len)
    731                         != digest_len)) {
    732          log_info(LD_DIR, "Skipping non-decodable digest %s", escaped(cp));
    733          smartlist_del_keeporder(fp_tmp, i--);
    734          goto again;
    735      }
    736      smartlist_set(fp_tmp, i, d);
    737      d = NULL;
    738    again:
    739      tor_free(cp);
    740      tor_free(d);
    741    }
    742  }
    743  if (sort_uniq) {
    744    if (decode_hex || decode_base64) {
    745      if (digests_are_256) {
    746        smartlist_sort_digests256(fp_tmp);
    747        smartlist_uniq_digests256(fp_tmp);
    748      } else {
    749        smartlist_sort_digests(fp_tmp);
    750        smartlist_uniq_digests(fp_tmp);
    751      }
    752    } else {
    753      smartlist_sort_strings(fp_tmp);
    754      smartlist_uniq_strings(fp_tmp);
    755    }
    756  }
    757  smartlist_add_all(fp_out, fp_tmp);
    758  smartlist_free(fp_tmp);
    759  return 0;
    760 }