start, stop, reload commands.

git-svn-id: file:///svn/unbound/trunk@1235 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
Wouter Wijngaards 2008-09-15 08:35:45 +00:00
parent 08e0563483
commit 3137c88a43
4 changed files with 139 additions and 15 deletions

View file

@ -378,32 +378,152 @@ clean_point(struct daemon_remote* rc, struct rc_state* s)
free(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 */ /** handle remote control request */
static void static void
handle_req(struct daemon_remote* rc, struct rc_state* s, SSL* ssl) handle_req(struct daemon_remote* rc, struct rc_state* s, SSL* ssl)
{ {
char* msg = "ok\n";
int r; int r;
char magic[5];
char buf[1024]; char buf[1024];
fd_set_block(s->c->fd); fd_set_block(s->c->fd);
/* try to read magic UBCT string */
ERR_clear_error(); 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) if(SSL_get_error(ssl, r) == SSL_ERROR_ZERO_RETURN)
return; return;
log_crypto_err("could not SSL_read"); log_crypto_err("could not SSL_read");
return; return;
} }
buf[r] = 0; magic[4] = 0;
log_info("got '%s'", buf); if( r != 4 || strcmp(magic, "UBCT") != 0) {
verbose(VERB_QUERY, "control connection has bad magic string");
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");
return; return;
} }
/* 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, int remote_control_callback(struct comm_point* c, void* arg, int err,

View file

@ -1,3 +1,6 @@
15 September 2008: Wouter
- working start, stop, reload commands for unbound-control.
12 September 2008: Wouter 12 September 2008: Wouter
- removed browser control mentions. Proto speccy. - removed browser control mentions. Proto speccy.

View file

@ -41,13 +41,15 @@ address is read from the config file.
There are several commands that the server understands. There are several commands that the server understands.
.TP .TP
.B start .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 .TP
.B stop .B stop
Stop the server. Stop the server. The server daemon exits.
.TP .TP
.B reload .B reload
Reload the server. Reload the server. This flushes the cache and reads the config file fresh.
.SH "EXIT CODE" .SH "EXIT CODE"
The unbound-control program exits with status code 1 on error. The unbound-control program exits with status code 1 on error.
.SH "SET UP" .SH "SET UP"

View file

@ -186,7 +186,6 @@ setup_ssl(SSL_CTX* ctx, int fd)
static void static void
go_cmd(SSL* ssl, int argc, char* argv[]) go_cmd(SSL* ssl, int argc, char* argv[])
{ {
char* cmd = "GET / HTTP/1.0\n\n";
char* pre="UBCT"; char* pre="UBCT";
char* space=" "; char* space=" ";
char* newline="\n"; char* newline="\n";
@ -303,7 +302,7 @@ int main(int argc, char* argv[])
argv += optind; argv += optind;
if(argc == 0) if(argc == 0)
usage(); usage();
if(argc == 1 && strcmp(argv[0], "start")==0) { if(argc >= 1 && strcmp(argv[0], "start")==0) {
if(execlp("unbound", "unbound", "-c", cfgfile, if(execlp("unbound", "unbound", "-c", cfgfile,
(char*)NULL) < 0) { (char*)NULL) < 0) {
fatal_exit("could not exec unbound: %s", fatal_exit("could not exec unbound: %s",