diff options
Diffstat (limited to 'src/feature/dirclient')
-rw-r--r-- | src/feature/dirclient/.may_include | 1 | ||||
-rw-r--r-- | src/feature/dirclient/dir_server_st.h | 15 | ||||
-rw-r--r-- | src/feature/dirclient/dirclient.c | 423 | ||||
-rw-r--r-- | src/feature/dirclient/dirclient.h | 8 | ||||
-rw-r--r-- | src/feature/dirclient/dirclient_modes.c | 92 | ||||
-rw-r--r-- | src/feature/dirclient/dirclient_modes.h | 24 | ||||
-rw-r--r-- | src/feature/dirclient/dlstatus.c | 7 | ||||
-rw-r--r-- | src/feature/dirclient/dlstatus.h | 4 | ||||
-rw-r--r-- | src/feature/dirclient/download_status_st.h | 10 | ||||
-rw-r--r-- | src/feature/dirclient/feature_dirclient.md | 7 | ||||
-rw-r--r-- | src/feature/dirclient/include.am | 14 |
11 files changed, 390 insertions, 215 deletions
diff --git a/src/feature/dirclient/.may_include b/src/feature/dirclient/.may_include new file mode 100644 index 0000000000..424c745c12 --- /dev/null +++ b/src/feature/dirclient/.may_include @@ -0,0 +1 @@ +*.h diff --git a/src/feature/dirclient/dir_server_st.h b/src/feature/dirclient/dir_server_st.h index 2f5706cdd9..57530a571b 100644 --- a/src/feature/dirclient/dir_server_st.h +++ b/src/feature/dirclient/dir_server_st.h @@ -1,9 +1,14 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ +/** + * @file dir_server_st.h + * @brief Trusted/fallback directory server structure. + **/ + #ifndef DIR_SERVER_ST_H #define DIR_SERVER_ST_H @@ -19,10 +24,10 @@ struct dir_server_t { char *address; /**< Hostname. */ /* XX/teor - why do we duplicate the address and port fields here and in * fake_status? Surely we could just use fake_status (#17867). */ + tor_addr_t ipv4_addr; + uint16_t ipv4_dirport; /**< Directory port. */ + uint16_t ipv4_orport; /**< OR port: Used for tunneling connections. */ tor_addr_t ipv6_addr; /**< IPv6 address if present; AF_UNSPEC if not */ - uint32_t addr; /**< IPv4 address. */ - uint16_t dir_port; /**< Directory port. */ - uint16_t or_port; /**< OR port: Used for tunneling connections. */ uint16_t ipv6_orport; /**< OR port corresponding to ipv6_addr. */ double weight; /** Weight used when selecting this node at random */ char digest[DIGEST_LEN]; /**< Digest of identity key. */ @@ -51,4 +56,4 @@ struct dir_server_t { **/ }; -#endif +#endif /* !defined(DIR_SERVER_ST_H) */ diff --git a/src/feature/dirclient/dirclient.c b/src/feature/dirclient/dirclient.c index 6725fc3369..a5dd856729 100644 --- a/src/feature/dirclient/dirclient.c +++ b/src/feature/dirclient/dirclient.c @@ -1,8 +1,13 @@ /* Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ +/** + * @file dirclient.c + * @brief Download directory information + **/ + #define DIRCLIENT_PRIVATE #include "core/or/or.h" @@ -14,12 +19,14 @@ #include "core/or/policies.h" #include "feature/client/bridges.h" #include "feature/client/entrynodes.h" -#include "feature/control/control.h" +#include "feature/control/control_events.h" #include "feature/dirauth/authmode.h" +#include "feature/dirclient/dirclient.h" #include "feature/dirauth/dirvote.h" #include "feature/dirauth/shared_random.h" #include "feature/dircache/dirserv.h" #include "feature/dirclient/dirclient.h" +#include "feature/dirclient/dirclient_modes.h" #include "feature/dirclient/dlstatus.h" #include "feature/dircommon/consdiff.h" #include "feature/dircommon/directory.h" @@ -37,6 +44,7 @@ #include "feature/nodelist/routerinfo.h" #include "feature/nodelist/routerlist.h" #include "feature/nodelist/routerset.h" +#include "feature/relay/relay_find_addr.h" #include "feature/relay/routermode.h" #include "feature/relay/selftest.h" #include "feature/rend/rendcache.h" @@ -45,6 +53,7 @@ #include "feature/rend/rendservice.h" #include "feature/stats/predict_ports.h" +#include "lib/cc/ctassert.h" #include "lib/compress/compress.h" #include "lib/crypt_ops/crypto_format.h" #include "lib/crypt_ops/crypto_util.h" @@ -275,10 +284,10 @@ directory_post_to_dirservers(uint8_t dir_purpose, uint8_t router_purpose, } if (purpose_needs_anonymity(dir_purpose, router_purpose, NULL)) { indirection = DIRIND_ANONYMOUS; - } else if (!fascist_firewall_allows_dir_server(ds, + } else if (!reachable_addr_allows_dir_server(ds, FIREWALL_DIR_CONNECTION, 0)) { - if (fascist_firewall_allows_dir_server(ds, FIREWALL_OR_CONNECTION, 0)) + if (reachable_addr_allows_dir_server(ds, FIREWALL_OR_CONNECTION, 0)) indirection = DIRIND_ONEHOP; else indirection = DIRIND_ANONYMOUS; @@ -448,7 +457,7 @@ directory_get_from_dirserver,( { const routerstatus_t *rs = NULL; const or_options_t *options = get_options(); - int prefer_authority = (directory_fetches_from_authorities(options) + int prefer_authority = (dirclient_fetches_from_authorities(options) || want_authority == DL_WANT_AUTHORITY); int require_authority = 0; int get_via_tor = purpose_needs_anonymity(dir_purpose, router_purpose, @@ -478,7 +487,7 @@ directory_get_from_dirserver,( tor_addr_port_t or_ap; directory_request_t *req = directory_request_new(dir_purpose); /* we are willing to use a non-preferred address if we need to */ - fascist_firewall_choose_address_node(node, FIREWALL_OR_CONNECTION, 0, + reachable_addr_choose_from_node(node, FIREWALL_OR_CONNECTION, 0, &or_ap); directory_request_set_or_addr_port(req, &or_ap); directory_request_set_directory_id_digest(req, @@ -645,11 +654,11 @@ directory_choose_address_routerstatus(const routerstatus_t *status, /* ORPort connections */ if (indirection == DIRIND_ANONYMOUS) { - if (status->addr) { + if (!tor_addr_is_null(&status->ipv4_addr)) { /* Since we're going to build a 3-hop circuit and ask the 2nd relay * to extend to this address, always use the primary (IPv4) OR address */ - tor_addr_from_ipv4h(&use_or_ap->addr, status->addr); - use_or_ap->port = status->or_port; + tor_addr_copy(&use_or_ap->addr, &status->ipv4_addr); + use_or_ap->port = status->ipv4_orport; have_or = 1; } } else if (indirection == DIRIND_ONEHOP) { @@ -657,7 +666,7 @@ directory_choose_address_routerstatus(const routerstatus_t *status, * Use the preferred address and port if they are reachable, otherwise, * use the alternate address and port (if any). */ - fascist_firewall_choose_address_rs(status, FIREWALL_OR_CONNECTION, 0, + reachable_addr_choose_from_rs(status, FIREWALL_OR_CONNECTION, 0, use_or_ap); have_or = tor_addr_port_is_valid_ap(use_or_ap, 0); } @@ -667,8 +676,8 @@ directory_choose_address_routerstatus(const routerstatus_t *status, if (indirection == DIRIND_DIRECT_CONN || indirection == DIRIND_ANON_DIRPORT || (indirection == DIRIND_ONEHOP - && !directory_must_use_begindir(options))) { - fascist_firewall_choose_address_rs(status, FIREWALL_DIR_CONNECTION, 0, + && !dirclient_must_use_begindir(options))) { + reachable_addr_choose_from_rs(status, FIREWALL_DIR_CONNECTION, 0, use_dir_ap); have_dir = tor_addr_port_is_valid_ap(use_dir_ap, 0); } @@ -677,12 +686,14 @@ directory_choose_address_routerstatus(const routerstatus_t *status, * connect to it. */ if (!have_or && !have_dir) { static int logged_backtrace = 0; + char *ipv6_str = tor_addr_to_str_dup(&status->ipv6_addr); log_info(LD_BUG, "Rejected all OR and Dir addresses from %s when " "launching an outgoing directory connection to: IPv4 %s OR %d " "Dir %d IPv6 %s OR %d Dir %d", routerstatus_describe(status), - fmt_addr32(status->addr), status->or_port, - status->dir_port, fmt_addr(&status->ipv6_addr), - status->ipv6_orport, status->dir_port); + fmt_addr(&status->ipv4_addr), status->ipv4_orport, + status->ipv4_dirport, ipv6_str, status->ipv6_orport, + status->ipv4_dirport); + tor_free(ipv6_str); if (!logged_backtrace) { log_backtrace(LOG_INFO, LD_BUG, "Addresses came from"); logged_backtrace = 1; @@ -704,8 +715,8 @@ directory_conn_is_self_reachability_test(dir_connection_t *conn) const routerinfo_t *me = router_get_my_routerinfo(); if (me && router_digest_is_me(conn->identity_digest) && - tor_addr_eq_ipv4h(&conn->base_.addr, me->addr) && /*XXXX prop 118*/ - me->dir_port == conn->base_.port) + tor_addr_eq(&TO_CONN(conn)->addr, &me->ipv4_addr) && + me->ipv4_dirport == conn->base_.port) return 1; } return 0; @@ -731,8 +742,8 @@ connection_dir_client_request_failed(dir_connection_t *conn) if (conn->base_.purpose == DIR_PURPOSE_FETCH_SERVERDESC || conn->base_.purpose == DIR_PURPOSE_FETCH_EXTRAINFO) { log_info(LD_DIR, "Giving up on serverdesc/extrainfo fetch from " - "directory server at '%s'; retrying", - conn->base_.address); + "directory server at %s; retrying", + connection_describe_peer(TO_CONN(conn))); if (conn->router_purpose == ROUTER_PURPOSE_BRIDGE) connection_dir_bridge_routerdesc_failed(conn); connection_dir_download_routerdesc_failed(conn); @@ -741,18 +752,19 @@ connection_dir_client_request_failed(dir_connection_t *conn) networkstatus_consensus_download_failed(0, conn->requested_resource); } else if (conn->base_.purpose == DIR_PURPOSE_FETCH_CERTIFICATE) { log_info(LD_DIR, "Giving up on certificate fetch from directory server " - "at '%s'; retrying", - conn->base_.address); + "at %s; retrying", + connection_describe_peer(TO_CONN(conn))); connection_dir_download_cert_failed(conn, 0); } else if (conn->base_.purpose == DIR_PURPOSE_FETCH_DETACHED_SIGNATURES) { - log_info(LD_DIR, "Giving up downloading detached signatures from '%s'", - conn->base_.address); + log_info(LD_DIR, "Giving up downloading detached signatures from %s", + connection_describe_peer(TO_CONN(conn))); } else if (conn->base_.purpose == DIR_PURPOSE_FETCH_STATUS_VOTE) { - log_info(LD_DIR, "Giving up downloading votes from '%s'", - conn->base_.address); + log_info(LD_DIR, "Giving up downloading votes from %s", + connection_describe_peer(TO_CONN(conn))); } else if (conn->base_.purpose == DIR_PURPOSE_FETCH_MICRODESC) { log_info(LD_DIR, "Giving up on downloading microdescriptors from " - "directory server at '%s'; will retry", conn->base_.address); + "directory server at %s; will retry", + connection_describe_peer(TO_CONN(conn))); connection_dir_download_routerdesc_failed(conn); } } @@ -866,16 +878,6 @@ connection_dir_download_cert_failed(dir_connection_t *conn, int status) update_certificate_downloads(time(NULL)); } -/* Should this tor instance only use begindir for all its directory requests? - */ -int -directory_must_use_begindir(const or_options_t *options) -{ - /* Clients, onion services, and bridges must use begindir, - * relays and authorities do not have to */ - return !public_server_mode(options); -} - /** Evaluate the situation and decide if we should use an encrypted * "begindir-style" connection for this directory request. * 0) If there is no DirPort, yes. @@ -919,7 +921,7 @@ directory_command_should_use_begindir(const or_options_t *options, } if (indirection == DIRIND_ONEHOP) { /* We're firewalled and want a direct OR connection */ - if (!fascist_firewall_allows_address_addr(or_addr, or_port, + if (!reachable_addr_allows_addr(or_addr, or_port, FIREWALL_OR_CONNECTION, 0, 0)) { *reason = "ORPort not reachable"; return 0; @@ -927,7 +929,7 @@ directory_command_should_use_begindir(const or_options_t *options, } /* Reasons why we want to avoid using begindir */ if (indirection == DIRIND_ONEHOP) { - if (!directory_must_use_begindir(options)) { + if (!dirclient_must_use_begindir(options)) { *reason = "in relay mode"; return 0; } @@ -1289,7 +1291,7 @@ directory_initiate_request,(directory_request_t *request)) /* use encrypted begindir connections for everything except relays * this provides better protection for directory fetches */ - if (!use_begindir && directory_must_use_begindir(options)) { + if (!use_begindir && dirclient_must_use_begindir(options)) { log_warn(LD_BUG, "Client could not use begindir connection: %s", begindir_reason ? begindir_reason : "(NULL)"); return; @@ -1447,9 +1449,7 @@ compare_strs_(const void **a, const void **b) } #define CONDITIONAL_CONSENSUS_FPR_LEN 3 -#if (CONDITIONAL_CONSENSUS_FPR_LEN > DIGEST_LEN) -#error "conditional consensus fingerprint length is larger than digest length" -#endif +CTASSERT(CONDITIONAL_CONSENSUS_FPR_LEN <= DIGEST_LEN); /** Return the URL we should use for a consensus download. * @@ -1757,10 +1757,10 @@ directory_send_command(dir_connection_t *conn, smartlist_free(headers); log_debug(LD_DIR, - "Sent request to directory server '%s:%d': " + "Sent request to directory server %s " "(purpose: %d, request size: %"TOR_PRIuSZ", " "payload size: %"TOR_PRIuSZ")", - conn->base_.address, conn->base_.port, + connection_describe_peer(TO_CONN(conn)), conn->base_.purpose, (total_request_len), (payload ? payload_len : 0)); @@ -1896,9 +1896,10 @@ dir_client_decompress_response_body(char **bodyp, size_t *bodylenp, } tor_log(severity, LD_HTTP, - "HTTP body from server '%s:%d' was labeled as %s, " + "HTTP body from %s was labeled as %s, " "%s it seems to be %s.%s", - conn->base_.address, conn->base_.port, description1, + connection_describe(TO_CONN(conn)), + description1, guessed != compression?"but":"and", description2, (compression>0 && guessed>0 && want_to_try_both)? @@ -1944,11 +1945,11 @@ dir_client_decompress_response_body(char **bodyp, size_t *bodylenp, * we didn't manage to uncompress it, then warn and bail. */ if (!plausible && !new_body) { log_fn(LOG_PROTOCOL_WARN, LD_HTTP, - "Unable to decompress HTTP body (tried %s%s%s, server '%s:%d').", + "Unable to decompress HTTP body (tried %s%s%s, on %s).", description1, tried_both?" and ":"", tried_both?description2:"", - conn->base_.address, conn->base_.port); + connection_describe(TO_CONN(conn))); rv = -1; goto done; } @@ -1968,6 +1969,48 @@ dir_client_decompress_response_body(char **bodyp, size_t *bodylenp, return rv; } +/** + * Total number of bytes downloaded of each directory purpose, when + * bootstrapped, and when not bootstrapped. + * + * (For example, the number of bytes downloaded of purpose p while + * not fully bootstrapped is total_dl[p][false].) + **/ +static uint64_t total_dl[DIR_PURPOSE_MAX_][2]; + +/** + * Heartbeat: dump a summary of how many bytes of which purpose we've + * downloaded, when bootstrapping and when not bootstrapping. + **/ +void +dirclient_dump_total_dls(void) +{ + const or_options_t *options = get_options(); + for (int bootstrapped = 0; bootstrapped < 2; ++bootstrapped) { + smartlist_t *lines = smartlist_new(); + for (int i=0; i < DIR_PURPOSE_MAX_; ++i) { + uint64_t n = total_dl[i][bootstrapped]; + if (n == 0) + continue; + if (options->SafeLogging_ != SAFELOG_SCRUB_NONE && + purpose_needs_anonymity(i, ROUTER_PURPOSE_GENERAL, NULL)) + continue; + smartlist_add_asprintf(lines, "%"PRIu64" (%s)", + n, dir_conn_purpose_to_string(i)); + } + + if (smartlist_len(lines) > 0) { + char *log_line = smartlist_join_strings(lines, "; ", 0, NULL); + log_notice(LD_NET, "While %sbootstrapping, fetched this many bytes: %s", + bootstrapped?"not ":"", log_line); + tor_free(log_line); + + SMARTLIST_FOREACH(lines, char *, s, tor_free(s)); + } + smartlist_free(lines); + } +} + /** We are a client, and we've finished reading the server's * response. Parse it and act appropriately. * @@ -2001,14 +2044,24 @@ connection_dir_client_reached_eof(dir_connection_t *conn) received_bytes = connection_get_inbuf_len(TO_CONN(conn)); + log_debug(LD_DIR, "Downloaded %"TOR_PRIuSZ" bytes on connection of purpose " + "%s; bootstrap %d%%", + received_bytes, + dir_conn_purpose_to_string(conn->base_.purpose), + control_get_bootstrap_percent()); + { + bool bootstrapped = control_get_bootstrap_percent() == 100; + total_dl[conn->base_.purpose][bootstrapped] += received_bytes; + } + switch (connection_fetch_from_buf_http(TO_CONN(conn), &headers, MAX_HEADERS_SIZE, &body, &body_len, MAX_DIR_DL_SIZE, allow_partial)) { case -1: /* overflow */ log_warn(LD_PROTOCOL, - "'fetch' response too large (server '%s:%d'). Closing.", - conn->base_.address, conn->base_.port); + "'fetch' response too large (%s). Closing.", + connection_describe(TO_CONN(conn))); return -1; case 0: log_info(LD_HTTP, @@ -2019,22 +2072,22 @@ connection_dir_client_reached_eof(dir_connection_t *conn) if (parse_http_response(headers, &status_code, &date_header, &compression, &reason) < 0) { - log_warn(LD_HTTP,"Unparseable headers (server '%s:%d'). Closing.", - conn->base_.address, conn->base_.port); - + log_warn(LD_HTTP,"Unparseable headers (%s). Closing.", + connection_describe(TO_CONN(conn))); rv = -1; goto done; } if (!reason) reason = tor_strdup("[no reason given]"); tor_log(LOG_DEBUG, LD_DIR, - "Received response from directory server '%s:%d': %d %s " + "Received response on %s: %d %s " "(purpose: %d, response size: %"TOR_PRIuSZ #ifdef MEASUREMENTS_21206 ", data cells received: %d, data cells sent: %d" #endif ", compression: %d)", - conn->base_.address, conn->base_.port, status_code, + connection_describe(TO_CONN(conn)), + status_code, escaped(reason), conn->base_.purpose, (received_bytes), #ifdef MEASUREMENTS_21206 @@ -2059,7 +2112,13 @@ connection_dir_client_reached_eof(dir_connection_t *conn) if (conn->dirconn_direct) { char *guess = http_get_header(headers, X_ADDRESS_HEADER); if (guess) { - router_new_address_suggestion(guess, conn); + tor_addr_t addr; + if (tor_addr_parse(&addr, guess) < 0) { + log_debug(LD_DIR, "Malformed X-Your-Address-Is header %s. Ignoring.", + escaped(guess)); + } else { + relay_address_new_suggestion(&addr, &TO_CONN(conn)->addr, NULL); + } tor_free(guess); } } @@ -2088,9 +2147,9 @@ connection_dir_client_reached_eof(dir_connection_t *conn) dir_server_t *ds; const char *id_digest = conn->identity_digest; log_info(LD_DIR,"Received http status code %d (%s) from server " - "'%s:%d'. I'll try again soon.", - status_code, escaped(reason), conn->base_.address, - conn->base_.port); + "%s. I'll try again soon.", + status_code, escaped(reason), + connection_describe_peer(TO_CONN(conn))); time_t now = approx_time(); if ((rs = router_get_mutable_consensus_status_by_id(id_digest))) rs->last_dir_503_at = now; @@ -2195,9 +2254,9 @@ handle_response_fetch_consensus(dir_connection_t *conn, int severity = (status_code == 304) ? LOG_INFO : LOG_WARN; tor_log(severity, LD_DIR, "Received http status code %d (%s) from server " - "'%s:%d' while fetching consensus directory.", - status_code, escaped(reason), conn->base_.address, - conn->base_.port); + "%s while fetching consensus directory.", + status_code, escaped(reason), + connection_describe_peer(TO_CONN(conn))); networkstatus_consensus_download_failed(status_code, flavname); return -1; } @@ -2205,51 +2264,61 @@ handle_response_fetch_consensus(dir_connection_t *conn, if (looks_like_a_consensus_diff(body, body_len)) { /* First find our previous consensus. Maybe it's in ram, maybe not. */ cached_dir_t *cd = dirserv_get_consensus(flavname); - const char *consensus_body; - char *owned_consensus = NULL; + const char *consensus_body = NULL; + size_t consensus_body_len; + tor_mmap_t *mapped_consensus = NULL; if (cd) { consensus_body = cd->dir; + consensus_body_len = cd->dir_len; } else { - owned_consensus = networkstatus_read_cached_consensus(flavname); - consensus_body = owned_consensus; + mapped_consensus = networkstatus_map_cached_consensus(flavname); + if (mapped_consensus) { + consensus_body = mapped_consensus->data; + consensus_body_len = mapped_consensus->size; + } } if (!consensus_body) { log_warn(LD_DIR, "Received a consensus diff, but we can't find " "any %s-flavored consensus in our current cache.",flavname); + tor_munmap_file(mapped_consensus); networkstatus_consensus_download_failed(0, flavname); // XXXX if this happens too much, see below return -1; } - new_consensus = consensus_diff_apply(consensus_body, body); - tor_free(owned_consensus); + new_consensus = consensus_diff_apply(consensus_body, consensus_body_len, + body, body_len); + tor_munmap_file(mapped_consensus); if (new_consensus == NULL) { log_warn(LD_DIR, "Could not apply consensus diff received from server " - "'%s:%d'", conn->base_.address, conn->base_.port); + "%s", connection_describe_peer(TO_CONN(conn))); // XXXX If this happens too many times, we should maybe not use // XXXX this directory for diffs any more? networkstatus_consensus_download_failed(0, flavname); return -1; } log_info(LD_DIR, "Applied consensus diff (size %d) from server " - "'%s:%d', resulting in a new consensus document (size %d).", - (int)body_len, conn->base_.address, conn->base_.port, + "%s, resulting in a new consensus document (size %d).", + (int)body_len, connection_describe_peer(TO_CONN(conn)), (int)strlen(new_consensus)); consensus = new_consensus; sourcename = "generated based on a diff"; } else { log_info(LD_DIR,"Received consensus directory (body size %d) from server " - "'%s:%d'", (int)body_len, conn->base_.address, conn->base_.port); + "%s", (int)body_len, connection_describe_peer(TO_CONN(conn))); consensus = body; sourcename = "downloaded"; } - if ((r=networkstatus_set_current_consensus(consensus, flavname, 0, + if ((r=networkstatus_set_current_consensus(consensus, + strlen(consensus), + flavname, 0, conn->identity_digest))<0) { log_fn(r<-1?LOG_WARN:LOG_INFO, LD_DIR, "Unable to load %s consensus directory %s from " - "server '%s:%d'. I'll try again soon.", - flavname, sourcename, conn->base_.address, conn->base_.port); + "server %s. I'll try again soon.", + flavname, sourcename, + connection_describe_peer(TO_CONN(conn))); networkstatus_consensus_download_failed(0, flavname); tor_free(new_consensus); return -1; @@ -2290,15 +2359,16 @@ handle_response_fetch_certificate(dir_connection_t *conn, if (status_code != 200) { log_warn(LD_DIR, "Received http status code %d (%s) from server " - "'%s:%d' while fetching \"/tor/keys/%s\".", - status_code, escaped(reason), conn->base_.address, - conn->base_.port, conn->requested_resource); + "%s while fetching \"/tor/keys/%s\".", + status_code, escaped(reason), + connection_describe_peer(TO_CONN(conn)), + conn->requested_resource); connection_dir_download_cert_failed(conn, status_code); return -1; } log_info(LD_DIR,"Received authority certificates (body size %d) from " - "server '%s:%d'", - (int)body_len, conn->base_.address, conn->base_.port); + "server %s", + (int)body_len, connection_describe_peer(TO_CONN(conn))); /* * Tell trusted_dirs_load_certs_from_string() whether it was by fp @@ -2349,17 +2419,18 @@ handle_response_fetch_status_vote(dir_connection_t *conn, const char *msg; int st; - log_info(LD_DIR,"Got votes (body size %d) from server %s:%d", - (int)body_len, conn->base_.address, conn->base_.port); + log_notice(LD_DIR,"Got votes (body size %d) from server %s", + (int)body_len, connection_describe_peer(TO_CONN(conn))); if (status_code != 200) { log_warn(LD_DIR, "Received http status code %d (%s) from server " - "'%s:%d' while fetching \"/tor/status-vote/next/%s.z\".", - status_code, escaped(reason), conn->base_.address, - conn->base_.port, conn->requested_resource); + "%s while fetching \"/tor/status-vote/next/%s.z\".", + status_code, escaped(reason), + connection_describe_peer(TO_CONN(conn)), + conn->requested_resource); return -1; } - dirvote_add_vote(body, &msg, &st); + dirvote_add_vote(body, 0, TO_CONN(conn)->address, &msg, &st); if (st > 299) { log_warn(LD_DIR, "Error adding retrieved vote: %s", msg); } else { @@ -2384,19 +2455,21 @@ handle_response_fetch_detached_signatures(dir_connection_t *conn, const size_t body_len = args->body_len; const char *msg = NULL; - log_info(LD_DIR,"Got detached signatures (body size %d) from server %s:%d", - (int)body_len, conn->base_.address, conn->base_.port); + log_info(LD_DIR,"Got detached signatures (body size %d) from server %s", + (int)body_len, + connection_describe_peer(TO_CONN(conn))); if (status_code != 200) { log_warn(LD_DIR, - "Received http status code %d (%s) from server '%s:%d' while fetching " + "Received http status code %d (%s) from server %s while fetching " "\"/tor/status-vote/next/consensus-signatures.z\".", - status_code, escaped(reason), conn->base_.address, - conn->base_.port); + status_code, escaped(reason), + connection_describe_peer(TO_CONN(conn))); return -1; } if (dirvote_add_signatures(body, conn->base_.address, &msg)<0) { - log_warn(LD_DIR, "Problem adding detached signatures from %s:%d: %s", - conn->base_.address, conn->base_.port, msg?msg:"???"); + log_warn(LD_DIR, "Problem adding detached signatures from %s: %s", + connection_describe_peer(TO_CONN(conn)), + msg?msg:"???"); } return 0; @@ -2422,9 +2495,9 @@ handle_response_fetch_desc(dir_connection_t *conn, int n_asked_for = 0; int descriptor_digests = conn->requested_resource && !strcmpstart(conn->requested_resource,"d/"); - log_info(LD_DIR,"Received %s (body size %d) from server '%s:%d'", + log_info(LD_DIR,"Received %s (body size %d) from server %s", was_ei ? "extra server info" : "server info", - (int)body_len, conn->base_.address, conn->base_.port); + (int)body_len, connection_describe_peer(TO_CONN(conn))); if (conn->requested_resource && (!strcmpstart(conn->requested_resource,"d/") || !strcmpstart(conn->requested_resource,"fp/"))) { @@ -2436,14 +2509,18 @@ handle_response_fetch_desc(dir_connection_t *conn, } if (status_code != 200) { int dir_okay = status_code == 404 || - (status_code == 400 && !strcmp(reason, "Servers unavailable.")); + (status_code == 400 && !strcmp(reason, "Servers unavailable.")) || + status_code == 301; /* 404 means that it didn't have them; no big deal. - * Older (pre-0.1.1.8) servers said 400 Servers unavailable instead. */ + * Older (pre-0.1.1.8) servers said 400 Servers unavailable instead. + * 301 is considered as an error since Tor does not follow redirects, + * which means we failed to reach the server we wanted. */ log_fn(dir_okay ? LOG_INFO : LOG_WARN, LD_DIR, - "Received http status code %d (%s) from server '%s:%d' " + "Received http status code %d (%s) from server %s " "while fetching \"/tor/server/%s\". I'll try again soon.", - status_code, escaped(reason), conn->base_.address, - conn->base_.port, conn->requested_resource); + status_code, escaped(reason), + connection_describe_peer(TO_CONN(conn)), + conn->requested_resource); if (!which) { connection_dir_download_routerdesc_failed(conn); } else { @@ -2483,10 +2560,10 @@ handle_response_fetch_desc(dir_connection_t *conn, } } if (which) { /* mark remaining ones as failed */ - log_info(LD_DIR, "Received %d/%d %s requested from %s:%d", + log_info(LD_DIR, "Received %d/%d %s requested from %s", n_asked_for-smartlist_len(which), n_asked_for, was_ei ? "extra-info documents" : "router descriptors", - conn->base_.address, (int)conn->base_.port); + connection_describe_peer(TO_CONN(conn))); if (smartlist_len(which)) { dir_routerdesc_download_failed(which, status_code, conn->router_purpose, @@ -2517,22 +2594,23 @@ handle_response_fetch_microdesc(dir_connection_t *conn, smartlist_t *which = NULL; log_info(LD_DIR,"Received answer to microdescriptor request (status %d, " - "body size %d) from server '%s:%d'", - status_code, (int)body_len, conn->base_.address, - conn->base_.port); + "body size %d) from server %s", + status_code, (int)body_len, + connection_describe_peer(TO_CONN(conn))); tor_assert(conn->requested_resource && !strcmpstart(conn->requested_resource, "d/")); - tor_assert_nonfatal(!tor_mem_is_zero(conn->identity_digest, DIGEST_LEN)); + tor_assert_nonfatal(!fast_mem_is_zero(conn->identity_digest, DIGEST_LEN)); which = smartlist_new(); dir_split_resource_into_fingerprints(conn->requested_resource+2, which, NULL, DSR_DIGEST256|DSR_BASE64); if (status_code != 200) { log_info(LD_DIR, "Received status code %d (%s) from server " - "'%s:%d' while fetching \"/tor/micro/%s\". I'll try again " + "%s while fetching \"/tor/micro/%s\". I'll try again " "soon.", - status_code, escaped(reason), conn->base_.address, - (int)conn->base_.port, conn->requested_resource); + status_code, escaped(reason), + connection_describe_peer(TO_CONN(conn)), + conn->requested_resource); dir_microdesc_download_failed(which, status_code, conn->identity_digest); SMARTLIST_FOREACH(which, char *, cp, tor_free(cp)); smartlist_free(which); @@ -2607,8 +2685,8 @@ handle_response_upload_dir(dir_connection_t *conn, break; case 400: log_warn(LD_GENERAL,"http status 400 (%s) response from " - "dirserver '%s:%d'. Please correct.", - escaped(reason), conn->base_.address, conn->base_.port); + "dirserver %s. Please correct.", + escaped(reason), connection_describe_peer(TO_CONN(conn))); control_event_server_status(LOG_WARN, "BAD_SERVER_DESCRIPTOR DIRAUTH=%s:%d REASON=\"%s\"", conn->base_.address, conn->base_.port, escaped(reason)); @@ -2616,10 +2694,10 @@ handle_response_upload_dir(dir_connection_t *conn, default: log_warn(LD_GENERAL, "HTTP status %d (%s) was unexpected while uploading " - "descriptor to server '%s:%d'. Possibly the server is " + "descriptor to server %s'. Possibly the server is " "misconfigured?", - status_code, escaped(reason), conn->base_.address, - conn->base_.port); + status_code, escaped(reason), + connection_describe_peer(TO_CONN(conn))); break; } /* return 0 in all cases, since we don't want to mark any @@ -2642,21 +2720,21 @@ handle_response_upload_vote(dir_connection_t *conn, switch (status_code) { case 200: { - log_notice(LD_DIR,"Uploaded a vote to dirserver %s:%d", - conn->base_.address, conn->base_.port); + log_notice(LD_DIR,"Uploaded my vote to dirserver %s", + connection_describe_peer(TO_CONN(conn))); } break; case 400: log_warn(LD_DIR,"http status 400 (%s) response after uploading " - "vote to dirserver '%s:%d'. Please correct.", - escaped(reason), conn->base_.address, conn->base_.port); + "vote to dirserver %s. Please correct.", + escaped(reason), connection_describe_peer(TO_CONN(conn))); break; default: log_warn(LD_GENERAL, "HTTP status %d (%s) was unexpected while uploading " - "vote to server '%s:%d'.", - status_code, escaped(reason), conn->base_.address, - conn->base_.port); + "vote to server %s.", + status_code, escaped(reason), + connection_describe_peer(TO_CONN(conn))); break; } /* return 0 in all cases, since we don't want to mark any @@ -2678,21 +2756,21 @@ handle_response_upload_signatures(dir_connection_t *conn, switch (status_code) { case 200: { - log_notice(LD_DIR,"Uploaded signature(s) to dirserver %s:%d", - conn->base_.address, conn->base_.port); + log_notice(LD_DIR,"Uploaded signature(s) to dirserver %s", + connection_describe_peer(TO_CONN(conn))); } break; case 400: log_warn(LD_DIR,"http status 400 (%s) response after uploading " - "signatures to dirserver '%s:%d'. Please correct.", - escaped(reason), conn->base_.address, conn->base_.port); + "signatures to dirserver %s. Please correct.", + escaped(reason), connection_describe_peer(TO_CONN(conn))); break; default: log_warn(LD_GENERAL, "HTTP status %d (%s) was unexpected while uploading " - "signatures to server '%s:%d'.", - status_code, escaped(reason), conn->base_.address, - conn->base_.port); + "signatures to server %s.", + status_code, escaped(reason), + connection_describe_peer(TO_CONN(conn))); break; } /* return 0 in all cases, since we don't want to mark any @@ -2719,62 +2797,7 @@ handle_response_fetch_hsdesc_v3(dir_connection_t *conn, log_info(LD_REND,"Received v3 hsdesc (body size %d, status %d (%s))", (int)body_len, status_code, escaped(reason)); - switch (status_code) { - case 200: - /* We got something: Try storing it in the cache. */ - if (hs_cache_store_as_client(body, &conn->hs_ident->identity_pk) < 0) { - log_info(LD_REND, "Failed to store hidden service descriptor"); - /* Fire control port FAILED event. */ - hs_control_desc_event_failed(conn->hs_ident, conn->identity_digest, - "BAD_DESC"); - hs_control_desc_event_content(conn->hs_ident, conn->identity_digest, - NULL); - } else { - log_info(LD_REND, "Stored hidden service descriptor successfully."); - TO_CONN(conn)->purpose = DIR_PURPOSE_HAS_FETCHED_HSDESC; - hs_client_desc_has_arrived(conn->hs_ident); - /* Fire control port RECEIVED event. */ - hs_control_desc_event_received(conn->hs_ident, conn->identity_digest); - hs_control_desc_event_content(conn->hs_ident, conn->identity_digest, - body); - } - break; - case 404: - /* Not there. We'll retry when connection_about_to_close_connection() - * tries to clean this conn up. */ - log_info(LD_REND, "Fetching hidden service v3 descriptor not found: " - "Retrying at another directory."); - /* Fire control port FAILED event. */ - hs_control_desc_event_failed(conn->hs_ident, conn->identity_digest, - "NOT_FOUND"); - hs_control_desc_event_content(conn->hs_ident, conn->identity_digest, - NULL); - break; - case 400: - log_warn(LD_REND, "Fetching v3 hidden service descriptor failed: " - "http status 400 (%s). Dirserver didn't like our " - "query? Retrying at another directory.", - escaped(reason)); - /* Fire control port FAILED event. */ - hs_control_desc_event_failed(conn->hs_ident, conn->identity_digest, - "QUERY_REJECTED"); - hs_control_desc_event_content(conn->hs_ident, conn->identity_digest, - NULL); - break; - default: - log_warn(LD_REND, "Fetching v3 hidden service descriptor failed: " - "http status %d (%s) response unexpected from HSDir server " - "'%s:%d'. Retrying at another directory.", - status_code, escaped(reason), TO_CONN(conn)->address, - TO_CONN(conn)->port); - /* Fire control port FAILED event. */ - hs_control_desc_event_failed(conn->hs_ident, conn->identity_digest, - "UNEXPECTED"); - hs_control_desc_event_content(conn->hs_ident, conn->identity_digest, - NULL); - break; - } - + hs_client_dir_fetch_done(conn, reason, body, status_code); return 0; } @@ -2862,10 +2885,10 @@ handle_response_fetch_renddesc_v2(dir_connection_t *conn, default: log_warn(LD_REND, "Fetching v2 rendezvous descriptor failed: " "http status %d (%s) response unexpected while " - "fetching v2 hidden service descriptor (server '%s:%d'). " + "fetching v2 hidden service descriptor (server %s). " "Retrying at another directory.", - status_code, escaped(reason), conn->base_.address, - conn->base_.port); + status_code, escaped(reason), + connection_describe_peer(TO_CONN(conn))); SEND_HS_DESC_FAILED_EVENT("UNEXPECTED"); SEND_HS_DESC_FAILED_CONTENT(); break; @@ -2909,15 +2932,15 @@ handle_response_upload_renddesc_v2(dir_connection_t *conn, break; case 400: log_warn(LD_REND,"http status 400 (%s) response from dirserver " - "'%s:%d'. Malformed rendezvous descriptor?", - escaped(reason), conn->base_.address, conn->base_.port); + "%s. Malformed rendezvous descriptor?", + escaped(reason), connection_describe_peer(TO_CONN(conn))); SEND_HS_DESC_UPLOAD_FAILED_EVENT("UPLOAD_REJECTED"); break; default: log_warn(LD_REND,"http status %d (%s) response unexpected (server " - "'%s:%d').", - status_code, escaped(reason), conn->base_.address, - conn->base_.port); + "%s).", + status_code, escaped(reason), + connection_describe_peer(TO_CONN(conn))); SEND_HS_DESC_UPLOAD_FAILED_EVENT("UNEXPECTED"); break; } @@ -2955,17 +2978,17 @@ handle_response_upload_hsdesc(dir_connection_t *conn, log_fn(LOG_PROTOCOL_WARN, LD_REND, "Uploading hidden service descriptor: http " "status 400 (%s) response from dirserver " - "'%s:%d'. Malformed hidden service descriptor?", - escaped(reason), conn->base_.address, conn->base_.port); + "%s. Malformed hidden service descriptor?", + escaped(reason), connection_describe_peer(TO_CONN(conn))); hs_control_desc_event_failed(conn->hs_ident, conn->identity_digest, "UPLOAD_REJECTED"); break; default: log_warn(LD_REND, "Uploading hidden service descriptor: http " "status %d (%s) response unexpected (server " - "'%s:%d').", - status_code, escaped(reason), conn->base_.address, - conn->base_.port); + "%s').", + status_code, escaped(reason), + connection_describe_peer(TO_CONN(conn))); hs_control_desc_event_failed(conn->hs_ident, conn->identity_digest, "UNEXPECTED"); break; @@ -3117,7 +3140,7 @@ connection_dir_close_consensus_fetches(dir_connection_t *except_this_one, if (d == except_this_one) continue; log_info(LD_DIR, "Closing consensus fetch (to %s) since one " - "has just arrived.", TO_CONN(d)->address); + "has just arrived.", connection_describe_peer(TO_CONN(d))); connection_mark_for_close(TO_CONN(d)); } SMARTLIST_FOREACH_END(d); smartlist_free(conns_to_close); @@ -3134,7 +3157,7 @@ dir_routerdesc_download_failed(smartlist_t *failed, int status_code, { char digest[DIGEST_LEN]; time_t now = time(NULL); - int server = directory_fetches_from_authorities(get_options()); + int server = dirclient_fetches_from_authorities(get_options()); if (!was_descriptor_digests) { if (router_purpose == ROUTER_PURPOSE_BRIDGE) { tor_assert(!was_extrainfo); @@ -3179,7 +3202,7 @@ dir_microdesc_download_failed(smartlist_t *failed, routerstatus_t *rs; download_status_t *dls; time_t now = time(NULL); - int server = directory_fetches_from_authorities(get_options()); + int server = dirclient_fetches_from_authorities(get_options()); if (! consensus) return; diff --git a/src/feature/dirclient/dirclient.h b/src/feature/dirclient/dirclient.h index 1a93265dc3..096b197526 100644 --- a/src/feature/dirclient/dirclient.h +++ b/src/feature/dirclient/dirclient.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -14,6 +14,8 @@ #include "feature/hs/hs_ident.h" +void dirclient_dump_total_dls(void); + int directories_have_accepted_server_descriptor(void); void directory_post_to_dirservers(uint8_t dir_purpose, uint8_t router_purpose, dirinfo_type_t type, const char *payload, @@ -41,8 +43,6 @@ typedef enum { DIRIND_ANON_DIRPORT, } dir_indirection_t; -int directory_must_use_begindir(const or_options_t *options); - /** * A directory_request_t describes the information about a directory request * at the client side. It describes what we're going to ask for, which @@ -167,6 +167,6 @@ STATIC int handle_response_fetch_consensus(dir_connection_t *conn, STATIC dirinfo_type_t dir_fetch_type(int dir_purpose, int router_purpose, const char *resource); -#endif +#endif /* defined(DIRCLIENT_PRIVATE) */ #endif /* !defined(TOR_DIRCLIENT_H) */ diff --git a/src/feature/dirclient/dirclient_modes.c b/src/feature/dirclient/dirclient_modes.c new file mode 100644 index 0000000000..db25196213 --- /dev/null +++ b/src/feature/dirclient/dirclient_modes.c @@ -0,0 +1,92 @@ +/* Copyright (c) 2001 Matej Pfajfar. + * Copyright (c) 2001-2004, Roger Dingledine. + * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. + * Copyright (c) 2007-2020, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +/** + * @file dirclient_modes.c + * @brief Functions to answer questions about how we'd like to behave + * as a directory client + **/ + +#include "orconfig.h" + +#include "core/or/or.h" + +#include "feature/dirclient/dirclient_modes.h" +#include "feature/dircache/dirserv.h" +#include "feature/relay/relay_find_addr.h" +#include "feature/relay/router.h" +#include "feature/relay/routermode.h" +#include "feature/stats/predict_ports.h" + +#include "app/config/or_options_st.h" +#include "feature/nodelist/routerinfo_st.h" + +/* Should this tor instance only use begindir for all its directory requests? + */ +int +dirclient_must_use_begindir(const or_options_t *options) +{ + /* Clients, onion services, and bridges must use begindir, + * relays and authorities do not have to */ + return !public_server_mode(options); +} + +/** Return 1 if we fetch our directory material directly from the + * authorities, rather than from a mirror. */ +int +dirclient_fetches_from_authorities(const or_options_t *options) +{ + const routerinfo_t *me; + int refuseunknown; + if (options->FetchDirInfoEarly) + return 1; + if (options->BridgeRelay == 1) + return 0; + refuseunknown = ! router_my_exit_policy_is_reject_star() && + should_refuse_unknown_exits(options); + if (!dir_server_mode(options) && !refuseunknown) + return 0; + if (!server_mode(options) || !advertised_server_mode()) + return 0; + me = router_get_my_routerinfo(); + if (!me || (!me->supports_tunnelled_dir_requests && !refuseunknown)) + return 0; /* if we don't service directory requests, return 0 too */ + return 1; +} + +/** Return 1 if we should fetch new networkstatuses, descriptors, etc + * on the "mirror" schedule rather than the "client" schedule. + */ +int +dirclient_fetches_dir_info_early(const or_options_t *options) +{ + return dirclient_fetches_from_authorities(options); +} + +/** Return 1 if we should fetch new networkstatuses, descriptors, etc + * on a very passive schedule -- waiting long enough for ordinary clients + * to probably have the info we want. These would include bridge users, + * and maybe others in the future e.g. if a Tor client uses another Tor + * client as a directory guard. + */ +int +dirclient_fetches_dir_info_later(const or_options_t *options) +{ + return options->UseBridges != 0; +} + +/** Return 1 if we have no need to fetch new descriptors. This generally + * happens when we're not a dir cache and we haven't built any circuits + * lately. + */ +int +dirclient_too_idle_to_fetch_descriptors(const or_options_t *options, + time_t now) +{ + return !directory_caches_dir_info(options) && + !options->FetchUselessDescriptors && + rep_hist_circbuilding_dormant(now); +} diff --git a/src/feature/dirclient/dirclient_modes.h b/src/feature/dirclient/dirclient_modes.h new file mode 100644 index 0000000000..c402207724 --- /dev/null +++ b/src/feature/dirclient/dirclient_modes.h @@ -0,0 +1,24 @@ +/* Copyright (c) 2001 Matej Pfajfar. + * Copyright (c) 2001-2004, Roger Dingledine. + * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. + * Copyright (c) 2007-2020, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +/** + * @file dirclient_modes.h + * @brief Header for feature/dirclient/dirclient_modes.c + **/ + +#ifndef TOR_FEATURE_DIRCLIENT_DIRCLIENT_MODES_H +#define TOR_FEATURE_DIRCLIENT_DIRCLIENT_MODES_H + +struct or_options_t; + +int dirclient_must_use_begindir(const or_options_t *options); +int dirclient_fetches_from_authorities(const struct or_options_t *options); +int dirclient_fetches_dir_info_early(const struct or_options_t *options); +int dirclient_fetches_dir_info_later(const struct or_options_t *options); +int dirclient_too_idle_to_fetch_descriptors(const struct or_options_t *options, + time_t now); + +#endif /* !defined(TOR_FEATURE_DIRCLIENT_DIRCLIENT_MODES_H) */ diff --git a/src/feature/dirclient/dlstatus.c b/src/feature/dirclient/dlstatus.c index 0842a2c676..ab3fbb8577 100644 --- a/src/feature/dirclient/dlstatus.c +++ b/src/feature/dirclient/dlstatus.c @@ -1,8 +1,13 @@ /* Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ +/** + * @file dlstatus.c + * @brief Track status and retry schedule of a downloadable object. + **/ + #define DLSTATUS_PRIVATE #include "core/or/or.h" diff --git a/src/feature/dirclient/dlstatus.h b/src/feature/dirclient/dlstatus.h index 99e0d0225b..e5c8b756c4 100644 --- a/src/feature/dirclient/dlstatus.h +++ b/src/feature/dirclient/dlstatus.h @@ -1,7 +1,7 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -53,6 +53,6 @@ STATIC void next_random_exponential_delay_range(int *low_bound_out, /* no more than triple the previous delay */ #define DIR_TEST_NET_RANDOM_MULTIPLIER (2) -#endif +#endif /* defined(DLSTATUS_PRIVATE) */ #endif /* !defined(TOR_DLSTATUS_H) */ diff --git a/src/feature/dirclient/download_status_st.h b/src/feature/dirclient/download_status_st.h index 11555a1dcc..92efcb44d0 100644 --- a/src/feature/dirclient/download_status_st.h +++ b/src/feature/dirclient/download_status_st.h @@ -1,9 +1,14 @@ /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ +/** + * @file download_status_st.h + * @brief Directory download status/schedule structure. + **/ + #ifndef DOWNLOAD_STATUS_ST_H #define DOWNLOAD_STATUS_ST_H @@ -61,5 +66,4 @@ struct download_status_t { * only updated if backoff == 1 */ }; -#endif - +#endif /* !defined(DOWNLOAD_STATUS_ST_H) */ diff --git a/src/feature/dirclient/feature_dirclient.md b/src/feature/dirclient/feature_dirclient.md new file mode 100644 index 0000000000..5c7ee964d3 --- /dev/null +++ b/src/feature/dirclient/feature_dirclient.md @@ -0,0 +1,7 @@ +@dir /feature/dirclient +@brief feature/dirclient: Directory client implementation. + +The code here is used by all Tor instances that need to download directory +information. Currently, that is all of them, since even authorities need to +launch downloads to learn about relays that other authorities have listed. + diff --git a/src/feature/dirclient/include.am b/src/feature/dirclient/include.am new file mode 100644 index 0000000000..24cae9eedd --- /dev/null +++ b/src/feature/dirclient/include.am @@ -0,0 +1,14 @@ + +# ADD_C_FILE: INSERT SOURCES HERE. +LIBTOR_APP_A_SOURCES += \ + src/feature/dirclient/dirclient.c \ + src/feature/dirclient/dirclient_modes.c \ + src/feature/dirclient/dlstatus.c + +# ADD_C_FILE: INSERT HEADERS HERE. +noinst_HEADERS += \ + src/feature/dirclient/dir_server_st.h \ + src/feature/dirclient/dirclient.h \ + src/feature/dirclient/dirclient_modes.h \ + src/feature/dirclient/dlstatus.h \ + src/feature/dirclient/download_status_st.h |