r8608@Kushana: nickm | 2006-08-27 16:57:47 -0400

Make it possible to change nameserver options while Tor is running.


svn:r8255
This commit is contained in:
Nick Mathewson 2006-08-28 03:15:55 +00:00
parent be7054c626
commit 54ca0387a5
6 changed files with 84 additions and 27 deletions

View File

@ -100,7 +100,8 @@ N . Improve memory usage on tight-memory machines.
reload.
o Fail when we have no configured nameservers!
o Make it the default on platforms where it works.
- Make resolv.conf (or local equivalent) get checked on reload,
- Document SearchDomains, ResolvConf options
o Make resolv.conf (or local equivalent) get checked on reload,
settable while running, etc.
- Add ipv6 support; make API closer to getaddrinfo(). (i.e., allow a
single AAAA/A query, return cname as well)

View File

@ -802,8 +802,13 @@ options_act(or_options_t *old_options)
inform_testing_reachability();
}
cpuworkers_rotate();
dnsworkers_rotate();
dns_reset();
}
#ifdef USE_EVENTDNS
else {
dns_reset();
}
#endif
}
/* Check if we need to parse and add the EntryNodes config option. */
@ -2555,6 +2560,7 @@ options_transition_affects_workers(or_options_t *old_options,
if (!opt_streq(old_options->DataDirectory, new_options->DataDirectory) ||
old_options->NumCpus != new_options->NumCpus ||
old_options->ORPort != new_options->ORPort ||
old_options->SearchDomains != new_options->SearchDomains ||
old_options->SafeLogging != new_options->SafeLogging ||
!config_lines_eq(old_options->Logs, new_options->Logs))
return 1;

View File

@ -101,20 +101,28 @@ static void dns_found_answer(const char *address, uint32_t addr, char outcome,
static void send_resolved_cell(edge_connection_t *conn, uint8_t answer_type);
static int launch_resolve(edge_connection_t *exitconn);
#ifndef USE_EVENTDNS
static void dnsworkers_rotate(void);
static int dnsworker_main(void *data);
static int spawn_dnsworker(void);
static int spawn_enough_dnsworkers(void);
#else
static int configure_nameservers(void);
static int configure_nameservers(int force);
#endif
#ifdef DEBUG_DNS_CACHE
static void _assert_cache_ok(void);
#define assert_cache_ok() _assert_cache_ok()
#else
#define assert_cache_ok() do {} while(0)
#define assert_cache_ok() do {} while (0)
#endif
static void assert_resolve_ok(cached_resolve_t *resolve);
#ifdef USE_EVENTDNS
/* DOCDOC */
static int nameservers_configured = 0;
static char *resolv_conf_fname = NULL;
static time_t resolv_conf_mtime = 0;
#endif
/** Hash table of cached_resolve objects. */
static HT_HEAD(cache_map, cached_resolve_t) cache_root;
@ -164,14 +172,37 @@ int
dns_init(void)
{
init_cache_map();
dnsworkers_rotate();
#ifdef USE_EVENTDNS
if (server_mode(get_options()))
return configure_nameservers();
return configure_nameservers(1);
#else
dnsworkers_rotate();
#endif
return 0;
}
/* DOCDOC */
void
dns_reset(void)
{
#ifdef USE_EVENTDNS
or_options_t *options = get_options();
if (! server_mode(options)) {
eventdns_clear_nameservers_and_suspend();
eventdns_search_clear();
nameservers_configured = 0;
tor_free(resolv_conf_fname);
resolv_conf_mtime = 0;
} else {
if (configure_nameservers(0) < 0)
/* XXXX */
return;
}
#else
dnsworkers_rotate();
#endif
}
uint32_t
dns_clip_ttl(uint32_t ttl)
{
@ -910,7 +941,7 @@ connection_dns_process_inbuf(connection_t *conn)
/** Close and re-open all idle dnsworkers; schedule busy ones to be closed
* and re-opened once they're no longer busy.
**/
void
static void
dnsworkers_rotate(void)
{
connection_t *dnsconn;
@ -1162,10 +1193,6 @@ eventdns_err_is_transient(int err)
return 0;
}
}
void
dnsworkers_rotate(void)
{
}
int
connection_dns_finished_flushing(connection_t *conn)
{
@ -1187,26 +1214,37 @@ connection_dns_reached_eof(connection_t *conn)
tor_assert(0);
return 0;
}
static int nameservers_configured = 0;
/* DOCDOC */
static int
configure_nameservers(void)
configure_nameservers(int force)
{
or_options_t *options;
const char *conf_fname;
struct stat st;
if (nameservers_configured)
return 0;
options = get_options();
eventdns_set_log_fn(eventdns_log_cb);
conf_fname = options->ResolvConf;
#ifndef MS_WINDOWS
if (!conf_fname) conf_fname = "/etc/resolv.conf";
if (!conf_fname)
conf_fname = "/etc/resolv.conf";
#endif
eventdns_set_log_fn(eventdns_log_cb);
if (conf_fname) {
if (stat(conf_fname, &st)) {
log_warn(LD_EXIT, "Unable to stat resolver configuration in '%s'",
conf_fname);
return -1;
}
if (!force && resolv_conf_fname && !strcmp(conf_fname,resolv_conf_fname)
&& st.st_mtime == resolv_conf_mtime) {
log_info(LD_EXIT, "No change to '%s'", conf_fname);
return 0;
}
if (nameservers_configured) {
eventdns_search_clear();
eventdns_clear_nameservers_and_suspend();
}
log_info(LD_EXIT, "Parsing resolver configuration in '%s'", conf_fname);
if (eventdns_resolv_conf_parse(DNS_OPTIONS_ALL, conf_fname))
return -1;
@ -1214,9 +1252,18 @@ configure_nameservers(void)
log_warn(LD_EXIT, "Unable to find any nameservers in '%s'.", conf_fname);
return -1;
}
tor_free(resolv_conf_fname);
resolv_conf_fname = tor_strdup(resolv_conf_fname);
resolv_conf_mtime = st.st_mtime;
if (nameservers_configured)
eventdns_resume();
}
#ifdef MS_WINDOWS
else {
if (nameservers_configured) {
eventdns_search_clear();
eventdns_clear_nameservers_and_suspend();
}
if (eventdns_config_windows_nameservers())
return -1;
if (eventdns_count_nameservers() == 0) {
@ -1225,6 +1272,10 @@ configure_nameservers(void)
"ResolvConf file in your torrc?");
return -1;
}
if (nameservers_configured)
eventdns_resume();
tor_free(resolv_conf_fname);
resolv_conf_mtime = 0;
}
#endif
@ -1275,7 +1326,7 @@ launch_resolve(edge_connection_t *exitconn)
int r;
int options = get_options()->SearchDomains ? 0 : DNS_QUERY_NO_SEARCH;
if (!nameservers_configured)
if (configure_nameservers() < 0)
if (configure_nameservers(1) < 0)
return -1;
log_info(LD_EXIT, "Launching eventdns request for %s",
escaped_safe_str(exitconn->_base.address));
@ -1338,3 +1389,4 @@ _assert_cache_ok(void)
_compare_cached_resolves_by_expiry);
}
#endif

