diff options
-rw-r--r-- | ChangeLog | 11 | ||||
-rw-r--r-- | src/common/compat.c | 19 | ||||
-rw-r--r-- | src/common/container.h | 4 | ||||
-rw-r--r-- | src/common/log.c | 9 | ||||
-rw-r--r-- | src/common/mempool.c | 3 | ||||
-rw-r--r-- | src/or/connection.c | 9 | ||||
-rw-r--r-- | src/or/connection_edge.c | 28 | ||||
-rw-r--r-- | src/or/directory.c | 19 | ||||
-rw-r--r-- | src/or/dirserv.c | 25 | ||||
-rw-r--r-- | src/or/dnsserv.c | 62 | ||||
-rw-r--r-- | src/or/main.c | 20 | ||||
-rw-r--r-- | src/or/or.h | 56 | ||||
-rw-r--r-- | src/or/relay.c | 2 | ||||
-rw-r--r-- | src/or/rendservice.c | 2 | ||||
-rw-r--r-- | src/or/router.c | 57 | ||||
-rw-r--r-- | src/or/routerlist.c | 105 |
16 files changed, 289 insertions, 142 deletions
@@ -22,12 +22,11 @@ Changes in version 0.2.0.1-alpha - 2007-??-?? logging information that would be very useful to an attacker. - Start work implementing proposal 103: Add a standalone tool to generate key certificates. - - Initial implementation of a client-side DNS proxy feature to replace - the need for dns-proxy-tor: Just set "DNSPort 9999", and Tor will - now listen for DNS requests on port 9999, use the Tor network to - resolve them anonymously, and send the reply back like a regular DNS - server. The code is still buggy, undocumented, and only implements - a subset of DNS. + - A client-side DNS proxy feature to replace the need for dns-proxy-tor: + Just set "DNSPort 9999", and Tor will now listen for DNS requests on + port 9999, use the Tor network to resolve them anonymously, and send + the reply back like a regular DNS server. The code is still only + implements a subset of DNS. o Security fixes: - Directory authorities now call routers stable if they have an diff --git a/src/common/compat.c b/src/common/compat.c index 852cfffae..ed06701ab 100644 --- a/src/common/compat.c +++ b/src/common/compat.c @@ -807,7 +807,14 @@ tor_inet_aton(const char *c, struct in_addr* addr) #endif } -/** DOCDOC */ +/** Given <b>af</b>==AF_INET and <b>src</b> a struct in_addr, or + * <b>af</b>==AF_INET6 and <b>src</b> a struct in6_addr, try to format the + * address and store it in the <b>len</b>-byte buffer <b>dst</b>. Returns + * <b>dst</b> on success, NULL on failure. + * + * (Like inet_ntop(af,src,dst,len), but works on platforms that don't have it: + * Tor sometimes needs to format ipv6 addresses even on platforms without ipv6 + * support.) */ const char * tor_inet_ntop(int af, const void *src, char *dst, size_t len) { @@ -881,7 +888,15 @@ tor_inet_ntop(int af, const void *src, char *dst, size_t len) #endif } -/** DOCDOC */ +/** Given <b>af</b>==AF_INET or <b>af</b>==AF_INET6, and a string <b>src</b> + * encoding an IPv4 address or IPv6 address correspondingly, try to parse the + * address and store the result in <b>dst</b> (which must have space for a + * struct in_addr or a struct in6_addr, as appropriate). Return 1 on success, + * 0 on a bad parse, and -1 on a bad <b>af</b>. + * + * (Like inet_pton(af,src,dst) but works on platforms that don't have it: Tor + * sometimes needs to format ipv6 addresses even on platforms without ipv6 + * support.) */ int tor_inet_pton(int af, const char *src, void *dst) { diff --git a/src/common/container.h b/src/common/container.h index 280c1a8c7..735965358 100644 --- a/src/common/container.h +++ b/src/common/container.h @@ -78,8 +78,8 @@ extern INLINE void smartlist_set(smartlist_t *sl, int idx, void *val) { #define smartlist_set(sl, idx, val) ((sl)->list[idx] = (val)) #endif -// void smartlist_swap(smartlist_t *sl, int idx1, int idx2); -/**DOCDOC*/ +/** Exchange the elements at indices <b>idx1</b> and <b>idx2</b> of the + * smartlist <b>sl</b>. */ static INLINE void smartlist_swap(smartlist_t *sl, int idx1, int idx2) { if (idx1 != idx2) { diff --git a/src/common/log.c b/src/common/log.c index 7e83d831a..ac28830df 100644 --- a/src/common/log.c +++ b/src/common/log.c @@ -88,10 +88,15 @@ int _log_global_min_severity = LOG_NOTICE; static void delete_log(logfile_t *victim); static void close_log(logfile_t *victim); -/** DOCDOC */ +/** Name of the application: used to generate the message we write at the + * start of each new log. */ static char *appname = NULL; -/** DOCDOC */ +/** Set the "application name" for the logs to <b>name</b>: we'll use this + * name in the message we write when starting up, and at the start of each new + * log. + * + * Tor uses this string to write the version number to the log file. */ void log_set_application_name(const char *name) { diff --git a/src/common/mempool.c b/src/common/mempool.c index 16a7f1390..fa5636f88 100644 --- a/src/common/mempool.c +++ b/src/common/mempool.c @@ -498,8 +498,9 @@ mp_pool_assert_ok(mp_pool_t *pool) } #ifdef TOR +/** Dump information about <b>pool</b>'s memory usage to the Tor log at level + * <b>severity</b>. */ /*FFFF uses Tor logging functions. */ -/**DOCDOC*/ void mp_pool_log_status(mp_pool_t *pool, int severity) { diff --git a/src/or/connection.c b/src/or/connection.c index 52bb2e9ce..cfc00e3e5 100644 --- a/src/or/connection.c +++ b/src/or/connection.c @@ -2277,7 +2277,12 @@ connection_state_is_connecting(connection_t *conn) return 0; } -/** DOCDOC */ +/* XXXX020 move this into main.c */ +/** Return true iff <b>conn</b> is linked conn, and reading from the conn + * linked to it would be good and feasible. (Reading is "feasible" if the + * other conn exists and has data in its outbuf, and is "good" if we have our + * reading_from_linked_conn flag set and the other conn has its + * writing_to_linked_conn flag set.)*/ int connection_should_read_from_linked_conn(connection_t *conn) { @@ -2630,7 +2635,7 @@ assert_connection_ok(connection_t *conn, time_t now) tor_assert(edge_conn->socks_request); if (conn->state == AP_CONN_STATE_OPEN) { - tor_assert(edge_conn->socks_request->has_finished); + tor_assert(edge_conn->socks_request->has_finished != 0); if (!conn->marked_for_close) { tor_assert(edge_conn->cpath_layer); assert_cpath_layer_ok(edge_conn->cpath_layer); diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c index c9a09a5bf..b2d0cf589 100644 --- a/src/or/connection_edge.c +++ b/src/or/connection_edge.c @@ -1851,7 +1851,12 @@ connection_ap_handshake_send_resolve(edge_connection_t *ap_conn) uint32_t a; size_t len = strlen(ap_conn->socks_request->address); char c = 0; + /* XXXX020 This logic is a little ugly: we check for an in-addr.arpa ending + * on the address. If we have one, the address is already in the right + * order, so we'll leave it alone later. Otherwise, we reverse it and + * turn it into an in-addr.arpa address. */ if (!strcasecmpend(ap_conn->socks_request->address, ".in-addr.arpa")) { + /* Temporarily truncate the address, so we can give it to inet_aton. */ c = ap_conn->socks_request->address[len-13]; ap_conn->socks_request->address[len-13] = '\0'; } @@ -1859,7 +1864,6 @@ connection_ap_handshake_send_resolve(edge_connection_t *ap_conn) connection_mark_unattached_ap(ap_conn, END_STREAM_REASON_INTERNAL); return -1; } - /* DOCDOC */ if (c) { /* this path happens on DNS. Can we unify? XXXX020 */ ap_conn->socks_request->address[len-13] = c; @@ -1893,13 +1897,12 @@ connection_ap_handshake_send_resolve(edge_connection_t *ap_conn) return 0; } -/** Make an AP connection_t, do a socketpair and attach one side - * to the conn, connection_add it, initialize it to circuit_wait, +/** Make an AP connection_t, make a new linked connection pair, and attach + * one side to the conn, connection_add it, initialize it to circuit_wait, * and call connection_ap_handshake_attach_circuit(conn) on it. * - * Return the other end of the socketpair, or -1 if error. + * Return the other end of the linked connection pair, or -1 if error. * - * DOCDOC The above is now wrong; we use links. * DOCDOC start_reading */ edge_connection_t * @@ -1982,8 +1985,9 @@ connection_ap_handshake_socks_resolved(edge_connection_t *conn, } if (conn->dns_server_request) { + /* We had a request on our DNS port: answer it. */ dnsserv_resolved(conn, answer_type, answer_len, answer, ttl); - conn->socks_request->has_finished = 1; /* DOCDOC */ + conn->socks_request->has_finished = 1; return; } @@ -2430,13 +2434,11 @@ connection_exit_connect(edge_connection_t *edge_conn) } /** Given an exit conn that should attach to us as a directory server, open a - * bridge connection with a socketpair, create a new directory conn, and join - * them together. Return 0 on success (or if there was an error we could send - * back an end cell for). Return -(some circuit end reason) if the circuit - * needs to be torn down. Either connects <b>exitconn<b/>, frees it, - * or marks it, as appropriate. - * - * DOCDOC no longer uses socketpair + * bridge connection with a linked connection pir, create a new directory + * conn, and join them together. Return 0 on success (or if there was an + * error we could send back an end cell for). Return -(some circuit end + * reason) if the circuit needs to be torn down. Either connects + * <b>exitconn<b/>, frees it, or marks it, as appropriate. */ static int connection_exit_connect_dir(edge_connection_t *exitconn) diff --git a/src/or/directory.c b/src/or/directory.c index e837155be..087029f4c 100644 --- a/src/or/directory.c +++ b/src/or/directory.c @@ -108,7 +108,9 @@ authority_type_to_string(authority_type_t auth) return result; } -/* DOCDOC */ +/** Return true iff <b>identity_digest</b> is the digest of a router we + * believe to support extrainfo downloads. (If <b>is_authority</b> we do + * additional checking that's only valid for authorities.) */ int router_supports_extrainfo(const char *identity_digest, int is_authority) { @@ -130,7 +132,7 @@ router_supports_extrainfo(const char *identity_digest, int is_authority) return 0; } -/** Start a connection to every suitable directory server, using +/** Start a connection to every suitable directory authority, using * connection purpose 'purpose' and uploading the payload 'payload' * (length 'payload_len'). The purpose should be one of * 'DIR_PURPOSE_UPLOAD_DIR' or 'DIR_PURPOSE_UPLOAD_RENDDESC'. @@ -138,7 +140,11 @@ router_supports_extrainfo(const char *identity_digest, int is_authority) * <b>type</b> specifies what sort of dir authorities (V1, V2, * HIDSERV, BRIDGE) we should upload to. * - * DOCDOC extrainfo_len is in addition to payload_len. + * If <b>extrainfo_len</b> is nonzero, the first <b>payload_len</b> bytes of + * <b>payload</b> hold a router descriptor, and the next <b>extrainfo_len</b> + * bytes of <b>payload</b> hold an extra-info document. Upload the descriptor + * to all authorities, and the extra-info document to all authorities that + * support it. */ void directory_post_to_dirservers(uint8_t purpose, authority_type_t type, @@ -2118,10 +2124,9 @@ dir_networkstatus_download_failed(smartlist_t *failed, int status_code) }); } -/** Called when one or more routerdesc fetches have failed (with uppercase - * fingerprints listed in <b>failed</b>). - * - * DOCDOC was_extrainfo */ +/** Called when one or more routerdesc (or extrainfo, if <b>was_extrainfo</b>) + * fetches have failed (with uppercase fingerprints listed in + * <b>failed</b>). */ static void dir_routerdesc_download_failed(smartlist_t *failed, int status_code, int was_extrainfo) diff --git a/src/or/dirserv.c b/src/or/dirserv.c index cdbb39088..28fefe435 100644 --- a/src/or/dirserv.c +++ b/src/or/dirserv.c @@ -557,9 +557,9 @@ dirserv_add_multiple_descriptors(const char *desc, const char **msg) return r <= 2 ? r : 2; } -/** Parse the server descriptor at <b>desc</b> and maybe insert it into the - * list of server descriptors. Set *<b>msg</b> to a message that should be - * passed back to the origin of this descriptor. DOCDOC no longer parses. +/** Examine the parsed server descriptor in <b>ri</b> and maybe insert it into + * the list of server descriptors. Set *<b>msg</b> to a message that should be + * passed back to the origin of this descriptor. * * Return 2 if descriptor is well-formed and accepted; * 1 if well-formed and accepted but origin should hear *msg; @@ -616,7 +616,7 @@ dirserv_add_descriptor(routerinfo_t *ri, const char **msg) } } -/** DOCDOC */ +/** As dirserv_add_descriptor, but for an extrainfo_t <b>ei</b>. */ static int dirserv_add_extrainfo(extrainfo_t *ei, const char **msg) { @@ -1575,7 +1575,11 @@ dirserv_compute_performance_thresholds(routerlist_t *rl) smartlist_free(bandwidths_excluding_exits); } -/** DOCDOC */ +/** Helper: write the router-status information in <b>rs</b> into <b>buf</b>, + * which has at least <b>buf_len</b> free characters. Do NUL-termination. + * Use the same format as in network-status documents. If <b>platform</b> is + * non-NULL, add a "v" line for the platform. Return 0 on success, -1 on + * failure. */ int routerstatus_format_entry(char *buf, size_t buf_len, routerstatus_t *rs, const char *platform) @@ -1646,7 +1650,8 @@ routerstatus_format_entry(char *buf, size_t buf_len, return 0; } -/** DOCDOC */ +/** Helper for sorting: compare two routerinfos by their identity + * digest. */ static int _compare_routerinfo_by_id_digest(const void **a, const void **b) { @@ -1656,9 +1661,11 @@ _compare_routerinfo_by_id_digest(const void **a, const void **b) DIGEST_LEN); } -/** For v2 authoritative directories only: replace the contents of - * <b>the_v2_networkstatus</b> with a newly generated network status - * object. DOCDOC v2*/ +/** For v2 and v3 authoritative directories only: If <b>v2</b> is set, replace + * the contents of <b>the_v2_networkstatus</b> with a newly generated network + * status object. If <b>v2</b> is zero, replace the contents of + * <b>the_v3_networkstatus_vote</b> with a newly generated consensus vote + * object. */ static cached_dir_t * generate_networkstatus_opinion(int v2) { diff --git a/src/or/dnsserv.c b/src/or/dnsserv.c index 89077342c..bda4be56c 100644 --- a/src/or/dnsserv.c +++ b/src/or/dnsserv.c @@ -12,6 +12,9 @@ const char dnsserv_c_id[] = #include "or.h" #include "eventdns.h" +/* Helper function: called by evdns whenever the client sends a request to our + * DNSPort. We need to eventually answer the request <b>req</b>. + */ static void evdns_server_callback(struct evdns_server_request *req, void *_data) { @@ -23,11 +26,13 @@ evdns_server_callback(struct evdns_server_request *req, void *_data) int addrlen; uint32_t ipaddr; int err = DNS_ERR_NONE; + char *q_name; tor_assert(req); tor_assert(_data == NULL); log_info(LD_APP, "Got a new DNS request!"); + /* First, check whether the requesting address matches our SOCKSPolicy. */ if ((addrlen = evdns_server_request_get_requesting_addr(req, (struct sockaddr*)&addr, sizeof(addr))) < 0) { log_warn(LD_APP, "Couldn't get requesting address."); @@ -49,6 +54,11 @@ evdns_server_callback(struct evdns_server_request *req, void *_data) evdns_server_request_respond(req, DNS_ERR_REFUSED); return; } + + /* Now, let's find the first actual question of a type we can answer in this + * DNS request. It makes us a little noncompliant to act like this; we + * should fix that eventually if it turns out to make a difference for + * anybody. */ if (req->nquestions == 0) { log_info(LD_APP, "No questions in DNS request; sending back nil reply."); evdns_server_request_respond(req, 0); @@ -76,22 +86,27 @@ evdns_server_callback(struct evdns_server_request *req, void *_data) return; } if (q->type == EVDNS_TYPE_A) { + /* Refuse any attempt to resolve a noconnect address, right now. */ if (hostname_is_noconnect_address(q->name)) { err = DNS_ERR_REFUSED; } } else { tor_assert(q->type == EVDNS_TYPE_PTR); } + + /* Make sure the name isn't too long: This should be impossible, I think. */ if (err == DNS_ERR_NONE && strlen(q->name) > MAX_SOCKS_ADDR_LEN-1) err = DNS_ERR_FORMAT; if (err != DNS_ERR_NONE) { + /* We got an error? Then send back an answer immediately; we're done. */ evdns_server_request_respond(req, err); return; } /* XXXX020 Send a stream event to the controller. */ + /* Make a new dummy AP connection, and attach the request to it. */ conn = TO_EDGE_CONN(connection_new(CONN_TYPE_AP)); conn->_base.state = AP_CONN_STATE_RESOLVE_WAIT; if (q->type == EVDNS_TYPE_A) @@ -104,20 +119,36 @@ evdns_server_callback(struct evdns_server_request *req, void *_data) conn->dns_server_request = req; - log_info(LD_APP, "Passing request for %s to rewrite_and_attach.", q->name); + /* Now, throw the connection over to get rewritten (which will answer it + * immediately if it's in the cache, or completely bogus, or automapped), + * and then attached to a circuit. */ + log_info(LD_APP, "Passing request for %s to rewrite_and_attach.", + escaped_safe_str(q->name)); + q_name = tor_strdup(q->name); /* q could be freed in rewrite_and_attach */ connection_ap_handshake_rewrite_and_attach(conn, NULL, NULL); - /* Now the connection is marked if it was bad. */ + /* Now, the connection is marked if it was bad. */ - log_info(LD_APP, "Passed request for %s to rewrite_and_attach.", q->name); + log_info(LD_APP, "Passed request for %s to rewrite_and_attach.", + escaped_safe_str(q_name)); + tor_free(q_name); } +/** If there is a pending request on <b>conn</b> that's waiting for an answer, + * send back an error and free the request. */ void dnsserv_reject_request(edge_connection_t *conn) { - evdns_server_request_respond(conn->dns_server_request, DNS_ERR_SERVERFAILED); - conn->dns_server_request = NULL; + if (conn->dns_server_request) { + evdns_server_request_respond(conn->dns_server_request, + DNS_ERR_SERVERFAILED); + conn->dns_server_request = NULL; + } } +/** Tell the dns request waiting for an answer on <b>conn</b> that we have an + * answer of type <b>answer_type</b> (RESOLVE_TYPE_IPV4/IPV6/ERR), of length + * <b>answer_len</b>, in <b>answer</b>, with TTL <b>ttl</b>. Doesn't do + * any caching; that's handled elsewhere. */ void dnsserv_resolved(edge_connection_t *conn, int answer_type, @@ -130,10 +161,13 @@ dnsserv_resolved(edge_connection_t *conn, if (!req) return; - /* XXXX Re-do. */ + /* XXXX020 Re-do; this is dumb. */ if (ttl < 60) ttl = 60; + /* The evdns interface is: add a bunch of reply items (corresponding to one + * or more of the questions in the request); then, call + * evdns_server_request_respond. */ if (answer_type == RESOLVED_TYPE_IPV6) { log_info(LD_APP, "Got an IPv6 answer; that's not implemented."); err = DNS_ERR_NOTIMPL; @@ -150,26 +184,36 @@ dnsserv_resolved(edge_connection_t *conn, (char*)answer, ttl); tor_free(ans); } else { - err = DNS_ERR_SERVERFAILED; + err = DNS_ERR_SERVERFAILED; /* Really? Not noent? */ } evdns_server_request_respond(req, err); conn->dns_server_request = NULL; } +/* Set up the evdns server port for the UDP socket on <b>conn</b>, which + * must be an AP_DNS_LISTENER */ void dnsserv_configure_listener(connection_t *conn) { tor_assert(conn); tor_assert(conn->s); + tor_assert(conn->type == CONN_TYPE_AP_DNS_LISTENER); evdns_add_server_port(conn->s, 0, evdns_server_callback, NULL); } +/** Free the evdns server port for <b>conn</b>, which must be an + * AP_DNS_LISTENER. */ void dnsserv_close_listener(connection_t *conn) { - evdns_close_server_port(conn->dns_server_port); - conn->dns_server_port = NULL; + tor_assert(conn); + tor_assert(conn->type == CONN_TYPE_AP_DNS_LISTENER); + + if (conn->dns_server_port) { + evdns_close_server_port(conn->dns_server_port); + conn->dns_server_port = NULL; + } } diff --git a/src/or/main.c b/src/or/main.c index 6b8943696..ce0d6bce7 100644 --- a/src/or/main.c +++ b/src/or/main.c @@ -28,6 +28,7 @@ static void conn_write_callback(int fd, short event, void *_conn); static void signal_callback(int fd, short events, void *arg); static void second_elapsed_callback(int fd, short event, void *args); static int conn_close_if_marked(int i); +static void connection_start_reading_from_linked_conn(connection_t *conn); /********* START VARIABLES **********/ @@ -72,9 +73,12 @@ static smartlist_t *connection_array = NULL; /** List of connections that have been marked for close and need to be freed * and removed from connection_array. */ static smartlist_t *closeable_connection_lst = NULL; -/** DOCDOC */ +/** List of linked connections that are currently reading data into their + * inbuf from their partner's outbuf. */ static smartlist_t *active_linked_connection_lst = NULL; -/** DOCDOC */ +/** Flag: Set to true iff we entered the current libevent main loop via + * <b>loop_once</b>. If so, there's no need to trigger a loopexit in order + * to handle linked connections. */ static int called_loop_once = 0; /** We set this to 1 when we've opened a circuit, so we can print a log @@ -395,8 +399,10 @@ connection_start_writing(connection_t *conn) } } -/** DOCDOC*/ -void +/** Helper: Tell the main loop to begin reading bytes into <b>conn</b> from + * its linked connection, if it is not doing so already. Called by + * connection_start_reading and connection_start_writing as appropriate. */ +static void connection_start_reading_from_linked_conn(connection_t *conn) { tor_assert(conn); @@ -418,7 +424,9 @@ connection_start_reading_from_linked_conn(connection_t *conn) } } -/** DOCDOC*/ +/** Tell the main loop to stop reading bytes into <b>conn</b> from its linked + * connection, if is currently doing so. Called by connection_stop_reading, + * connection_stop_writing, and connection_read. */ void connection_stop_reading_from_linked_conn(connection_t *conn) { @@ -1298,7 +1306,7 @@ do_main_loop(void) } } - /* DOCDOC */ + /* Set up the packed_cell_t memory pool. */ init_cell_pool(); /* Set up our buckets */ diff --git a/src/or/or.h b/src/or/or.h index 983fad801..fb2f51a81 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -910,7 +910,8 @@ typedef struct edge_connection_t { * already retried several times. */ uint8_t num_socks_retries; - /** DOCDOC */ + /** If this is a DNSPort connection, this field holds the pending DNS + * request that we're going to try to answer. */ struct evdns_server_request *dns_server_request; } edge_connection_t; @@ -1057,7 +1058,8 @@ typedef enum { SAVED_IN_JOURNAL } saved_location_t; -/** DOCDOC */ +/** Information about our plans for retrying downloads for a downloadable + * object. */ typedef struct download_status_t { time_t next_attempt_at; /**< When should we try downloading this descriptor * again? */ @@ -1078,18 +1080,19 @@ typedef struct signed_descriptor_t { char identity_digest[DIGEST_LEN]; /** Declared publication time of the descriptor */ time_t published_on; - /** DOCDOC; routerinfo_t only. */ + /** For routerdescs only: digest of the corresponding extrainfo. */ char extra_info_digest[DIGEST_LEN]; - /** DOCDOC; routerinfo_t only: for the corresponding extrainfo. */ + /** For routerdescs only: Status of downloading the corresponding + * extrainfo. */ download_status_t ei_dl_status; /** Where is the descriptor saved? */ saved_location_t saved_location ; /** If saved_location is SAVED_IN_CACHE or SAVED_IN_JOURNAL, the offset of * this descriptor in the corresponding file. */ off_t saved_offset; - /* DOCDOC */ + /* If true, we do not ever try to save this object in the cache. */ unsigned int do_not_cache : 1; - /* DOCDOC */ + /* If true, this item is meant to represent an extrainfo. */ unsigned int is_extrainfo : 1; } signed_descriptor_t; @@ -1124,7 +1127,8 @@ typedef struct { * hibernating */ unsigned int has_old_dnsworkers:1; /**< Whether the router is using * dnsworker code. */ - unsigned int caches_extra_info:1; /**< DOCDOC */ + unsigned int caches_extra_info:1; /**< Whether the router caches and serves + * extrainfo documents. */ /* local info */ unsigned int is_running:1; /**< As far as we know, is this OR currently @@ -1179,7 +1183,7 @@ typedef struct extrainfo_t { /** If present, we didn't have the right key to verify this extra-info, * so this is a copy of the signature in the document. */ char *pending_sig; - /** DOCDOC */ + /** Length of pending_sig. */ size_t pending_sig_len; } extrainfo_t; @@ -1296,10 +1300,12 @@ typedef struct { /** Map from server descriptor digest to a signed_descriptor_t from * routers or old_routers. */ digestmap_t *desc_digest_map; - /** Map from extra-info digest to a signed_descriptor_t. Only for + /** Map from extra-info digest to an extrainfo_t. Only exists for * routers in routers or old_routers. */ digestmap_t *extra_info_map; - /** DOCDOC */ + /** Map from extra-info digests to a signed_descriptor_t for a router + * descriptor having that extra-info digest. Only exists for + * routers in routers or old_routers. */ digestmap_t *desc_by_eid_map; /** List of routerinfo_t for all currently live routers we know. */ smartlist_t *routers; @@ -1328,7 +1334,8 @@ typedef struct extend_info_t { crypto_pk_env_t *onion_key; /**< Current onionskin key. */ } extend_info_t; -/** DOCDOC */ +/** Certificate for v3 directory protocol: binds long-term authority identity + * keys to medium-term authority signing keys. */ typedef struct authority_cert_t { signed_descriptor_t cache_info; crypto_pk_env_t *identity_key; @@ -1336,7 +1343,8 @@ typedef struct authority_cert_t { time_t expires; } authority_cert_t; -/** DOCDOC */ +/** Bitfield enum type listing types of directory authority/directory + * server. */ typedef enum { NO_AUTHORITY = 0, V1_AUTHORITY = 1 << 0, @@ -1822,8 +1830,12 @@ typedef struct { int TrackHostExitsExpire; /**< Number of seconds until we expire an * addressmap */ config_line_t *AddressMap; /**< List of address map directives. */ - int AutomapHostsOnResolve; /**< DOCDOC */ - smartlist_t *AutomapHostsSuffixes; /**< DOCDOC */ + int AutomapHostsOnResolve; /**< If true, when we get a resolve request for a + * hostname ending with one of the suffixes in + * <b>AutomapHostsSuffixes</b>, map it to a + * virtual address. */ + smartlist_t *AutomapHostsSuffixes; /**< List of suffixes for + * <b>AutomapHostsOnResolve</b>. */ int RendPostPeriod; /**< How often do we post each rendezvous service * descriptor? Remember to publish them independently. */ int KeepalivePeriod; /**< How often do we send padding cells to keep @@ -2029,7 +2041,9 @@ static INLINE void or_state_mark_dirty(or_state_t *state, time_t when) #define SOCKS_COMMAND_IS_RESOLVE(c) ((c)==SOCKS_COMMAND_RESOLVE || \ (c)==SOCKS_COMMAND_RESOLVE_PTR) -/** State of a SOCKS request from a user to an OP */ +/** State of a SOCKS request from a user to an OP. Also used to encode other + * information for non-socks user request (such as those on TransPort and + * DNSPort) */ struct socks_request_t { /** Which version of SOCKS did the client use? One of "0, 4, 5" -- where * 0 means that no socks handshake ever took place, and this is just a @@ -2043,10 +2057,12 @@ struct socks_request_t { * socks5 socks reply. We use this for the * two-stage socks5 handshake. */ - int has_finished; /**< Has the SOCKS handshake finished? */ char address[MAX_SOCKS_ADDR_LEN]; /**< What address did the client ask to - connect to? */ + connect to/resolve? */ uint16_t port; /**< What port did the client ask to connect to? */ + unsigned has_finished : 1; /**< Has the SOCKS handshake finished? Used to + * make sure we send back a socks reply for + * every connection. */ }; /* all the function prototypes go here */ @@ -2718,7 +2734,6 @@ void connection_stop_writing(connection_t *conn); void connection_start_writing(connection_t *conn); void connection_stop_reading_from_linked_conn(connection_t *conn); -void connection_start_reading_from_linked_conn(connection_t *conn); void directory_all_unreachable(time_t now); void directory_info_has_arrived(time_t now, int from_cache); @@ -3024,7 +3039,8 @@ authority_cert_t *get_my_v3_authority_cert(void); crypto_pk_env_t *get_my_v3_authority_signing_key(void); void dup_onion_keys(crypto_pk_env_t **key, crypto_pk_env_t **last); void rotate_onion_key(void); -crypto_pk_env_t *init_key_from_file(const char *fname); +crypto_pk_env_t *init_key_from_file(const char *fname, int generate, + int severity); int init_keys(void); int check_whether_orport_reachable(void); @@ -3098,7 +3114,7 @@ typedef struct trusted_dir_server_t { * we tried to upload to it. */ unsigned int has_accepted_serverdesc:1; - /** DOCDOC */ + /** What kind of authority is this? (Bitfield.) */ authority_type_t type; authority_cert_t *v3_cert; /**< V3 key certificate for this authority */ diff --git a/src/or/relay.c b/src/or/relay.c index a1cde2d3d..d83247d16 100644 --- a/src/or/relay.c +++ b/src/or/relay.c @@ -1480,7 +1480,7 @@ circuit_consider_sending_sendme(circuit_t *circ, crypt_path_t *layer_hint) #define assert_active_circuits_ok_paranoid(conn) #endif -/** DOCDOC */ +/** The total number of cells we have allocated from the memory pool. */ static int total_cells_allocated = 0; #ifdef ENABLE_CELL_POOL /* Defined in ./configure. True by default. */ diff --git a/src/or/rendservice.c b/src/or/rendservice.c index 5f6820285..e20804438 100644 --- a/src/or/rendservice.c +++ b/src/or/rendservice.c @@ -350,7 +350,7 @@ rend_service_load_keys(void) s->directory); return -1; } - s->private_key = init_key_from_file(fname); + s->private_key = init_key_from_file(fname, 1, LOG_ERR); if (!s->private_key) return -1; diff --git a/src/or/router.c b/src/or/router.c index 0b63eee60..db433f5b5 100644 --- a/src/or/router.c +++ b/src/or/router.c @@ -44,6 +44,11 @@ static crypto_pk_env_t *authority_signing_key = NULL; * authorities. */ static authority_cert_t *authority_key_certificate = NULL; +/* (Note that v3 authorities also have a separate "authority identity key", + * but this key is never actually loaded by the Tor process. Instead, it's + * used by tor-gencert to sign new signing keys and make new key + * certificates. */ + /** Replace the current onion key with <b>k</b>. Does not affect lastonionkey; * to update onionkey correctly, call rotate_onion_key(). */ @@ -122,14 +127,16 @@ identity_key_is_set(void) return identitykey != NULL; } -/** DOCDOC */ +/** Return the key certificate for this v3 (voting) authority, or NULL + * if we have no such certificate. */ authority_cert_t * get_my_v3_authority_cert(void) { return authority_key_certificate; } -/** DOCDOC */ +/** Return the v3 signing key for this v3 (voting) authority, or NULL + * if we have no such key. */ crypto_pk_env_t * get_my_v3_authority_signing_key(void) { @@ -189,9 +196,13 @@ rotate_onion_key(void) log_warn(LD_GENERAL, "Couldn't rotate onion key."); } -/** DOCDOC */ -static crypto_pk_env_t * -init_key_from_file_impl(const char *fname, int generate, int severity) +/** Try to read an RSA key from <b>fname</b>. If <b>fname</b> doesn't exist + * and <b>generate</b> is true, create a new RSA key and save it in + * <b>fname</b>. Return the read/created key, or NULL on error. Log all + * errors at level <b>severity</b>. + */ +crypto_pk_env_t * +init_key_from_file(const char *fname, int generate, int severity) { crypto_pk_env_t *prkey = NULL; FILE *file = NULL; @@ -246,17 +257,9 @@ init_key_from_file_impl(const char *fname, int generate, int severity) return NULL; } -/** Try to read an RSA key from <b>fname</b>. If <b>fname</b> doesn't exist, - * create a new RSA key and save it in <b>fname</b>. Return the read/created - * key, or NULL on error. - */ -crypto_pk_env_t * -init_key_from_file(const char *fname) -{ - return init_key_from_file_impl(fname, 1, LOG_ERR); -} - -/** DOCDOC; XXXX020 maybe move to dirserv.c */ +/** Load the v3 (voting) authority signing key and certificate from + * <b>keydir</b>, if they are present. */ +/* XXXX020 maybe move to dirserv.c */ static void init_v3_authority_keys(const char *keydir) { @@ -269,7 +272,7 @@ init_v3_authority_keys(const char *keydir) fname = tor_malloc(fname_len); tor_snprintf(fname, fname_len, "%s"PATH_SEPARATOR"authority_signing_key", keydir); - signing_key = init_key_from_file_impl(fname, 0, LOG_INFO); + signing_key = init_key_from_file(fname, 0, LOG_INFO); if (!signing_key) { log_warn(LD_DIR, "No version 3 directory key found in %s", fname); goto done; @@ -364,7 +367,7 @@ init_keys(void) tor_snprintf(keydir,sizeof(keydir), "%s"PATH_SEPARATOR"keys"PATH_SEPARATOR"secret_id_key",datadir); log_info(LD_GENERAL,"Reading/making identity key \"%s\"...",keydir); - prkey = init_key_from_file(keydir); + prkey = init_key_from_file(keydir, 1, LOG_ERR); if (!prkey) return -1; set_identity_key(prkey); @@ -376,7 +379,7 @@ init_keys(void) tor_snprintf(keydir,sizeof(keydir), "%s"PATH_SEPARATOR"keys"PATH_SEPARATOR"secret_onion_key",datadir); log_info(LD_GENERAL,"Reading/making onion key \"%s\"...",keydir); - prkey = init_key_from_file(keydir); + prkey = init_key_from_file(keydir, 1, LOG_ERR); if (!prkey) return -1; set_onion_key(prkey); if (state->LastRotatedOnionKey > 100) { /* allow for some parsing slop. */ @@ -393,7 +396,7 @@ init_keys(void) tor_snprintf(keydir,sizeof(keydir), "%s"PATH_SEPARATOR"keys"PATH_SEPARATOR"secret_onion_key.old",datadir); if (file_status(keydir) == FN_FILE) { - prkey = init_key_from_file(keydir); + prkey = init_key_from_file(keydir, 1, LOG_ERR); if (prkey) lastonionkey = prkey; } @@ -844,7 +847,7 @@ router_is_clique_mode(routerinfo_t *router) /** My routerinfo. */ static routerinfo_t *desc_routerinfo = NULL; -/** DOCDOC */ +/** My extrainfo */ static extrainfo_t *desc_extrainfo = NULL; /** Since when has our descriptor been "clean"? 0 if we need to regenerate it * now. */ @@ -966,7 +969,8 @@ router_get_my_descriptor(void) return body; } -/** DOCDOC */ +/* Return the extrainfo document for this OR, or NULL if we have none. + * Rebuilt it (and the server descriptor) if necessary. */ extrainfo_t * router_get_my_extrainfo(void) { @@ -1001,10 +1005,9 @@ router_pick_published_address(or_options_t *options, uint32_t *addr) return 0; } -/** If <b>force</b> is true, or our descriptor is out-of-date, rebuild - * a fresh routerinfo and signed server descriptor for this OR. +/** If <b>force</b> is true, or our descriptor is out-of-date, rebuild a fresh + * routerinfo, signed server descriptor, and extra-info document for this OR. * Return 0 on success, -1 on temporary error. - * DOCDOC extrainfo. */ int router_rebuild_descriptor(int force) @@ -1541,7 +1544,9 @@ router_dump_router_to_string(char *s, size_t maxlen, routerinfo_t *router, return written+1; } -/** DOCDOC */ +/** Write the contents of <b>extrainfo</b> to the <b>maxlen</b>-byte string + * <b>s</b>, signing them with <b>ident_key</b>. Return 0 on success, + * negative on failure. */ int extrainfo_dump_to_string(char *s, size_t maxlen, extrainfo_t *extrainfo, crypto_pk_env_t *ident_key) diff --git a/src/or/routerlist.c b/src/or/routerlist.c index a92bbe61d..069c819c1 100644 --- a/src/or/routerlist.c +++ b/src/or/routerlist.c @@ -49,7 +49,9 @@ static void router_dir_info_changed(void); /** Global list of a trusted_dir_server_t object for each trusted directory * server. */ static smartlist_t *trusted_dir_servers = NULL; -/** DOCDOC */ +/** True iff the key certificate in at least one member of + * <b>trusted_dir_server_t</b> has changed since we last flushed the + * certificates to disk. */ static int trusted_dir_servers_certs_changed = 0; /** Global list of all of the routers that we know about. */ @@ -62,7 +64,8 @@ static smartlist_t *networkstatus_list = NULL; /** Global list of local_routerstatus_t for each router, known or unknown. * Kept sorted by digest. */ static smartlist_t *routerstatus_list = NULL; -/** DOCDOC */ +/** Map from descriptor digest to a member of routerstatus_list: used to + * update download status when a download fails. */ static digestmap_t *routerstatus_by_desc_digest_map = NULL; /** Map from lowercase nickname to digest of named server, if any. */ @@ -165,7 +168,8 @@ router_reload_networkstatus(void) return 0; } -/** DOCDOC */ +/** Reload the cached v3 key certificates from the cached-certs file in + * the data directory. Return 0 on success, -1 on failure. */ int trusted_dirs_reload_certs(void) { @@ -183,7 +187,11 @@ trusted_dirs_reload_certs(void) return r; } -/** DOCDOC */ +/** Load a bunch of new key certificates from the string <b>contents</b>. If + * <b>from_store</b> is true, the certificates are from the cache, and we + * don't need to flush them to disk. If <b>from_store</b> is false, we need + * to flush any changed certificates to disk. Return 0 on success, -1 on + * failure. */ int trusted_dirs_load_certs_from_string(const char *contents, int from_store) { @@ -206,7 +214,10 @@ trusted_dirs_load_certs_from_string(const char *contents, int from_store) if (ds->v3_cert) { if (ds->v3_cert->expires < cert->expires) { authority_cert_free(ds->v3_cert); + ds->v3_cert = NULL; /* redundant, but let's be safe. */ } else { + /* This also covers the case where the certificate is the same + * as the one we have. */ authority_cert_free(cert); continue; } @@ -221,7 +232,7 @@ trusted_dirs_load_certs_from_string(const char *contents, int from_store) return 0; } -/** DOCDOC */ +/** Save all v3 key certifiacates to the cached-certs file. */ void trusted_dirs_flush_certs_to_disk(void) { @@ -260,19 +271,21 @@ trusted_dirs_flush_certs_to_disk(void) * On startup, we read both files. */ -/** DOCDOC */ +/** Information about disk space usage in a cached-routers or cached-extrainfo + * file and its associcated journal. */ typedef struct store_stats_t { /** The size of the router log, in bytes. */ size_t journal_len; /** The size of the router store, in bytes. */ size_t store_len; - /** Total bytes dropped since last rebuild. */ + /** Total bytes dropped since last rebuild: this is space currently + * used in the cache and the journal that could be freed by a rebuild. */ size_t bytes_dropped; } store_stats_t; -/** DOCDOC */ +/** Disk usage for cached-routers and cached-routers.new */ static store_stats_t router_store_stats = { 0, 0, 0 }; -/** DOCDOC */ +/** Disk usage for cached-extrainfo and cached-extrainfo.new */ static store_stats_t extrainfo_store_stats = { 0, 0, 0 }; /** Helper: return 1 iff the router log is so big we want to rebuild the @@ -351,7 +364,8 @@ _compare_signed_descriptors_by_age(const void **_a, const void **_b) * replace the router store with the routers currently in our routerlist, and * clear the journal. Return 0 on success, -1 on failure. * - * DOCDOC extrainfo + * If <b>extrainfo</b> is true, rebuild the extrainfo store; else rebuild the + * router descriptor store. */ static int router_rebuild_store(int force, int extrainfo) @@ -492,7 +506,9 @@ router_rebuild_store(int force, int extrainfo) return r; } -/** DOCDOC */ +/** Helper: Reload a cache file and its associated journal, setting metadata + * appropriately. If <b>extrainfo</b> is true, reload the extrainfo store; + * else reload the router descriptor store. */ static int router_reload_router_list_impl(int extrainfo) { @@ -1632,8 +1648,9 @@ router_get_by_descriptor_digest(const char *digest) return digestmap_get(routerlist->desc_digest_map, digest); } -/** Return the router in our routerlist whose 20-byte descriptor - * is <b>digest</b>. Return NULL if no such router is known. */ +/** Return the signed descriptor for the router in our routerlist whose + * 20-byte extra-info digest is <b>digest</b>. Return NULL if no such router + * is known. */ signed_descriptor_t * router_get_by_extrainfo_digest(const char *digest) { @@ -1644,7 +1661,9 @@ router_get_by_extrainfo_digest(const char *digest) return digestmap_get(routerlist->desc_by_eid_map, digest); } -/** DOCDOC */ +/** Return the signed descriptor for the extrainfo_t in our routerlist whose + * extra-info-digest is <b>digest</b>. Return NULL if no such extra-info + * document is known. */ signed_descriptor_t * extrainfo_get_by_descriptor_digest(const char *digest) { @@ -1736,7 +1755,7 @@ routerinfo_free(routerinfo_t *router) tor_free(router); } -/** DOCDOC */ +/** Release all storage held by <b>extrainfo</b> */ void extrainfo_free(extrainfo_t *extrainfo) { @@ -1745,8 +1764,8 @@ extrainfo_free(extrainfo_t *extrainfo) tor_free(extrainfo->cache_info.signed_descriptor_body); tor_free(extrainfo->pending_sig); - /* Remove once 414/417 is fixed. But I have a hunch... */ - memset(extrainfo, 88, sizeof(extrainfo_t)); + /* XXXX020 remove this once more bugs go away. */ + memset(extrainfo, 88, sizeof(extrainfo_t)); /* debug bad memory usage */ tor_free(extrainfo); } @@ -1756,8 +1775,8 @@ signed_descriptor_free(signed_descriptor_t *sd) { tor_free(sd->signed_descriptor_body); - /* Remove once 414/417 is fixed. But I have a hunch... */ - memset(sd, 99, sizeof(signed_descriptor_t)); + /* XXXX020 remove this once more bugs go away. */ + memset(sd, 99, sizeof(signed_descriptor_t)); /* Debug bad mem usage */ tor_free(sd); } @@ -1773,7 +1792,7 @@ signed_descriptor_from_routerinfo(routerinfo_t *ri) return sd; } -/** DOCDOC */ +/** Helper: free the storage held by the extrainfo_t in <b>e</b>. */ static void _extrainfo_free(void *e) { @@ -1891,8 +1910,9 @@ routerlist_insert(routerlist_t *rl, routerinfo_t *ri) routerlist_check_bug_417(); } -/** DOCDOC - * Returns true if actually inserted. */ +/** Adds the extrainfo_t <b>ei</b> to the routerlist <b>rl</b>, if there is a + * corresponding router in rl-\>routers or rl-\>old_routers. Return true iff + * we actually inserted <b>ei</b>. Free <b>ei</b> if it isn't inserted. */ static int extrainfo_insert(routerlist_t *rl, extrainfo_t *ei) { @@ -2037,7 +2057,9 @@ routerlist_remove(routerlist_t *rl, routerinfo_t *ri, int idx, int make_old) routerlist_check_bug_417(); } -/** DOCDOC */ +/** Remove a signed_descriptor_t <b>sd</b> from <b>rl</b>-\>old_routers, and + * adjust <b>rl</b> as appropriate. <b>idx</i> is -1, or the index of + * <b>sd</b>. */ static void routerlist_remove_old(routerlist_t *rl, signed_descriptor_t *sd, int idx) { @@ -2455,7 +2477,8 @@ router_add_to_routerlist(routerinfo_t *router, const char **msg, return 0; } -/** DOCDOC */ +/** Insert <b>ei</b> into the routerlist, or free it. Other arguments are + * as for router_add_to_routerlist(). */ void router_add_extrainfo_to_routerlist(extrainfo_t *ei, const char **msg, int from_cache, int from_fetch) @@ -2809,7 +2832,9 @@ router_load_routers_from_string(const char *s, const char *eos, smartlist_free(changed); } -/** DOCDOC */ +/** Parse one or more extrainfos from <b>s</b> (ending immediately before + * <b>eos</b> if <b>eos</b> is present). Other arguments are as for + * router_load_routers_from_string(). */ void router_load_extrainfo_from_string(const char *s, const char *eos, saved_location_t saved_location, @@ -3142,8 +3167,8 @@ networkstatus_find_entry(networkstatus_t *ns, const char *digest) _compare_digest_to_routerstatus_entry); } -/** Return the consensus view of the status of the router whose digest is - * <b>digest</b>, or NULL if we don't know about any such router. */ +/** Return the consensus view of the status of the router whose identity + * digest is <b>digest</b>, or NULL if we don't know about any such router. */ local_routerstatus_t * router_get_combined_status_by_digest(const char *digest) { @@ -3153,7 +3178,9 @@ router_get_combined_status_by_digest(const char *digest) _compare_digest_to_routerstatus_entry); } -/** DOCDOC */ +/** Return the consensus view of the status of the router whose current + * <i>descriptor</i> digest is <b>digest</b>, or NULL if no such router is + * known. */ local_routerstatus_t * router_get_combined_status_by_descriptor_digest(const char *digest) { @@ -4258,8 +4285,9 @@ routers_update_status_from_networkstatus(smartlist_t *routers, router_dir_info_changed(); } -/** For every router descriptor we are currently downloading by descriptor - * digest, set result[d] to 1. DOCDOC extrainfo */ +/** For every router descriptor (or extra-info document if <b>extrainfo</b> is + * true) we are currently downloading by descriptor digest, set result[d] to + * (void*)1. */ static void list_pending_descriptor_downloads(digestmap_t *result, int extrainfo) { @@ -4681,7 +4709,9 @@ update_router_descriptor_downloads(time_t now) } } -/** DOCDOC */ +/** Return true iff <b>sd</b> is the descriptor for a router descriptor that + * has an extrainfo that we don't currently have, are not currently + * downloading, and have not recently tried to download. */ static INLINE int should_download_extrainfo(signed_descriptor_t *sd, const routerlist_t *rl, @@ -4689,13 +4719,14 @@ should_download_extrainfo(signed_descriptor_t *sd, time_t now) { const char *d = sd->extra_info_digest; - return (!tor_digest_is_zero(d) && + return (!sd->is_extrainfo && + !tor_digest_is_zero(d) && sd->ei_dl_status.next_attempt_at <= now && !digestmap_get(rl->extra_info_map, d) && !digestmap_get(pending, d)); } -/** DOCDOC */ +/** Laucnch extrainfo downloads as needed. */ void update_extrainfo_downloads(time_t now) { @@ -4967,8 +4998,12 @@ router_differences_are_cosmetic(routerinfo_t *r1, routerinfo_t *r2) return 1; } -/** DOCDOC Returns 1 for "reject with message"; -1 for "reject silently", - * 0 for "accept". */ +/** Check whether <b>ri</b> is a router compatible with the extrainfo document + * <b>ei</b>. If no router is compatible with <b>ei</b>, <b>ei</b> should be + * dropped. Return 0 for "compatible", return 1 for "reject, and inform + * whoever uploaded <b>ei</b>, and return -1 for "reject silently.". If + * <b>msg</b> is present, set *<b>msg</b> to a description of the + * incompatibility (if any). */ int routerinfo_incompatible_with_extrainfo(routerinfo_t *ri, extrainfo_t *ei, const char **msg) |