summaryrefslogtreecommitdiff
path: root/src/or/control.c
diff options
context:
space:
mode:
authorPeter Palfrader <peter@palfrader.org>2008-03-10 12:41:52 +0000
committerPeter Palfrader <peter@palfrader.org>2008-03-10 12:41:52 +0000
commit79f1ee8a2daafab587a274c0bf409ac5e6e09d93 (patch)
tree3446c10c871430b453d8c741e33d5e17e65f66f1 /src/or/control.c
parentbc4095c70cabb6457e89308b51d5d2b7d04ae3c4 (diff)
downloadtor-79f1ee8a2daafab587a274c0bf409ac5e6e09d93.tar.gz
tor-79f1ee8a2daafab587a274c0bf409ac5e6e09d93.zip
Implement LOADCONF control command
The LOADCONF control command allows posting a config file to Tor over the control interface. This config file is then loaded as if it had been read from disk. Sending a HUP signal to Tor will make it try to load its old config from disk again, thereby forgetting the config loaded with this command. svn:r13948
Diffstat (limited to 'src/or/control.c')
-rw-r--r--src/or/control.c48
1 files changed, 48 insertions, 0 deletions
diff --git a/src/or/control.c b/src/or/control.c
index c2337e9830..788af76d94 100644
--- a/src/or/control.c
+++ b/src/or/control.c
@@ -100,6 +100,8 @@ static int handle_control_resetconf(control_connection_t *conn, uint32_t len,
char *body);
static int handle_control_getconf(control_connection_t *conn, uint32_t len,
const char *body);
+static int handle_control_loadconf(control_connection_t *conn, uint32_t len,
+ const char *body);
static int handle_control_setevents(control_connection_t *conn, uint32_t len,
const char *body);
static int handle_control_authenticate(control_connection_t *conn,
@@ -862,6 +864,49 @@ handle_control_getconf(control_connection_t *conn, uint32_t body_len,
return 0;
}
+
+/** Called when we get a +LOADCONF message. */
+static int
+handle_control_loadconf(control_connection_t *conn, uint32_t len,
+ const char *body)
+{
+ int retval;
+ char *errstring = NULL;
+ char *msg = NULL;
+
+ retval = options_init_from_string(body, CMD_RUN_TOR, NULL, &errstring);
+
+ if (retval < 0) {
+ log_warn(LD_CONTROL,
+ "Controller gave us config file that didn't validate: %s",
+ errstring);
+ switch (retval) {
+ case -2:
+ msg = "552 Invalid config file";
+ break;
+ case -3:
+ msg = "553 Transition not allowed";
+ break;
+ case -4:
+ msg = "553 Unable to set option";
+ break;
+ case -1:
+ default:
+ msg = "550 Unable to load config";
+ break;
+ }
+ if (*errstring)
+ connection_printf_to_buf(conn, "%s: %s\r\n", msg, errstring);
+ else
+ connection_printf_to_buf(conn, "%s\r\n", msg);
+ tor_free(errstring);
+ return 0;
+ }
+ send_control_done(conn);
+ return 0;
+}
+
+
/** Called when we get a SETEVENTS message: update conn->event_mask,
* and reply with DONE or ERROR. */
static int
@@ -2801,6 +2846,9 @@ connection_control_process_inbuf(control_connection_t *conn)
} else if (!strcasecmp(conn->incoming_cmd, "GETCONF")) {
if (handle_control_getconf(conn, cmd_data_len, args))
return -1;
+ } else if (!strcasecmp(conn->incoming_cmd, "+LOADCONF")) {
+ if (handle_control_loadconf(conn, cmd_data_len, args))
+ return -1;
} else if (!strcasecmp(conn->incoming_cmd, "SETEVENTS")) {
if (handle_control_setevents(conn, cmd_data_len, args))
return -1;