r12080@catbus: nickm | 2007-03-04 21:40:55 -0500

Remove dnsworkers and related code. there goes another 550 lines of code.


svn:r9736
This commit is contained in:
Nick Mathewson 2007-03-05 02:40:58 +00:00
parent 92f62b3684
commit 52713788b4
10 changed files with 15 additions and 563 deletions

View File

@ -11,6 +11,9 @@ Changes in version 0.2.0.1-alpha - 2007-??-??
This has been deprecated since 0.1.1, and warnings have been issued This has been deprecated since 0.1.1, and warnings have been issued
since 0.1.2. When we encounter a v0 control message, we now send back since 0.1.2. When we encounter a v0 control message, we now send back
an error and close the connection. an error and close the connection.
- Remove the old "dns worker" server DNS code: it hasn't been default
since 0.1.2.2-alpha, and all the servers seem to be using the new
eventdns code.
Changes in version 0.1.2.10-rc - 2007-03-?? Changes in version 0.1.2.10-rc - 2007-03-??

View File

@ -19,18 +19,6 @@ AC_ARG_ENABLE(debug,
CFLAGS="$CFLAGS -g" CFLAGS="$CFLAGS -g"
fi]) fi])
AC_ARG_ENABLE(eventdns,
AS_HELP_STRING(--enable-eventdns, enable asynchronous dns module),
[case "${enableval}" in
yes) eventdns=true ;;
no) eventdns=false ;;
*) AC_MSG_ERROR(bad value for --enable-eventdns) ;;
esac], [eventdns=true])
AM_CONDITIONAL(EVENTDNS, test x$eventdns = xtrue)
if test x$eventdns = xtrue; then
AC_DEFINE([USE_EVENTDNS], 1, "Define to 1 if we'll be using eventdns.c")
fi
AC_ARG_ENABLE(transparent, AC_ARG_ENABLE(transparent,
AS_HELP_STRING(--disable-transparent, disable transparent proxy support), AS_HELP_STRING(--disable-transparent, disable transparent proxy support),
[case "${enableval}" in [case "${enableval}" in
@ -44,14 +32,6 @@ AC_ARG_ENABLE(threads,
if test x$enable_threads = x; then if test x$enable_threads = x; then
case $host in case $host in
*-*-netbsd* | *-*-openbsd* )
# Don't try multithreading on netbsd -- there is no threadsafe DNS
# lookup function there.
if test x$eventdns != xtrue; then
AC_MSG_NOTICE([You are running OpenBSD or NetBSD; I am assuming that
getaddrinfo is not threadsafe here, so I will disable threads.])
enable_threads="no"
fi ;;
*-*-solaris* ) *-*-solaris* )
# Don't try multithreading on solaris -- cpuworkers seem to lock. # Don't try multithreading on solaris -- cpuworkers seem to lock.
AC_MSG_NOTICE([You are running Solaris; Sometimes threading makes AC_MSG_NOTICE([You are running Solaris; Sometimes threading makes

View File

@ -4,19 +4,13 @@ noinst_PROGRAMS = test
bin_PROGRAMS = tor bin_PROGRAMS = tor
if EVENTDNS
EVDNSSRC = eventdns.c
else
EVDNSSRC =
endif
tor_SOURCES = buffers.c circuitbuild.c circuitlist.c \ tor_SOURCES = buffers.c circuitbuild.c circuitlist.c \
circuituse.c command.c config.c \ circuituse.c command.c config.c \
connection.c connection_edge.c connection_or.c control.c \ connection.c connection_edge.c connection_or.c control.c \
cpuworker.c directory.c dirserv.c dns.c hibernate.c main.c \ cpuworker.c directory.c dirserv.c dns.c hibernate.c main.c \
onion.c policies.c relay.c rendcommon.c rendclient.c rendmid.c \ onion.c policies.c relay.c rendcommon.c rendclient.c rendmid.c \
rendservice.c rephist.c router.c routerlist.c routerparse.c \ rendservice.c rephist.c router.c routerlist.c routerparse.c \
$(EVDNSSRC) \ eventdns.c \
tor_main.c tor_main.c
tor_LDADD = ../common/libor.a ../common/libor-crypto.a -lz -lssl -lcrypto tor_LDADD = ../common/libor.a ../common/libor-crypto.a -lz -lssl -lcrypto
@ -27,10 +21,10 @@ test_SOURCES = buffers.c circuitbuild.c circuitlist.c \
cpuworker.c directory.c dirserv.c dns.c hibernate.c main.c \ cpuworker.c directory.c dirserv.c dns.c hibernate.c main.c \
onion.c policies.c relay.c rendcommon.c rendclient.c rendmid.c \ onion.c policies.c relay.c rendcommon.c rendclient.c rendmid.c \
rendservice.c rephist.c router.c routerlist.c routerparse.c \ rendservice.c rephist.c router.c routerlist.c routerparse.c \
$(EVDNSSRC) \ eventdns.c \
test.c test.c
test_LDADD = ../common/libor.a ../common/libor-crypto.a -lz -lssl -lcrypto test_LDADD = ../common/libor.a ../common/libor-crypto.a -lz -lssl -lcrypto
noinst_HEADERS = or.h eventdns.h eventdns_tor.h eventdns.c noinst_HEADERS = or.h eventdns.h eventdns_tor.h

View File

@ -1001,13 +1001,10 @@ options_act(or_options_t *old_options)
cpuworkers_rotate(); cpuworkers_rotate();
if (dns_reset()) if (dns_reset())
return -1; return -1;
} } else {
#ifdef USE_EVENTDNS
else {
if (dns_reset()) if (dns_reset())
return -1; return -1;
} }
#endif
} }
/* Check if we need to parse and add the EntryNodes config option. */ /* Check if we need to parse and add the EntryNodes config option. */
@ -2714,12 +2711,6 @@ options_validate(or_options_t *old_options, or_options_t *options,
if (options->UseEntryGuards && ! options->NumEntryGuards) if (options->UseEntryGuards && ! options->NumEntryGuards)
REJECT("Cannot enable UseEntryGuards with NumEntryGuards set to 0"); REJECT("Cannot enable UseEntryGuards with NumEntryGuards set to 0");
#ifndef USE_EVENTDNS
if (options->ServerDNSResolvConfFile)
log(LOG_WARN, LD_CONFIG,
"ServerDNSResolvConfFile only works when eventdns support is enabled.");
#endif
if (check_nickname_list(options->ExitNodes, "ExitNodes", msg)) if (check_nickname_list(options->ExitNodes, "ExitNodes", msg))
return -1; return -1;
if (check_nickname_list(options->EntryNodes, "EntryNodes", msg)) if (check_nickname_list(options->EntryNodes, "EntryNodes", msg))

View File

@ -51,7 +51,6 @@ conn_type_to_string(int type)
case CONN_TYPE_AP: return "Socks"; case CONN_TYPE_AP: return "Socks";
case CONN_TYPE_DIR_LISTENER: return "Directory listener"; case CONN_TYPE_DIR_LISTENER: return "Directory listener";
case CONN_TYPE_DIR: return "Directory"; case CONN_TYPE_DIR: return "Directory";
case CONN_TYPE_DNSWORKER: return "DNS worker";
case CONN_TYPE_CPUWORKER: return "CPU worker"; case CONN_TYPE_CPUWORKER: return "CPU worker";
case CONN_TYPE_CONTROL_LISTENER: return "Control listener"; case CONN_TYPE_CONTROL_LISTENER: return "Control listener";
case CONN_TYPE_CONTROL: return "Control"; case CONN_TYPE_CONTROL: return "Control";
@ -118,12 +117,6 @@ conn_state_to_string(int type, int state)
case DIR_CONN_STATE_SERVER_WRITING: return "writing"; case DIR_CONN_STATE_SERVER_WRITING: return "writing";
} }
break; break;
case CONN_TYPE_DNSWORKER:
switch (state) {
case DNSWORKER_STATE_IDLE: return "idle";
case DNSWORKER_STATE_BUSY: return "busy";
}
break;
case CONN_TYPE_CPUWORKER: case CONN_TYPE_CPUWORKER:
switch (state) { switch (state) {
case CPUWORKER_STATE_IDLE: return "idle"; case CPUWORKER_STATE_IDLE: return "idle";
@ -496,11 +489,6 @@ connection_about_to_close_connection(connection_t *conn)
if (edge_conn->bridge_for_conn) if (edge_conn->bridge_for_conn)
connection_dirserv_unlink_from_bridge(edge_conn->bridge_for_conn); connection_dirserv_unlink_from_bridge(edge_conn->bridge_for_conn);
break; break;
case CONN_TYPE_DNSWORKER:
if (conn->state == DNSWORKER_STATE_BUSY) {
dns_cancel_pending_resolve(conn->address);
}
break;
} }
} }
@ -2242,8 +2230,6 @@ connection_process_inbuf(connection_t *conn, int package_partial)
package_partial); package_partial);
case CONN_TYPE_DIR: case CONN_TYPE_DIR:
return connection_dir_process_inbuf(TO_DIR_CONN(conn)); return connection_dir_process_inbuf(TO_DIR_CONN(conn));
case CONN_TYPE_DNSWORKER:
return connection_dns_process_inbuf(conn);
case CONN_TYPE_CPUWORKER: case CONN_TYPE_CPUWORKER:
return connection_cpu_process_inbuf(conn); return connection_cpu_process_inbuf(conn);
case CONN_TYPE_CONTROL: case CONN_TYPE_CONTROL:
@ -2289,8 +2275,6 @@ connection_finished_flushing(connection_t *conn)
return connection_edge_finished_flushing(TO_EDGE_CONN(conn)); return connection_edge_finished_flushing(TO_EDGE_CONN(conn));
case CONN_TYPE_DIR: case CONN_TYPE_DIR:
return connection_dir_finished_flushing(TO_DIR_CONN(conn)); return connection_dir_finished_flushing(TO_DIR_CONN(conn));
case CONN_TYPE_DNSWORKER:
return connection_dns_finished_flushing(conn);
case CONN_TYPE_CPUWORKER: case CONN_TYPE_CPUWORKER:
return connection_cpu_finished_flushing(conn); return connection_cpu_finished_flushing(conn);
case CONN_TYPE_CONTROL: case CONN_TYPE_CONTROL:
@ -2339,8 +2323,6 @@ connection_reached_eof(connection_t *conn)
return connection_edge_reached_eof(TO_EDGE_CONN(conn)); return connection_edge_reached_eof(TO_EDGE_CONN(conn));
case CONN_TYPE_DIR: case CONN_TYPE_DIR:
return connection_dir_reached_eof(TO_DIR_CONN(conn)); return connection_dir_reached_eof(TO_DIR_CONN(conn));
case CONN_TYPE_DNSWORKER:
return connection_dns_reached_eof(conn);
case CONN_TYPE_CPUWORKER: case CONN_TYPE_CPUWORKER:
return connection_cpu_reached_eof(conn); return connection_cpu_reached_eof(conn);
case CONN_TYPE_CONTROL: case CONN_TYPE_CONTROL:
@ -2513,10 +2495,6 @@ assert_connection_ok(connection_t *conn, time_t now)
tor_assert(conn->purpose >= _DIR_PURPOSE_MIN); tor_assert(conn->purpose >= _DIR_PURPOSE_MIN);
tor_assert(conn->purpose <= _DIR_PURPOSE_MAX); tor_assert(conn->purpose <= _DIR_PURPOSE_MAX);
break; break;
case CONN_TYPE_DNSWORKER:
tor_assert(conn->state >= _DNSWORKER_STATE_MIN);
tor_assert(conn->state <= _DNSWORKER_STATE_MAX);
break;
case CONN_TYPE_CPUWORKER: case CONN_TYPE_CPUWORKER:
tor_assert(conn->state >= _CPUWORKER_STATE_MIN); tor_assert(conn->state >= _CPUWORKER_STATE_MIN);
tor_assert(conn->state <= _CPUWORKER_STATE_MAX); tor_assert(conn->state <= _CPUWORKER_STATE_MAX);

