]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
start, stop, reload commands.
authorWouter Wijngaards <wouter@nlnetlabs.nl>
Mon, 15 Sep 2008 08:35:45 +0000 (08:35 +0000)
committerWouter Wijngaards <wouter@nlnetlabs.nl>
Mon, 15 Sep 2008 08:35:45 +0000 (08:35 +0000)
git-svn-id: file:///svn/unbound/trunk@1235 be551aaa-1e26-0410-a405-d3ace91eadb9

daemon/remote.c
doc/Changelog
doc/unbound-control.8.in
smallapp/unbound-control.c

index 8e8cc18ee759213305db692560a6a71f5727a391..855e3b1758071fe5384771215a0e499415668b21 100644 (file)
@@ -378,32 +378,152 @@ clean_point(struct daemon_remote* rc, struct rc_state* s)
        free(s);
 }
 
+/** print fixed line over the ssl connection */
+static int
+ssl_print_text(SSL* ssl, const char* text)
+{
+       int r;
+       ERR_clear_error();
+       if((r=SSL_write(ssl, text, (int)strlen(text))) <= 0) {
+               if(SSL_get_error(ssl, r) == SSL_ERROR_ZERO_RETURN) {
+                       verbose(VERB_QUERY, "warning, in SSL_write, peer "
+                               "closed connection");
+                       return 0;
+               }
+               log_crypto_err("could not SSL_write");
+               return 0;
+       }
+       return 1;
+}
+
+/** print text over the ssl connection */
+static int
+ssl_print_vmsg(SSL* ssl, const char* format, va_list args)
+{
+       char msg[1024];
+       vsnprintf(msg, sizeof(msg), format, args);
+       return ssl_print_text(ssl, msg);
+}
+
+/** declare for printf format checking by gcc 
+ * @param ssl: the SSL connection to print to. Blocking.
+ * @param format: printf style format string.
+ * @return success or false on a network failure.
+ */
+static int ssl_printf(SSL* ssl, const char* format, ...) 
+       ATTR_FORMAT(printf, 2, 3);
+
+/** printf style printing to the ssl connection */
+static int ssl_printf(SSL* ssl, const char* format, ...)
+{
+       va_list args;
+       int ret;
+       va_start(args, format);
+       ret = ssl_print_vmsg(ssl, format, args);
+       va_end(args);
+       return ret;
+}
+
+/** read until \n */
+static int
+ssl_read_line(SSL* ssl, char* buf, size_t max)
+{
+       int r;
+       size_t len = 0;
+       while(len < max) {
+               ERR_clear_error();
+               if((r=SSL_read(ssl, buf+len, 1)) <= 0) {
+                       if(SSL_get_error(ssl, r) == SSL_ERROR_ZERO_RETURN) {
+                               buf[len] = 0;
+                               return 1;
+                       }
+                       log_crypto_err("could not SSL_read");
+                       return 0;
+               }
+               if(buf[len] == '\n') {
+                       /* return string without \n */
+                       buf[len] = 0;
+                       return 1;
+               }
+               len++;
+       }
+       buf[max-1] = 0;
+       log_err("control line too long (%d): %s", (int)max, buf);
+       return 0;
+}
+
+/** send the OK to the control client */
+static void send_ok(SSL* ssl)
+{
+       (void)ssl_printf(ssl, "ok\n");
+}
+
+/** do the stop command */
+static void
+do_stop(struct daemon_remote* rc, SSL* ssl)
+{
+       rc->worker->need_to_exit = 1;
+       comm_base_exit(rc->worker->base);
+       send_ok(ssl);
+}
+
+/** do the reload command */
+static void
+do_reload(struct daemon_remote* rc, SSL* ssl)
+{
+       rc->worker->need_to_exit = 0;
+       comm_base_exit(rc->worker->base);
+       send_ok(ssl);
+}
+
+/** execute a remote control command */
+static void
+execute_cmd(struct daemon_remote* rc, SSL* ssl, char* cmd)
+{
+       char* p = cmd;
+       /* skip whitespace */
+       while( isspace(*p) ) p++;
+       /* compare command - check longer strings first */
+       if(strncmp(p, "stop", 4) == 0) {
+               do_stop(rc, ssl);
+       } else if(strncmp(p, "reload", 6) == 0) {
+               do_reload(rc, ssl);
+       } else {
+               (void)ssl_printf(ssl, "error unknown command '%s'\n", p);
+       }
+}
+
 /** handle remote control request */
 static void
 handle_req(struct daemon_remote* rc, struct rc_state* s, SSL* ssl)
 {
-       char* msg = "ok\n";
        int r;
+       char magic[5];
        char buf[1024];
        fd_set_block(s->c->fd);
 
+       /* try to read magic UBCT string */
        ERR_clear_error();
-       if((r=SSL_read(ssl, buf, (int)sizeof(buf)-1)) <= 0) {
+       if((r=SSL_read(ssl, magic, (int)sizeof(magic)-1)) <= 0) {
                if(SSL_get_error(ssl, r) == SSL_ERROR_ZERO_RETURN)
                        return;
                log_crypto_err("could not SSL_read");
                return;
        }
-       buf[r] = 0;
-       log_info("got '%s'", buf);
+       magic[4] = 0;
+       if( r != 4 || strcmp(magic, "UBCT") != 0) {
+               verbose(VERB_QUERY, "control connection has bad magic string");
+               return;
+       }
 
-       ERR_clear_error();
-       if((r=SSL_write(ssl, msg, (int)strlen(msg))) <= 0) {
-               if(SSL_get_error(ssl, r) == SSL_ERROR_ZERO_RETURN)
-                       return;
-               log_crypto_err("could not SSL_write");
+       /* read the command line */
+       if(!ssl_read_line(ssl, buf, sizeof(buf))) {
                return;
        }
+       verbose(VERB_DETAIL, "control cmd: %s", buf);
+
+       /* figure out what to do */
+       execute_cmd(rc, ssl, buf);
 }
 
 int remote_control_callback(struct comm_point* c, void* arg, int err, 
index 4946239971336a1d4a2b7e5dff080f1a34104b11..261d51a57bba70916d9519d5933c57104a2ba9e9 100644 (file)
@@ -1,3 +1,6 @@
+15 September 2008: Wouter
+       - working start, stop, reload commands for unbound-control.
+
 12 September 2008: Wouter
        - removed browser control mentions. Proto speccy.
 
index 3eca71fec540ed6ba5f482f9082a91802ee1e630..d4ed17195fcb122347dd7bd858e3eef25f020b0c 100644 (file)
@@ -41,13 +41,15 @@ address is read from the config file.
 There are several commands that the server understands.
 .TP
 .B start
-Start the server. Simply execs \fIunbound\fR(8).
+Start the server. Simply execs \fIunbound\fR(8).  The unbound executable 
+is searched for in the \fBPATH\fR set in the environment.  It is started 
+with the config file specified using \fI\-c\fR or the default config file.
 .TP
 .B stop
-Stop the server.
+Stop the server. The server daemon exits.
 .TP
 .B reload
-Reload the server.
+Reload the server. This flushes the cache and reads the config file fresh.
 .SH "EXIT CODE"
 The unbound-control program exits with status code 1 on error.
 .SH "SET UP"
index 59e8f9aa654f3bf1716388a33a848cc0b64fe384..f4446c3c3bb38c0b1ea557f85814e86178a7d6ee 100644 (file)
@@ -186,7 +186,6 @@ setup_ssl(SSL_CTX* ctx, int fd)
 static void
 go_cmd(SSL* ssl, int argc, char* argv[])
 {
-       char* cmd = "GET / HTTP/1.0\n\n";
        char* pre="UBCT";
        char* space=" ";
        char* newline="\n";
@@ -303,7 +302,7 @@ int main(int argc, char* argv[])
        argv += optind;
        if(argc == 0)
                usage();
-       if(argc == 1 && strcmp(argv[0], "start")==0) {
+       if(argc >= 1 && strcmp(argv[0], "start")==0) {
                if(execlp("unbound", "unbound", "-c", cfgfile, 
                        (char*)NULL) < 0) {
                        fatal_exit("could not exec unbound: %s",