Commit 1d92d8a2 authored by Brian Wellington's avatar Brian Wellington

792. [cleanup] Replace the OMAPI command channel protocol with a

			simpler one.
parent 11ba7973
792. [cleanup] Replace the OMAPI command channel protocol with a
simpler one.
791. [bug] The command channel now works over IPv6.
790. [bug] Wildcards created using dynamic update or IXFR
......
......@@ -13,7 +13,7 @@
# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
# $Id: Makefile.in,v 1.70 2001/03/06 02:40:11 bwelling Exp $
# $Id: Makefile.in,v 1.71 2001/03/27 00:44:30 bwelling Exp $
srcdir = @srcdir@
VPATH = @srcdir@
......@@ -32,37 +32,38 @@ DBDRIVER_INCLUDES =
DBDRIVER_LIBS =
CINCLUDES = -I${srcdir}/include -I${srcdir}/unix/include \
${LWRES_INCLUDES} ${OMAPI_INCLUDES} ${DNS_INCLUDES} \
${ISCCFG_INCLUDES} ${ISC_INCLUDES} ${DBDRIVER_INCLUDES}
${LWRES_INCLUDES} ${DNS_INCLUDES} \
${ISCCFG_INCLUDES} ${ISCCC_INCLUDES} ${ISC_INCLUDES} \
${DBDRIVER_INCLUDES}
CDEFINES =
CWARNINGS =
OMAPILIBS = ../../lib/omapi/libomapi.@A@
DNSLIBS = ../../lib/dns/libdns.@A@ @DNS_OPENSSL_LIBS@ @DNS_GSSAPI_LIBS@
ISCCFGLIBS = ../../lib/isccfg/libisccfg.@A@
ISCCCLIBS = ../../lib/isccc/libisccc.@A@
ISCLIBS = ../../lib/isc/libisc.@A@
LWRESLIBS = ../../lib/lwres/liblwres.@A@
OMAPIDEPLIBS = ../../lib/omapi/libomapi.@A@
DNSDEPLIBS = ../../lib/dns/libdns.@A@
ISCCFGDEPLIBS = ../../lib/isccfg/libisccfg.@A@
ISCCCDEPLIBS = ../../lib/isccc/libisccc.@A@
ISCDEPLIBS = ../../lib/isc/libisc.@A@
LWRESDEPLIBS = ../../lib/lwres/liblwres.@A@
DEPLIBS = ${LWRESDEPLIBS} ${OMAPIDEPLIBS} ${DNSDEPLIBS} \
${ISCCFGDEPLIBS} ${ISCDEPLIBS}
DEPLIBS = ${LWRESDEPLIBS} ${DNSDEPLIBS} \
${ISCCFGDEPLIBS} ${ISCCCDEPLIBS} ${ISCDEPLIBS}
LIBS = ${LWRESLIBS} ${OMAPILIBS} ${DNSLIBS} \
${ISCCFGLIBS} ${ISCLIBS} ${DBDRIVER_LIBS} @LIBS@
LIBS = ${LWRESLIBS} ${DNSLIBS} \
${ISCCFGLIBS} ${ISCCCLIBS} ${ISCLIBS} ${DBDRIVER_LIBS} @LIBS@
SUBDIRS = unix
TARGETS = named lwresd
OBJS = aclconf.@O@ client.@O@ config.@O@ interfacemgr.@O@ \
OBJS = aclconf.@O@ client.@O@ config.@O@ control.@O@ controlconf.@O@ interfacemgr.@O@ \
listenlist.@O@ log.@O@ logconf.@O@ main.@O@ notify.@O@ \
omapi.@O@ omapiconf.@O@ query.@O@ server.@O@ sortlist.@O@ \
query.@O@ server.@O@ sortlist.@O@ \
tkeyconf.@O@ tsigconf.@O@ update.@O@ xfrout.@O@ \
zoneconf.@O@ \
lwaddr.@O@ lwresd.@O@ lwdclient.@O@ lwderror.@O@ lwdgabn.@O@ \
......@@ -71,9 +72,9 @@ OBJS = aclconf.@O@ client.@O@ config.@O@ interfacemgr.@O@ \
UOBJS = unix/os.@O@
SRCS = aclconf.c client.c config.c interfacemgr.c \
SRCS = aclconf.c client.c config.c control.c controlconf.c interfacemgr.c \
listenlist.c log.c logconf.c main.c notify.c \
omapi.c omapiconf.c query.c server.c sortlist.c \
query.c server.c sortlist.c \
tkeyconf.c tsigconf.c update.c xfrout.c \
zoneconf.c \
lwaddr.c lwresd.c lwdclient.c lwderror.c lwdgabn.c \
......
......@@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: globals.h,v 1.53 2001/03/04 21:21:32 bwelling Exp $ */
/* $Id: globals.h,v 1.54 2001/03/27 00:44:36 bwelling Exp $ */
#ifndef NAMED_GLOBALS_H
#define NAMED_GLOBALS_H 1
......@@ -28,8 +28,6 @@
#include <dns/zone.h>
#include <omapi/types.h>
#include <named/types.h>
#undef EXTERN
......@@ -54,7 +52,6 @@ EXTERN isc_entropy_t * ns_g_entropy INIT(NULL);
*/
EXTERN isc_timermgr_t * ns_g_timermgr INIT(NULL);
EXTERN isc_socketmgr_t * ns_g_socketmgr INIT(NULL);
EXTERN omapi_object_t * ns_g_omapimgr INIT(NULL);
EXTERN cfg_parser_t * ns_g_parser INIT(NULL);
EXTERN const char * ns_g_version INIT(VERSION);
EXTERN in_port_t ns_g_port INIT(0);
......
......@@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: log.h,v 1.17 2001/01/09 21:40:17 bwelling Exp $ */
/* $Id: log.h,v 1.18 2001/03/27 00:44:38 bwelling Exp $ */
#ifndef NAMED_LOG_H
#define NAMED_LOG_H 1
......@@ -47,7 +47,7 @@
#define NS_LOGMODULE_XFER_IN (&ns_g_modules[6])
#define NS_LOGMODULE_XFER_OUT (&ns_g_modules[7])
#define NS_LOGMODULE_NOTIFY (&ns_g_modules[8])
#define NS_LOGMODULE_OMAPI (&ns_g_modules[9])
#define NS_LOGMODULE_CONTROL (&ns_g_modules[9])
#define NS_LOGMODULE_LWRESD (&ns_g_modules[10])
isc_result_t
......
......@@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: log.c,v 1.30 2001/03/13 03:04:09 gson Exp $ */
/* $Id: log.c,v 1.31 2001/03/27 00:44:31 bwelling Exp $ */
#include <config.h>
......@@ -52,7 +52,7 @@ static isc_logmodule_t modules[] = {
{ "xfer-in", 0 },
{ "xfer-out", 0 },
{ "notify", 0 },
{ "omapi", 0 },
{ "control", 0 },
{ "lwresd", 0 },
{ NULL, 0 }
};
......
......@@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: main.c,v 1.105 2001/03/06 02:40:13 bwelling Exp $ */
/* $Id: main.c,v 1.106 2001/03/27 00:44:33 bwelling Exp $ */
#include <config.h>
......@@ -33,20 +33,24 @@
#include <isc/timer.h>
#include <isc/util.h>
#include <isccc/result.h>
#include <dns/dispatch.h>
#include <dst/result.h>
#include <dns/result.h>
#include <dns/view.h>
#include <dst/result.h>
/*
* Defining NS_MAIN provides storage declarations (rather than extern)
* for variables in named/globals.h.
*/
#define NS_MAIN 1
#include <named/control.h>
#include <named/globals.h> /* Explicit, though named/log.h includes it. */
#include <named/interfacemgr.h>
#include <named/log.h>
#include <named/omapi.h>
#include <named/os.h>
#include <named/server.h>
#include <named/lwresd.h>
......@@ -417,10 +421,10 @@ static void
destroy_managers(void) {
if (!ns_g_lwresdonly)
/*
* The omapi listeners need to be stopped here so that
* isc_taskmgr_destroy() won't block on the omapi task.
* The command channel listeners need to be stopped here so
* that isc_taskmgr_destroy() won't block on the server task.
*/
ns_omapi_shutdown(ISC_TRUE);
ns_control_shutdown(ISC_TRUE);
ns_lwresd_shutdown();
......@@ -498,13 +502,6 @@ setup(void) {
/* xxdb_init(); */
ns_server_create(ns_g_mctx, &ns_g_server);
if (!ns_g_lwresdonly) {
result = ns_omapi_init();
if (result != ISC_R_SUCCESS)
ns_main_earlyfatal("ns_omapi_init() failed: %s",
isc_result_totext(result));
}
}
static void
......@@ -546,6 +543,7 @@ main(int argc, char *argv[]) {
dns_result_register();
dst_result_register();
isccc_result_register();
parse_command_line(argc, argv);
......
......@@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: server.c,v 1.311 2001/03/26 23:03:05 gson Exp $ */
/* $Id: server.c,v 1.312 2001/03/27 00:44:34 bwelling Exp $ */
#include <config.h>
......@@ -60,11 +60,11 @@
#include <named/client.h>
#include <named/config.h>
#include <named/control.h>
#include <named/interfacemgr.h>
#include <named/log.h>
#include <named/logconf.h>
#include <named/lwresd.h>
#include <named/omapi.h>
#include <named/os.h>
#include <named/server.h>
#include <named/tkeyconf.h>
......@@ -1855,9 +1855,9 @@ load_configuration(const char *filename, ns_server_t *server,
}
/*
* Bind the OMAPI port(s).
* Bind the control port(s).
*/
CHECKM(ns_omapi_configure(ns_g_mctx, config, &aclconfctx),
CHECKM(ns_control_configure(ns_g_mctx, config, &aclconfctx),
"binding control channel(s)");
/*
......
......@@ -13,7 +13,7 @@
# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
# $Id: Makefile.in,v 1.20 2001/02/16 04:17:00 tale Exp $
# $Id: Makefile.in,v 1.21 2001/03/27 00:44:41 bwelling Exp $
srcdir = @srcdir@
VPATH = @srcdir@
......@@ -24,23 +24,22 @@ top_srcdir = @top_srcdir@
@BIND9_INCLUDES@
CINCLUDES = -I${top_srcdir}/bin/named/include \
${ISC_INCLUDES} ${ISCCFG_INCLUDES} \
${DNS_INCLUDES} ${OMAPI_INCLUDES}
${ISC_INCLUDES} ${ISCCC_INCLUDES} ${ISCCFG_INCLUDES}
CDEFINES =
CWARNINGS =
OMAPILIBS = ../../lib/omapi/libomapi.@A@
ISCCFGLIBS = ../../lib/isccfg/libisccfg.@A@
ISCCCLIBS = ../../lib/isccc/libisccc.@A@
ISCLIBS = ../../lib/isc/libisc.@A@
OMAPIDEPLIBS = ../../lib/omapi/libomapi.@A@
ISCDEPLIBS = ../../lib/isccfg/libisccfg.@A@
ISCCFGDEPLIBS = ../../lib/isccfg/libisccfg.@A@
ISCCCDEPLIBS = ../../lib/isccc/libisccc.@A@
ISCDEPLIBS = ../../lib/isc/libisc.@A@
DEPLIBS = ${OMAPIDEPLIBS} ${ISCCFGLIBS} ${ISCDEPLIBS}
DEPLIBS = ${ISCCFGDEPLIBS} ${ISCCCDEPLIBS} ${ISCDEPLIBS}
LIBS = ${OMAPILIBS} ${ISCCFGLIBS} ${ISCLIBS} @LIBS@
LIBS = ${ISCCFGLIBS} ${ISCCCLIBS} ${ISCLIBS} @LIBS@
TARGETS = rndc
......
......@@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: rndc.c,v 1.43 2001/03/22 00:07:01 bwelling Exp $ */
/* $Id: rndc.c,v 1.44 2001/03/27 00:44:42 bwelling Exp $ */
/*
* Principal Author: DCL
......@@ -24,36 +24,59 @@
#include <config.h>
#include <stdlib.h>
#include <netdb.h>
#include <isc/base64.h>
#include <isc/app.h>
#include <isc/buffer.h>
#include <isc/commandline.h>
#include <isc/log.h>
#include <isc/mem.h>
#include <isc/socket.h>
#include <isc/stdtime.h>
#include <isc/string.h>
#include <isc/task.h>
#include <isc/util.h>
#include <isccfg/cfg.h>
#include <named/omapi.h>
#include <isccc/alist.h>
#include <isccc/base64.h>
#include <isccc/cc.h>
#include <isccc/ccmsg.h>
#include <isccc/result.h>
#include <isccc/sexpr.h>
#include <isccc/types.h>
#include <isccc/util.h>
#include <named/control.h>
#ifdef HAVE_ADDRINFO
#ifdef HAVE_GETADDRINFO
#ifdef HAVE_GAISTRERROR
#define USE_GETADDRINFO
#endif
#endif
#endif
#ifndef USE_GETADDRINFO
extern int h_errno;
#endif
static const char *progname;
static const char *conffile = RNDC_SYSCONFDIR "/rndc.conf";
static const char *version = VERSION;
static unsigned int remoteport = NS_CONTROL_PORT;
static const char *servername = NULL;
static isc_socketmgr_t *socketmgr = NULL;
static unsigned char databuf[2048];
static isccc_ccmsg_t ccmsg;
static char *args;
static isc_boolean_t have_ipv4, have_ipv6;
static isccc_region_t secret;
static isc_boolean_t verbose;
static isc_boolean_t failed = ISC_FALSE;
static isc_mem_t *mctx;
typedef struct ndc_object {
OMAPI_OBJECT_PREAMBLE;
} ndc_object_t;
#define REGION_FMT(x) (int)(x)->length, (x)->base
static ndc_object_t ndc_g_ndc;
static omapi_objecttype_t *ndc_type;
char *command;
static void
notify(const char *fmt, ...) {
......@@ -67,188 +90,6 @@ notify(const char *fmt, ...) {
}
}
/*
* Send a control command to the server. 'command' is the command
* name, and 'args' is a space-delimited sequence of words, the
* first being the command name itself.
*/
static isc_result_t
send_command(omapi_object_t *manager, char *command, char *args) {
omapi_object_t *message = NULL;
isc_result_t result;
REQUIRE(manager != NULL && command != NULL);
/*
* Create a new message object to store the information that will
* be sent to the server.
*/
result = omapi_message_create(&message);
if (result != ISC_R_SUCCESS)
return (result);
/*
* Specify the OPEN operation, with the UPDATE option if requested.
*/
result = omapi_object_setinteger(message, "op", OMAPI_OP_OPEN);
if (result == ISC_R_SUCCESS)
result = omapi_object_setboolean(message, "update", ISC_TRUE);
/*
* Tell the server the type of the object being opened; it needs
* to know this so that it can apply the proper object methods
* for lookup/setvalue.
*/
if (result == ISC_R_SUCCESS)
result = omapi_object_setstring(message, "type",
NS_OMAPI_CONTROL);
/*
* Associate the ndc object with the message, so that it will have its
* values stuffed in the message. Without it, the OPEN operation will
* fail because there is no name/value pair to use as a key for looking
* up the desired object at the server; this is true even though the
* particular object being accessed on the server does not need a key
* to be found.
*
* This object will also have its signal handler called with a
* "status" signal that sends the result of the operation on the
* server.
*/
if (result == ISC_R_SUCCESS)
result = omapi_object_setobject(message, "object",
(omapi_object_t *)&ndc_g_ndc);
/*
* Create a generic object to be the outer object for ndc_g_ndc, to
* handle the job of storing the command and stuffing it into the
* message.
*
* XXXDCL provide API so client does not need to refer to the
* outer member -- does not even need to know about how the whole
* outer/inner thing works.
*/
if (result == ISC_R_SUCCESS)
result = omapi_object_create(&ndc_g_ndc.outer, NULL, 0);
/*
* Set the command being sent.
*/
result = omapi_object_setstring((omapi_object_t *)&ndc_g_ndc,
command, args);
if (result == ISC_R_SUCCESS) {
/*
* Add the new message to the list of known messages. When the
* server's response comes back, the client will verify that
* the response was for a message it really sent.
*/
omapi_message_register(message);
/*
* Deliver the message to the server and await its
* response.
*/
result = omapi_message_send(message, manager);
}
/*
* Free the generic object and the message.
*/
if (ndc_g_ndc.outer != NULL)
omapi_object_dereference(&ndc_g_ndc.outer);
omapi_message_unregister(message);
omapi_object_dereference(&message);
return (result);
}
/*
* The signal handler gets the "status" signals when the server's response
* is processed. It also gets the "updated" signal after all the values
* from the server have been incorporated via ndc_setvalue.
*/
static isc_result_t
ndc_signalhandler(omapi_object_t *handle, const char *name, va_list ap) {
ndc_object_t *ndc;
omapi_value_t *tv;
isc_region_t region;
isc_result_t result;
REQUIRE(handle->type == ndc_type);
ndc = (ndc_object_t *)handle;
notify("ndc_signalhandler: %s", name);
if (strcmp(name, "status") == 0) {
/*
* "status" is signalled with the result of the message's
* operation.
*/
ndc->waitresult = va_arg(ap, isc_result_t);
if (ndc->waitresult != ISC_R_SUCCESS) {
fprintf(stderr, "%s: operation failed: %s",
progname, isc_result_totext(ndc->waitresult));
tv = va_arg(ap, omapi_value_t *);
if (tv != NULL) {
omapi_value_getregion(tv, &region);
fprintf(stderr, " (%.*s)",
(int)region.length, region.base);
}
fprintf(stderr, "\n");
}
/*
* Even if the waitresult was not ISC_R_SUCCESS, the processing
* by the function still was.
*/
result = ISC_R_SUCCESS;
} else if (strcmp(name, "updated") == 0) {
/*
* Nothing to do, really.
*/
result = ISC_R_SUCCESS;
} else {
/*
* Pass any unknown signal any internal object.
* (This normally does not happen; there is no
* inner object, nor anything else being signalled.)
*/
fprintf(stderr, "%s: ndc_signalhandler: unknown signal: %s",
progname, name);
result = omapi_object_passsignal(handle, name, ap);
}
return (result);
}
static isc_result_t
ndc_setvalue(omapi_object_t *handle, omapi_string_t *name,
omapi_data_t *value)
{
isc_region_t region;
/*
isc_result_t result;
char *message;
*/
INSIST(handle == (omapi_object_t *)&ndc_g_ndc);
UNUSED(value);
UNUSED(handle);
omapi_string_totext(name, &region);
notify("ndc_setvalue: %.*s\n", REGION_FMT(&region));
return (ISC_R_SUCCESS);
}
static void
usage(void) {
fprintf(stderr, "\
......@@ -278,6 +119,19 @@ Version: %s\n",
progname, version);
}
static void
fatal(const char *format, ...) {
va_list args;
fprintf(stderr, "%s: ", progname);
va_start(args, format);
vfprintf(stderr, format, args);
va_end(args);
fprintf(stderr, "\n");
exit(1);
}
#undef DO
#define DO(name, function) \
do { \
......@@ -290,16 +144,185 @@ Version: %s\n",
notify(name); \
} while (0)
static void
get_address(const char *host, in_port_t port, isc_sockaddr_t *sockaddr) {
struct in_addr in4;
struct in6_addr in6;
#ifdef USE_GETADDRINFO
struct addrinfo *res = NULL, hints;
int result;
#else
struct hostent *he;
#endif
/*
* Assume we have v4 if we don't have v6, since setup_libs
* fatal()'s out if we don't have either.
*/
if (have_ipv6 && inet_pton(AF_INET6, host, &in6) == 1)
isc_sockaddr_fromin6(sockaddr, &in6, port);
else if (inet_pton(AF_INET, host, &in4) == 1)
isc_sockaddr_fromin(sockaddr, &in4, port);
else {
#ifdef USE_GETADDRINFO
memset(&hints, 0, sizeof(hints));
if (!have_ipv6)
hints.ai_family = PF_INET;
else if (!have_ipv4)
hints.ai_family = PF_INET6;
else
hints.ai_family = PF_UNSPEC;
isc_app_block();
result = getaddrinfo(host, NULL, &hints, &res);
isc_app_unblock();
if (result != 0)
fatal("Couldn't find server '%s': %s",
host, gai_strerror(result));
memcpy(&sockaddr->type.sa,res->ai_addr, res->ai_addrlen);
sockaddr->length = res->ai_addrlen;
isc_sockaddr_setport(sockaddr, port);
freeaddrinfo(res);
#else
isc_app_block();
he = gethostbyname(host);
isc_app_unblock();
if (he == NULL)
fatal("Couldn't find server '%s' (h_errno=%d)",
host, h_errno);
INSIST(he->h_addrtype == AF_INET);
isc_sockaddr_fromin(sockaddr,
(struct in_addr *)(he->h_addr_list[0]),
port);
#endif
}
}
static void
rndc_senddone(isc_task_t *task, isc_event_t *event) {
isc_socketevent_t *sevent = (isc_socketevent_t *)event;
UNUSED(task);
if (sevent->result != ISC_R_SUCCESS)
fatal("send failed: %s", isc_result_totext(sevent->result));
isc_event_free(&event);
}
static void
rndc_recvdone(isc_task_t *task, isc_event_t *event) {
isc_socket_t *sock = ccmsg.sock;
isccc_sexpr_t *response = NULL;
isccc_sexpr_t *data;
isccc_region_t source;
char *errormsg = NULL;
isc_result_t result;
if (ccmsg.result == ISC_R_EOF) {
fprintf(stderr, "%s: connection to remote host closed\n",
progname);
fprintf(stderr,
"This may indicate that the remote server is using "
"an older version of the\n"
"command protocol or this host is not authorized "
"to connect.\n");
exit(1);