View File

@ -8,32 +8,18 @@ const char dns_c_id[] =
/** /**
* \file dns.c * \file dns.c
* \brief Implements a local cache for DNS results for Tor servers. * \brief Implements a local cache for DNS results for Tor servers.
* We provide two asynchronous backend implementations: * This is implemetned as a wrapper around Adam Langley's eventdns.c code.
* 1) A farm of 'DNS worker' threads or processes to perform DNS lookups for
* onion routers and cache the results.
* 2) A wrapper around Adam Langley's eventdns.c code, to send requests
* to the nameservers asynchronously.
* (We can't just use gethostbyname() and friends because we really need to * (We can't just use gethostbyname() and friends because we really need to
* be nonblocking.) * be nonblocking.)
**/ **/
#include "or.h" #include "or.h"
#include "../common/ht.h" #include "../common/ht.h"
#ifdef USE_EVENTDNS
#include "eventdns.h" #include "eventdns.h"
#endif
/** Longest hostname we're willing to resolve. */ /** Longest hostname we're willing to resolve. */
#define MAX_ADDRESSLEN 256 #define MAX_ADDRESSLEN 256
/** Maximum DNS processes to spawn. */
#define MAX_DNSWORKERS 100
/** Minimum DNS processes to spawn. */
#define MIN_DNSWORKERS 3
/** If more than this many processes are idle, shut down the extras. */
#define MAX_IDLE_DNSWORKERS 10
/** How long will we wait for an answer from the resolver before we decide /** How long will we wait for an answer from the resolver before we decide
* that the resolver is wedged? */ * that the resolver is wedged? */
#define RESOLVE_MAX_TIMEOUT 300 #define RESOLVE_MAX_TIMEOUT 300
@ -44,14 +30,6 @@ const char dns_c_id[] =
#define DNS_RESOLVE_FAILED_PERMANENT 2 #define DNS_RESOLVE_FAILED_PERMANENT 2
#define DNS_RESOLVE_SUCCEEDED 3 #define DNS_RESOLVE_SUCCEEDED 3
#ifndef USE_EVENTDNS
/** How many dnsworkers we have running right now. */
static int num_dnsworkers=0;
/** How many of the running dnsworkers have an assigned task right now. */
static int num_dnsworkers_busy=0;
/** When did we last rotate the dnsworkers? */
static time_t last_rotation_time=0;
#else
/** Have we currently configured nameservers with eventdns? */ /** Have we currently configured nameservers with eventdns? */
static int nameservers_configured = 0; static int nameservers_configured = 0;
/** What was the resolv_conf fname we last used when configuring the /** What was the resolv_conf fname we last used when configuring the
@ -60,7 +38,6 @@ static char *resolv_conf_fname = NULL;
/** What was the mtime on the resolv.conf file we last used when configuring /** What was the mtime on the resolv.conf file we last used when configuring
* the nameservers? Used to check whether we need to reconfigure. */ * the nameservers? Used to check whether we need to reconfigure. */
static time_t resolv_conf_mtime = 0; static time_t resolv_conf_mtime = 0;
#endif
/** Linked list of connections waiting for a DNS answer. */ /** Linked list of connections waiting for a DNS answer. */
typedef struct pending_connection_t { typedef struct pending_connection_t {
@ -118,16 +95,9 @@ static void dns_found_answer(const char *address, int is_reverse,
static void send_resolved_cell(edge_connection_t *conn, or_circuit_t *circ, static void send_resolved_cell(edge_connection_t *conn, or_circuit_t *circ,
uint8_t answer_type); uint8_t answer_type);
static int launch_resolve(edge_connection_t *exitconn, or_circuit_t *circ); static int launch_resolve(edge_connection_t *exitconn, or_circuit_t *circ);
#ifndef USE_EVENTDNS
static void dnsworkers_rotate(void);
static void dnsworker_main(void *data);
static int spawn_dnsworker(void);
static int spawn_enough_dnsworkers(void);
#else
static void add_wildcarded_test_address(const char *address); static void add_wildcarded_test_address(const char *address);
static int configure_nameservers(int force); static int configure_nameservers(int force);
static int answer_is_wildcarded(const char *ip); static int answer_is_wildcarded(const char *ip);
#endif
#ifdef DEBUG_DNS_CACHE #ifdef DEBUG_DNS_CACHE
static void _assert_cache_ok(void); static void _assert_cache_ok(void);
#define assert_cache_ok() _assert_cache_ok() #define assert_cache_ok() _assert_cache_ok()
@ -168,7 +138,6 @@ init_cache_map(void)
HT_INIT(cache_map, &cache_root); HT_INIT(cache_map, &cache_root);
} }
#ifdef USE_EVENTDNS
/** Helper: called by eventdns when eventdns wants to log something. */ /** Helper: called by eventdns when eventdns wants to log something. */
static void static void
evdns_log_cb(int warn, const char *msg) evdns_log_cb(int warn, const char *msg)
@ -208,19 +177,14 @@ evdns_log_cb(int warn, const char *msg)
} }
log(severity, LD_EXIT, "eventdns: %s", msg); log(severity, LD_EXIT, "eventdns: %s", msg);
} }
#endif
/** Initialize the DNS subsystem; called by the OR process. */ /** Initialize the DNS subsystem; called by the OR process. */
int int
dns_init(void) dns_init(void)
{ {
init_cache_map(); init_cache_map();
#ifdef USE_EVENTDNS
if (server_mode(get_options())) if (server_mode(get_options()))
return configure_nameservers(1); return configure_nameservers(1);
#else
dnsworkers_rotate();
#endif
return 0; return 0;
} }
@ -229,7 +193,6 @@ dns_init(void)
int int
dns_reset(void) dns_reset(void)
{ {
#ifdef USE_EVENTDNS
or_options_t *options = get_options(); or_options_t *options = get_options();
if (! server_mode(options)) { if (! server_mode(options)) {
evdns_clear_nameservers_and_suspend(); evdns_clear_nameservers_and_suspend();
@ -241,9 +204,6 @@ dns_reset(void)
if (configure_nameservers(0) < 0) if (configure_nameservers(0) < 0)
return -1; return -1;
} }
#else
dnsworkers_rotate();
#endif
return 0; return 0;
} }
@ -338,9 +298,7 @@ dns_free_all(void)
if (cached_resolve_pqueue) if (cached_resolve_pqueue)
smartlist_free(cached_resolve_pqueue); smartlist_free(cached_resolve_pqueue);
cached_resolve_pqueue = NULL; cached_resolve_pqueue = NULL;
#ifdef USE_EVENTDNS
tor_free(resolv_conf_fname); tor_free(resolv_conf_fname);
#endif
} }
/** Remove every cached_resolve whose <b>expire</b> time is before <b>now</b> /** Remove every cached_resolve whose <b>expire</b> time is before <b>now</b>
@ -635,7 +593,6 @@ dns_resolve(edge_connection_t *exitconn, or_circuit_t *oncirc)
if (r == 1) if (r == 1)
is_reverse = 1; is_reverse = 1;
#ifdef USE_EVENTDNS
if (!is_reverse || !is_resolve) { if (!is_reverse || !is_resolve) {
if (!is_reverse) if (!is_reverse)
log_info(LD_EXIT, "Bad .in-addr.arpa address \"%s\"; sending error.", log_info(LD_EXIT, "Bad .in-addr.arpa address \"%s\"; sending error.",
@ -645,12 +602,6 @@ dns_resolve(edge_connection_t *exitconn, or_circuit_t *oncirc)
"Attempt to connect to a .in-addr.arpa address \"%s\"; " "Attempt to connect to a .in-addr.arpa address \"%s\"; "
"sending error.", "sending error.",
escaped_safe_str(exitconn->_base.address)); escaped_safe_str(exitconn->_base.address));
#else
if (1) {
log_info(LD_PROTOCOL, "Dnsworker code does not support in-addr.arpa "
"domain, but received a request for \"%s\"; sending error.",
escaped_safe_str(exitconn->_base.address));
#endif
if (exitconn->_base.purpose == EXIT_PURPOSE_RESOLVE) if (exitconn->_base.purpose == EXIT_PURPOSE_RESOLVE)
send_resolved_cell(exitconn, oncirc, RESOLVED_TYPE_ERROR); send_resolved_cell(exitconn, oncirc, RESOLVED_TYPE_ERROR);
@ -1062,412 +1013,6 @@ dns_found_answer(const char *address, int is_reverse, uint32_t addr,
assert_cache_ok(); assert_cache_ok();
} }
#ifndef USE_EVENTDNS
/** Find or spawn a dns worker process to handle resolving
* <b>exitconn</b>-\>address; tell that dns worker to begin resolving.
*/
static int
launch_resolve(edge_connection_t *exitconn, or_circuit_t *circ)
{
connection_t *dnsconn;
unsigned char len;
tor_assert(exitconn->_base.state == EXIT_CONN_STATE_RESOLVING);
assert_connection_ok(TO_CONN(exitconn), 0);
tor_assert(exitconn->_base.s == -1);
/* respawn here, to be sure there are enough */
if (spawn_enough_dnsworkers() < 0) {
goto err;
}
dnsconn = connection_get_by_type_state(CONN_TYPE_DNSWORKER,
DNSWORKER_STATE_IDLE);
if (!dnsconn) {
log_warn(LD_EXIT,"no idle dns workers. Failing.");
if (exitconn->_base.purpose == EXIT_PURPOSE_RESOLVE)
send_resolved_cell(exitconn, circ, RESOLVED_TYPE_ERROR_TRANSIENT);
goto err;
}
log_debug(LD_EXIT,
"Connection (fd %d) needs to resolve %s; assigning "
"to DNSWorker (fd %d)", exitconn->_base.s,
escaped_safe_str(exitconn->_base.address), dnsconn->s);
tor_free(dnsconn->address);
dnsconn->address = tor_strdup(exitconn->_base.address);
dnsconn->state = DNSWORKER_STATE_BUSY;
/* touch the lastwritten timestamp, since that's how we check to
* see how long it's been since we asked the question, and sometimes
* we check before the first call to connection_handle_write(). */
dnsconn->timestamp_lastwritten = time(NULL);
num_dnsworkers_busy++;
len = strlen(dnsconn->address);
connection_write_to_buf((char*)&len, 1, dnsconn);
connection_write_to_buf(dnsconn->address, len, dnsconn);
return 0;
err:
/* also sends end and frees */
dns_cancel_pending_resolve(exitconn->_base.address);
return -1;
}
/******************************************************************/
/*
* Connection between OR and dnsworker
*/
/** Write handler: called when we've pushed a request to a dnsworker. */
int
connection_dns_finished_flushing(connection_t *conn)
{
tor_assert(conn);
tor_assert(conn->type == CONN_TYPE_DNSWORKER);
connection_stop_writing(conn);
return 0;
}
/** Called when a connection to a dnsworker hits an EOF; this only happens
* when a dnsworker dies unexpectedly. */
int
connection_dns_reached_eof(connection_t *conn)
{
log_warn(LD_EXIT,"Read eof. DNS worker died unexpectedly.");
if (conn->state == DNSWORKER_STATE_BUSY) {
/* don't cancel the resolve here -- it would be cancelled in
* connection_about_to_close_connection(), since conn is still
* in state BUSY
*/
num_dnsworkers_busy--;
}
num_dnsworkers--;
connection_mark_for_close(conn);
return 0;
}
/** Read handler: called when we get data from a dnsworker. See
* if we have a complete answer. If so, call dns_found_answer on the
* result. If not, wait. Returns 0. */
int
connection_dns_process_inbuf(connection_t *conn)
{
char success;
uint32_t addr;
int ttl;
tor_assert(conn);
tor_assert(conn->type == CONN_TYPE_DNSWORKER);
if (conn->state != DNSWORKER_STATE_BUSY && buf_datalen(conn->inbuf)) {
log_warn(LD_BUG,
"read data (%d bytes) from an idle dns worker (fd %d, "
"address %s). Please report.", (int)buf_datalen(conn->inbuf),
conn->s, escaped_safe_str(conn->address));
tor_fragile_assert();
/* Pull it off the buffer anyway, or it will just stay there.
* Keep pulling things off because sometimes we get several
* answers at once (!). */
while (buf_datalen(conn->inbuf)) {
connection_fetch_from_buf(&success,1,conn);
connection_fetch_from_buf((char *)&addr,sizeof(uint32_t),conn);
log_warn(LD_EXIT,"Discarding idle dns answer (success %d, addr %d.)",
success, addr);
}
return 0;
}
if (buf_datalen(conn->inbuf) < 5) /* entire answer available? */
return 0; /* not yet */
tor_assert(conn->state == DNSWORKER_STATE_BUSY);
tor_assert(buf_datalen(conn->inbuf) == 5);
connection_fetch_from_buf(&success,1,conn);
connection_fetch_from_buf((char *)&addr,sizeof(uint32_t),conn);
log_debug(LD_EXIT, "DNSWorker (fd %d) returned answer for %s",
conn->s, escaped_safe_str(conn->address));
tor_assert(success >= DNS_RESOLVE_FAILED_TRANSIENT);
tor_assert(success <= DNS_RESOLVE_SUCCEEDED);
ttl = (success == DNS_RESOLVE_FAILED_TRANSIENT) ? 0 : MAX_DNS_ENTRY_AGE;
dns_found_answer(conn->address, 0, ntohl(addr), NULL, success, ttl);
tor_free(conn->address);
conn->address = tor_strdup("<idle>");
conn->state = DNSWORKER_STATE_IDLE;
num_dnsworkers_busy--;
if (conn->timestamp_created < last_rotation_time) {
connection_mark_for_close(conn);
num_dnsworkers--;
spawn_enough_dnsworkers();
}
return 0;
}
/** Close and re-open all idle dnsworkers; schedule busy ones to be closed
* and re-opened once they're no longer busy.
**/
static void
dnsworkers_rotate(void)
{
connection_t *dnsconn;
while ((dnsconn = connection_get_by_type_state(CONN_TYPE_DNSWORKER,
DNSWORKER_STATE_IDLE))) {
connection_mark_for_close(dnsconn);
num_dnsworkers--;
}
last_rotation_time = time(NULL);
if (server_mode(get_options()))
spawn_enough_dnsworkers();
}
/** Implementation for DNS workers; this code runs in a separate
* execution context. It takes as its argument an fdarray as returned
* by socketpair(), and communicates via fdarray[1]. The protocol is
* as follows:
* - The OR says:
* - ADDRESSLEN [1 byte]
* - ADDRESS [ADDRESSLEN bytes]
* - The DNS worker does the lookup, and replies:
* - OUTCOME [1 byte]
* - IP [4 bytes]
*
* OUTCOME is one of DNS_RESOLVE_{FAILED_TRANSIENT|FAILED_PERMANENT|SUCCEEDED}.
* IP is in host order.
*
* The dnsworker runs indefinitely, until its connection is closed or an error
* occurs.
*/
static void
dnsworker_main(void *data)
{
char address[MAX_ADDRESSLEN+1]; /* Plus a byte for a final '.' */
unsigned char address_len;
char *log_address;
char answer[5];
uint32_t ip;
int *fdarray = data;
int fd;
int result;
int search = get_options()->ServerDNSSearchDomains;
/* log_fn(LOG_NOTICE,"After spawn: fdarray @%d has %d:%d", (int)fdarray,
* fdarray[0],fdarray[1]); */
fd = fdarray[1]; /* this side is ours */
#ifndef TOR_IS_MULTITHREADED
tor_close_socket(fdarray[0]); /* this is the side of the socketpair the
* parent uses */
tor_free_all(1); /* so the child doesn't hold the parent's fd's open */
handle_signals(0); /* ignore interrupts from the keyboard, etc */
#endif
tor_free(data);
for (;;) {
int r;
if ((r = recv(fd, &address_len, 1, 0)) != 1) {
if (r == 0) {
log_info(LD_EXIT,"DNS worker exiting because Tor process closed "
"connection (either pruned idle dnsworker or died).");
} else {
log_info(LD_EXIT,"DNS worker exiting because of error on connection "
"to Tor process.");
log_info(LD_EXIT,"(Error on %d was %s)", fd,
tor_socket_strerror(tor_socket_errno(fd)));
}
tor_close_socket(fd);
crypto_thread_cleanup();
spawn_exit();
}
if (address_len && read_all(fd, address, address_len, 1) != address_len) {
log_err(LD_BUG,"read hostname failed. Child exiting.");
tor_close_socket(fd);
crypto_thread_cleanup();
spawn_exit();
}
/* Add a period to prevent local domain search, and NUL-terminate. */
if (address[address_len-1] != '.' && !search) {
address[address_len] = '.';
address[address_len+1] = '\0';
} else {
address[address_len] = '\0';
}
log_address = esc_for_log(safe_str(address));
result = tor_lookup_hostname(address, &ip);
/* Make 0.0.0.0 an error, so that we can use "0" to mean "no addr") */
if (!ip)
result = -1;
switch (result) {
case 1:
/* XXX result can never be 1, because we set it to -1 above on error */
log_info(LD_NET,"Could not resolve dest addr %s (transient)",
log_address);
answer[0] = DNS_RESOLVE_FAILED_TRANSIENT;
break;
case -1:
log_info(LD_NET,"Could not resolve dest addr %s (permanent)",
log_address);
answer[0] = DNS_RESOLVE_FAILED_PERMANENT;
break;
case 0:
log_info(LD_NET,"Resolved address %s", log_address);
answer[0] = DNS_RESOLVE_SUCCEEDED;
break;
}
tor_free(log_address);
set_uint32(answer+1, ip);
if (write_all(fd, answer, 5, 1) != 5) {
log_err(LD_NET,"writing answer failed. Child exiting.");
tor_close_socket(fd);
crypto_thread_cleanup();
spawn_exit();
}
}
}
/** Launch a new DNS worker; return 0 on success, -1 on failure.
*/
static int
spawn_dnsworker(void)
{
int *fdarray;
int fd;
connection_t *conn;
int err;
fdarray = tor_malloc(sizeof(int)*2);
if ((err = tor_socketpair(AF_UNIX, SOCK_STREAM, 0, fdarray)) < 0) {
log_warn(LD_NET, "Couldn't construct socketpair for dns worker: %s",
tor_socket_strerror(-err));
tor_free(fdarray);
return -1;
}
tor_assert(fdarray[0] >= 0);
tor_assert(fdarray[1] >= 0);
/* log_fn(LOG_NOTICE,"Before spawn: fdarray @%d has %d:%d",
(int)fdarray, fdarray[0],fdarray[1]); */
fd = fdarray[0]; /* We copy this out here, since dnsworker_main may free
* fdarray */
spawn_func((void*) dnsworker_main, (void*)fdarray);
log_debug(LD_EXIT,"just spawned a dns worker.");
#ifndef TOR_IS_MULTITHREADED
tor_close_socket(fdarray[1]); /* don't need the worker's side of the pipe */
tor_free(fdarray);
#endif
conn = connection_new(CONN_TYPE_DNSWORKER);
set_socket_nonblocking(fd);
/* set up conn so it's got all the data we need to remember */
conn->s = fd;
conn->address = tor_strdup("<unused>");
if (connection_add(conn) < 0) { /* no space, forget it */
log_warn(LD_NET,"connection_add for dnsworker failed. Giving up.");
connection_free(conn); /* this closes fd */
return -1;
}
conn->state = DNSWORKER_STATE_IDLE;
connection_start_reading(conn);
return 0; /* success */
}
/** If we have too many or too few DNS workers, spawn or kill some.
* Return 0 if we are happy, return -1 if we tried to spawn more but
* we couldn't.
*/
static int
spawn_enough_dnsworkers(void)
{
int num_dnsworkers_needed; /* aim to have 1 more than needed,
* but no less than min and no more than max */
connection_t *dnsconn;
/* XXX This may not be the best strategy. Maybe we should queue pending
* requests until the old ones finish or time out: otherwise, if the
* connection requests come fast enough, we never get any DNS done. -NM
*
* XXX But if we queue them, then the adversary can pile even more
* queries onto us, blocking legitimate requests for even longer. Maybe
* we should compromise and only kill if it's been at it for more than,
* e.g., 2 seconds. -RD
*/
if (num_dnsworkers_busy == MAX_DNSWORKERS) {
/* We always want at least one worker idle.
* So find the oldest busy worker and kill it.
*/
dnsconn = connection_get_by_type_state_lastwritten(CONN_TYPE_DNSWORKER,
DNSWORKER_STATE_BUSY);
tor_assert(dnsconn);
log_warn(LD_EXIT, "%d DNS workers are spawned; all are busy. Killing one.",
MAX_DNSWORKERS);
connection_mark_for_close(dnsconn);
num_dnsworkers_busy--;
num_dnsworkers--;
}
if (num_dnsworkers_busy >= MIN_DNSWORKERS)
num_dnsworkers_needed = num_dnsworkers_busy+1;
else
num_dnsworkers_needed = MIN_DNSWORKERS;
while (num_dnsworkers < num_dnsworkers_needed) {
if (spawn_dnsworker() < 0) {
log_warn(LD_EXIT,"DNS worker spawn failed. Will try again later.");
return -1;
}
num_dnsworkers++;
}
while (num_dnsworkers > num_dnsworkers_busy+MAX_IDLE_DNSWORKERS) {
/* too many idle? */
/* cull excess workers */
log_info(LD_EXIT,"%d of %d dnsworkers are idle. Killing one.",
num_dnsworkers-num_dnsworkers_busy, num_dnsworkers);
dnsconn = connection_get_by_type_state(CONN_TYPE_DNSWORKER,
DNSWORKER_STATE_IDLE);
tor_assert(dnsconn);
connection_mark_for_close(dnsconn);
num_dnsworkers--;
}
return 0;
}
void
dns_launch_correctness_checks(void)
{
}
int
dns_seems_to_be_broken(void)
{
return 0;
}
void
dns_reset_correctness_checks(void)
{
}
#else /* !USE_EVENTDNS */
/** Eventdns helper: return true iff the eventdns result <b>err</b> is /** Eventdns helper: return true iff the eventdns result <b>err</b> is
* a transient failure. */ * a transient failure. */
static int static int
@ -1483,30 +1028,6 @@ evdns_err_is_transient(int err)
return 0; return 0;
} }
} }
/* Dummy function; never called with eventdns enabled. */
int
connection_dns_finished_flushing(connection_t *conn)
{
(void)conn;
tor_assert(0);
return 0;
}
/* Dummy function; never called with eventdns enabled. */
int
connection_dns_process_inbuf(connection_t *conn)
{
(void)conn;
tor_assert(0);
return 0;
}
/* Dummy function; never called with eventdns enabled. */
int
connection_dns_reached_eof(connection_t *conn)
{
(void)conn;
tor_assert(0);
return 0;
}
/** Configure eventdns nameservers if force is true, or if the configuration /** Configure eventdns nameservers if force is true, or if the configuration
* has changed since the last time we called this function. On Unix, this * has changed since the last time we called this function. On Unix, this
@ -1978,7 +1499,6 @@ answer_is_wildcarded(const char *ip)
{ {
return dns_wildcard_list && smartlist_string_isin(dns_wildcard_list, ip); return dns_wildcard_list && smartlist_string_isin(dns_wildcard_list, ip);
} }
#endif /* USE_EVENTDNS */
/** Exit with an assertion if <b>resolve</b> is corrupt. */ /** Exit with an assertion if <b>resolve</b> is corrupt. */
static void static void

