From: Nick Mathewson Date: Sun, 24 Oct 2004 01:22:40 +0000 (+0000) Subject: Every 60 seconds, check whether the listeners are still alive, and relaunch the dead... X-Git-Tag: debian-version-0.0.8+0.0.9pre5-1~200 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=57f09573f5a4701bb799eedf7336432b8567d85b;p=thirdparty%2Ftor.git Every 60 seconds, check whether the listeners are still alive, and relaunch the dead ones. svn:r2581 --- diff --git a/src/or/connection.c b/src/or/connection.c index 0c8b9f7424..ce6e6fa306 100644 --- a/src/or/connection.c +++ b/src/or/connection.c @@ -553,12 +553,47 @@ static void listener_close_if_present(int type) { } static int retry_listeners(int type, struct config_line_t *cfg, - int port_option, const char *default_addr) + int port_option, const char *default_addr, + int force) { + if (!force) { + int want, have, n_conn, i; + struct config_line_t *c; + connection_t *conn; + connection_t **carray; + /* How many should there be? */ + if (cfg && port_option) { + want = 0; + for (c = cfg; c; c = c->next) + ++want; + } else if (port_option) { + want = 1; + } else { + want = 0; + } + + /* How many are there actually? */ + have = 0; + get_connection_array(&carray,&n_conn); + for(i=0;itype == type && !conn->marked_for_close) + ++have; + } + + /* If we have the right number of listeners, do nothing. */ + if (have == want) + return 0; + + /* Otherwise, warn the user and relaunch. */ + log_fn(LOG_WARN,"We have %d %s(s) open, but we want %d; relaunching.", + have, conn_type_to_string[type], want); + } + listener_close_if_present(type); if (port_option) { if (!cfg) { - if (connection_create_listener(default_addr, (uint16_t) port_option, + if (connection_create_listener(default_addr, (uint16_t) port_option, type)<0) return -1; } else { @@ -572,18 +607,21 @@ static int retry_listeners(int type, struct config_line_t *cfg, return 0; } -/** (Re)launch listeners for each port you should have open. +/** (Re)launch listeners for each port you should have open. If + * force is true, close and relaunch all listeners. If force + * is false, then only relaunch listeners when we have the wrong number of + * connections for a given type. */ -int retry_all_listeners(void) { +int retry_all_listeners(int force) { if (retry_listeners(CONN_TYPE_OR_LISTENER, options.ORBindAddress, - options.ORPort, "0.0.0.0")<0) + options.ORPort, "0.0.0.0", force)<0) return -1; if (retry_listeners(CONN_TYPE_DIR_LISTENER, options.DirBindAddress, - options.DirPort, "0.0.0.0")<0) + options.DirPort, "0.0.0.0", force)<0) return -1; if (retry_listeners(CONN_TYPE_AP_LISTENER, options.SocksBindAddress, - options.SocksPort, "127.0.0.1")<0) + options.SocksPort, "127.0.0.1", force)<0) return -1; return 0; diff --git a/src/or/main.c b/src/or/main.c index ee1d329506..76aff1ac02 100644 --- a/src/or/main.c +++ b/src/or/main.c @@ -502,6 +502,7 @@ static void run_scheduled_events(time_t now) { static long time_to_fetch_directory = 0; static time_t last_uploaded_services = 0; static time_t last_rotated_certificate = 0; + static time_t time_to_check_listeners = 0; int i; /** 0. See if we've been asked to shut down and our timeout has @@ -596,6 +597,12 @@ static void run_scheduled_events(time_t now) { */ connection_expire_held_open(); + /** 3d. And every 60 secionds, we relaunch listeners if any died. */ + if (time_to_check_listeners < now) { + retry_all_listeners(0); /* 0 means "only if some died." */ + time_to_check_listeners = now+60; + } + /** 4. Every second, we try a new circuit if there are no valid * circuits. Every NewCircuitPeriod seconds, we expire circuits * that became dirty more than NewCircuitPeriod seconds ago, @@ -744,7 +751,7 @@ static int do_hup(void) { log_fn(LOG_ERR,"Error reloading rendezvous service keys"); return -1; } - if(retry_all_listeners() < 0) { + if(retry_all_listeners(1) < 0) { log_fn(LOG_ERR,"Failed to bind one of the listener ports."); return -1; } @@ -808,7 +815,7 @@ static int do_main_loop(void) { } /* start up the necessary listeners based on which ports are non-zero. */ - if(retry_all_listeners() < 0) { + if(retry_all_listeners(1) < 0) { log_fn(LOG_ERR,"Failed to bind one of the listener ports."); return -1; } diff --git a/src/or/or.h b/src/or/or.h index 540520df77..668422c8d7 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -1093,7 +1093,7 @@ int _connection_mark_for_close(connection_t *conn); void connection_expire_held_open(void); int connection_connect(connection_t *conn, char *address, uint32_t addr, uint16_t port); -int retry_all_listeners(void); +int retry_all_listeners(int force); void connection_bucket_init(void); void connection_bucket_refill(struct timeval *now);