Ver código fonte

Implement SIGNAL control command.

svn:r3307
Nick Mathewson 21 anos atrás
pai
commit
dcd228585d
4 arquivos alterados com 60 adições e 1 exclusões
  1. 1 0
      doc/TODO
  2. 23 1
      src/or/control.c
  3. 35 0
      src/or/main.c
  4. 1 0
      src/or/or.h

+ 1 - 0
doc/TODO

@@ -122,6 +122,7 @@ N    - Clean up NT service code; make it work
      - Win32 installer plus privoxy, sockscap/freecap, etc.
 
    - Controller enhancements.
+     o Implement SIGNAL feature so windows can hup, shutdown, etc.
      - controller should have 'getinfo' command to query about rephist,
        about rendezvous status, etc.
 

+ 23 - 1
src/or/control.c

@@ -39,7 +39,8 @@ const char control_c_id[] = "$Id$";
 #define CONTROL_CMD_EVENT        0x0006
 #define CONTROL_CMD_AUTHENTICATE 0x0007
 #define CONTROL_CMD_SAVECONF     0x0008
-#define _CONTROL_CMD_MAX_RECOGNIZED 0x0008
+#define CONTROL_CMD_SIGNAL       0x0009
+#define _CONTROL_CMD_MAX_RECOGNIZED 0x0009
 
 /* Recognized error codes. */
 #define ERR_UNSPECIFIED             0x0000
@@ -113,6 +114,8 @@ static int handle_control_authenticate(connection_t *conn, uint16_t len,
                                        const char *body);
 static int handle_control_saveconf(connection_t *conn, uint16_t len,
                                    const char *body);
+static int handle_control_signal(connection_t *conn, uint16_t len,
+                                 const char *body);
 
 /** Given a possibly invalid message type code <b>cmd</b>, return a
  * human-readable string equivalent. */
@@ -398,6 +401,21 @@ handle_control_saveconf(connection_t *conn, uint16_t len,
   return 0;
 }
 
+static int
+handle_control_signal(connection_t *conn, uint16_t len,
+                      const char *body)
+{
+  if (len != 1) {
+    send_control_error(conn, ERR_SYNTAX,
+                       "Body of SIGNAL command too long or two short.");
+  } else if (control_signal_act((uint8_t)body[0]) < 0) {
+    send_control_error(conn, ERR_SYNTAX, "Unrecognized signal number.");
+  } else {
+    send_control_done(conn);
+  }
+  return 0;
+}
+
 /** Called when <b>conn</b> has no more bytes left on its outbuf. */
 int
 connection_control_finished_flushing(connection_t *conn) {
@@ -477,6 +495,10 @@ connection_control_process_inbuf(connection_t *conn) {
       if (handle_control_saveconf(conn, body_len, body))
         return -1;
       break;
+    case CONTROL_CMD_SIGNAL:
+      if (handle_control_signal(conn, body_len, body))
+        return -1;
+      break;
     case CONTROL_CMD_ERROR:
     case CONTROL_CMD_DONE:
     case CONTROL_CMD_CONFVALUE:

+ 35 - 0
src/or/main.c

@@ -922,6 +922,41 @@ static int do_main_loop(void) {
   }
 }
 
+/** Used to implement the SIGNAL control command: if we accept
+ * <b>the_signal</b> as a remote pseudo-signal, then act on it and
+ * return 0.  Else return -1. */
+/* We don't re-use catch() here because:
+ *   1. We handle a different set of signals than those allowed in catch.
+ *   2. Platforms without signal() are unlikely to define SIGfoo.
+ *   3. The control spec is defined to use fixed numeric signal values
+ *      which just happen to match the unix values.
+ */
+int
+control_signal_act(int the_signal)
+{
+  switch(the_signal)
+    {
+    case 1:
+      please_reset = 1;
+      break;
+    case 2:
+      please_shutdown = 1;
+      break;
+    case 10:
+      please_dumpstats = 1;
+      break;
+    case 12:
+      please_debug = 1;
+      break;
+    case 15:
+      please_die = 1;
+      break;
+    default:
+      return -1;
+    }
+  return 0;
+}
+
 /** Unix signal handler. */
 static void catch(int the_signal) {
 

+ 1 - 0
src/or/or.h

@@ -1387,6 +1387,7 @@ int server_mode(or_options_t *options);
 int advertised_server_mode(void);
 int proxy_mode(or_options_t *options);
 
+int control_signal_act(int the_signal);
 void handle_signals(int is_parent);
 void tor_cleanup(void);