[or-cvs] implement first piece of hibernation

Roger Dingledine arma at seul.org
Sun Oct 31 20:28:44 UTC 2004


Update of /home2/or/cvsroot/src/or
In directory moria.mit.edu:/tmp/cvs-serv321

Modified Files:
	Makefile.am command.c connection.c connection_edge.c main.c 
	or.h 
Log Message:
implement first piece of hibernation
still need to track bandwidth, and make decisions based on bandwidth


Index: Makefile.am
===================================================================
RCS file: /home2/or/cvsroot/src/or/Makefile.am,v
retrieving revision 1.36
retrieving revision 1.37
diff -u -d -r1.36 -r1.37
--- Makefile.am	30 Oct 2004 19:27:06 -0000	1.36
+++ Makefile.am	31 Oct 2004 20:28:41 -0000	1.37
@@ -7,7 +7,7 @@
 tor_SOURCES = buffers.c circuitbuild.c circuitlist.c \
 	circuituse.c command.c config.c \
 	connection.c connection_edge.c connection_or.c \
-	cpuworker.c directory.c dirserv.c dns.c main.c \
+	cpuworker.c directory.c dirserv.c dns.c hibernate.c main.c \
 	onion.c relay.c rendcommon.c rendclient.c rendmid.c \
 	rendservice.c rephist.c router.c routerlist.c routerparse.c \
 	tor_main.c
@@ -17,7 +17,7 @@
 test_SOURCES = buffers.c circuitbuild.c circuitlist.c \
 	circuituse.c command.c config.c \
 	connection.c connection_edge.c connection_or.c \
-	cpuworker.c directory.c dirserv.c dns.c main.c \
+	cpuworker.c directory.c dirserv.c dns.c hibernate.c main.c \
 	onion.c relay.c rendcommon.c rendclient.c rendmid.c \
 	rendservice.c rephist.c router.c routerlist.c routerparse.c \
 	test.c

Index: command.c
===================================================================
RCS file: /home2/or/cvsroot/src/or/command.c,v
retrieving revision 1.68
retrieving revision 1.69
diff -u -d -r1.68 -r1.69
--- command.c	18 Aug 2004 11:20:15 -0000	1.68
+++ command.c	31 Oct 2004 20:28:41 -0000	1.69
@@ -16,7 +16,6 @@
 #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;
