summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/or/dns.c3
-rw-r--r--src/or/eventdns.c41
-rw-r--r--src/or/eventdns.h3
-rw-r--r--src/or/main.c8
4 files changed, 53 insertions, 2 deletions
diff --git a/src/or/dns.c b/src/or/dns.c
index 343560a046..f38b6fff09 100644
--- a/src/or/dns.c
+++ b/src/or/dns.c
@@ -1557,7 +1557,8 @@ evdns_callback(int result, char type, int count, int ttl, void *addresses,
if (evdns_err_is_transient(result))
status = DNS_RESOLVE_FAILED_TRANSIENT;
}
- dns_found_answer(string_address, is_reverse, addr, hostname, status, ttl);
+ if (result != DNS_ERR_SHUTDOWN)
+ dns_found_answer(string_address, is_reverse, addr, hostname, status, ttl);
tor_free(string_address);
}
diff --git a/src/or/eventdns.c b/src/or/eventdns.c
index ea1305a4f9..c41065818b 100644
--- a/src/or/eventdns.c
+++ b/src/or/eventdns.c
@@ -2294,7 +2294,7 @@ main(int c, char **v) {
}
int
-evdns_init()
+evdns_init(void)
{
int res = 0;
#ifdef MS_WINDOWS
@@ -2308,6 +2308,45 @@ evdns_init()
#endif
+void
+evdns_shutdown(int fail_requests)
+{
+ struct nameserver *server, *server_next;
+ struct search_domain *dom, *dom_next;
+
+ while (req_head) {
+ if (fail_requests)
+ reply_callback(req_head, 0, DNS_ERR_SHUTDOWN, NULL);
+ request_finished(req_head, &req_head);
+ }
+ while (req_waiting_head) {
+ if (fail_requests)
+ reply_callback(req_waiting_head, 0, DNS_ERR_SHUTDOWN, NULL);
+ request_finished(req_waiting_head, &req_waiting_head);
+ }
+ global_requests_inflight = global_requests_waiting = 0;
+
+ for (server = server_head; server; server = server_next) {
+ server_next = server->next;
+ if (server->socket >= 0)
+ CLOSE_SOCKET(server->socket);
+ (void) event_del(&server->event);
+ free(server);
+ }
+ server_head = NULL;
+ global_good_nameservers = 0;
+
+ if (global_search_state) {
+ for (dom = global_search_state->head; dom; dom = dom_next) {
+ dom_next = dom->next;
+ free(dom);
+ }
+ free(global_search_state);
+ global_search_state = NULL;
+ }
+ evdns_log_fn = NULL;
+}
+
// Local Variables:
// tab-width: 4
// c-basic-offset: 4
diff --git a/src/or/eventdns.h b/src/or/eventdns.h
index a475c28624..2aca5ef988 100644
--- a/src/or/eventdns.h
+++ b/src/or/eventdns.h
@@ -36,6 +36,8 @@
#define DNS_ERR_UNKNOWN 66
/* Communication with the server timed out */
#define DNS_ERR_TIMEOUT 67
+/* The request was canceled because the DNS subsystem was shut down. */
+#define DNS_ERR_SHUTDOWN 68
#define DNS_IPv4_A 1
#define DNS_PTR 2
@@ -50,6 +52,7 @@
typedef void (*evdns_callback_type) (int result, char type, int count, int ttl, void *addresses, void *arg);
int evdns_init(void);
+void evdns_shutdown(int fail_requests);
int evdns_nameserver_add(unsigned long int address);
int evdns_count_nameservers(void);
int evdns_clear_nameservers_and_suspend(void);
diff --git a/src/or/main.c b/src/or/main.c
index 8b4e3a6f0d..c221c1e440 100644
--- a/src/or/main.c
+++ b/src/or/main.c
@@ -16,6 +16,9 @@ const char main_c_id[] =
#ifdef USE_DMALLOC
#include <dmalloc.h>
#endif
+#ifdef USE_EVENTDNS
+void evdns_shutdown(int);
+#endif
/********* PROTOTYPES **********/
@@ -1548,6 +1551,11 @@ tor_init(int argc, char *argv[])
void
tor_free_all(int postfork)
{
+#ifdef USE_EVENTDNS
+ if (!postfork) {
+ evdns_shutdown(1);
+ }
+#endif
routerlist_free_all();
addressmap_free_all();
set_exit_redirects(NULL); /* free the registered exit redirects */