View File

@ -16,9 +16,8 @@ const char main_c_id[] =
#ifdef USE_DMALLOC #ifdef USE_DMALLOC
#include <dmalloc.h> #include <dmalloc.h>
#endif #endif
#ifdef USE_EVENTDNS
void evdns_shutdown(int); void evdns_shutdown(int);
#endif
/********* PROTOTYPES **********/ /********* PROTOTYPES **********/
@ -1640,11 +1639,9 @@ tor_init(int argc, char *argv[])
void void
tor_free_all(int postfork) tor_free_all(int postfork)
{ {
#ifdef USE_EVENTDNS
if (!postfork) { if (!postfork) {
evdns_shutdown(1); evdns_shutdown(1);
} }
#endif
routerlist_free_all(); routerlist_free_all();
addressmap_free_all(); addressmap_free_all();
set_exit_redirects(NULL); /* free the registered exit redirects */ set_exit_redirects(NULL); /* free the registered exit redirects */

View File

@ -229,21 +229,19 @@ typedef enum {
#define CONN_TYPE_DIR_LISTENER 8 #define CONN_TYPE_DIR_LISTENER 8
/** Type for HTTP connections to the directory server. */ /** Type for HTTP connections to the directory server. */
#define CONN_TYPE_DIR 9 #define CONN_TYPE_DIR 9
/** Connection from the main process to a DNS worker process. */
#define CONN_TYPE_DNSWORKER 10
/** Connection from the main process to a CPU worker process. */ /** Connection from the main process to a CPU worker process. */
#define CONN_TYPE_CPUWORKER 11 #define CONN_TYPE_CPUWORKER 10
/** Type for listening for connections from user interface process. */ /** Type for listening for connections from user interface process. */
#define CONN_TYPE_CONTROL_LISTENER 12 #define CONN_TYPE_CONTROL_LISTENER 11
/** Type for connections from user interface process. */ /** Type for connections from user interface process. */
#define CONN_TYPE_CONTROL 13 #define CONN_TYPE_CONTROL 12
/** Type for sockets listening for transparent connections redirected by pf or /** Type for sockets listening for transparent connections redirected by pf or
* netfilter. */ * netfilter. */
#define CONN_TYPE_AP_TRANS_LISTENER 14 #define CONN_TYPE_AP_TRANS_LISTENER 13
/** Type for sockets listening for transparent connections redirected by /** Type for sockets listening for transparent connections redirected by
* natd. */ * natd. */
#define CONN_TYPE_AP_NATD_LISTENER 15 #define CONN_TYPE_AP_NATD_LISTENER 14
#define _CONN_TYPE_MAX 15 #define _CONN_TYPE_MAX 14
#define CONN_IS_EDGE(x) \ #define CONN_IS_EDGE(x) \
((x)->type == CONN_TYPE_EXIT || (x)->type == CONN_TYPE_AP) ((x)->type == CONN_TYPE_EXIT || (x)->type == CONN_TYPE_AP)
@ -2473,9 +2471,6 @@ void cached_dir_decref(cached_dir_t *d);
int dns_init(void); int dns_init(void);
void dns_free_all(void); void dns_free_all(void);
uint32_t dns_clip_ttl(uint32_t ttl); 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);
int dns_reset(void); int dns_reset(void);
void connection_dns_remove(edge_connection_t *conn); void connection_dns_remove(edge_connection_t *conn);
void assert_connection_edge_not_dns_pending(edge_connection_t *conn); void assert_connection_edge_not_dns_pending(edge_connection_t *conn);

View File

@ -1224,9 +1224,6 @@ router_dump_router_to_string(char *s, size_t maxlen, routerinfo_t *router,
"bandwidth %d %d %d\n" "bandwidth %d %d %d\n"
"onion-key\n%s" "onion-key\n%s"
"signing-key\n%s" "signing-key\n%s"
#ifndef USE_EVENTDNS
"opt eventdns 0\n"
#endif
"%s%s%s", "%s%s%s",
router->nickname, router->nickname,
router->address, router->address,

View File

@ -1557,9 +1557,6 @@ test_dir_format(void)
strlcat(buf2, pk1_str, sizeof(buf2)); strlcat(buf2, pk1_str, sizeof(buf2));
strlcat(buf2, "signing-key\n", sizeof(buf2)); strlcat(buf2, "signing-key\n", sizeof(buf2));
strlcat(buf2, pk2_str, sizeof(buf2)); strlcat(buf2, pk2_str, sizeof(buf2));
#ifndef USE_EVENTDNS
strlcat(buf2, "opt eventdns 0\n", sizeof(buf2));
#endif
strlcat(buf2, bw_lines, sizeof(buf2)); strlcat(buf2, bw_lines, sizeof(buf2));
strlcat(buf2, "router-signature\n", sizeof(buf2)); strlcat(buf2, "router-signature\n", sizeof(buf2));
buf[strlen(buf2)] = '\0'; /* Don't compare the sig; it's never the same buf[strlen(buf2)] = '\0'; /* Don't compare the sig; it's never the same