@@ -127,7 +126,7 @@
 static void command_process_create_cell(cell_t *cell, connection_t *conn) {
   circuit_t *circ;
 
-  if(shutting_down) {
+  if(we_are_hibernating()) {
     log_fn(LOG_INFO,"Received create cell but we're shutting down. Sending back destroy.");
     connection_send_destroy(cell->circ_id, conn);
     return;

Index: connection.c
===================================================================
RCS file: /home2/or/cvsroot/src/or/connection.c,v
retrieving revision 1.272
retrieving revision 1.273
diff -u -d -r1.272 -r1.273
--- connection.c	27 Oct 2004 21:14:11 -0000	1.272
+++ connection.c	31 Oct 2004 20:28:41 -0000	1.273
@@ -13,7 +13,6 @@
 /********* 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. */
 const char *conn_type_to_string[] = {
@@ -401,13 +400,6 @@
   }
   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);
 
   /* process entrance policies here, before we even create the connection */

Index: connection_edge.c
===================================================================
RCS file: /home2/or/cvsroot/src/or/connection_edge.c,v
retrieving revision 1.221
retrieving revision 1.222
diff -u -d -r1.221 -r1.222
--- connection_edge.c	27 Oct 2004 21:14:11 -0000	1.221
+++ connection_edge.c	31 Oct 2004 20:28:41 -0000	1.222
@@ -804,6 +804,11 @@
   n_stream->state = EXIT_CONN_STATE_RESOLVEFAILED;
   /* default to failed, change in dns_resolve if it turns out not to fail */
 
+  if(we_are_hibernating()) {
+    connection_edge_end(n_stream, END_STREAM_REASON_EXITPOLICY, n_stream->cpath_layer);
+    connection_free(n_stream);
+  }
+
   /* send it off to the gethostbyname farm */
   switch(dns_resolve(n_stream)) {
     case 1: /* resolve worked */

Index: main.c
===================================================================
RCS file: /home2/or/cvsroot/src/or/main.c,v
retrieving revision 1.344
retrieving revision 1.345
diff -u -d -r1.344 -r1.345
--- main.c	30 Oct 2004 19:18:37 -0000	1.344
+++ main.c	31 Oct 2004 20:28:41 -0000	1.345
@@ -53,13 +53,6 @@
 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. */
@@ -373,7 +366,8 @@
   if (!time_to_fetch_directory)
     time_to_fetch_directory = now + options.DirFetchPostPeriod;
 
-  if(server_mode()) { /* connect to the appropriate routers */
+  if (server_mode() &&
+      !we_are_hibernating()) { /* connect to the appropriate routers */
     router_retry_connections();
   }
 }
@@ -400,9 +394,10 @@
      now >= conn->timestamp_lastwritten + options.KeepalivePeriod) {
     routerinfo_t *router = router_get_by_digest(conn->identity_digest);
     if((!connection_state_is_open(conn)) ||
+       (we_are_hibernating() && !circuit_get_by_conn(conn)) ||
        (!clique_mode() && !circuit_get_by_conn(conn) &&
        (!router || !server_mode() || !router_is_clique_mode(router)))) {
-      /* our handshake has expired;
+      /* our handshake has expired; we're hibernating;
        * or we have no circuits and we're both either OPs or normal ORs,
        * then kill it. */
       log_fn(LOG_INFO,"Expiring connection to %d (%s:%d).",
@@ -510,13 +505,10 @@
   int i;
 
   /** 0. See if we've been asked to shut down and our timeout has
-   * expired. If so, exit now.
+   * expired; or if our bandwidth limits are exhausted and we
+   * should hibernate; or if it's time to wake up from hibernation.
    */
-  if(shutting_down && shutting_down <= now) {
-    log(LOG_NOTICE,"Clean shutdown finished. Exiting.");
-    tor_cleanup();
-    exit(0);
-  }
+  consider_hibernation(now);
 
   /** 1a. Every MIN_ONION_KEY_LIFETIME seconds, rotate the onion keys,
    *  shut down and restart all cpuworkers, and update the directory if
@@ -566,7 +558,7 @@
       /* We're a directory; dump any old descriptors. */
       dirserv_remove_old_servers(ROUTER_MAX_AGE);
     }
-    if(server_mode()) {
+    if(server_mode() && !we_are_hibernating()) {
       /* dirservers try to reconnect, in case connections have failed;
        * and normal servers try to reconnect to dirservers */
       router_retry_connections();
@@ -574,9 +566,11 @@
 
     directory_get_from_dirserver(DIR_PURPOSE_FETCH_DIR, NULL, 0);
 
-    /* Force an upload of our rend descriptors every DirFetchPostPeriod seconds. */
-    rend_services_upload(1);
-    last_uploaded_services = now;
+    if(!we_are_hibernating()) {
+      /* Force an upload of our rend descriptors every DirFetchPostPeriod seconds. */
+      rend_services_upload(1);
+      last_uploaded_services = now;
+    }
     rend_cache_clean(); /* should this go elsewhere? */
 
     time_to_fetch_directory = now + options.DirFetchPostPeriod;
@@ -601,8 +595,8 @@
    */
   connection_expire_held_open();
 
-  /** 3d. And every 60 secionds, we relaunch listeners if any died. */
-  if (time_to_check_listeners < now) {
+  /** 3d. And every 60 seconds, we relaunch listeners if any died. */
+  if (!we_are_hibernating() && time_to_check_listeners < now) {
     retry_all_listeners(0); /* 0 means "only if some died." */
     time_to_check_listeners = now+60;
   }
@@ -612,7 +606,7 @@
    *    that became dirty more than NewCircuitPeriod seconds ago,
    *    and we make a new circ if there are no clean circuits.
    */
-  if(has_fetched_directory)
+  if(has_fetched_directory && !we_are_hibernating())
     circuit_build_needed_circs(now);
 
   /** 5. We do housekeeping for each connection... */
@@ -842,14 +836,7 @@
         tor_cleanup();
         exit(0);
       }
-      if(shutting_down) { /* we've already been asked. do it now. */
-        log(LOG_NOTICE,"Second sigint received; exiting now.");
-        tor_cleanup();
-        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;
-      }
+      hibernate_begin_shutdown();
       please_shutdown = 0;
     }
     if(please_sigpipe) {

Index: or.h
===================================================================
RCS file: /home2/or/cvsroot/src/or/or.h,v
retrieving revision 1.449
retrieving revision 1.450
diff -u -d -r1.449 -r1.450
--- or.h	30 Oct 2004 19:18:37 -0000	1.449
+++ or.h	31 Oct 2004 20:28:41 -0000	1.450
@@ -1236,6 +1236,12 @@
 void dns_cancel_pending_resolve(char *question);
 int dns_resolve(connection_t *exitconn);
 
+/********************************* hibernate.c **********************/
+
+void hibernate_begin_shutdown(void);
+int we_are_hibernating(void);
+void consider_hibernation(time_t now);
+
 /********************************* main.c ***************************/
 
 int connection_add(connection_t *conn);



More information about the tor-commits mailing list