mirror of
https://github.com/NLnetLabs/unbound.git
synced 2025-12-20 23:00:56 -05:00
fixup remote control so most commands work in nonthreaded environment.
git-svn-id: file:///svn/unbound/trunk@1382 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
parent
bcf49eaf96
commit
4ac7881829
8 changed files with 99 additions and 20 deletions
|
|
@ -445,6 +445,8 @@ int
|
||||||
ssl_print_text(SSL* ssl, const char* text)
|
ssl_print_text(SSL* ssl, const char* text)
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
|
if(!ssl)
|
||||||
|
return 0;
|
||||||
ERR_clear_error();
|
ERR_clear_error();
|
||||||
if((r=SSL_write(ssl, text, (int)strlen(text))) <= 0) {
|
if((r=SSL_write(ssl, text, (int)strlen(text))) <= 0) {
|
||||||
if(SSL_get_error(ssl, r) == SSL_ERROR_ZERO_RETURN) {
|
if(SSL_get_error(ssl, r) == SSL_ERROR_ZERO_RETURN) {
|
||||||
|
|
@ -483,6 +485,8 @@ ssl_read_line(SSL* ssl, char* buf, size_t max)
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
|
if(!ssl)
|
||||||
|
return 0;
|
||||||
while(len < max) {
|
while(len < max) {
|
||||||
ERR_clear_error();
|
ERR_clear_error();
|
||||||
if((r=SSL_read(ssl, buf+len, 1)) <= 0) {
|
if((r=SSL_read(ssl, buf+len, 1)) <= 0) {
|
||||||
|
|
@ -1182,45 +1186,96 @@ do_flush_name(SSL* ssl, struct worker* worker, char* arg)
|
||||||
send_ok(ssl);
|
send_ok(ssl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** tell other processes to execute the command */
|
||||||
|
void
|
||||||
|
distribute_cmd(struct daemon_remote* rc, SSL* ssl, char* cmd)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
if(!cmd || !ssl)
|
||||||
|
return;
|
||||||
|
/* skip i=0 which is me */
|
||||||
|
for(i=1; i<rc->worker->daemon->num; i++) {
|
||||||
|
worker_send_cmd(rc->worker->daemon->workers[i],
|
||||||
|
worker_cmd_remote);
|
||||||
|
if(!tube_write_msg(rc->worker->daemon->workers[i]->cmd,
|
||||||
|
(uint8_t*)cmd, strlen(cmd)+1, 0)) {
|
||||||
|
ssl_printf(ssl, "error could not distribute cmd\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** execute a remote control command */
|
/** execute a remote control command */
|
||||||
static void
|
static void
|
||||||
execute_cmd(struct daemon_remote* rc, SSL* ssl, char* cmd)
|
execute_cmd(struct daemon_remote* rc, SSL* ssl, char* cmd,
|
||||||
|
struct worker* worker)
|
||||||
{
|
{
|
||||||
char* p = skipwhite(cmd);
|
char* p = skipwhite(cmd);
|
||||||
/* compare command - check longer strings first in case of substrings*/
|
/* compare command - check longer strings first in case of substrings*/
|
||||||
if(strncmp(p, "stop", 4) == 0) {
|
if(strncmp(p, "stop", 4) == 0) {
|
||||||
do_stop(ssl, rc);
|
do_stop(ssl, rc);
|
||||||
|
return;
|
||||||
} else if(strncmp(p, "reload", 6) == 0) {
|
} else if(strncmp(p, "reload", 6) == 0) {
|
||||||
do_reload(ssl, rc);
|
do_reload(ssl, rc);
|
||||||
} else if(strncmp(p, "verbosity", 9) == 0) {
|
return;
|
||||||
do_verbosity(ssl, skipwhite(p+9));
|
|
||||||
} else if(strncmp(p, "stats", 5) == 0) {
|
} else if(strncmp(p, "stats", 5) == 0) {
|
||||||
do_stats(ssl, rc);
|
do_stats(ssl, rc);
|
||||||
} else if(strncmp(p, "local_zone_remove", 17) == 0) {
|
return;
|
||||||
do_zone_remove(ssl, rc->worker, skipwhite(p+17));
|
|
||||||
} else if(strncmp(p, "local_zone", 10) == 0) {
|
|
||||||
do_zone_add(ssl, rc->worker, skipwhite(p+10));
|
|
||||||
} else if(strncmp(p, "local_data_remove", 17) == 0) {
|
|
||||||
do_data_remove(ssl, rc->worker, skipwhite(p+17));
|
|
||||||
} else if(strncmp(p, "local_data", 10) == 0) {
|
|
||||||
do_data_add(ssl, rc->worker, skipwhite(p+10));
|
|
||||||
} else if(strncmp(p, "dump_cache", 10) == 0) {
|
} else if(strncmp(p, "dump_cache", 10) == 0) {
|
||||||
(void)dump_cache(ssl, rc->worker);
|
(void)dump_cache(ssl, worker);
|
||||||
|
return;
|
||||||
} else if(strncmp(p, "load_cache", 10) == 0) {
|
} else if(strncmp(p, "load_cache", 10) == 0) {
|
||||||
if(load_cache(ssl, rc->worker)) send_ok(ssl);
|
if(load_cache(ssl, worker)) send_ok(ssl);
|
||||||
|
return;
|
||||||
} else if(strncmp(p, "lookup", 6) == 0) {
|
} else if(strncmp(p, "lookup", 6) == 0) {
|
||||||
do_lookup(ssl, rc->worker, skipwhite(p+6));
|
do_lookup(ssl, worker, skipwhite(p+6));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef THREADS_DISABLED
|
||||||
|
/* other processes must execute the command as well */
|
||||||
|
/* commands that should not be distributed, returned above. */
|
||||||
|
if(rc) { /* only if this thread is the master (rc) thread */
|
||||||
|
/* done before the code below, which may split the string */
|
||||||
|
distribute_cmd(rc, ssl, cmd);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if(strncmp(p, "verbosity", 9) == 0) {
|
||||||
|
do_verbosity(ssl, skipwhite(p+9));
|
||||||
|
} else if(strncmp(p, "local_zone_remove", 17) == 0) {
|
||||||
|
do_zone_remove(ssl, worker, skipwhite(p+17));
|
||||||
|
} else if(strncmp(p, "local_zone", 10) == 0) {
|
||||||
|
do_zone_add(ssl, worker, skipwhite(p+10));
|
||||||
|
} else if(strncmp(p, "local_data_remove", 17) == 0) {
|
||||||
|
do_data_remove(ssl, worker, skipwhite(p+17));
|
||||||
|
} else if(strncmp(p, "local_data", 10) == 0) {
|
||||||
|
do_data_add(ssl, worker, skipwhite(p+10));
|
||||||
} else if(strncmp(p, "flush_zone", 10) == 0) {
|
} else if(strncmp(p, "flush_zone", 10) == 0) {
|
||||||
do_flush_zone(ssl, rc->worker, skipwhite(p+10));
|
do_flush_zone(ssl, worker, skipwhite(p+10));
|
||||||
} else if(strncmp(p, "flush_type", 10) == 0) {
|
} else if(strncmp(p, "flush_type", 10) == 0) {
|
||||||
do_flush_type(ssl, rc->worker, skipwhite(p+10));
|
do_flush_type(ssl, worker, skipwhite(p+10));
|
||||||
} else if(strncmp(p, "flush", 5) == 0) {
|
} else if(strncmp(p, "flush", 5) == 0) {
|
||||||
do_flush_name(ssl, rc->worker, skipwhite(p+5));
|
do_flush_name(ssl, worker, skipwhite(p+5));
|
||||||
} else {
|
} else {
|
||||||
(void)ssl_printf(ssl, "error unknown command '%s'\n", p);
|
(void)ssl_printf(ssl, "error unknown command '%s'\n", p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
daemon_remote_exec(struct worker* worker)
|
||||||
|
{
|
||||||
|
/* read the cmd string */
|
||||||
|
uint8_t* msg = NULL;
|
||||||
|
size_t len = 0;
|
||||||
|
if(!tube_read_msg(worker->cmd, &msg, &len, 0)) {
|
||||||
|
log_err("daemon_remote_exec: tube_read_msg failed");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
verbose(VERB_ALGO, "remote exec distributed: %s", (char*)msg);
|
||||||
|
execute_cmd(NULL, NULL, (char*)msg, worker);
|
||||||
|
free(msg);
|
||||||
|
}
|
||||||
|
|
||||||
/** 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)
|
||||||
|
|
@ -1256,7 +1311,7 @@ handle_req(struct daemon_remote* rc, struct rc_state* s, SSL* ssl)
|
||||||
verbose(VERB_DETAIL, "control cmd: %s", buf);
|
verbose(VERB_DETAIL, "control cmd: %s", buf);
|
||||||
|
|
||||||
/* figure out what to do */
|
/* figure out what to do */
|
||||||
execute_cmd(rc, ssl, buf);
|
execute_cmd(rc, ssl, buf, rc->worker);
|
||||||
}
|
}
|
||||||
|
|
||||||
int remote_control_callback(struct comm_point* c, void* arg, int err,
|
int remote_control_callback(struct comm_point* c, void* arg, int err,
|
||||||
|
|
|
||||||
|
|
@ -124,6 +124,12 @@ struct listen_port* daemon_remote_open_ports(struct config_file* cfg);
|
||||||
int daemon_remote_open_accept(struct daemon_remote* rc,
|
int daemon_remote_open_accept(struct daemon_remote* rc,
|
||||||
struct listen_port* ports);
|
struct listen_port* ports);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle nonthreaded remote cmd execution.
|
||||||
|
* @param worker: this worker (the remote worker).
|
||||||
|
*/
|
||||||
|
void daemon_remote_exec(struct worker* worker);
|
||||||
|
|
||||||
/** handle remote control accept callbacks */
|
/** handle remote control accept callbacks */
|
||||||
int remote_accept_callback(struct comm_point*, void*, int, struct comm_reply*);
|
int remote_accept_callback(struct comm_point*, void*, int, struct comm_reply*);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -344,6 +344,12 @@ worker_handle_control_cmd(struct tube* ATTR_UNUSED(tube), uint8_t* msg,
|
||||||
verbose(VERB_ALGO, "got control cmd stats");
|
verbose(VERB_ALGO, "got control cmd stats");
|
||||||
server_stats_reply(worker);
|
server_stats_reply(worker);
|
||||||
break;
|
break;
|
||||||
|
#ifdef THREADS_DISABLED
|
||||||
|
case worker_cmd_remote:
|
||||||
|
verbose(VERB_ALGO, "got control cmd remote");
|
||||||
|
daemon_remote_exec(worker);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
log_err("bad command %d", (int)cmd);
|
log_err("bad command %d", (int)cmd);
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,9 @@ enum worker_commands {
|
||||||
/** make the worker quit */
|
/** make the worker quit */
|
||||||
worker_cmd_quit,
|
worker_cmd_quit,
|
||||||
/** obtain statistics */
|
/** obtain statistics */
|
||||||
worker_cmd_stats
|
worker_cmd_stats,
|
||||||
|
/** execute remote control command */
|
||||||
|
worker_cmd_remote
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,10 @@
|
||||||
was using multiple processes.
|
was using multiple processes.
|
||||||
- iana portlist updated.
|
- iana portlist updated.
|
||||||
- test for remote control with interprocess communication.
|
- test for remote control with interprocess communication.
|
||||||
|
- created command distribution mechanism so that remote control
|
||||||
|
commands other than 'stats' work on all processes in a nonthreaded
|
||||||
|
compiled version. dump/load cache work, on the first process.
|
||||||
|
- fixup remote control local_data addition memory corruption bug.
|
||||||
|
|
||||||
1 December 2008: Wouter
|
1 December 2008: Wouter
|
||||||
- SElinux policy files in contrib/selinux for the unbound daemon,
|
- SElinux policy files in contrib/selinux for the unbound daemon,
|
||||||
|
|
|
||||||
|
|
@ -1233,10 +1233,11 @@ local_zones_add_RR(struct local_zones* zones, const char* rr, ldns_buffer* buf)
|
||||||
lock_quick_unlock(&zones->lock);
|
lock_quick_unlock(&zones->lock);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
free(rr_name);
|
||||||
}
|
}
|
||||||
lock_rw_wrlock(&z->lock);
|
lock_rw_wrlock(&z->lock);
|
||||||
lock_quick_unlock(&zones->lock);
|
lock_quick_unlock(&zones->lock);
|
||||||
free(rr_name);
|
|
||||||
r = lz_enter_rr_into_zone(z, buf, rr);
|
r = lz_enter_rr_into_zone(z, buf, rr);
|
||||||
lock_rw_unlock(&z->lock);
|
lock_rw_unlock(&z->lock);
|
||||||
return r;
|
return r;
|
||||||
|
|
|
||||||
|
|
@ -57,6 +57,7 @@
|
||||||
#include "testcode/ldns-testpkts.h"
|
#include "testcode/ldns-testpkts.h"
|
||||||
#include "util/log.h"
|
#include "util/log.h"
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
struct worker;
|
||||||
|
|
||||||
/** Global variable: the scenario. Saved here for when event_init is done. */
|
/** Global variable: the scenario. Saved here for when event_init is done. */
|
||||||
static struct replay_scenario* saved_scenario = NULL;
|
static struct replay_scenario* saved_scenario = NULL;
|
||||||
|
|
@ -1160,4 +1161,8 @@ struct event_base* comm_base_internal(struct comm_base* ATTR_UNUSED(b))
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void daemon_remote_exec(struct worker* ATTR_UNUSED(worker))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
/*********** End of Dummy routines ***********/
|
/*********** End of Dummy routines ***********/
|
||||||
|
|
|
||||||
BIN
testdata/remote-threaded.tpkg
vendored
BIN
testdata/remote-threaded.tpkg
vendored
Binary file not shown.
Loading…
Reference in a new issue