r15170@catbus: nickm | 2007-09-19 11:41:50 -0400

Carry a new evdns function over from libevent: do not rely on compile-time code to set the transaction ID correctly.  This will be important when we finally drop our internal copy of eventdns.c


svn:r11517
This commit is contained in:
Nick Mathewson 2007-09-19 15:53:36 +00:00
parent faeedbb8af
commit 5e81b0ecb8
3 changed files with 60 additions and 32 deletions

View File

@ -179,11 +179,21 @@ evdns_log_cb(int warn, const char *msg)
log(severity, LD_EXIT, "eventdns: %s", msg);
}
/** Helper: generate a good random transaction ID. */
static uint16_t
dns_get_transaction_id(void)
{
uint16_t result;
crypto_rand((void*)&result, sizeof(result));
return result;
}
/** Initialize the DNS subsystem; called by the OR process. */
int
dns_init(void)
{
init_cache_map();
evdns_set_transaction_id_fn(dns_get_transaction_id);
if (server_mode(get_options()))
return configure_nameservers(1);
return 0;

View File

@ -1034,43 +1034,59 @@ err:
#undef GET8
}
static uint16_t
default_transaction_id_fn(void)
{
u16 trans_id;
#ifdef DNS_USE_CPU_CLOCK_FOR_ID
struct timespec ts;
#ifdef CLOCK_MONOTONIC
if (clock_gettime(CLOCK_MONOTONIC, &ts) == -1)
#else
if (clock_gettime(CLOCK_REALTIME, &ts) == -1)
#endif
event_err(1, "clock_gettime");
trans_id = ts.tv_nsec & 0xffff;
#endif
#ifdef DNS_USE_GETTIMEOFDAY_FOR_ID
struct timeval tv;
gettimeofday(&tv, NULL);
trans_id = tv.tv_usec & 0xffff;
#endif
#ifdef DNS_USE_OPENSSL_FOR_ID
if (RAND_pseudo_bytes((u8 *) &trans_id, 2) == -1) {
/* in the case that the RAND call fails we back */
/* down to using gettimeofday. */
/*
struct timeval tv;
gettimeofday(&tv, NULL);
trans_id = tv.tv_usec & 0xffff;
*/
abort();
}
#endif
return (unsigned short) trans_id;
}
static uint16_t (*trans_id_function)(void) = default_transaction_id_fn;
void
evdns_set_transaction_id_fn(uint16_t (*fn)(void))
{
if (fn)
trans_id_function = fn;
else
trans_id_function = default_transaction_id_fn;
}
/* Try to choose a strong transaction id which isn't already in flight */
static u16
transaction_id_pick(void) {
for (;;) {
const struct request *req = req_head, *started_at;
#ifdef DNS_USE_CPU_CLOCK_FOR_ID
struct timespec ts;
u16 trans_id;
#ifdef CLOCK_MONOTONIC
if (clock_gettime(CLOCK_MONOTONIC, &ts) == -1)
#else
if (clock_gettime(CLOCK_REALTIME, &ts) == -1)
#endif
event_err(1, "clock_gettime");
trans_id = ts.tv_nsec & 0xffff;
#endif
#ifdef DNS_USE_GETTIMEOFDAY_FOR_ID
struct timeval tv;
u16 trans_id;
gettimeofday(&tv, NULL);
trans_id = tv.tv_usec & 0xffff;
#endif
#ifdef DNS_USE_OPENSSL_FOR_ID
u16 trans_id;
if (RAND_pseudo_bytes((u8 *) &trans_id, 2) == -1) {
/* in the case that the RAND call fails we back */
/* down to using gettimeofday. */
/*
struct timeval tv;
gettimeofday(&tv, NULL);
trans_id = tv.tv_usec & 0xffff;
*/
abort();
}
#endif
u16 trans_id = trans_id_function();
if (trans_id == 0xffff) continue;
/* now check to see if that id is already inflight */

View File

@ -281,6 +281,8 @@ void evdns_search_ndots_set(const int ndots);
typedef void (*evdns_debug_log_fn_type)(int is_warning, const char *msg);
void evdns_set_log_fn(evdns_debug_log_fn_type fn);
void evdns_set_transaction_id_fn(uint16_t (*fn)(void));
#define DNS_NO_SEARCH 1
/* Structures and functions used to implement a DNS server. */