Browse Source

Merge branch 'bug1692-squashed'

Nick Mathewson 14 years ago
parent
commit
b76f46c6d8
6 changed files with 97 additions and 2 deletions
  1. 5 0
      changes/bug1692
  2. 24 0
      src/common/util.c
  3. 5 0
      src/common/util.h
  4. 27 1
      src/or/config.c
  5. 35 1
      src/or/control.c
  6. 1 0
      src/or/control.h

+ 5 - 0
changes/bug1692

@@ -0,0 +1,5 @@
+  o Minor features:
+    - CONF_CHANGED event is provided so that controllers can be notified
+      of any configuration changes made by other controllers/SETCONF/HUP.
+      Implements #1692.
+

+ 24 - 0
src/common/util.c

@@ -2681,6 +2681,30 @@ tor_sscanf(const char *buf, const char *pattern, ...)
   return r;
 }
 
+/** Append the string produced by tor_asprintf(<b>pattern</b>, <b>...</b>)
+ * to <b>sl</b>. */
+void
+smartlist_asprintf_add(struct smartlist_t *sl, const char *pattern, ...)
+{
+  va_list ap;
+  va_start(ap, pattern);
+  smartlist_vasprintf_add(sl, pattern, ap);
+  va_end(ap);
+}
+
+/** va_list-based backend of smartlist_asprintf_add. */
+void
+smartlist_vasprintf_add(struct smartlist_t *sl, const char *pattern,
+                        va_list args)
+{
+  char *str = NULL;
+
+  tor_vasprintf(&str, pattern, args);
+  tor_assert(str != NULL);
+
+  smartlist_add(sl, str);
+}
+
 /** Return a new list containing the filenames in the directory <b>dirname</b>.
  * Return NULL on error or if <b>dirname</b> is not a directory.
  */

+ 5 - 0
src/common/util.h

@@ -220,6 +220,11 @@ int tor_sscanf(const char *buf, const char *pattern, ...)
 #endif
   ;
 
+void smartlist_asprintf_add(struct smartlist_t *sl, const char *pattern, ...)
+  CHECK_PRINTF(2, 3);
+void smartlist_vasprintf_add(struct smartlist_t *sl, const char *pattern,
+                             va_list args);
+
 int hex_decode_digit(char c);
 void base16_encode(char *dest, size_t destlen, const char *src, size_t srclen);
 int base16_decode(char *dest, size_t destlen, const char *src, size_t srclen);

+ 27 - 1
src/or/config.c

@@ -696,6 +696,9 @@ get_options(void)
 int
 set_options(or_options_t *new_val, char **msg)
 {
+  int i;
+  smartlist_t *elements;
+  config_line_t *line;
   or_options_t *old_options = global_options;
   global_options = new_val;
   /* Note that we pass the *old* options below, for comparison. It
@@ -710,7 +713,30 @@ set_options(or_options_t *new_val, char **msg)
             "Acting on config options left us in a broken state. Dying.");
     exit(1);
   }
-
+  /* Issues a CONF_CHANGED event to notify controller of the change. If Tor is
+   * just starting up then the old_options will be undefined. */
+  if (old_options) {
+    elements = smartlist_create();
+    for (i=0; options_format.vars[i].name; ++i) {
+      if (!option_is_same(&options_format, new_val, old_options,
+        options_format.vars[i].name)) {
+        line = get_assigned_option(&options_format, new_val,
+        options_format.vars[i].name, 1);
+
+        if (line) {
+          for (; line; line = line->next) {
+            smartlist_add(elements, line->key);
+            smartlist_add(elements, line->value);
+          }
+        } else {
+          smartlist_add(elements, options_format.vars[i].name);
+          smartlist_add(elements, NULL);
+        }
+      }
+    }
+    control_event_conf_changed(elements);
+    smartlist_free(elements);
+  }
   config_free(&options_format, old_options);
 
   return 0;

+ 35 - 1
src/or/control.c

@@ -74,7 +74,8 @@
 #define EVENT_NEWCONSENSUS     0x0016
 #define EVENT_BUILDTIMEOUT_SET     0x0017
 #define EVENT_SIGNAL           0x0018
-#define _EVENT_MAX             0x0018
+#define EVENT_CONF_CHANGED     0x0019
+#define _EVENT_MAX             0x0019
 /* 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,7 @@ static const struct control_event_t control_event_table[] = {
   { EVENT_NEWCONSENSUS, "NEWCONSENSUS" },
   { EVENT_BUILDTIMEOUT_SET, "BUILDTIMEOUT_SET" },
   { EVENT_SIGNAL, "SIGNAL" },
+  { EVENT_CONF_CHANGED, "CONF_CHANGED"},
   { 0, NULL },
 };
 
@@ -3996,6 +3998,38 @@ control_event_guard(const char *nickname, const char *digest,
   return 0;
 }
 
+/** Called when a configuration option changes. This is generally triggered
+ * by SETCONF requests and RELOAD/SIGHUP signals. The <b>elements</b> is
+ * a smartlist_t containing (key, value, ...) pairs in sequence.
+ * <b>value</b> can be NULL. */
+int
+control_event_conf_changed(smartlist_t *elements)
+{
+  int i;
+  char *result;
+  smartlist_t *lines;
+  if (!EVENT_IS_INTERESTING(EVENT_CONF_CHANGED) || smartlist_len(elements) == 0) {
+    return 0;
+  }
+  lines = smartlist_create();
+  for (i = 0; i < smartlist_len(elements); i += 2) {
+    char *k = smartlist_get(elements, i);
+    char *v = smartlist_get(elements, i+1);
+    if (v == NULL) {
+      smartlist_asprintf_add(lines, "650-%s", k);
+    } else {
+      smartlist_asprintf_add(lines, "650-%s=%s", k, v);
+    }
+  }
+  result = smartlist_join_strings(lines, "\r\n", 0, NULL);
+  send_control_event(EVENT_CONF_CHANGED, 0,
+    "650-CONF_CHANGED\r\n%s\r\n650 OK\r\n", result);
+  tor_free(result);
+  SMARTLIST_FOREACH(lines, char *, cp, tor_free(cp));
+  smartlist_free(lines);
+  return 0;
+}
+
 /** Helper: Return a newly allocated string containing a path to the
  * file where we store our authentication cookie. */
 static char *

+ 1 - 0
src/or/control.h

@@ -66,6 +66,7 @@ int control_event_server_status(int severity, const char *format, ...)
   CHECK_PRINTF(2,3);
 int control_event_guard(const char *nickname, const char *digest,
                         const char *status);
+int control_event_conf_changed(smartlist_t *elements);
 int control_event_buildtimeout_set(const circuit_build_times_t *cbt,
                                    buildtimeout_set_event_t type);
 int control_event_signal(uintptr_t signal);