mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-24 04:13:28 +01:00
r13050@catbus: nickm | 2007-05-29 13:31:11 -0400
Resolve all but 3 DOCDOCs. svn:r10393
This commit is contained in:
parent
69c712f189
commit
f89a3b1448
11
ChangeLog
11
ChangeLog
@ -22,12 +22,11 @@ Changes in version 0.2.0.1-alpha - 2007-??-??
|
|||||||
logging information that would be very useful to an attacker.
|
logging information that would be very useful to an attacker.
|
||||||
- Start work implementing proposal 103: Add a standalone tool to
|
- Start work implementing proposal 103: Add a standalone tool to
|
||||||
generate key certificates.
|
generate key certificates.
|
||||||
- Initial implementation of a client-side DNS proxy feature to replace
|
- A client-side DNS proxy feature to replace the need for dns-proxy-tor:
|
||||||
the need for dns-proxy-tor: Just set "DNSPort 9999", and Tor will
|
Just set "DNSPort 9999", and Tor will now listen for DNS requests on
|
||||||
now listen for DNS requests on port 9999, use the Tor network to
|
port 9999, use the Tor network to resolve them anonymously, and send
|
||||||
resolve them anonymously, and send the reply back like a regular DNS
|
the reply back like a regular DNS server. The code is still only
|
||||||
server. The code is still buggy, undocumented, and only implements
|
implements a subset of DNS.
|
||||||
a subset of DNS.
|
|
||||||
|
|
||||||
o Security fixes:
|
o Security fixes:
|
||||||
- Directory authorities now call routers stable if they have an
|
- Directory authorities now call routers stable if they have an
|
||||||
|
@ -807,7 +807,14 @@ tor_inet_aton(const char *c, struct in_addr* addr)
|
|||||||
#endif
|
#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 *
|
const char *
|
||||||
tor_inet_ntop(int af, const void *src, char *dst, size_t len)
|
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
|
#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
|
int
|
||||||
tor_inet_pton(int af, const char *src, void *dst)
|
tor_inet_pton(int af, const char *src, void *dst)
|
||||||
{
|
{
|
||||||
|
@ -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))
|
#define smartlist_set(sl, idx, val) ((sl)->list[idx] = (val))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// void smartlist_swap(smartlist_t *sl, int idx1, int idx2);
|
/** Exchange the elements at indices <b>idx1</b> and <b>idx2</b> of the
|
||||||
/**DOCDOC*/
|
* smartlist <b>sl</b>. */
|
||||||
static INLINE void smartlist_swap(smartlist_t *sl, int idx1, int idx2)
|
static INLINE void smartlist_swap(smartlist_t *sl, int idx1, int idx2)
|
||||||
{
|
{
|
||||||
if (idx1 != idx2) {
|
if (idx1 != idx2) {
|
||||||
|
@ -88,10 +88,15 @@ int _log_global_min_severity = LOG_NOTICE;
|
|||||||
static void delete_log(logfile_t *victim);
|
static void delete_log(logfile_t *victim);
|
||||||
static void close_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;
|
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
|
void
|
||||||
log_set_application_name(const char *name)
|
log_set_application_name(const char *name)
|
||||||
{
|
{
|
||||||
|
@ -498,8 +498,9 @@ mp_pool_assert_ok(mp_pool_t *pool)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef TOR
|
#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. */
|
/*FFFF uses Tor logging functions. */
|
||||||
/**DOCDOC*/
|
|
||||||
void
|
void
|
||||||
mp_pool_log_status(mp_pool_t *pool, int severity)
|
mp_pool_log_status(mp_pool_t *pool, int severity)
|
||||||
{
|
{
|
||||||
|
@ -2277,7 +2277,12 @@ connection_state_is_connecting(connection_t *conn)
|
|||||||
return 0;
|
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
|
int
|
||||||
connection_should_read_from_linked_conn(connection_t *conn)
|
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);
|
tor_assert(edge_conn->socks_request);
|
||||||
if (conn->state == AP_CONN_STATE_OPEN) {
|
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) {
|
if (!conn->marked_for_close) {
|
||||||
tor_assert(edge_conn->cpath_layer);
|
tor_assert(edge_conn->cpath_layer);
|
||||||
assert_cpath_layer_ok(edge_conn->cpath_layer);
|
assert_cpath_layer_ok(edge_conn->cpath_layer);
|
||||||
|
@ -1851,7 +1851,12 @@ connection_ap_handshake_send_resolve(edge_connection_t *ap_conn)
|
|||||||
uint32_t a;
|
uint32_t a;
|
||||||
size_t len = strlen(ap_conn->socks_request->address);
|
size_t len = strlen(ap_conn->socks_request->address);
|
||||||
char c = 0;
|
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")) {
|
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];
|
c = ap_conn->socks_request->address[len-13];
|
||||||
ap_conn->socks_request->address[len-13] = '\0';
|
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);
|
connection_mark_unattached_ap(ap_conn, END_STREAM_REASON_INTERNAL);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
/* DOCDOC */
|
|
||||||
if (c) {
|
if (c) {
|
||||||
/* this path happens on DNS. Can we unify? XXXX020 */
|
/* this path happens on DNS. Can we unify? XXXX020 */
|
||||||
ap_conn->socks_request->address[len-13] = c;
|
ap_conn->socks_request->address[len-13] = c;
|
||||||
@ -1893,13 +1897,12 @@ connection_ap_handshake_send_resolve(edge_connection_t *ap_conn)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Make an AP connection_t, do a socketpair and attach one side
|
/** Make an AP connection_t, make a new linked connection pair, and attach
|
||||||
* to the conn, connection_add it, initialize it to circuit_wait,
|
* one side to the conn, connection_add it, initialize it to circuit_wait,
|
||||||
* and call connection_ap_handshake_attach_circuit(conn) on it.
|
* 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
|
* DOCDOC start_reading
|
||||||
*/
|
*/
|
||||||
edge_connection_t *
|
edge_connection_t *
|
||||||
@ -1982,8 +1985,9 @@ connection_ap_handshake_socks_resolved(edge_connection_t *conn,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (conn->dns_server_request) {
|
if (conn->dns_server_request) {
|
||||||
|
/* We had a request on our DNS port: answer it. */
|
||||||
dnsserv_resolved(conn, answer_type, answer_len, answer, ttl);
|
dnsserv_resolved(conn, answer_type, answer_len, answer, ttl);
|
||||||
conn->socks_request->has_finished = 1; /* DOCDOC */
|
conn->socks_request->has_finished = 1;
|
||||||
return;
|
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
|
/** 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
|
* bridge connection with a linked connection pir, create a new directory
|
||||||
* them together. Return 0 on success (or if there was an error we could send
|
* conn, and join them together. Return 0 on success (or if there was an
|
||||||
* back an end cell for). Return -(some circuit end reason) if the circuit
|
* error we could send back an end cell for). Return -(some circuit end
|
||||||
* needs to be torn down. Either connects <b>exitconn<b/>, frees it,
|
* reason) if the circuit needs to be torn down. Either connects
|
||||||
* or marks it, as appropriate.
|
* <b>exitconn<b/>, frees it, or marks it, as appropriate.
|
||||||
*
|
|
||||||
* DOCDOC no longer uses socketpair
|
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
connection_exit_connect_dir(edge_connection_t *exitconn)
|
connection_exit_connect_dir(edge_connection_t *exitconn)
|
||||||
|
@ -108,7 +108,9 @@ authority_type_to_string(authority_type_t auth)
|
|||||||
return result;
|
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
|
int
|
||||||
router_supports_extrainfo(const char *identity_digest, int is_authority)
|
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;
|
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'
|
* connection purpose 'purpose' and uploading the payload 'payload'
|
||||||
* (length 'payload_len'). The purpose should be one of
|
* (length 'payload_len'). The purpose should be one of
|
||||||
* 'DIR_PURPOSE_UPLOAD_DIR' or 'DIR_PURPOSE_UPLOAD_RENDDESC'.
|
* '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,
|
* <b>type</b> specifies what sort of dir authorities (V1, V2,
|
||||||
* HIDSERV, BRIDGE) we should upload to.
|
* 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
|
void
|
||||||
directory_post_to_dirservers(uint8_t purpose, authority_type_t type,
|
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
|
/** Called when one or more routerdesc (or extrainfo, if <b>was_extrainfo</b>)
|
||||||
* fingerprints listed in <b>failed</b>).
|
* fetches have failed (with uppercase fingerprints listed in
|
||||||
*
|
* <b>failed</b>). */
|
||||||
* DOCDOC was_extrainfo */
|
|
||||||
static void
|
static void
|
||||||
dir_routerdesc_download_failed(smartlist_t *failed, int status_code,
|
dir_routerdesc_download_failed(smartlist_t *failed, int status_code,
|
||||||
int was_extrainfo)
|
int was_extrainfo)
|
||||||
|
@ -557,9 +557,9 @@ dirserv_add_multiple_descriptors(const char *desc, const char **msg)
|
|||||||
return r <= 2 ? r : 2;
|
return r <= 2 ? r : 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Parse the server descriptor at <b>desc</b> and maybe insert it into the
|
/** Examine the parsed server descriptor in <b>ri</b> and maybe insert it into
|
||||||
* list of server descriptors. Set *<b>msg</b> to a message that should be
|
* 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.
|
* passed back to the origin of this descriptor.
|
||||||
*
|
*
|
||||||
* Return 2 if descriptor is well-formed and accepted;
|
* Return 2 if descriptor is well-formed and accepted;
|
||||||
* 1 if well-formed and accepted but origin should hear *msg;
|
* 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
|
static int
|
||||||
dirserv_add_extrainfo(extrainfo_t *ei, const char **msg)
|
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);
|
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
|
int
|
||||||
routerstatus_format_entry(char *buf, size_t buf_len,
|
routerstatus_format_entry(char *buf, size_t buf_len,
|
||||||
routerstatus_t *rs, const char *platform)
|
routerstatus_t *rs, const char *platform)
|
||||||
@ -1646,7 +1650,8 @@ routerstatus_format_entry(char *buf, size_t buf_len,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** DOCDOC */
|
/** Helper for sorting: compare two routerinfos by their identity
|
||||||
|
* digest. */
|
||||||
static int
|
static int
|
||||||
_compare_routerinfo_by_id_digest(const void **a, const void **b)
|
_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);
|
DIGEST_LEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** For v2 authoritative directories only: replace the contents of
|
/** For v2 and v3 authoritative directories only: If <b>v2</b> is set, replace
|
||||||
* <b>the_v2_networkstatus</b> with a newly generated network status
|
* the contents of <b>the_v2_networkstatus</b> with a newly generated network
|
||||||
* object. DOCDOC v2*/
|
* 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 *
|
static cached_dir_t *
|
||||||
generate_networkstatus_opinion(int v2)
|
generate_networkstatus_opinion(int v2)
|
||||||
{
|
{
|
||||||
|
@ -12,6 +12,9 @@ const char dnsserv_c_id[] =
|
|||||||
#include "or.h"
|
#include "or.h"
|
||||||
#include "eventdns.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
|
static void
|
||||||
evdns_server_callback(struct evdns_server_request *req, void *_data)
|
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;
|
int addrlen;
|
||||||
uint32_t ipaddr;
|
uint32_t ipaddr;
|
||||||
int err = DNS_ERR_NONE;
|
int err = DNS_ERR_NONE;
|
||||||
|
char *q_name;
|
||||||
|
|
||||||
tor_assert(req);
|
tor_assert(req);
|
||||||
tor_assert(_data == NULL);
|
tor_assert(_data == NULL);
|
||||||
log_info(LD_APP, "Got a new DNS request!");
|
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,
|
if ((addrlen = evdns_server_request_get_requesting_addr(req,
|
||||||
(struct sockaddr*)&addr, sizeof(addr))) < 0) {
|
(struct sockaddr*)&addr, sizeof(addr))) < 0) {
|
||||||
log_warn(LD_APP, "Couldn't get requesting address.");
|
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);
|
evdns_server_request_respond(req, DNS_ERR_REFUSED);
|
||||||
return;
|
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) {
|
if (req->nquestions == 0) {
|
||||||
log_info(LD_APP, "No questions in DNS request; sending back nil reply.");
|
log_info(LD_APP, "No questions in DNS request; sending back nil reply.");
|
||||||
evdns_server_request_respond(req, 0);
|
evdns_server_request_respond(req, 0);
|
||||||
@ -76,22 +86,27 @@ evdns_server_callback(struct evdns_server_request *req, void *_data)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (q->type == EVDNS_TYPE_A) {
|
if (q->type == EVDNS_TYPE_A) {
|
||||||
|
/* Refuse any attempt to resolve a noconnect address, right now. */
|
||||||
if (hostname_is_noconnect_address(q->name)) {
|
if (hostname_is_noconnect_address(q->name)) {
|
||||||
err = DNS_ERR_REFUSED;
|
err = DNS_ERR_REFUSED;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
tor_assert(q->type == EVDNS_TYPE_PTR);
|
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)
|
if (err == DNS_ERR_NONE && strlen(q->name) > MAX_SOCKS_ADDR_LEN-1)
|
||||||
err = DNS_ERR_FORMAT;
|
err = DNS_ERR_FORMAT;
|
||||||
|
|
||||||
if (err != DNS_ERR_NONE) {
|
if (err != DNS_ERR_NONE) {
|
||||||
|
/* We got an error? Then send back an answer immediately; we're done. */
|
||||||
evdns_server_request_respond(req, err);
|
evdns_server_request_respond(req, err);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* XXXX020 Send a stream event to the controller. */
|
/* 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 = TO_EDGE_CONN(connection_new(CONN_TYPE_AP));
|
||||||
conn->_base.state = AP_CONN_STATE_RESOLVE_WAIT;
|
conn->_base.state = AP_CONN_STATE_RESOLVE_WAIT;
|
||||||
if (q->type == EVDNS_TYPE_A)
|
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;
|
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);
|
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
|
void
|
||||||
dnsserv_reject_request(edge_connection_t *conn)
|
dnsserv_reject_request(edge_connection_t *conn)
|
||||||
{
|
{
|
||||||
evdns_server_request_respond(conn->dns_server_request, DNS_ERR_SERVERFAILED);
|
if (conn->dns_server_request) {
|
||||||
conn->dns_server_request = NULL;
|
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
|
void
|
||||||
dnsserv_resolved(edge_connection_t *conn,
|
dnsserv_resolved(edge_connection_t *conn,
|
||||||
int answer_type,
|
int answer_type,
|
||||||
@ -130,10 +161,13 @@ dnsserv_resolved(edge_connection_t *conn,
|
|||||||
if (!req)
|
if (!req)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* XXXX Re-do. */
|
/* XXXX020 Re-do; this is dumb. */
|
||||||
if (ttl < 60)
|
if (ttl < 60)
|
||||||
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) {
|
if (answer_type == RESOLVED_TYPE_IPV6) {
|
||||||
log_info(LD_APP, "Got an IPv6 answer; that's not implemented.");
|
log_info(LD_APP, "Got an IPv6 answer; that's not implemented.");
|
||||||
err = DNS_ERR_NOTIMPL;
|
err = DNS_ERR_NOTIMPL;
|
||||||
@ -150,26 +184,36 @@ dnsserv_resolved(edge_connection_t *conn,
|
|||||||
(char*)answer, ttl);
|
(char*)answer, ttl);
|
||||||
tor_free(ans);
|
tor_free(ans);
|
||||||
} else {
|
} else {
|
||||||
err = DNS_ERR_SERVERFAILED;
|
err = DNS_ERR_SERVERFAILED; /* Really? Not noent? */
|
||||||
}
|
}
|
||||||
|
|
||||||
evdns_server_request_respond(req, err);
|
evdns_server_request_respond(req, err);
|
||||||
conn->dns_server_request = NULL;
|
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
|
void
|
||||||
dnsserv_configure_listener(connection_t *conn)
|
dnsserv_configure_listener(connection_t *conn)
|
||||||
{
|
{
|
||||||
tor_assert(conn);
|
tor_assert(conn);
|
||||||
tor_assert(conn->s);
|
tor_assert(conn->s);
|
||||||
|
tor_assert(conn->type == CONN_TYPE_AP_DNS_LISTENER);
|
||||||
|
|
||||||
evdns_add_server_port(conn->s, 0, evdns_server_callback, NULL);
|
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
|
void
|
||||||
dnsserv_close_listener(connection_t *conn)
|
dnsserv_close_listener(connection_t *conn)
|
||||||
{
|
{
|
||||||
evdns_close_server_port(conn->dns_server_port);
|
tor_assert(conn);
|
||||||
conn->dns_server_port = NULL;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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 signal_callback(int fd, short events, void *arg);
|
||||||
static void second_elapsed_callback(int fd, short event, void *args);
|
static void second_elapsed_callback(int fd, short event, void *args);
|
||||||
static int conn_close_if_marked(int i);
|
static int conn_close_if_marked(int i);
|
||||||
|
static void connection_start_reading_from_linked_conn(connection_t *conn);
|
||||||
|
|
||||||
/********* START VARIABLES **********/
|
/********* 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
|
/** List of connections that have been marked for close and need to be freed
|
||||||
* and removed from connection_array. */
|
* and removed from connection_array. */
|
||||||
static smartlist_t *closeable_connection_lst = NULL;
|
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;
|
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;
|
static int called_loop_once = 0;
|
||||||
|
|
||||||
/** We set this to 1 when we've opened a circuit, so we can print a log
|
/** 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*/
|
/** Helper: Tell the main loop to begin reading bytes into <b>conn</b> from
|
||||||
void
|
* 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)
|
connection_start_reading_from_linked_conn(connection_t *conn)
|
||||||
{
|
{
|
||||||
tor_assert(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
|
void
|
||||||
connection_stop_reading_from_linked_conn(connection_t *conn)
|
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();
|
init_cell_pool();
|
||||||
|
|
||||||
/* Set up our buckets */
|
/* Set up our buckets */
|
||||||
|
56
src/or/or.h
56
src/or/or.h
@ -910,7 +910,8 @@ typedef struct edge_connection_t {
|
|||||||
* already retried several times. */
|
* already retried several times. */
|
||||||
uint8_t num_socks_retries;
|
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;
|
struct evdns_server_request *dns_server_request;
|
||||||
|
|
||||||
} edge_connection_t;
|
} edge_connection_t;
|
||||||
@ -1057,7 +1058,8 @@ typedef enum {
|
|||||||
SAVED_IN_JOURNAL
|
SAVED_IN_JOURNAL
|
||||||
} saved_location_t;
|
} saved_location_t;
|
||||||
|
|
||||||
/** DOCDOC */
|
/** Information about our plans for retrying downloads for a downloadable
|
||||||
|
* object. */
|
||||||
typedef struct download_status_t {
|
typedef struct download_status_t {
|
||||||
time_t next_attempt_at; /**< When should we try downloading this descriptor
|
time_t next_attempt_at; /**< When should we try downloading this descriptor
|
||||||
* again? */
|
* again? */
|
||||||
@ -1078,18 +1080,19 @@ typedef struct signed_descriptor_t {
|
|||||||
char identity_digest[DIGEST_LEN];
|
char identity_digest[DIGEST_LEN];
|
||||||
/** Declared publication time of the descriptor */
|
/** Declared publication time of the descriptor */
|
||||||
time_t published_on;
|
time_t published_on;
|
||||||
/** DOCDOC; routerinfo_t only. */
|
/** For routerdescs only: digest of the corresponding extrainfo. */
|
||||||
char extra_info_digest[DIGEST_LEN];
|
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;
|
download_status_t ei_dl_status;
|
||||||
/** Where is the descriptor saved? */
|
/** Where is the descriptor saved? */
|
||||||
saved_location_t saved_location ;
|
saved_location_t saved_location ;
|
||||||
/** If saved_location is SAVED_IN_CACHE or SAVED_IN_JOURNAL, the offset of
|
/** If saved_location is SAVED_IN_CACHE or SAVED_IN_JOURNAL, the offset of
|
||||||
* this descriptor in the corresponding file. */
|
* this descriptor in the corresponding file. */
|
||||||
off_t saved_offset;
|
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;
|
unsigned int do_not_cache : 1;
|
||||||
/* DOCDOC */
|
/* If true, this item is meant to represent an extrainfo. */
|
||||||
unsigned int is_extrainfo : 1;
|
unsigned int is_extrainfo : 1;
|
||||||
} signed_descriptor_t;
|
} signed_descriptor_t;
|
||||||
|
|
||||||
@ -1124,7 +1127,8 @@ typedef struct {
|
|||||||
* hibernating */
|
* hibernating */
|
||||||
unsigned int has_old_dnsworkers:1; /**< Whether the router is using
|
unsigned int has_old_dnsworkers:1; /**< Whether the router is using
|
||||||
* dnsworker code. */
|
* 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 */
|
/* local info */
|
||||||
unsigned int is_running:1; /**< As far as we know, is this OR currently
|
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,
|
/** 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. */
|
* so this is a copy of the signature in the document. */
|
||||||
char *pending_sig;
|
char *pending_sig;
|
||||||
/** DOCDOC */
|
/** Length of pending_sig. */
|
||||||
size_t pending_sig_len;
|
size_t pending_sig_len;
|
||||||
} extrainfo_t;
|
} extrainfo_t;
|
||||||
|
|
||||||
@ -1296,10 +1300,12 @@ typedef struct {
|
|||||||
/** Map from server descriptor digest to a signed_descriptor_t from
|
/** Map from server descriptor digest to a signed_descriptor_t from
|
||||||
* routers or old_routers. */
|
* routers or old_routers. */
|
||||||
digestmap_t *desc_digest_map;
|
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. */
|
* routers in routers or old_routers. */
|
||||||
digestmap_t *extra_info_map;
|
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;
|
digestmap_t *desc_by_eid_map;
|
||||||
/** List of routerinfo_t for all currently live routers we know. */
|
/** List of routerinfo_t for all currently live routers we know. */
|
||||||
smartlist_t *routers;
|
smartlist_t *routers;
|
||||||
@ -1328,7 +1334,8 @@ typedef struct extend_info_t {
|
|||||||
crypto_pk_env_t *onion_key; /**< Current onionskin key. */
|
crypto_pk_env_t *onion_key; /**< Current onionskin key. */
|
||||||
} extend_info_t;
|
} 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 {
|
typedef struct authority_cert_t {
|
||||||
signed_descriptor_t cache_info;
|
signed_descriptor_t cache_info;
|
||||||
crypto_pk_env_t *identity_key;
|
crypto_pk_env_t *identity_key;
|
||||||
@ -1336,7 +1343,8 @@ typedef struct authority_cert_t {
|
|||||||
time_t expires;
|
time_t expires;
|
||||||
} authority_cert_t;
|
} authority_cert_t;
|
||||||
|
|
||||||
/** DOCDOC */
|
/** Bitfield enum type listing types of directory authority/directory
|
||||||
|
* server. */
|
||||||
typedef enum {
|
typedef enum {
|
||||||
NO_AUTHORITY = 0,
|
NO_AUTHORITY = 0,
|
||||||
V1_AUTHORITY = 1 << 0,
|
V1_AUTHORITY = 1 << 0,
|
||||||
@ -1822,8 +1830,12 @@ typedef struct {
|
|||||||
int TrackHostExitsExpire; /**< Number of seconds until we expire an
|
int TrackHostExitsExpire; /**< Number of seconds until we expire an
|
||||||
* addressmap */
|
* addressmap */
|
||||||
config_line_t *AddressMap; /**< List of address map directives. */
|
config_line_t *AddressMap; /**< List of address map directives. */
|
||||||
int AutomapHostsOnResolve; /**< DOCDOC */
|
int AutomapHostsOnResolve; /**< If true, when we get a resolve request for a
|
||||||
smartlist_t *AutomapHostsSuffixes; /**< DOCDOC */
|
* 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
|
int RendPostPeriod; /**< How often do we post each rendezvous service
|
||||||
* descriptor? Remember to publish them independently. */
|
* descriptor? Remember to publish them independently. */
|
||||||
int KeepalivePeriod; /**< How often do we send padding cells to keep
|
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 || \
|
#define SOCKS_COMMAND_IS_RESOLVE(c) ((c)==SOCKS_COMMAND_RESOLVE || \
|
||||||
(c)==SOCKS_COMMAND_RESOLVE_PTR)
|
(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 {
|
struct socks_request_t {
|
||||||
/** Which version of SOCKS did the client use? One of "0, 4, 5" -- where
|
/** 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
|
* 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
|
* socks5 socks reply. We use this for the
|
||||||
* two-stage socks5 handshake.
|
* 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
|
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? */
|
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 */
|
/* 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_start_writing(connection_t *conn);
|
||||||
|
|
||||||
void connection_stop_reading_from_linked_conn(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_all_unreachable(time_t now);
|
||||||
void directory_info_has_arrived(time_t now, int from_cache);
|
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);
|
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 dup_onion_keys(crypto_pk_env_t **key, crypto_pk_env_t **last);
|
||||||
void rotate_onion_key(void);
|
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 init_keys(void);
|
||||||
|
|
||||||
int check_whether_orport_reachable(void);
|
int check_whether_orport_reachable(void);
|
||||||
@ -3098,7 +3114,7 @@ typedef struct trusted_dir_server_t {
|
|||||||
* we tried to upload to it. */
|
* we tried to upload to it. */
|
||||||
unsigned int has_accepted_serverdesc:1;
|
unsigned int has_accepted_serverdesc:1;
|
||||||
|
|
||||||
/** DOCDOC */
|
/** What kind of authority is this? (Bitfield.) */
|
||||||
authority_type_t type;
|
authority_type_t type;
|
||||||
|
|
||||||
authority_cert_t *v3_cert; /**< V3 key certificate for this authority */
|
authority_cert_t *v3_cert; /**< V3 key certificate for this authority */
|
||||||
|
@ -1480,7 +1480,7 @@ circuit_consider_sending_sendme(circuit_t *circ, crypt_path_t *layer_hint)
|
|||||||
#define assert_active_circuits_ok_paranoid(conn)
|
#define assert_active_circuits_ok_paranoid(conn)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/** DOCDOC */
|
/** The total number of cells we have allocated from the memory pool. */
|
||||||
static int total_cells_allocated = 0;
|
static int total_cells_allocated = 0;
|
||||||
|
|
||||||
#ifdef ENABLE_CELL_POOL /* Defined in ./configure. True by default. */
|
#ifdef ENABLE_CELL_POOL /* Defined in ./configure. True by default. */
|
||||||
|
@ -350,7 +350,7 @@ rend_service_load_keys(void)
|
|||||||
s->directory);
|
s->directory);
|
||||||
return -1;
|
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)
|
if (!s->private_key)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
@ -44,6 +44,11 @@ static crypto_pk_env_t *authority_signing_key = NULL;
|
|||||||
* authorities. */
|
* authorities. */
|
||||||
static authority_cert_t *authority_key_certificate = NULL;
|
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;
|
/** Replace the current onion key with <b>k</b>. Does not affect lastonionkey;
|
||||||
* to update onionkey correctly, call rotate_onion_key().
|
* to update onionkey correctly, call rotate_onion_key().
|
||||||
*/
|
*/
|
||||||
@ -122,14 +127,16 @@ identity_key_is_set(void)
|
|||||||
return identitykey != NULL;
|
return identitykey != NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** DOCDOC */
|
/** Return the key certificate for this v3 (voting) authority, or NULL
|
||||||
|
* if we have no such certificate. */
|
||||||
authority_cert_t *
|
authority_cert_t *
|
||||||
get_my_v3_authority_cert(void)
|
get_my_v3_authority_cert(void)
|
||||||
{
|
{
|
||||||
return authority_key_certificate;
|
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 *
|
crypto_pk_env_t *
|
||||||
get_my_v3_authority_signing_key(void)
|
get_my_v3_authority_signing_key(void)
|
||||||
{
|
{
|
||||||
@ -189,9 +196,13 @@ rotate_onion_key(void)
|
|||||||
log_warn(LD_GENERAL, "Couldn't rotate onion key.");
|
log_warn(LD_GENERAL, "Couldn't rotate onion key.");
|
||||||
}
|
}
|
||||||
|
|
||||||
/** DOCDOC */
|
/** Try to read an RSA key from <b>fname</b>. If <b>fname</b> doesn't exist
|
||||||
static crypto_pk_env_t *
|
* and <b>generate</b> is true, create a new RSA key and save it in
|
||||||
init_key_from_file_impl(const char *fname, int generate, int severity)
|
* <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;
|
crypto_pk_env_t *prkey = NULL;
|
||||||
FILE *file = NULL;
|
FILE *file = NULL;
|
||||||
@ -246,17 +257,9 @@ init_key_from_file_impl(const char *fname, int generate, int severity)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Try to read an RSA key from <b>fname</b>. If <b>fname</b> doesn't exist,
|
/** Load the v3 (voting) authority signing key and certificate from
|
||||||
* create a new RSA key and save it in <b>fname</b>. Return the read/created
|
* <b>keydir</b>, if they are present. */
|
||||||
* key, or NULL on error.
|
/* XXXX020 maybe move to dirserv.c */
|
||||||
*/
|
|
||||||
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 */
|
|
||||||
static void
|
static void
|
||||||
init_v3_authority_keys(const char *keydir)
|
init_v3_authority_keys(const char *keydir)
|
||||||
{
|
{
|
||||||
@ -269,7 +272,7 @@ init_v3_authority_keys(const char *keydir)
|
|||||||
fname = tor_malloc(fname_len);
|
fname = tor_malloc(fname_len);
|
||||||
tor_snprintf(fname, fname_len, "%s"PATH_SEPARATOR"authority_signing_key",
|
tor_snprintf(fname, fname_len, "%s"PATH_SEPARATOR"authority_signing_key",
|
||||||
keydir);
|
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) {
|
if (!signing_key) {
|
||||||
log_warn(LD_DIR, "No version 3 directory key found in %s", fname);
|
log_warn(LD_DIR, "No version 3 directory key found in %s", fname);
|
||||||
goto done;
|
goto done;
|
||||||
@ -364,7 +367,7 @@ init_keys(void)
|
|||||||
tor_snprintf(keydir,sizeof(keydir),
|
tor_snprintf(keydir,sizeof(keydir),
|
||||||
"%s"PATH_SEPARATOR"keys"PATH_SEPARATOR"secret_id_key",datadir);
|
"%s"PATH_SEPARATOR"keys"PATH_SEPARATOR"secret_id_key",datadir);
|
||||||
log_info(LD_GENERAL,"Reading/making identity key \"%s\"...",keydir);
|
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;
|
if (!prkey) return -1;
|
||||||
set_identity_key(prkey);
|
set_identity_key(prkey);
|
||||||
|
|
||||||
@ -376,7 +379,7 @@ init_keys(void)
|
|||||||
tor_snprintf(keydir,sizeof(keydir),
|
tor_snprintf(keydir,sizeof(keydir),
|
||||||
"%s"PATH_SEPARATOR"keys"PATH_SEPARATOR"secret_onion_key",datadir);
|
"%s"PATH_SEPARATOR"keys"PATH_SEPARATOR"secret_onion_key",datadir);
|
||||||
log_info(LD_GENERAL,"Reading/making onion key \"%s\"...",keydir);
|
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;
|
if (!prkey) return -1;
|
||||||
set_onion_key(prkey);
|
set_onion_key(prkey);
|
||||||
if (state->LastRotatedOnionKey > 100) { /* allow for some parsing slop. */
|
if (state->LastRotatedOnionKey > 100) { /* allow for some parsing slop. */
|
||||||
@ -393,7 +396,7 @@ init_keys(void)
|
|||||||
tor_snprintf(keydir,sizeof(keydir),
|
tor_snprintf(keydir,sizeof(keydir),
|
||||||
"%s"PATH_SEPARATOR"keys"PATH_SEPARATOR"secret_onion_key.old",datadir);
|
"%s"PATH_SEPARATOR"keys"PATH_SEPARATOR"secret_onion_key.old",datadir);
|
||||||
if (file_status(keydir) == FN_FILE) {
|
if (file_status(keydir) == FN_FILE) {
|
||||||
prkey = init_key_from_file(keydir);
|
prkey = init_key_from_file(keydir, 1, LOG_ERR);
|
||||||
if (prkey)
|
if (prkey)
|
||||||
lastonionkey = prkey;
|
lastonionkey = prkey;
|
||||||
}
|
}
|
||||||
@ -844,7 +847,7 @@ router_is_clique_mode(routerinfo_t *router)
|
|||||||
|
|
||||||
/** My routerinfo. */
|
/** My routerinfo. */
|
||||||
static routerinfo_t *desc_routerinfo = NULL;
|
static routerinfo_t *desc_routerinfo = NULL;
|
||||||
/** DOCDOC */
|
/** My extrainfo */
|
||||||
static extrainfo_t *desc_extrainfo = NULL;
|
static extrainfo_t *desc_extrainfo = NULL;
|
||||||
/** Since when has our descriptor been "clean"? 0 if we need to regenerate it
|
/** Since when has our descriptor been "clean"? 0 if we need to regenerate it
|
||||||
* now. */
|
* now. */
|
||||||
@ -966,7 +969,8 @@ router_get_my_descriptor(void)
|
|||||||
return body;
|
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 *
|
extrainfo_t *
|
||||||
router_get_my_extrainfo(void)
|
router_get_my_extrainfo(void)
|
||||||
{
|
{
|
||||||
@ -1001,10 +1005,9 @@ router_pick_published_address(or_options_t *options, uint32_t *addr)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** If <b>force</b> is true, or our descriptor is out-of-date, rebuild
|
/** If <b>force</b> is true, or our descriptor is out-of-date, rebuild a fresh
|
||||||
* a fresh routerinfo and signed server descriptor for this OR.
|
* routerinfo, signed server descriptor, and extra-info document for this OR.
|
||||||
* Return 0 on success, -1 on temporary error.
|
* Return 0 on success, -1 on temporary error.
|
||||||
* DOCDOC extrainfo.
|
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
router_rebuild_descriptor(int force)
|
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;
|
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
|
int
|
||||||
extrainfo_dump_to_string(char *s, size_t maxlen, extrainfo_t *extrainfo,
|
extrainfo_dump_to_string(char *s, size_t maxlen, extrainfo_t *extrainfo,
|
||||||
crypto_pk_env_t *ident_key)
|
crypto_pk_env_t *ident_key)
|
||||||
|
@ -49,7 +49,9 @@ static void router_dir_info_changed(void);
|
|||||||
/** Global list of a trusted_dir_server_t object for each trusted directory
|
/** Global list of a trusted_dir_server_t object for each trusted directory
|
||||||
* server. */
|
* server. */
|
||||||
static smartlist_t *trusted_dir_servers = NULL;
|
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;
|
static int trusted_dir_servers_certs_changed = 0;
|
||||||
|
|
||||||
/** Global list of all of the routers that we know about. */
|
/** 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.
|
/** Global list of local_routerstatus_t for each router, known or unknown.
|
||||||
* Kept sorted by digest. */
|
* Kept sorted by digest. */
|
||||||
static smartlist_t *routerstatus_list = NULL;
|
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;
|
static digestmap_t *routerstatus_by_desc_digest_map = NULL;
|
||||||
|
|
||||||
/** Map from lowercase nickname to digest of named server, if any. */
|
/** Map from lowercase nickname to digest of named server, if any. */
|
||||||
@ -165,7 +168,8 @@ router_reload_networkstatus(void)
|
|||||||
return 0;
|
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
|
int
|
||||||
trusted_dirs_reload_certs(void)
|
trusted_dirs_reload_certs(void)
|
||||||
{
|
{
|
||||||
@ -183,7 +187,11 @@ trusted_dirs_reload_certs(void)
|
|||||||
return r;
|
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
|
int
|
||||||
trusted_dirs_load_certs_from_string(const char *contents, int from_store)
|
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) {
|
||||||
if (ds->v3_cert->expires < cert->expires) {
|
if (ds->v3_cert->expires < cert->expires) {
|
||||||
authority_cert_free(ds->v3_cert);
|
authority_cert_free(ds->v3_cert);
|
||||||
|
ds->v3_cert = NULL; /* redundant, but let's be safe. */
|
||||||
} else {
|
} else {
|
||||||
|
/* This also covers the case where the certificate is the same
|
||||||
|
* as the one we have. */
|
||||||
authority_cert_free(cert);
|
authority_cert_free(cert);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -221,7 +232,7 @@ trusted_dirs_load_certs_from_string(const char *contents, int from_store)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** DOCDOC */
|
/** Save all v3 key certifiacates to the cached-certs file. */
|
||||||
void
|
void
|
||||||
trusted_dirs_flush_certs_to_disk(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.
|
* 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 {
|
typedef struct store_stats_t {
|
||||||
/** The size of the router log, in bytes. */
|
/** The size of the router log, in bytes. */
|
||||||
size_t journal_len;
|
size_t journal_len;
|
||||||
/** The size of the router store, in bytes. */
|
/** The size of the router store, in bytes. */
|
||||||
size_t store_len;
|
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;
|
size_t bytes_dropped;
|
||||||
} store_stats_t;
|
} store_stats_t;
|
||||||
|
|
||||||
/** DOCDOC */
|
/** Disk usage for cached-routers and cached-routers.new */
|
||||||
static store_stats_t router_store_stats = { 0, 0, 0 };
|
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 };
|
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
|
/** 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
|
* replace the router store with the routers currently in our routerlist, and
|
||||||
* clear the journal. Return 0 on success, -1 on failure.
|
* 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
|
static int
|
||||||
router_rebuild_store(int force, int extrainfo)
|
router_rebuild_store(int force, int extrainfo)
|
||||||
@ -492,7 +506,9 @@ router_rebuild_store(int force, int extrainfo)
|
|||||||
return r;
|
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
|
static int
|
||||||
router_reload_router_list_impl(int extrainfo)
|
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 digestmap_get(routerlist->desc_digest_map, digest);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Return the router in our routerlist whose 20-byte descriptor
|
/** Return the signed descriptor for the router in our routerlist whose
|
||||||
* is <b>digest</b>. Return NULL if no such router is known. */
|
* 20-byte extra-info digest is <b>digest</b>. Return NULL if no such router
|
||||||
|
* is known. */
|
||||||
signed_descriptor_t *
|
signed_descriptor_t *
|
||||||
router_get_by_extrainfo_digest(const char *digest)
|
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);
|
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 *
|
signed_descriptor_t *
|
||||||
extrainfo_get_by_descriptor_digest(const char *digest)
|
extrainfo_get_by_descriptor_digest(const char *digest)
|
||||||
{
|
{
|
||||||
@ -1736,7 +1755,7 @@ routerinfo_free(routerinfo_t *router)
|
|||||||
tor_free(router);
|
tor_free(router);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** DOCDOC */
|
/** Release all storage held by <b>extrainfo</b> */
|
||||||
void
|
void
|
||||||
extrainfo_free(extrainfo_t *extrainfo)
|
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->cache_info.signed_descriptor_body);
|
||||||
tor_free(extrainfo->pending_sig);
|
tor_free(extrainfo->pending_sig);
|
||||||
|
|
||||||
/* Remove once 414/417 is fixed. But I have a hunch... */
|
/* XXXX020 remove this once more bugs go away. */
|
||||||
memset(extrainfo, 88, sizeof(extrainfo_t));
|
memset(extrainfo, 88, sizeof(extrainfo_t)); /* debug bad memory usage */
|
||||||
tor_free(extrainfo);
|
tor_free(extrainfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1756,8 +1775,8 @@ signed_descriptor_free(signed_descriptor_t *sd)
|
|||||||
{
|
{
|
||||||
tor_free(sd->signed_descriptor_body);
|
tor_free(sd->signed_descriptor_body);
|
||||||
|
|
||||||
/* Remove once 414/417 is fixed. But I have a hunch... */
|
/* XXXX020 remove this once more bugs go away. */
|
||||||
memset(sd, 99, sizeof(signed_descriptor_t));
|
memset(sd, 99, sizeof(signed_descriptor_t)); /* Debug bad mem usage */
|
||||||
tor_free(sd);
|
tor_free(sd);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1773,7 +1792,7 @@ signed_descriptor_from_routerinfo(routerinfo_t *ri)
|
|||||||
return sd;
|
return sd;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** DOCDOC */
|
/** Helper: free the storage held by the extrainfo_t in <b>e</b>. */
|
||||||
static void
|
static void
|
||||||
_extrainfo_free(void *e)
|
_extrainfo_free(void *e)
|
||||||
{
|
{
|
||||||
@ -1891,8 +1910,9 @@ routerlist_insert(routerlist_t *rl, routerinfo_t *ri)
|
|||||||
routerlist_check_bug_417();
|
routerlist_check_bug_417();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** DOCDOC
|
/** Adds the extrainfo_t <b>ei</b> to the routerlist <b>rl</b>, if there is a
|
||||||
* Returns true if actually inserted. */
|
* 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
|
static int
|
||||||
extrainfo_insert(routerlist_t *rl, extrainfo_t *ei)
|
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();
|
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
|
static void
|
||||||
routerlist_remove_old(routerlist_t *rl, signed_descriptor_t *sd, int idx)
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** DOCDOC */
|
/** Insert <b>ei</b> into the routerlist, or free it. Other arguments are
|
||||||
|
* as for router_add_to_routerlist(). */
|
||||||
void
|
void
|
||||||
router_add_extrainfo_to_routerlist(extrainfo_t *ei, const char **msg,
|
router_add_extrainfo_to_routerlist(extrainfo_t *ei, const char **msg,
|
||||||
int from_cache, int from_fetch)
|
int from_cache, int from_fetch)
|
||||||
@ -2809,7 +2832,9 @@ router_load_routers_from_string(const char *s, const char *eos,
|
|||||||
smartlist_free(changed);
|
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
|
void
|
||||||
router_load_extrainfo_from_string(const char *s, const char *eos,
|
router_load_extrainfo_from_string(const char *s, const char *eos,
|
||||||
saved_location_t saved_location,
|
saved_location_t saved_location,
|
||||||
@ -3142,8 +3167,8 @@ networkstatus_find_entry(networkstatus_t *ns, const char *digest)
|
|||||||
_compare_digest_to_routerstatus_entry);
|
_compare_digest_to_routerstatus_entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Return the consensus view of the status of the router whose digest is
|
/** Return the consensus view of the status of the router whose identity
|
||||||
* <b>digest</b>, or NULL if we don't know about any such router. */
|
* digest is <b>digest</b>, or NULL if we don't know about any such router. */
|
||||||
local_routerstatus_t *
|
local_routerstatus_t *
|
||||||
router_get_combined_status_by_digest(const char *digest)
|
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);
|
_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 *
|
local_routerstatus_t *
|
||||||
router_get_combined_status_by_descriptor_digest(const char *digest)
|
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();
|
router_dir_info_changed();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** For every router descriptor we are currently downloading by descriptor
|
/** For every router descriptor (or extra-info document if <b>extrainfo</b> is
|
||||||
* digest, set result[d] to 1. DOCDOC extrainfo */
|
* true) we are currently downloading by descriptor digest, set result[d] to
|
||||||
|
* (void*)1. */
|
||||||
static void
|
static void
|
||||||
list_pending_descriptor_downloads(digestmap_t *result, int extrainfo)
|
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
|
static INLINE int
|
||||||
should_download_extrainfo(signed_descriptor_t *sd,
|
should_download_extrainfo(signed_descriptor_t *sd,
|
||||||
const routerlist_t *rl,
|
const routerlist_t *rl,
|
||||||
@ -4689,13 +4719,14 @@ should_download_extrainfo(signed_descriptor_t *sd,
|
|||||||
time_t now)
|
time_t now)
|
||||||
{
|
{
|
||||||
const char *d = sd->extra_info_digest;
|
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 &&
|
sd->ei_dl_status.next_attempt_at <= now &&
|
||||||
!digestmap_get(rl->extra_info_map, d) &&
|
!digestmap_get(rl->extra_info_map, d) &&
|
||||||
!digestmap_get(pending, d));
|
!digestmap_get(pending, d));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** DOCDOC */
|
/** Laucnch extrainfo downloads as needed. */
|
||||||
void
|
void
|
||||||
update_extrainfo_downloads(time_t now)
|
update_extrainfo_downloads(time_t now)
|
||||||
{
|
{
|
||||||
@ -4967,8 +4998,12 @@ router_differences_are_cosmetic(routerinfo_t *r1, routerinfo_t *r2)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** DOCDOC Returns 1 for "reject with message"; -1 for "reject silently",
|
/** Check whether <b>ri</b> is a router compatible with the extrainfo document
|
||||||
* 0 for "accept". */
|
* <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
|
int
|
||||||
routerinfo_incompatible_with_extrainfo(routerinfo_t *ri, extrainfo_t *ei,
|
routerinfo_incompatible_with_extrainfo(routerinfo_t *ri, extrainfo_t *ei,
|
||||||
const char **msg)
|
const char **msg)
|
||||||
|
Loading…
Reference in New Issue
Block a user