Browse Source

Add a SIGNAL event for control connections

Implements ticket #1955
John Brooks 14 years ago
parent
commit
7441999738
4 changed files with 62 additions and 2 deletions
  1. 18 1
      doc/spec/control-spec.txt
  2. 38 1
      src/or/control.c
  3. 1 0
      src/or/control.h
  4. 5 0
      src/or/main.c

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

@@ -228,7 +228,7 @@
          "INFO" / "NOTICE" / "WARN" / "ERR" / "NEWDESC" / "ADDRMAP" /
          "AUTHDIR_NEWDESCS" / "DESCCHANGED" / "STATUS_GENERAL" /
          "STATUS_CLIENT" / "STATUS_SERVER" / "GUARD" / "NS" / "STREAM_BW" /
-         "CLIENTS_SEEN" / "NEWCONSENSUS" / "BUILDTIMEOUT_SET"
+         "CLIENTS_SEEN" / "NEWCONSENSUS" / "BUILDTIMEOUT_SET" / "SIGNAL"
 
   Any events *not* listed in the SETEVENTS line are turned off; thus, sending
   SETEVENTS with an empty body turns off all event reporting.
@@ -1708,6 +1708,23 @@
 
   [First added in 0.2.2.7-alpha]
 
+4.1.17. Signal received
+
+  The syntax is:
+     "650" SP "SIGNAL" SP Signal CRLF
+
+     Signal = "RELOAD" / "DUMP" / "DEBUG" / "NEWNYM" / "CLEARDNSCACHE"
+
+  A signal has been received and actions taken by Tor. The meaning of each
+  signal, and the mapping to Unix signals, is as defined in section 3.7.
+  If Tor chose to ignore a signal (such as NEWNYM), this event will not be
+  sent.
+
+  Note that the HALT (SIGTERM) and SHUTDOWN (SIGINT) signals do not currently
+  generate any event.
+
+  [First added in X.X.X.X-alpha]
+
 5. Implementation notes
 
 5.1. Authentication

+ 38 - 1
src/or/control.c

@@ -65,7 +65,8 @@
 #define EVENT_CLIENTS_SEEN     0x0015
 #define EVENT_NEWCONSENSUS     0x0016
 #define EVENT_BUILDTIMEOUT_SET     0x0017
-#define _EVENT_MAX             0x0017
+#define EVENT_SIGNAL           0x0018
+#define _EVENT_MAX             0x0018
 /* If _EVENT_MAX ever hits 0x0020, we need to make the mask wider. */
 
 /** Bitfield: The bit 1&lt;&lt;e is set if <b>any</b> open control
@@ -946,6 +947,8 @@ handle_control_setevents(control_connection_t *conn, uint32_t len,
         event_code = EVENT_NEWCONSENSUS;
       else if (!strcasecmp(ev, "BUILDTIMEOUT_SET"))
         event_code = EVENT_BUILDTIMEOUT_SET;
+      else if (!strcasecmp(ev, "SIGNAL"))
+        event_code = EVENT_SIGNAL;
       else {
         connection_printf_to_buf(conn, "552 Unrecognized event \"%s\"\r\n",
                                  ev);
@@ -3589,6 +3592,40 @@ control_event_buildtimeout_set(const circuit_build_times_t *cbt,
   return 0;
 }
 
+/** Called when a signal has been processed from signal_callback */
+int
+control_event_signal(uintptr_t signal)
+{
+  const char *signal_string = NULL;
+
+  if (!control_event_is_interesting(EVENT_SIGNAL))
+    return 0;
+
+  switch (signal) {
+    case SIGHUP:
+      signal_string = "RELOAD";
+      break;
+    case SIGUSR1:
+      signal_string = "DUMP";
+      break;
+    case SIGUSR2:
+      signal_string = "DEBUG";
+      break;
+    case SIGNEWNYM:
+      signal_string = "NEWNYM";
+      break;
+    case SIGCLEARDNSCACHE:
+      signal_string = "CLEARDNSCACHE";
+      break;
+    default:
+      log_warn(LD_BUG, "Unrecognized signal %lu in control_event_signal", signal);
+      return -1;
+  }
+
+  send_control_event(EVENT_SIGNAL, ALL_FORMATS, "650 SIGNAL %s\r\n", signal_string);
+  return 0;
+}
+
 /** Called when a single local_routerstatus_t has changed: Sends an NS event
  * to any controller that cares. */
 int

+ 1 - 0
src/or/control.h

@@ -64,6 +64,7 @@ int control_event_guard(const char *nickname, const char *digest,
                         const char *status);
 int control_event_buildtimeout_set(const circuit_build_times_t *cbt,
                                    buildtimeout_set_event_t type);
+int control_event_signal(uintptr_t signal);
 
 int init_cookie_authentication(int enabled);
 smartlist_t *decode_hashed_passwords(config_line_t *passwords);

+ 5 - 0
src/or/main.c

@@ -1840,11 +1840,13 @@ signal_callback(int fd, short events, void *arg)
     case SIGUSR1:
       /* 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);
+      control_event_signal(sig);
       break;
     case SIGUSR2:
       switch_logs_debug();
       log_debug(LD_GENERAL,"Caught USR2, going to loglevel debug. "
                 "Send HUP to change back.");
+      control_event_signal(sig);
       break;
     case SIGHUP:
       if (do_hup() < 0) {
@@ -1852,6 +1854,7 @@ signal_callback(int fd, short events, void *arg)
         tor_cleanup();
         exit(1);
       }
+      control_event_signal(sig);
       break;
 #ifdef SIGCHLD
     case SIGCHLD:
@@ -1868,11 +1871,13 @@ signal_callback(int fd, short events, void *arg)
             (int)(MAX_SIGNEWNYM_RATE+time_of_last_signewnym-now));
       } else {
         signewnym_impl(now);
+        control_event_signal(sig);
       }
       break;
     }
     case SIGCLEARDNSCACHE:
       addressmap_clear_transient();
+      control_event_signal(sig);
       break;
   }
 }