[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[or-cvs] when we get a sigint, don"t accept new connections/circuits,



Update of /home/or/cvsroot/src/or
In directory moria.mit.edu:/home2/arma/work/onion/cvs/src/or

Modified Files:
	command.c connection.c main.c rephist.c 
Log Message:
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.


Index: command.c
===================================================================
RCS file: /home/or/cvsroot/src/or/command.c,v
retrieving revision 1.66
retrieving revision 1.67
diff -u -d -r1.66 -r1.67
--- command.c	12 May 2004 23:48:57 -0000	1.66
+++ command.c	20 Jul 2004 23:31:00 -0000	1.67
@@ -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 @@
 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) {

Index: connection.c
===================================================================
RCS file: /home/or/cvsroot/src/or/connection.c,v
retrieving revision 1.243
retrieving revision 1.244
diff -u -d -r1.243 -r1.244
--- connection.c	20 Jul 2004 10:17:43 -0000	1.243
+++ connection.c	20 Jul 2004 23:31:00 -0000	1.244
@@ -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 @@
   }
   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);

Index: main.c
===================================================================
RCS file: /home/or/cvsroot/src/or/main.c,v
retrieving revision 1.296
retrieving revision 1.297
diff -u -d -r1.296 -r1.297
--- main.c	20 Jul 2004 19:45:29 -0000	1.296
+++ main.c	20 Jul 2004 23:31:00 -0000	1.297
@@ -44,8 +44,16 @@
 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 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 @@
 #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 @@
   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 @@
  */
 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 @@
   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 */
 }

Index: rephist.c
===================================================================
RCS file: /home/or/cvsroot/src/or/rephist.c,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -d -r1.16 -r1.17
--- rephist.c	20 Jul 2004 23:25:00 -0000	1.16
+++ rephist.c	20 Jul 2004 23:31:00 -0000	1.17
@@ -315,7 +315,7 @@
 #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 @@
   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 @@
   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;