summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoger Dingledine <arma@torproject.org>2004-01-06 07:53:40 +0000
committerRoger Dingledine <arma@torproject.org>2004-01-06 07:53:40 +0000
commitc485725c5a284b9d08eba3eeab71a97c704351eb (patch)
tree9b3013b1e4a1e791841e05806498298c868cabe9
parent276dae52b5cb02e84205bcbd710ff8fa34d71185 (diff)
downloadtor-c485725c5a284b9d08eba3eeab71a97c704351eb.tar.gz
tor-c485725c5a284b9d08eba3eeab71a97c704351eb.zip
Fix the dns bug: children weren't dying
We were telling a child to die by closing the parent's file descriptor to him. But newer children were inheriting the open file descriptor from the parent, and since they weren't closing them, the socket never closed, so the child never read eof, so he never knew to exit. As a side effect to this bug, we were probably failing to properly close connections to remote hosts, ORs, and OPs, after a dns child was born. I'm surprised Tor worked at all. svn:r974
-rw-r--r--src/or/connection.c9
-rw-r--r--src/or/cpuworker.c1
-rw-r--r--src/or/dns.c3
-rw-r--r--src/or/or.h1
4 files changed, 13 insertions, 1 deletions
diff --git a/src/or/connection.c b/src/or/connection.c
index 5299e8965c..03134d3355 100644
--- a/src/or/connection.c
+++ b/src/or/connection.c
@@ -128,6 +128,15 @@ void connection_free(connection_t *conn) {
free(conn);
}
+void connection_free_all(void) {
+ int i, n;
+ connection_t **carray;
+
+ get_connection_array(&carray,&n);
+ for(i=0;i<n;i++)
+ connection_free(carray[i]);
+}
+
int connection_create_listener(char *bindaddress, uint16_t bindport, int type) {
struct sockaddr_in bindaddr; /* where to bind */
struct hostent *rent;
diff --git a/src/or/cpuworker.c b/src/or/cpuworker.c
index 40a5e6f39d..51c582c1c0 100644
--- a/src/or/cpuworker.c
+++ b/src/or/cpuworker.c
@@ -126,6 +126,7 @@ int cpuworker_main(void *data) {
close(fdarray[0]); /* this is the side of the socketpair the parent uses */
fd = fdarray[1]; /* this side is ours */
+ connection_free_all(); /* so the child doesn't hold the parent's fd's open */
for(;;) {
diff --git a/src/or/dns.c b/src/or/dns.c
index 0cf437afef..88607172de 100644
--- a/src/or/dns.c
+++ b/src/or/dns.c
@@ -395,6 +395,7 @@ int dnsworker_main(void *data) {
close(fdarray[0]); /* this is the side of the socketpair the parent uses */
fd = fdarray[1]; /* this side is ours */
+ connection_free_all(); /* so the child doesn't hold the parent's fd's open */
for(;;) {
@@ -506,7 +507,7 @@ static void spawn_enough_dnsworkers(void) {
num_dnsworkers++;
}
- while(num_dnsworkers > num_dnsworkers_needed+MAX_IDLE_DNSWORKERS) { /* too many idle? */
+ while(num_dnsworkers > num_dnsworkers_busy+MAX_IDLE_DNSWORKERS) { /* too many idle? */
/* cull excess workers */
log_fn(LOG_WARN,"%d of %d dnsworkers are idle. Killing one.",
num_dnsworkers-num_dnsworkers_needed, num_dnsworkers);
diff --git a/src/or/or.h b/src/or/or.h
index 76d2afeb5c..b7e323b3d0 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -615,6 +615,7 @@ int getconfig(int argc, char **argv, or_options_t *options);
connection_t *connection_new(int type);
void connection_free(connection_t *conn);
+void connection_free_all(void);
int connection_create_listener(char *bindaddress, uint16_t bindport, int type);