mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2025-02-24 06:48:05 +01:00
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
This commit is contained in:
parent
18d752e518
commit
0da256ef97
4 changed files with 57 additions and 14 deletions
|
@ -16,6 +16,7 @@
|
||||||
#include "or.h"
|
#include "or.h"
|
||||||
|
|
||||||
extern or_options_t options; /* command-line and config-file options */
|
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. */
|
/** Keep statistics about how many of each type of cell we've received. */
|
||||||
unsigned long stats_n_padding_cells_processed = 0;
|
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) {
|
static void command_process_create_cell(cell_t *cell, connection_t *conn) {
|
||||||
circuit_t *circ;
|
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);
|
circ = circuit_get_by_circ_id_conn(cell->circ_id, conn);
|
||||||
|
|
||||||
if(circ) {
|
if(circ) {
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
/********* START VARIABLES **********/
|
/********* START VARIABLES **********/
|
||||||
|
|
||||||
extern or_options_t options; /* command-line and config-file options */
|
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. */
|
/** Array of strings to make conn-\>type human-readable. */
|
||||||
char *conn_type_to_string[] = {
|
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);
|
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);
|
set_socket_nonblocking(news);
|
||||||
|
|
||||||
newconn = connection_new(new_type);
|
newconn = connection_new(new_type);
|
||||||
|
|
|
@ -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_dumpstats=0; /**< Whether we should dump stats during the loop. */
|
||||||
static int please_reset=0; /**< Whether we just got a sighup. */
|
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_reap_children=0; /**< Whether we should waitpid for exited children. */
|
||||||
|
static int please_shutdown=0; /**< Whether we should shut down Tor. */
|
||||||
#endif /* signal stuff */
|
#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
|
/** We set this to 1 when we've fetched a dir, to know whether to complain
|
||||||
* yet about unrecognized nicknames in entrynodes, exitnodes, etc.
|
* yet about unrecognized nicknames in entrynodes, exitnodes, etc.
|
||||||
* Also, we don't try building circuits unless this is 1. */
|
* 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;
|
static time_t last_rotated_certificate = 0;
|
||||||
int i;
|
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,
|
/** 1a. Every MIN_ONION_KEY_LIFETIME seconds, rotate the onion keys,
|
||||||
* shut down and restart all cpuworkers, and update the directory if
|
* shut down and restart all cpuworkers, and update the directory if
|
||||||
* necessary.
|
* necessary.
|
||||||
|
@ -784,6 +800,16 @@ static int do_main_loop(void) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#else /* do signal stuff only on unix */
|
#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) {
|
if(please_dumpstats) {
|
||||||
/* prefer to log it at INFO, but make sure we always see it */
|
/* 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);
|
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) {
|
switch(the_signal) {
|
||||||
// case SIGABRT:
|
// case SIGABRT:
|
||||||
case SIGTERM:
|
case SIGTERM:
|
||||||
case SIGINT:
|
|
||||||
log(LOG_ERR,"Catching signal %d, exiting cleanly.", the_signal);
|
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);
|
exit(0);
|
||||||
|
case SIGINT:
|
||||||
|
please_shutdown = 1;
|
||||||
|
break;
|
||||||
case SIGPIPE:
|
case SIGPIPE:
|
||||||
log(LOG_INFO,"Caught sigpipe. Ignoring.");
|
log(LOG_NOTICE,"Caught sigpipe. Ignoring.");
|
||||||
break;
|
break;
|
||||||
case SIGHUP:
|
case SIGHUP:
|
||||||
please_reset = 1;
|
please_reset = 1;
|
||||||
|
@ -947,6 +971,10 @@ int network_init(void)
|
||||||
*/
|
*/
|
||||||
void exit_function(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
|
#ifdef MS_WINDOWS
|
||||||
WSACleanup();
|
WSACleanup();
|
||||||
#endif
|
#endif
|
||||||
|
@ -988,10 +1016,10 @@ int tor_init(int argc, char *argv[]) {
|
||||||
sigemptyset(&action.sa_mask);
|
sigemptyset(&action.sa_mask);
|
||||||
|
|
||||||
action.sa_handler = catch;
|
action.sa_handler = catch;
|
||||||
sigaction(SIGINT, &action, NULL);
|
sigaction(SIGINT, &action, NULL); /* do a controlled slow shutdown */
|
||||||
sigaction(SIGTERM, &action, NULL);
|
sigaction(SIGTERM, &action, NULL); /* to terminate now */
|
||||||
sigaction(SIGPIPE, &action, NULL);
|
sigaction(SIGPIPE, &action, NULL); /* otherwise sigpipe kills us */
|
||||||
sigaction(SIGUSR1, &action, NULL);
|
sigaction(SIGUSR1, &action, NULL); /* dump stats */
|
||||||
sigaction(SIGHUP, &action, NULL); /* to reload config, retry conns, etc */
|
sigaction(SIGHUP, &action, NULL); /* to reload config, retry conns, etc */
|
||||||
sigaction(SIGCHLD, &action, NULL); /* handle dns/cpu workers that exit */
|
sigaction(SIGCHLD, &action, NULL); /* handle dns/cpu workers that exit */
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
#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.
|
* time period.
|
||||||
*/
|
*/
|
||||||
typedef struct bw_array_t {
|
typedef struct bw_array_t {
|
||||||
|
@ -338,7 +338,7 @@ typedef struct bw_array_t {
|
||||||
int maxima[NUM_TOTALS];
|
int maxima[NUM_TOTALS];
|
||||||
} bw_array_t;
|
} 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) {
|
static void commit_max(bw_array_t *b) {
|
||||||
/* Store maximum from current period. */
|
/* Store maximum from current period. */
|
||||||
|
@ -351,7 +351,7 @@ static void commit_max(bw_array_t *b) {
|
||||||
b->max_total = 0;
|
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) {
|
static INLINE void advance_obs(bw_array_t *b) {
|
||||||
int nextidx;
|
int nextidx;
|
||||||
|
|
Loading…
Add table
Reference in a new issue