View File

@ -553,7 +553,7 @@ nameserver_failed(struct nameserver *const ns, const char *msg) {
global_good_nameservers--;
assert(global_good_nameservers >= 0);
if (global_good_nameservers == 0) {
log("All nameservers have failed");
log(1,"All nameservers have failed");
}
ns->state = 0;
@ -561,7 +561,7 @@ nameserver_failed(struct nameserver *const ns, const char *msg) {
evtimer_set(&ns->timeout_event, nameserver_prod_callback, ns);
if (evtimer_add(&ns->timeout_event, (struct timeval *) &global_nameserver_timeouts[0]) < 0) {
log("Error from libevent when adding timer event for %s",
log(1,"Error from libevent when adding timer event for %s",
debug_ntoa(ns->address));
// ???? Do more?
}
@ -910,7 +910,7 @@ reply_parse(u8 *packet, int length) {
}
// XXXX do something sane with malformed A answers.
addrcount = datalength >> 2; // each IP address is 4 bytes
addrtocopy = MIN(MAX_ADDRS - reply.data.a.addrcount, addrcount);
addrtocopy = MIN(MAX_ADDRS - reply.data.a.addrcount, (unsigned)addrcount);
ttl_r = MIN(ttl_r, ttl);
// we only bother with the first four addresses.
if (j + 4*addrtocopy > length) return -1;
@ -1390,7 +1390,6 @@ eventdns_clear_nameservers_and_suspend(void)
return 0;
}
// exported function
int
eventdns_resume(void)

View File

@ -1081,7 +1081,7 @@ do_hup(void)
/* Restart cpuworker and dnsworker processes, so they get up-to-date
* configuration options. */
cpuworkers_rotate();
dnsworkers_rotate();
dns_reset();
#if 0
/* Write out a fresh descriptor, but leave old one on failure. */
router_rebuild_descriptor(1);

View File

@ -710,7 +710,6 @@ typedef struct edge_connection_t {
* circuit? */
int deliver_window; /**< How many more relay cells can end at me? */
/** Nickname of planned exit node -- used with .exit support. */
char *chosen_exit_name;
@ -2133,7 +2132,7 @@ uint32_t dns_clip_ttl(uint32_t ttl);
int connection_dns_finished_flushing(connection_t *conn);
int connection_dns_reached_eof(connection_t *conn);
int connection_dns_process_inbuf(connection_t *conn);
void dnsworkers_rotate(void);
void 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);