Skip to content

Commit

Permalink
Merge defd941 into 7b6e81f
Browse files Browse the repository at this point in the history
  • Loading branch information
nmathewson committed Feb 19, 2020
2 parents 7b6e81f + defd941 commit 3a3eb05
Show file tree
Hide file tree
Showing 9 changed files with 90 additions and 67 deletions.
3 changes: 3 additions & 0 deletions changes/ticket33366
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
o Minor features (compilation size):
- Most Server-side DNS code is now disabled when building without
support for relay mode. Closes ticket 33366.
1 change: 0 additions & 1 deletion src/core/mainloop/mainloop.c
Original file line number Diff line number Diff line change
Expand Up @@ -966,7 +966,6 @@ conn_close_if_marked(int i)
return 0; /* nothing to see here, move along */
now = time(NULL);
assert_connection_ok(conn, now);
/* assert_all_pending_dns_resolves_ok(); */

log_debug(LD_NET,"Cleaning up connection (fd "TOR_SOCKET_T_FORMAT").",
conn->s);
Expand Down
19 changes: 17 additions & 2 deletions src/core/or/connection_edge.c
Original file line number Diff line number Diff line change
Expand Up @@ -432,6 +432,21 @@ warn_if_hs_unreachable(const edge_connection_t *conn, uint8_t reason)
}
}

/** Given a TTL (in seconds) from a DNS response or from a relay, determine
* what TTL clients and relays should actually use for caching it. */
uint32_t
clip_dns_ttl(uint32_t ttl)
{
/* This logic is a defense against "DefectTor" DNS-based traffic
* confirmation attacks, as in https://nymity.ch/tor-dns/tor-dns.pdf .
* We only give two values: a "low" value and a "high" value.
*/
if (ttl < MIN_DNS_TTL)
return MIN_DNS_TTL;
else
return MAX_DNS_TTL;
}

/** Send a relay end cell from stream <b>conn</b> down conn's circuit, and
* remember that we've done so. If this is not a client connection, set the
* relay end cell's reason for closing as <b>reason</b>.
Expand Down Expand Up @@ -480,7 +495,7 @@ connection_edge_end(edge_connection_t *conn, uint8_t reason)
memcpy(payload+1, tor_addr_to_in6_addr8(&conn->base_.addr), 16);
addrlen = 16;
}
set_uint32(payload+1+addrlen, htonl(dns_clip_ttl(conn->address_ttl)));
set_uint32(payload+1+addrlen, htonl(clip_dns_ttl(conn->address_ttl)));
payload_len += 4+addrlen;
}

Expand Down Expand Up @@ -845,7 +860,7 @@ connected_cell_format_payload(uint8_t *payload_out,
return -1;
}

set_uint32(payload_out + connected_payload_len, htonl(dns_clip_ttl(ttl)));
set_uint32(payload_out + connected_payload_len, htonl(clip_dns_ttl(ttl)));
connected_payload_len += 4;

tor_assert(connected_payload_len <= MAX_CONNECTED_CELL_PAYLOAD_LEN);
Expand Down
15 changes: 15 additions & 0 deletions src/core/or/connection_edge.h
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,21 @@ void connection_ap_warn_and_unmark_if_pending_circ(
entry_connection_t *entry_conn,
const char *where);

/** Lowest value for DNS ttl that a server should give or a client should
* believe. */
#define MIN_DNS_TTL (5*60)
/** Highest value for DNS ttl that a server should give or a client should
* believe. */
#define MAX_DNS_TTL (60*60)
/** How long do we keep DNS cache entries before purging them (regardless of
* their TTL)? */
#define MAX_DNS_ENTRY_AGE (3*60*60)
/** How long do we cache/tell clients to cache DNS records when no TTL is
* known? */
#define DEFAULT_DNS_TTL (30*60)

uint32_t clip_dns_ttl(uint32_t ttl);

