Commit a0cf95e1 authored by Nick Mathewson's avatar Nick Mathewson 🎨
Browse files

Add some debugging asserts to dns.c; these are too expensive to leave in permanently.


svn:r6756
parent 3388722c
...@@ -57,12 +57,15 @@ typedef struct pending_connection_t { ...@@ -57,12 +57,15 @@ typedef struct pending_connection_t {
struct pending_connection_t *next; struct pending_connection_t *next;
} pending_connection_t; } pending_connection_t;
#define CACHED_RESOLVE_MAGIC 0x1234F00D
/** A DNS request: possibly completed, possibly pending; cached_resolve /** A DNS request: possibly completed, possibly pending; cached_resolve
* structs are stored at the OR side in a hash table, and as a linked * structs are stored at the OR side in a hash table, and as a linked
* list from oldest to newest. * list from oldest to newest.
*/ */
typedef struct cached_resolve_t { typedef struct cached_resolve_t {
HT_ENTRY(cached_resolve_t) node; HT_ENTRY(cached_resolve_t) node;
uint32_t magic;
char address[MAX_ADDRESSLEN]; /**< The hostname to be resolved. */ char address[MAX_ADDRESSLEN]; /**< The hostname to be resolved. */
uint32_t addr; /**< IPv4 addr for <b>address</b>. */ uint32_t addr; /**< IPv4 addr for <b>address</b>. */
char state; /**< 0 is pending; 1 means answer is valid; 2 means resolve char state; /**< 0 is pending; 1 means answer is valid; 2 means resolve
...@@ -87,6 +90,8 @@ static int dnsworker_main(void *data); ...@@ -87,6 +90,8 @@ static int dnsworker_main(void *data);
static int spawn_dnsworker(void); static int spawn_dnsworker(void);
static int spawn_enough_dnsworkers(void); static int spawn_enough_dnsworkers(void);
#endif #endif
static void assert_cache_ok(void);
static void assert_resolve_ok(cached_resolve_t *resolve);
/** Hash table of cached_resolve objects. */ /** Hash table of cached_resolve objects. */
static HT_HEAD(cache_map, cached_resolve_t) cache_root; static HT_HEAD(cache_map, cached_resolve_t) cache_root;
...@@ -97,6 +102,7 @@ static INLINE int ...@@ -97,6 +102,7 @@ static INLINE int
cached_resolves_eq(cached_resolve_t *a, cached_resolve_t *b) cached_resolves_eq(cached_resolve_t *a, cached_resolve_t *b)
{ {
/* make this smarter one day? */ /* make this smarter one day? */
assert_resolve_ok(a); // Not b; b may be just a search.
return !strncmp(a->address, b->address, MAX_ADDRESSLEN); return !strncmp(a->address, b->address, MAX_ADDRESSLEN);
} }
...@@ -192,6 +198,7 @@ _free_cached_resolve(cached_resolve_t *r) ...@@ -192,6 +198,7 @@ _free_cached_resolve(cached_resolve_t *r)
r->pending_connections = victim->next; r->pending_connections = victim->next;
tor_free(victim); tor_free(victim);
} }
r->magic = 0xFF00FF00;
tor_free(r); tor_free(r);
} }
...@@ -258,6 +265,7 @@ purge_expired_resolves(uint32_t now) ...@@ -258,6 +265,7 @@ purge_expired_resolves(uint32_t now)
newest_cached_resolve = NULL; /* then make sure the list's tail knows newest_cached_resolve = NULL; /* then make sure the list's tail knows
* that too */ * that too */
HT_REMOVE(cache_map, &cache_root, resolve); HT_REMOVE(cache_map, &cache_root, resolve);
resolve->magic = 0xF0BBF0BB;
tor_free(resolve); tor_free(resolve);
} }
} }
...@@ -340,6 +348,8 @@ dns_resolve(connection_t *exitconn) ...@@ -340,6 +348,8 @@ dns_resolve(connection_t *exitconn)
assert_connection_ok(exitconn, 0); assert_connection_ok(exitconn, 0);
tor_assert(exitconn->s == -1); tor_assert(exitconn->s == -1);
assert_cache_ok();
/* first check if exitconn->address is an IP. If so, we already /* first check if exitconn->address is an IP. If so, we already
* know the answer. */ * know the answer. */
if (tor_inet_aton(exitconn->address, &in) != 0) { if (tor_inet_aton(exitconn->address, &in) != 0) {
...@@ -398,6 +408,7 @@ dns_resolve(connection_t *exitconn) ...@@ -398,6 +408,7 @@ dns_resolve(connection_t *exitconn)
} }
/* not there, need to add it */ /* not there, need to add it */
resolve = tor_malloc_zero(sizeof(cached_resolve_t)); resolve = tor_malloc_zero(sizeof(cached_resolve_t));
resolve->magic = CACHED_RESOLVE_MAGIC;
resolve->state = CACHE_STATE_PENDING; resolve->state = CACHE_STATE_PENDING;
resolve->expire = now + DEFAULT_DNS_TTL; /* this will get replaced. */ resolve->expire = now + DEFAULT_DNS_TTL; /* this will get replaced. */
strlcpy(resolve->address, exitconn->address, sizeof(resolve->address)); strlcpy(resolve->address, exitconn->address, sizeof(resolve->address));
...@@ -411,6 +422,7 @@ dns_resolve(connection_t *exitconn) ...@@ -411,6 +422,7 @@ dns_resolve(connection_t *exitconn)
insert_resolve(resolve); insert_resolve(resolve);
log_debug(LD_EXIT,"Assigning question %s to dnsworker.", log_debug(LD_EXIT,"Assigning question %s to dnsworker.",
escaped_safe_str(exitconn->address)); escaped_safe_str(exitconn->address));
assert_cache_ok();
return assign_to_dnsworker(exitconn); return assign_to_dnsworker(exitconn);
} }
...@@ -581,7 +593,7 @@ dns_purge_resolve(cached_resolve_t *resolve) ...@@ -581,7 +593,7 @@ dns_purge_resolve(cached_resolve_t *resolve)
/* remove resolve from the map */ /* remove resolve from the map */
HT_REMOVE(cache_map, &cache_root, resolve); HT_REMOVE(cache_map, &cache_root, resolve);
resolve->magic = 0xAAAAAAAA;
tor_free(resolve); tor_free(resolve);
} }
...@@ -593,7 +605,8 @@ dns_purge_resolve(cached_resolve_t *resolve) ...@@ -593,7 +605,8 @@ dns_purge_resolve(cached_resolve_t *resolve)
* DNS_RESOLVE_{FAILED_TRANSIENT|FAILED_PERMANENT|SUCCEEDED}. * DNS_RESOLVE_{FAILED_TRANSIENT|FAILED_PERMANENT|SUCCEEDED}.
*/ */
static void static void
dns_found_answer(const char *address, uint32_t addr, char outcome, uint32_t ttl) dns_found_answer(const char *address, uint32_t addr, char outcome,
uint32_t ttl)
{ {
pending_connection_t *pend; pending_connection_t *pend;
cached_resolve_t search; cached_resolve_t search;
...@@ -601,6 +614,8 @@ dns_found_answer(const char *address, uint32_t addr, char outcome, uint32_t ttl) ...@@ -601,6 +614,8 @@ dns_found_answer(const char *address, uint32_t addr, char outcome, uint32_t ttl)
connection_t *pendconn; connection_t *pendconn;
circuit_t *circ; circuit_t *circ;
assert_cache_ok();
strlcpy(search.address, address, sizeof(search.address)); strlcpy(search.address, address, sizeof(search.address));
resolve = HT_FIND(cache_map, &cache_root, &search); resolve = HT_FIND(cache_map, &cache_root, &search);
...@@ -608,6 +623,7 @@ dns_found_answer(const char *address, uint32_t addr, char outcome, uint32_t ttl) ...@@ -608,6 +623,7 @@ dns_found_answer(const char *address, uint32_t addr, char outcome, uint32_t ttl)
log_info(LD_EXIT,"Resolved unasked address %s; caching anyway.", log_info(LD_EXIT,"Resolved unasked address %s; caching anyway.",
escaped_safe_str(address)); escaped_safe_str(address));
resolve = tor_malloc_zero(sizeof(cached_resolve_t)); resolve = tor_malloc_zero(sizeof(cached_resolve_t));
resolve->magic = CACHED_RESOLVE_MAGIC;
resolve->state = (outcome == DNS_RESOLVE_SUCCEEDED) ? resolve->state = (outcome == DNS_RESOLVE_SUCCEEDED) ?
CACHE_STATE_VALID : CACHE_STATE_FAILED; CACHE_STATE_VALID : CACHE_STATE_FAILED;
strlcpy(resolve->address, address, sizeof(resolve->address)); strlcpy(resolve->address, address, sizeof(resolve->address));
...@@ -695,6 +711,8 @@ dns_found_answer(const char *address, uint32_t addr, char outcome, uint32_t ttl) ...@@ -695,6 +711,8 @@ dns_found_answer(const char *address, uint32_t addr, char outcome, uint32_t ttl)
if (outcome == DNS_RESOLVE_FAILED_TRANSIENT) { /* remove from cache */ if (outcome == DNS_RESOLVE_FAILED_TRANSIENT) { /* remove from cache */
dns_purge_resolve(resolve); dns_purge_resolve(resolve);
} }
assert_cache_ok();
} }
#ifndef USE_EVENTDNS #ifndef USE_EVENTDNS
...@@ -1175,3 +1193,24 @@ assign_to_dnsworker(connection_t *exitconn) ...@@ -1175,3 +1193,24 @@ assign_to_dnsworker(connection_t *exitconn)
} }
#endif /* USE_EVENTDNS */ #endif /* USE_EVENTDNS */
static void
assert_resolve_ok(cached_resolve_t *resolve)
{
tor_assert(resolve);
tor_assert(resolve->magic == CACHED_RESOLVE_MAGIC);
tor_assert(strlen(resolve->address) < MAX_ADDRESSLEN);
tor_assert(! resolve->next || resolve->next->magic == CACHED_RESOLVE_MAGIC);
}
static void
assert_cache_ok(void)
{
cached_resolve_t **resolve;
tor_assert(_cache_map_HT_REP_OK(&cache_root));
HT_FOREACH(resolve, cache_map, &cache_root) {
assert_resolve_ok(*resolve);
}
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment