summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2011-08-10 15:04:36 -0400
committerNick Mathewson <nickm@torproject.org>2011-08-10 15:04:36 -0400
commitb76f46c6d8ba5e7b3efa91ae5ef487ba05d3b3c4 (patch)
treedb6f138592b68dbf8f0dfc32a02d266bf956882f
parent333df6006d27fb7e11b504257e3ee22f97c5f04b (diff)
parent02a735dfa847e9cb7b78b58ef1f69d865e4d21bf (diff)
downloadtor-b76f46c6d8ba5e7b3efa91ae5ef487ba05d3b3c4.tar.gz
tor-b76f46c6d8ba5e7b3efa91ae5ef487ba05d3b3c4.zip
Merge branch 'bug1692-squashed'
-rw-r--r--changes/bug16925
-rw-r--r--src/common/util.c24
-rw-r--r--src/common/util.h5
-rw-r--r--src/or/config.c28
-rw-r--r--src/or/control.c36
-rw-r--r--src/or/control.h1
6 files changed, 97 insertions, 2 deletions
diff --git a/changes/bug1692 b/changes/bug1692
new file mode 100644
index 0000000000..c2a71cc428
--- /dev/null
+++ b/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.
+
diff --git a/src/common/util.c b/src/common/util.c
index 542093fb5d..c387318c0e 100644
--- a/src/common/util.c
+++ b/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.
*/
diff --git a/src/common/util.h b/src/common/util.h
index 99355871f6..a1def6cc3f 100644
--- a/src/common/util.h
+++ b/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);
diff --git a/src/or/config.c b/src/or/config.c
index 1f574c8233..e2e5cd3a6b 100644
--- a/src/or/config.c
+++ b/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;
diff --git a/src/or/control.c b/src/or/control.c
index ad11350fbd..afd0662df0 100644
--- a/src/or/control.c
+++ b/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 *
diff --git a/src/or/control.h b/src/or/control.h
index 147a5af0bb..544a9fcc9e 100644
--- a/src/or/control.h
+++ b/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);