Prechádzať zdrojové kódy

r11873@catbus: nickm | 2007-02-22 01:21:14 -0500
twiddle signewnym rate-limiting patch so every signal gets handled eventually. document it in control-spec. add a changelog.


svn:r9615

Nick Mathewson 18 rokov pred
rodič
commit
b3392559d4
4 zmenil súbory, kde vykonal 30 pridanie a 9 odobranie
  1. 3 0
      ChangeLog
  2. 1 1
      doc/TODO
  3. 2 1
      doc/spec/control-spec.txt
  4. 24 7
      src/or/main.c

+ 3 - 0
ChangeLog

@@ -52,6 +52,9 @@ Changes in version 0.1.2.8-alpha - 2007-??-??
       advance warning.
       advance warning.
     - Add STREAM_BW events to report per-entry-stream bandwidth use. (Patch
     - Add STREAM_BW events to report per-entry-stream bandwidth use. (Patch
       from Robert Hogan.)
       from Robert Hogan.)
+    - Rate-limit SIGNEWNYM events in response to controllers that impolitely
+      generate them for every single stream.  (Patch from mwenge; closes bug
+      394.)
 
 
   o Minor bugfixes (performance):
   o Minor bugfixes (performance):
     - Call router_have_min_dir_info half as often.  (This is showing up in
     - Call router_have_min_dir_info half as often.  (This is showing up in

+ 1 - 1
doc/TODO

@@ -334,7 +334,7 @@ R - add d64 and fp64 along-side d and fp so people can paste status
     https thing in the default configuration:
     https thing in the default configuration:
     http://wiki.noreply.org/noreply/TheOnionRouter/TorFAQ#PrivoxyWeirdSSLPort
     http://wiki.noreply.org/noreply/TheOnionRouter/TorFAQ#PrivoxyWeirdSSLPort
   . Flesh out options_description array in src/or/config.c
   . Flesh out options_description array in src/or/config.c
-  . Don't let 'newnym' be triggered more often than every n seconds.
+  o Don't let 'newnym' be triggered more often than every n seconds.
   X If we try to publish as a nickname that's already claimed, should
   X If we try to publish as a nickname that's already claimed, should
     we append a number (or increment the number) and try again? This
     we append a number (or increment the number) and try again? This
     way people who read their logs can fix it as before, but people
     way people who read their logs can fix it as before, but people

+ 2 - 1
doc/spec/control-spec.txt

@@ -258,7 +258,8 @@ $Id$
       CLEARDNSCACHE -- Forget the client-side cached IPs for all hostnames.
       CLEARDNSCACHE -- Forget the client-side cached IPs for all hostnames.
       NEWNYM    -- Switch to clean circuits, so new application requests
       NEWNYM    -- Switch to clean circuits, so new application requests
                    don't share any circuits with old ones.  Also clears
                    don't share any circuits with old ones.  Also clears
-                   the client-side DNS cache.
+                   the client-side DNS cache.  (Tor MAY rate-limit its
+                   response to this signal.)
 
 
   The server responds with "250 OK" if the signal is recognized (or simply
   The server responds with "250 OK" if the signal is recognized (or simply
   closes the socket if it was asked to close immediately), or "552
   closes the socket if it was asked to close immediately), or "552

+ 24 - 7
src/or/main.c

@@ -54,8 +54,13 @@ static time_t time_to_fetch_directory = 0;
 static time_t time_to_fetch_running_routers = 0;
 static time_t time_to_fetch_running_routers = 0;
 /** When do we next launch DNS wildcarding checks? */
 /** When do we next launch DNS wildcarding checks? */
 static time_t time_to_check_for_correct_dns = 0;
 static time_t time_to_check_for_correct_dns = 0;
-/** When do we next allow a SIGNEWNYM? */
+
-static time_t time_to_allow_next_signewnym = 0;
+/** How often will we honor SIGNEWNYM requests? */
+#define MAX_SIGNEWNYM_RATE 10
+/** When did we last process a SIGNEWNYM request? */
+static time_t time_of_last_signewnym = 0;
+/** Is there a signewnym request we're currently waiting to handle? */
+static int signewnym_is_pending = 0;
 
 
 /** Array of all open connections.  The first n_conns elements are valid. */
 /** Array of all open connections.  The first n_conns elements are valid. */
 static connection_t *connection_array[MAXCONNECTIONS+1] =
 static connection_t *connection_array[MAXCONNECTIONS+1] =
@@ -748,6 +753,16 @@ run_scheduled_events(time_t now)
    */
    */
   consider_hibernation(now);
   consider_hibernation(now);
 
 
+  /* 0b. If we've deferred a signewnym, make sure it gets handled
+   * eventually */
+  if (signewnym_is_pending &&
+      time_of_last_signewnym + MAX_SIGNEWNYM_RATE < now) {
+    circuit_expire_all_dirty_circs();
+    addressmap_clear_transient();
+    time_of_last_signewnym = now;
+    signewnym_is_pending = 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.
@@ -1330,7 +1345,6 @@ signal_callback(int fd, short events, void *arg)
   uintptr_t sig = (uintptr_t)arg;
   uintptr_t sig = (uintptr_t)arg;
   (void)fd;
   (void)fd;
   (void)events;
   (void)events;
-  time_t now = time(NULL);
   switch (sig)
   switch (sig)
     {
     {
     case SIGTERM:
     case SIGTERM:
@@ -1373,14 +1387,17 @@ signal_callback(int fd, short events, void *arg)
                                                 zombies */
                                                 zombies */
       break;
       break;
 #endif
 #endif
-    case SIGNEWNYM:
+    case SIGNEWNYM: {
-      if (time_to_allow_next_signewnym < now) {
+      time_t now = time(NULL);
+      if (time_of_last_signewnym + MAX_SIGNEWNYM_RATE >= now) {
+        signewnym_is_pending = 1;
+      } else {
         circuit_expire_all_dirty_circs();
         circuit_expire_all_dirty_circs();
         addressmap_clear_transient();
         addressmap_clear_transient();
-#define NEXT_SIGNEWNYM (5)
+        time_of_last_signewnym = now;
-        time_to_allow_next_signewnym = now + NEXT_SIGNEWNYM;
       }
       }
       break;
       break;
+    }
     case SIGCLEARDNSCACHE:
     case SIGCLEARDNSCACHE:
       addressmap_clear_transient();
       addressmap_clear_transient();
       break;
       break;