int connection_half_edge_is_valid_data(const smartlist_t *half_conns,
streamid_t stream_id);
int connection_half_edge_is_valid_sendme(const smartlist_t *half_conns,
Expand Down
3 changes: 1 addition & 2 deletions src/feature/client/addressmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
#include "app/config/config.h"
#include "core/or/connection_edge.h"
#include "feature/control/control_events.h"
#include "feature/relay/dns.h"
#include "feature/nodelist/nodelist.h"
#include "feature/nodelist/routerset.h"

Expand Down Expand Up @@ -689,7 +688,7 @@ client_dns_set_addressmap_impl(entry_connection_t *for_conn,
if (ttl<0)
ttl = DEFAULT_DNS_TTL;
else
ttl = dns_clip_ttl(ttl);
ttl = clip_dns_ttl(ttl);

if (exitname) {
/* XXXX fails to ever get attempts to get an exit address of
Expand Down
45 changes: 5 additions & 40 deletions src/feature/relay/dns.c
Original file line number Diff line number Diff line change
Expand Up @@ -268,22 +268,6 @@ has_dns_init_failed(void)
return nameserver_config_failed;
}

/** Helper: Given a TTL from a DNS response, determine what TTL to give the
* OP that asked us to resolve it, and how long to cache that record
* ourselves. */
uint32_t
dns_clip_ttl(uint32_t ttl)
{
/* This logic is a defense against "DefectTor" DNS-based traffic
* confirmation attacks, as in https://nymity.ch/tor-dns/tor-dns.pdf .
* We only give two values: a "low" value and a "high" value.
*/
if (ttl < MIN_DNS_TTL_AT_EXIT)
return MIN_DNS_TTL_AT_EXIT;
else
return MAX_DNS_TTL_AT_EXIT;
}

/** Helper: free storage held by an entry in the DNS cache. */
static void
free_cached_resolve_(cached_resolve_t *r)
Expand Down Expand Up @@ -521,7 +505,7 @@ send_resolved_cell,(edge_connection_t *conn, uint8_t answer_type,
uint32_t ttl;

buf[0] = answer_type;
ttl = dns_clip_ttl(conn->address_ttl);
ttl = clip_dns_ttl(conn->address_ttl);

switch (answer_type)
{
Expand Down Expand Up @@ -593,7 +577,7 @@ send_resolved_hostname_cell,(edge_connection_t *conn,
size_t namelen = strlen(hostname);

tor_assert(namelen < 256);
ttl = dns_clip_ttl(conn->address_ttl);
ttl = clip_dns_ttl(conn->address_ttl);

buf[0] = RESOLVED_TYPE_HOSTNAME;
buf[1] = (uint8_t)namelen;
Expand Down Expand Up @@ -987,25 +971,6 @@ assert_connection_edge_not_dns_pending(edge_connection_t *conn)
#endif /* 1 */
}

/** Log an error and abort if any connection waiting for a DNS resolve is
* corrupted. */
void
assert_all_pending_dns_resolves_ok(void)
{
pending_connection_t *pend;
cached_resolve_t **resolve;

HT_FOREACH(resolve, cache_map, &cache_root) {
for (pend = (*resolve)->pending_connections;
pend;
pend = pend->next) {
assert_connection_ok(TO_CONN(pend->conn), 0);
tor_assert(!SOCKET_OK(pend->conn->base_.s));
tor_assert(!connection_in_array(TO_CONN(pend->conn)));
}
}
}

/** Remove <b>conn</b> from the list of connections waiting for conn-\>address.
*/
void
Expand Down Expand Up @@ -1063,7 +1028,7 @@ connection_dns_remove(edge_connection_t *conn)
* the resolve for <b>address</b> itself, and remove any cached results for
* <b>address</b> from the cache.
*/
MOCK_IMPL(void,
MOCK_IMPL(STATIC void,
dns_cancel_pending_resolve,(const char *address))
{
pending_connection_t *pend;
Expand Down Expand Up @@ -1338,7 +1303,7 @@ make_pending_resolve_cached(cached_resolve_t *resolve)
resolve->ttl_hostname < ttl)
ttl = resolve->ttl_hostname;

set_expiry(new_resolve, time(NULL) + dns_clip_ttl(ttl));
set_expiry(new_resolve, time(NULL) + clip_dns_ttl(ttl));
}

assert_cache_ok();
Expand Down Expand Up @@ -2188,7 +2153,7 @@ dns_cache_handle_oom(time_t now, size_t min_remove_bytes)
total_bytes_removed += bytes_removed;

/* Increase time_inc by a reasonable fraction. */
time_inc += (MAX_DNS_TTL_AT_EXIT / 4);
time_inc += (MAX_DNS_TTL / 4);
} while (total_bytes_removed < min_remove_bytes);

return total_bytes_removed;
Expand Down
61 changes: 44 additions & 17 deletions src/feature/relay/dns.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,36 +12,63 @@
#ifndef TOR_DNS_H
#define TOR_DNS_H

/** Lowest value for DNS ttl that a server will give. */
#define MIN_DNS_TTL_AT_EXIT (5*60)
/** Highest value for DNS ttl that a server will give. */
#define MAX_DNS_TTL_AT_EXIT (60*60)

/** How long do we keep DNS cache entries before purging them (regardless of
* their TTL)? */
#define MAX_DNS_ENTRY_AGE (3*60*60)
/** How long do we cache/tell clients to cache DNS records when no TTL is
* known? */
#define DEFAULT_DNS_TTL (30*60)
#ifdef HAVE_MODULE_RELAY

int dns_init(void);
int has_dns_init_failed(void);
void dns_free_all(void);
uint32_t dns_clip_ttl(uint32_t ttl);
int dns_reset(void);
void connection_dns_remove(edge_connection_t *conn);
void assert_connection_edge_not_dns_pending(edge_connection_t *conn);
void assert_all_pending_dns_resolves_ok(void);
MOCK_DECL(void,dns_cancel_pending_resolve,(const char *question));
int dns_resolve(edge_connection_t *exitconn);
void dns_launch_correctness_checks(void);
int dns_seems_to_be_broken(void);
int dns_seems_to_be_broken_for_ipv6(void);
void dns_reset_correctness_checks(void);
size_t dns_cache_total_allocation(void);
void dump_dns_mem_usage(int severity);
size_t dns_cache_handle_oom(time_t now, size_t min_remove_bytes);

/* These functions are only used within the feature/relay module, and don't
* need stubs. */
void dns_free_all(void);
void dns_launch_correctness_checks(void);

#else /* !defined(HAVE_MODULE_RELAY) */

#define dns_init() (0)
#define dns_seems_to_be_broken() (0)
#define has_dns_init_failed() (0)
#define dns_cache_total_allocation() (0)

#define dns_reset_correctness_checks() STMT_NIL

#define assert_connection_edge_not_dns_pending(conn) \
((void)(conn))
#define dump_dns_mem_usage(severity)\
((void)(severity))
#define dns_cache_handle_oom(now, bytes) \
((void)(now), (void)(bytes), 0)

#define connection_dns_remove(conn) \
STMT_BEGIN \
(void)(conn); \
tor_assert_nonfatal_unreached(); \
STMT_END

static inline int
dns_reset(void)
{
return 0;
}
static inline int
dns_resolve(edge_connection_t *exitconn)
{
(void)exitconn;
tor_assert_nonfatal_unreached();
return -1;
}

#endif /* defined(HAVE_MODULE_RELAY) */

#ifdef DNS_PRIVATE
#include "feature/relay/dns_structs.h"

Expand All @@ -50,6 +77,7 @@ size_t number_of_configured_nameservers(void);
tor_addr_t *configured_nameserver_address(const size_t idx);
#endif

MOCK_DECL(STATIC void,dns_cancel_pending_resolve,(const char *question));
MOCK_DECL(STATIC int,dns_resolve_impl,(edge_connection_t *exitconn,
int is_resolve,or_circuit_t *oncirc, char **hostname_out,
int *made_connection_pending_out, cached_resolve_t **resolve_out));
Expand All @@ -74,4 +102,3 @@ launch_resolve,(cached_resolve_t *resolve));
#endif /* defined(DNS_PRIVATE) */

#endif /* !defined(TOR_DNS_H) */

2 changes: 1 addition & 1 deletion src/feature/relay/include.am
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@

# Legacy shared relay code: migrate to the relay module over time
LIBTOR_APP_A_SOURCES += \
src/feature/relay/dns.c \
src/feature/relay/ext_orport.c \
src/feature/relay/onion_queue.c \
src/feature/relay/router.c \
Expand All @@ -11,6 +10,7 @@ LIBTOR_APP_A_SOURCES += \

# ADD_C_FILE: INSERT SOURCES HERE.
MODULE_RELAY_SOURCES = \
src/feature/relay/dns.c \
src/feature/relay/routermode.c \
src/feature/relay/relay_config.c \
src/feature/relay/relay_periodic.c \
Expand Down
8 changes: 4 additions & 4 deletions src/test/test_dns.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,11 +80,11 @@ test_dns_clip_ttl(void *arg)
{
(void)arg;

uint32_t ttl_mid = MIN_DNS_TTL_AT_EXIT / 2 + MAX_DNS_TTL_AT_EXIT / 2;
uint32_t ttl_mid = MIN_DNS_TTL / 2 + MAX_DNS_TTL / 2;

tt_int_op(dns_clip_ttl(MIN_DNS_TTL_AT_EXIT - 1),OP_EQ,MIN_DNS_TTL_AT_EXIT);
tt_int_op(dns_clip_ttl(ttl_mid),OP_EQ,MAX_DNS_TTL_AT_EXIT);
tt_int_op(dns_clip_ttl(MAX_DNS_TTL_AT_EXIT + 1),OP_EQ,MAX_DNS_TTL_AT_EXIT);
tt_int_op(clip_dns_ttl(MIN_DNS_TTL - 1),OP_EQ,MIN_DNS_TTL);
tt_int_op(clip_dns_ttl(ttl_mid),OP_EQ,MAX_DNS_TTL);
tt_int_op(clip_dns_ttl(MAX_DNS_TTL + 1),OP_EQ,MAX_DNS_TTL);

done:
return;
Expand Down

0 comments on commit 3a3eb05

Please sign in to comment.