aboutsummaryrefslogtreecommitdiff
path: root/src/or
diff options
context:
space:
mode:
authorRoger Dingledine <arma@torproject.org>2004-07-20 23:31:00 +0000
committerRoger Dingledine <arma@torproject.org>2004-07-20 23:31:00 +0000
commit0da256ef976076709f7bbf503e6b6bc50a403380 (patch)
tree531b978e13bf5925c3cc91ed2f4aea3cd3bed2f0 /src/or
parent18d752e518c41f7190b77dc36d22150e89ffc115 (diff)
downloadtor-0da256ef976076709f7bbf503e6b6bc50a403380.tar
tor-0da256ef976076709f7bbf503e6b6bc50a403380.tar.gz
when we get a sigint, don't accept new connections/circuits,
but delay 30 seconds until exiting. if we get a second sigint, exit immediately. svn:r2070
Diffstat (limited to 'src/or')
-rw-r--r--src/or/command.c7
-rw-r--r--src/or/connection.c8
-rw-r--r--src/or/main.c50
-rw-r--r--src/or/rephist.c6
4 files changed, 57 insertions, 14 deletions
diff --git a/src/or/command.c b/src/or/command.c
index d65f8c309..284c4c6a9 100644
--- a/src/or/command.c
+++ b/src/or/command.c
@@ -16,6 +16,7 @@
#include "or.h"
extern or_options_t options; /* command-line and config-file options */
+extern int shutting_down; /* whether we should refuse create cells */
/** Keep statistics about how many of each type of cell we've received. */
unsigned long stats_n_padding_cells_processed = 0;
@@ -126,6 +127,12 @@ void command_process_cell(cell_t *cell, connection_t *conn) {
static void command_process_create_cell(cell_t *cell, connection_t *conn) {
circuit_t *circ;
+ if(shutting_down) {
+ log_fn(LOG_INFO,"Received create cell but we're shutting down. Sending back destroy.");
+ connection_send_destroy(cell->circ_id, conn);
+ return;
+ }
+
circ = circuit_get_by_circ_id_conn(cell->circ_id, conn);
if(circ) {
diff --git a/src/or/connection.c b/src/or/connection.c
index e0455ef95..7cbdff955 100644
--- a/src/or/connection.c
+++ b/src/or/connection.c
@@ -13,6 +13,7 @@
/********* START VARIABLES **********/
extern or_options_t options; /* command-line and config-file options */
+extern int shutting_down; /* whether we should refuse new connections */
/** Array of strings to make conn-\>type human-readable. */
char *conn_type_to_string[] = {
@@ -402,6 +403,13 @@ static int connection_handle_listener_read(connection_t *conn, int new_type) {
}
log(LOG_INFO,"Connection accepted on socket %d (child of fd %d).",news, conn->s);
+ if(shutting_down && new_type != CONN_TYPE_DIR) {
+ /* allow directory connections even while we're shutting down */
+ log(LOG_INFO,"But we're shutting down, so closing (type %d).", new_type);
+ tor_close_socket(news);
+ return 0;
+ }
+
set_socket_nonblocking(news);
newconn = connection_new(new_type);
diff --git a/src/or/main.c b/src/or/main.c
index 1050716c3..6b9e34d1b 100644
--- a/src/or/main.c
+++ b/src/or/main.c
@@ -44,8 +44,16 @@ static int nfds=0; /**< Number of connections currently active. */
static int please_dumpstats=0; /**< Whether we should dump stats during the loop. */
static int please_reset=0; /**< Whether we just got a sighup. */
static int please_reap_children=0; /**< Whether we should waitpid for exited children. */
+static int please_shutdown=0; /**< Whether we should shut down Tor. */
#endif /* signal stuff */
+/** We should exit if shutting_down != 0 and now <= shutting_down.
+ * If it's non-zero, don't accept any new circuits or connections.
+ * This gets assigned when we receive a sig_int, and if we receive a
+ * second one we exit immediately. */
+int shutting_down=0;
+#define SHUTDOWN_WAIT_LENGTH 30 /* seconds */
+
/** We set this to 1 when we've fetched a dir, to know whether to complain
* yet about unrecognized nicknames in entrynodes, exitnodes, etc.
* Also, we don't try building circuits unless this is 1. */
@@ -479,6 +487,14 @@ static void run_scheduled_events(time_t now) {
static time_t last_rotated_certificate = 0;
int i;
+ /** 0. See if we've been asked to shut down and our timeout has
+ * expired. If so, exit now.
+ */
+ if(shutting_down && shutting_down <= now) {
+ log(LOG_NOTICE,"Clean shutdown finished. Exiting.");
+ exit(0);
+ }
+
/** 1a. Every MIN_ONION_KEY_LIFETIME seconds, rotate the onion keys,
* shut down and restart all cpuworkers, and update the directory if
* necessary.
@@ -782,8 +798,18 @@ static int do_main_loop(void) {
#ifdef MS_WINDOWS /* Do service stuff only on windows. */
if (service_status.dwCurrentState != SERVICE_RUNNING) {
return 0;
- }
+ }
#else /* do signal stuff only on unix */
+ if(please_shutdown) {
+ if(shutting_down) { /* we've already been asked. do it now. */
+ log(LOG_NOTICE,"Second sigint received; exiting now.");
+ exit(0);
+ } else {
+ log(LOG_NOTICE,"Interrupt: will shut down in %d seconds. Interrupt again to exit now.", SHUTDOWN_WAIT_LENGTH);
+ shutting_down = time(NULL) + SHUTDOWN_WAIT_LENGTH;
+ }
+ please_shutdown = 0;
+ }
if(please_dumpstats) {
/* prefer to log it at INFO, but make sure we always see it */
dumpstats(get_min_log_level()>LOG_INFO ? get_min_log_level() : LOG_INFO);
@@ -842,15 +868,13 @@ static void catch(int the_signal) {
switch(the_signal) {
// case SIGABRT:
case SIGTERM:
- case SIGINT:
log(LOG_ERR,"Catching signal %d, exiting cleanly.", the_signal);
- /* we don't care if there was an error when we unlink, nothing
- we could do about it anyways */
- if(options.PidFile)
- unlink(options.PidFile);
exit(0);
+ case SIGINT:
+ please_shutdown = 1;
+ break;
case SIGPIPE:
- log(LOG_INFO,"Caught sigpipe. Ignoring.");
+ log(LOG_NOTICE,"Caught sigpipe. Ignoring.");
break;
case SIGHUP:
please_reset = 1;
@@ -947,6 +971,10 @@ int network_init(void)
*/
void exit_function(void)
{
+ /* Remove our pid file. We don't care if there was an error when we
+ * unlink, nothing we could do about it anyways. */
+ if(options.PidFile)
+ unlink(options.PidFile);
#ifdef MS_WINDOWS
WSACleanup();
#endif
@@ -988,10 +1016,10 @@ int tor_init(int argc, char *argv[]) {
sigemptyset(&action.sa_mask);
action.sa_handler = catch;
- sigaction(SIGINT, &action, NULL);
- sigaction(SIGTERM, &action, NULL);
- sigaction(SIGPIPE, &action, NULL);
- sigaction(SIGUSR1, &action, NULL);
+ sigaction(SIGINT, &action, NULL); /* do a controlled slow shutdown */
+ sigaction(SIGTERM, &action, NULL); /* to terminate now */
+ sigaction(SIGPIPE, &action, NULL); /* otherwise sigpipe kills us */
+ sigaction(SIGUSR1, &action, NULL); /* dump stats */
sigaction(SIGHUP, &action, NULL); /* to reload config, retry conns, etc */
sigaction(SIGCHLD, &action, NULL); /* handle dns/cpu workers that exit */
}
diff --git a/src/or/rephist.c b/src/or/rephist.c
index 5992a9581..0cca2097d 100644
--- a/src/or/rephist.c
+++ b/src/or/rephist.c
@@ -315,7 +315,7 @@ void write_rep_history(const char *filename)
#define NUM_TOTALS (NUM_SECS_BW_SUM_IS_VALID/NUM_SECS_BW_SUM_INTERVAL)
/**
- * Struture to track bandwidth use, and remember the maxima for a given
+ * Structure to track bandwidth use, and remember the maxima for a given
* time period.
*/
typedef struct bw_array_t {
@@ -338,7 +338,7 @@ typedef struct bw_array_t {
int maxima[NUM_TOTALS];
} bw_array_t;
-/** Shift the current period of b foreward by one.
+/** Shift the current period of b forward by one.
*/
static void commit_max(bw_array_t *b) {
/* Store maximum from current period. */
@@ -351,7 +351,7 @@ static void commit_max(bw_array_t *b) {
b->max_total = 0;
}
-/** Shift the current observation time of 'b' foreward by one second.
+/** Shift the current observation time of 'b' forward by one second.
*/
static INLINE void advance_obs(bw_array_t *b) {
int nextidx;