controlconf.c revision b4b47bf1874a9dd19796d5593de47bd4c9d3d896
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff/*
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff * Copyright (C) 2001 Internet Software Consortium.
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff *
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff * Permission to use, copy, modify, and distribute this software for any
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff * purpose with or without fee is hereby granted, provided that the above
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff * copyright notice and this permission notice appear in all copies.
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff *
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff */
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff/* $Id: controlconf.c,v 1.23 2001/08/03 20:05:42 gson Exp $ */
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff#include <config.h>
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff#include <isc/base64.h>
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff#include <isc/buffer.h>
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff#include <isc/event.h>
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff#include <isc/file.h>
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff#include <isc/fsaccess.h>
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff#include <isc/mem.h>
f9df80f4348ef68043903efa08299480324f4823Michael Graff#include <isc/netaddr.h>
f9df80f4348ef68043903efa08299480324f4823Michael Graff#include <isc/print.h>
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff#include <isc/random.h>
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff#include <isc/result.h>
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff#include <isc/stdio.h>
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff#include <isc/stdtime.h>
f9df80f4348ef68043903efa08299480324f4823Michael Graff#include <isc/string.h>
f9df80f4348ef68043903efa08299480324f4823Michael Graff#include <isc/timer.h>
f9df80f4348ef68043903efa08299480324f4823Michael Graff#include <isc/util.h>
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff#include <isccfg/cfg.h>
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff#include <isccfg/check.h>
75ec9bc9c7b4f2485647414330122e7b8e188097Andreas Gustafsson
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff#include <isccc/alist.h>
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff#include <isccc/cc.h>
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff#include <isccc/ccmsg.h>
f9df80f4348ef68043903efa08299480324f4823Michael Graff#include <isccc/events.h>
f9df80f4348ef68043903efa08299480324f4823Michael Graff#include <isccc/result.h>
f9df80f4348ef68043903efa08299480324f4823Michael Graff#include <isccc/sexpr.h>
f9df80f4348ef68043903efa08299480324f4823Michael Graff#include <isccc/util.h>
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff#include <dns/keyvalues.h>
f9df80f4348ef68043903efa08299480324f4823Michael Graff#include <dns/result.h>
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff#include <dst/dst.h>
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff#include <named/config.h>
e223094b2248afa2697c531f75e6f84855638becMichael Graff#include <named/control.h>
b02262cbcd550c63f85df76edc6fff556ea5e95dMichael Graff#include <named/log.h>
b02262cbcd550c63f85df76edc6fff556ea5e95dMichael Graff#include <named/server.h>
b02262cbcd550c63f85df76edc6fff556ea5e95dMichael Graff
b02262cbcd550c63f85df76edc6fff556ea5e95dMichael Graff/*
f9df80f4348ef68043903efa08299480324f4823Michael Graff * Note: Listeners and connections are not locked. All event handlers are
f9df80f4348ef68043903efa08299480324f4823Michael Graff * executed by the server task, and all callers of exported routines must
f9df80f4348ef68043903efa08299480324f4823Michael Graff * be running under the server task.
f9df80f4348ef68043903efa08299480324f4823Michael Graff */
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Grafftypedef struct controlkey controlkey_t;
f9df80f4348ef68043903efa08299480324f4823Michael Grafftypedef ISC_LIST(controlkey_t) controlkeylist_t;
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Grafftypedef struct controlconnection controlconnection_t;
f9df80f4348ef68043903efa08299480324f4823Michael Grafftypedef ISC_LIST(controlconnection_t) controlconnectionlist_t;
f9df80f4348ef68043903efa08299480324f4823Michael Graff
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Grafftypedef struct controllistener controllistener_t;
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Grafftypedef ISC_LIST(controllistener_t) controllistenerlist_t;
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graffstruct controlkey {
f9df80f4348ef68043903efa08299480324f4823Michael Graff char * keyname;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff isc_region_t secret;
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff ISC_LINK(controlkey_t) link;
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff};
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graffstruct controlconnection {
f9df80f4348ef68043903efa08299480324f4823Michael Graff isc_socket_t * sock;
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff isccc_ccmsg_t ccmsg;
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff isc_boolean_t ccmsg_valid;
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff isc_boolean_t sending;
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff isc_timer_t * timer;
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff unsigned char buffer[2048];
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff controllistener_t * listener;
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff ISC_LINK(controlconnection_t) link;
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff};
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graffstruct controllistener {
f9df80f4348ef68043903efa08299480324f4823Michael Graff ns_controls_t * controls;
f9df80f4348ef68043903efa08299480324f4823Michael Graff isc_mem_t * mctx;
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff isc_task_t * task;
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff isc_sockaddr_t address;
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff isc_socket_t * sock;
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff dns_acl_t * acl;
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff isc_boolean_t listening;
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff isc_boolean_t exiting;
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff controlkeylist_t keys;
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff controlconnectionlist_t connections;
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff ISC_LINK(controllistener_t) link;
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff};
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graffstruct ns_controls {
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff ns_server_t *server;
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff controllistenerlist_t listeners;
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff};
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graffstatic void control_newconn(isc_task_t *task, isc_event_t *event);
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graffstatic void control_recvmessage(isc_task_t *task, isc_event_t *event);
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graffstatic void
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Grafffree_controlkey(controlkey_t *key, isc_mem_t *mctx) {
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff if (key->keyname != NULL)
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff isc_mem_free(mctx, key->keyname);
f9df80f4348ef68043903efa08299480324f4823Michael Graff if (key->secret.base != NULL)
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff isc_mem_put(mctx, key->secret.base, key->secret.length);
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff isc_mem_put(mctx, key, sizeof(*key));
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff}
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graffstatic void
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Grafffree_controlkeylist(controlkeylist_t *keylist, isc_mem_t *mctx) {
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff while (!ISC_LIST_EMPTY(*keylist)) {
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff controlkey_t *key = ISC_LIST_HEAD(*keylist);
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff ISC_LIST_UNLINK(*keylist, key, link);
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff free_controlkey(key, mctx);
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff }
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff}
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graffstatic void
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Grafffree_listener(controllistener_t *listener) {
f9df80f4348ef68043903efa08299480324f4823Michael Graff INSIST(listener->exiting);
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff INSIST(!listener->listening);
f9df80f4348ef68043903efa08299480324f4823Michael Graff INSIST(ISC_LIST_EMPTY(listener->connections));
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff if (listener->sock != NULL)
f9df80f4348ef68043903efa08299480324f4823Michael Graff isc_socket_detach(&listener->sock);
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff free_controlkeylist(&listener->keys, listener->mctx);
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff if (listener->acl != NULL)
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff dns_acl_detach(&listener->acl);
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff isc_mem_put(listener->mctx, listener, sizeof(*listener));
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff}
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graffstatic void
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graffmaybe_free_listener(controllistener_t *listener) {
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff if (listener->exiting &&
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff !listener->listening &&
f9df80f4348ef68043903efa08299480324f4823Michael Graff ISC_LIST_EMPTY(listener->connections))
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff free_listener(listener);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff}
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graffstatic void
d68838693666ba930ec4143f848c18bff2bfc244Michael Graffmaybe_free_connection(controlconnection_t *conn) {
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff controllistener_t *listener = conn->listener;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff if (conn->timer != NULL)
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff isc_timer_detach(&conn->timer);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff if (conn->ccmsg_valid) {
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff isccc_ccmsg_cancelread(&conn->ccmsg);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff return;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff }
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff if (conn->sending) {
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff isc_socket_cancel(conn->sock, listener->task,
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff ISC_SOCKCANCEL_SEND);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff return;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff }
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff ISC_LIST_UNLINK(listener->connections, conn, link);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff isc_mem_put(listener->mctx, conn, sizeof(*conn));
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff}
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graffstatic void
d68838693666ba930ec4143f848c18bff2bfc244Michael Graffshutdown_listener(controllistener_t *listener) {
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff isc_boolean_t destroy = ISC_TRUE;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff if (!listener->exiting) {
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff char socktext[ISC_SOCKADDR_FORMATSIZE];
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff isc_sockaddr_format(&listener->address, socktext,
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff sizeof(socktext));
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff NS_LOGMODULE_CONTROL, ISC_LOG_NOTICE,
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff "stopping command channel on %s", socktext);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff listener->exiting = ISC_TRUE;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff }
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff if (!ISC_LIST_EMPTY(listener->connections)) {
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff controlconnection_t *conn;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff for (conn = ISC_LIST_HEAD(listener->connections);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff conn != NULL;
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff conn = ISC_LIST_NEXT(conn, link))
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff maybe_free_connection(conn);
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff destroy = ISC_FALSE;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff }
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff if (listener->sock != NULL) {
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff isc_socket_cancel(listener->sock, listener->task,
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff ISC_SOCKCANCEL_ACCEPT);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff destroy = ISC_FALSE;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff }
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff if (destroy)
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff free_listener(listener);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff}
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graffstatic isc_boolean_t
d68838693666ba930ec4143f848c18bff2bfc244Michael Graffaddress_ok(isc_sockaddr_t *sockaddr, dns_acl_t *acl) {
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff isc_netaddr_t netaddr;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff isc_result_t result;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff int match;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff isc_netaddr_fromsockaddr(&netaddr, sockaddr);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff result = dns_acl_match(&netaddr, NULL, acl,
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff &ns_g_server->aclenv, &match, NULL);
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff if (result != ISC_R_SUCCESS || match <= 0)
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff return (ISC_FALSE);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff else
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff return (ISC_TRUE);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff}
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graffstatic isc_result_t
d68838693666ba930ec4143f848c18bff2bfc244Michael Graffcontrol_accept(controllistener_t *listener) {
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff isc_result_t result;
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff result = isc_socket_accept(listener->sock,
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff listener->task,
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff control_newconn, listener);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff if (result != ISC_R_SUCCESS)
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff UNEXPECTED_ERROR(__FILE__, __LINE__,
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff "isc_socket_accept() failed: %s",
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff isc_result_totext(result));
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff else
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff listener->listening = ISC_TRUE;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff return (result);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff}
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graffstatic isc_result_t
d68838693666ba930ec4143f848c18bff2bfc244Michael Graffcontrol_listen(controllistener_t *listener) {
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff isc_result_t result;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff result = isc_socket_listen(listener->sock, 0);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff if (result != ISC_R_SUCCESS)
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff UNEXPECTED_ERROR(__FILE__, __LINE__,
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff "isc_socket_listen() failed: %s",
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff isc_result_totext(result));
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff return (result);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff}
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graffstatic void
d68838693666ba930ec4143f848c18bff2bfc244Michael Graffcontrol_next(controllistener_t *listener) {
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff (void)control_accept(listener);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff}
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graffstatic void
d68838693666ba930ec4143f848c18bff2bfc244Michael Graffcontrol_senddone(isc_task_t *task, isc_event_t *event) {
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff isc_socketevent_t *sevent = (isc_socketevent_t *) event;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff controlconnection_t *conn = event->ev_arg;
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff controllistener_t *listener = conn->listener;
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff isc_socket_t *sock = (isc_socket_t *)sevent->ev_sender;
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff isc_result_t result;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff REQUIRE(conn->sending);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff UNUSED(task);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff conn->sending = ISC_FALSE;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff if (sevent->result != ISC_R_SUCCESS &&
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff sevent->result != ISC_R_CANCELED)
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff {
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff char socktext[ISC_SOCKADDR_FORMATSIZE];
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff isc_sockaddr_t peeraddr;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff (void)isc_socket_getpeername(sock, &peeraddr);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff isc_sockaddr_format(&peeraddr, socktext, sizeof(socktext));
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff NS_LOGMODULE_CONTROL, ISC_LOG_WARNING,
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff "error sending command response to %s: %s",
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff socktext, isc_result_totext(sevent->result));
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff }
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff isc_event_free(&event);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff result = isccc_ccmsg_readmessage(&conn->ccmsg, listener->task,
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff control_recvmessage, conn);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff if (result != ISC_R_SUCCESS) {
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff isc_socket_detach(&conn->sock);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff maybe_free_connection(conn);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff maybe_free_listener(listener);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff }
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff}
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graffstatic inline void
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Grafflog_invalid(isccc_ccmsg_t *ccmsg, isc_result_t result) {
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff char socktext[ISC_SOCKADDR_FORMATSIZE];
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff isc_sockaddr_t peeraddr;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff (void)isc_socket_getpeername(ccmsg->sock, &peeraddr);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff isc_sockaddr_format(&peeraddr, socktext, sizeof(socktext));
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff NS_LOGMODULE_CONTROL, ISC_LOG_ERROR,
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff "invalid command from %s: %s",
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff socktext, isc_result_totext(result));
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff}
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graffstatic void
d68838693666ba930ec4143f848c18bff2bfc244Michael Graffcontrol_recvmessage(isc_task_t *task, isc_event_t *event) {
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff controlconnection_t *conn;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff controllistener_t *listener;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff controlkey_t *key;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff isccc_sexpr_t *request = NULL;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff isccc_sexpr_t *response = NULL;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff isccc_region_t ccregion;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff isccc_region_t secret;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff isc_stdtime_t now;
f9df80f4348ef68043903efa08299480324f4823Michael Graff isc_buffer_t b;
f9df80f4348ef68043903efa08299480324f4823Michael Graff isc_region_t r;
f9df80f4348ef68043903efa08299480324f4823Michael Graff isc_uint32_t len;
f9df80f4348ef68043903efa08299480324f4823Michael Graff isc_buffer_t text;
f9df80f4348ef68043903efa08299480324f4823Michael Graff char textarray[1024];
f9df80f4348ef68043903efa08299480324f4823Michael Graff isc_result_t result;
f9df80f4348ef68043903efa08299480324f4823Michael Graff isc_result_t eresult;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff REQUIRE(event->ev_type == ISCCC_EVENT_CCMSG);
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff conn = event->ev_arg;
f9df80f4348ef68043903efa08299480324f4823Michael Graff listener = conn->listener;
f9df80f4348ef68043903efa08299480324f4823Michael Graff secret.rstart = NULL;
e223094b2248afa2697c531f75e6f84855638becMichael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff if (conn->ccmsg.result != ISC_R_SUCCESS) {
e223094b2248afa2697c531f75e6f84855638becMichael Graff if (conn->ccmsg.result != ISC_R_CANCELED &&
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff conn->ccmsg.result != ISC_R_EOF)
823e45c1273512a8048cd5e7e57f31f58c964f7fMichael Graff log_invalid(&conn->ccmsg, conn->ccmsg.result);
e223094b2248afa2697c531f75e6f84855638becMichael Graff goto cleanup;
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff }
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff request = NULL;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff for (key = ISC_LIST_HEAD(listener->keys);
8f3ba5e9b2f4340ec3de039cb1cdf24521ee92a5Michael Graff key != NULL;
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff key = ISC_LIST_NEXT(key, link))
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff {
f9df80f4348ef68043903efa08299480324f4823Michael Graff ccregion.rstart = isc_buffer_base(&conn->ccmsg.buffer);
f9df80f4348ef68043903efa08299480324f4823Michael Graff ccregion.rend = isc_buffer_used(&conn->ccmsg.buffer);
f9df80f4348ef68043903efa08299480324f4823Michael Graff secret.rstart = isc_mem_get(listener->mctx, key->secret.length);
f9df80f4348ef68043903efa08299480324f4823Michael Graff if (secret.rstart == NULL)
f9df80f4348ef68043903efa08299480324f4823Michael Graff goto cleanup;
f9df80f4348ef68043903efa08299480324f4823Michael Graff memcpy(secret.rstart, key->secret.base, key->secret.length);
f9df80f4348ef68043903efa08299480324f4823Michael Graff secret.rend = secret.rstart + key->secret.length;
f9df80f4348ef68043903efa08299480324f4823Michael Graff result = isccc_cc_fromwire(&ccregion, &request, &secret);
f9df80f4348ef68043903efa08299480324f4823Michael Graff if (result == ISC_R_SUCCESS)
f9df80f4348ef68043903efa08299480324f4823Michael Graff break;
f9df80f4348ef68043903efa08299480324f4823Michael Graff else if (result == ISCCC_R_BADAUTH) {
f9df80f4348ef68043903efa08299480324f4823Michael Graff /*
f9df80f4348ef68043903efa08299480324f4823Michael Graff * For some reason, request is non-NULL when
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff * isccc_cc_fromwire returns ISCCC_R_BADAUTH.
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff */
f9df80f4348ef68043903efa08299480324f4823Michael Graff if (request != NULL)
f9df80f4348ef68043903efa08299480324f4823Michael Graff isccc_sexpr_free(&request);
f9df80f4348ef68043903efa08299480324f4823Michael Graff isc_mem_put(listener->mctx, secret.rstart,
f9df80f4348ef68043903efa08299480324f4823Michael Graff REGION_SIZE(secret));
f9df80f4348ef68043903efa08299480324f4823Michael Graff } else {
f9df80f4348ef68043903efa08299480324f4823Michael Graff log_invalid(&conn->ccmsg, result);
f9df80f4348ef68043903efa08299480324f4823Michael Graff goto cleanup;
f9df80f4348ef68043903efa08299480324f4823Michael Graff }
f9df80f4348ef68043903efa08299480324f4823Michael Graff }
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff if (key == NULL) {
f9df80f4348ef68043903efa08299480324f4823Michael Graff log_invalid(&conn->ccmsg, ISCCC_R_BADAUTH);
f9df80f4348ef68043903efa08299480324f4823Michael Graff goto cleanup;
f9df80f4348ef68043903efa08299480324f4823Michael Graff }
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff /* We shouldn't be getting a reply. */
f9df80f4348ef68043903efa08299480324f4823Michael Graff if (isccc_cc_isreply(request)) {
f9df80f4348ef68043903efa08299480324f4823Michael Graff log_invalid(&conn->ccmsg, ISC_R_FAILURE);
f9df80f4348ef68043903efa08299480324f4823Michael Graff goto cleanup;
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff }
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff isc_buffer_init(&text, textarray, sizeof(textarray));
f9df80f4348ef68043903efa08299480324f4823Michael Graff eresult = ns_control_docommand(request, &text);
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff isc_stdtime_get(&now);
f9df80f4348ef68043903efa08299480324f4823Michael Graff result = isccc_cc_createresponse(request, now, now + 60, &response);
f9df80f4348ef68043903efa08299480324f4823Michael Graff if (result != ISC_R_SUCCESS)
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff goto cleanup;
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff if (eresult != ISC_R_SUCCESS) {
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff isccc_sexpr_t *data;
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff data = isccc_alist_lookup(response, "_data");
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff if (data != NULL) {
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff const char *estr = isc_result_totext(eresult);
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff if (isccc_cc_definestring(data, "err", estr) == NULL)
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff goto cleanup;
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff }
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff }
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff if (isc_buffer_usedlength(&text) > 0) {
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff isccc_sexpr_t *data;
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff data = isccc_alist_lookup(response, "_data");
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff if (data != NULL) {
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff char *str = (char *)isc_buffer_base(&text);
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff if (isccc_cc_definestring(data, "text", str) == NULL)
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff goto cleanup;
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff }
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff }
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff ccregion.rstart = conn->buffer + 4;
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff ccregion.rend = conn->buffer + sizeof(conn->buffer);
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff result = isccc_cc_towire(response, &ccregion, &secret);
f9df80f4348ef68043903efa08299480324f4823Michael Graff if (result != ISC_R_SUCCESS)
f9df80f4348ef68043903efa08299480324f4823Michael Graff goto cleanup;
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff isc_buffer_init(&b, conn->buffer, 4);
f9df80f4348ef68043903efa08299480324f4823Michael Graff len = sizeof(conn->buffer) - REGION_SIZE(ccregion);
f9df80f4348ef68043903efa08299480324f4823Michael Graff isc_buffer_putuint32(&b, len - 4);
f9df80f4348ef68043903efa08299480324f4823Michael Graff r.base = conn->buffer;
f9df80f4348ef68043903efa08299480324f4823Michael Graff r.length = len;
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff result = isc_socket_send(conn->sock, &r, task, control_senddone, conn);
f9df80f4348ef68043903efa08299480324f4823Michael Graff if (result != ISC_R_SUCCESS)
f9df80f4348ef68043903efa08299480324f4823Michael Graff goto cleanup;
f9df80f4348ef68043903efa08299480324f4823Michael Graff conn->sending = ISC_TRUE;
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff if (secret.rstart != NULL)
f9df80f4348ef68043903efa08299480324f4823Michael Graff isc_mem_put(listener->mctx, secret.rstart,
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff REGION_SIZE(secret));
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff if (request != NULL)
f9df80f4348ef68043903efa08299480324f4823Michael Graff isccc_sexpr_free(&request);
f9df80f4348ef68043903efa08299480324f4823Michael Graff if (response != NULL)
f9df80f4348ef68043903efa08299480324f4823Michael Graff isccc_sexpr_free(&response);
f9df80f4348ef68043903efa08299480324f4823Michael Graff return;
f9df80f4348ef68043903efa08299480324f4823Michael Graff
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff cleanup:
f9df80f4348ef68043903efa08299480324f4823Michael Graff if (secret.rstart != NULL)
f9df80f4348ef68043903efa08299480324f4823Michael Graff isc_mem_put(listener->mctx, secret.rstart,
f9df80f4348ef68043903efa08299480324f4823Michael Graff REGION_SIZE(secret));
f9df80f4348ef68043903efa08299480324f4823Michael Graff isc_socket_detach(&conn->sock);
f9df80f4348ef68043903efa08299480324f4823Michael Graff isccc_ccmsg_invalidate(&conn->ccmsg);
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff conn->ccmsg_valid = ISC_FALSE;
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff maybe_free_connection(conn);
f9df80f4348ef68043903efa08299480324f4823Michael Graff maybe_free_listener(listener);
f9df80f4348ef68043903efa08299480324f4823Michael Graff if (request != NULL)
f9df80f4348ef68043903efa08299480324f4823Michael Graff isccc_sexpr_free(&request);
f9df80f4348ef68043903efa08299480324f4823Michael Graff if (response != NULL)
f9df80f4348ef68043903efa08299480324f4823Michael Graff isccc_sexpr_free(&response);
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff}
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graffstatic void
f9df80f4348ef68043903efa08299480324f4823Michael Graffcontrol_timeout(isc_task_t *task, isc_event_t *event) {
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff controlconnection_t *conn = event->ev_arg;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff UNUSED(task);
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff isc_timer_detach(&conn->timer);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff maybe_free_connection(conn);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff isc_event_free(&event);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff}
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graffstatic isc_result_t
d68838693666ba930ec4143f848c18bff2bfc244Michael Graffnewconnection(controllistener_t *listener, isc_socket_t *sock) {
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff controlconnection_t *conn;
ddd035637d92035a0d9e2bc32a7e2c9cc8a99d3fMichael Graff isc_interval_t interval;
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff isc_result_t result;
ddd035637d92035a0d9e2bc32a7e2c9cc8a99d3fMichael Graff
ddd035637d92035a0d9e2bc32a7e2c9cc8a99d3fMichael Graff conn = isc_mem_get(listener->mctx, sizeof(*conn));
ddd035637d92035a0d9e2bc32a7e2c9cc8a99d3fMichael Graff if (conn == NULL)
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff return (ISC_R_NOMEMORY);
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff
ddd035637d92035a0d9e2bc32a7e2c9cc8a99d3fMichael Graff conn->sock = sock;
ddd035637d92035a0d9e2bc32a7e2c9cc8a99d3fMichael Graff isccc_ccmsg_init(listener->mctx, sock, &conn->ccmsg);
ddd035637d92035a0d9e2bc32a7e2c9cc8a99d3fMichael Graff conn->ccmsg_valid = ISC_TRUE;
ddd035637d92035a0d9e2bc32a7e2c9cc8a99d3fMichael Graff conn->sending = ISC_FALSE;
ddd035637d92035a0d9e2bc32a7e2c9cc8a99d3fMichael Graff conn->timer = NULL;
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff isc_interval_set(&interval, 60, 0);
ddd035637d92035a0d9e2bc32a7e2c9cc8a99d3fMichael Graff result = isc_timer_create(ns_g_timermgr, isc_timertype_once,
f9df80f4348ef68043903efa08299480324f4823Michael Graff NULL, &interval, listener->task,
f9df80f4348ef68043903efa08299480324f4823Michael Graff control_timeout, conn, &conn->timer);
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff if (result != ISC_R_SUCCESS)
1d7987f4227c838f7fa790ad57255d3df3332ccaMichael Graff goto cleanup;
1d7987f4227c838f7fa790ad57255d3df3332ccaMichael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff conn->listener = listener;
f9df80f4348ef68043903efa08299480324f4823Michael Graff ISC_LINK_INIT(conn, link);
f9df80f4348ef68043903efa08299480324f4823Michael Graff
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff result = isccc_ccmsg_readmessage(&conn->ccmsg, listener->task,
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff control_recvmessage, conn);
f9df80f4348ef68043903efa08299480324f4823Michael Graff if (result != ISC_R_SUCCESS)
f9df80f4348ef68043903efa08299480324f4823Michael Graff goto cleanup;
f9df80f4348ef68043903efa08299480324f4823Michael Graff isccc_ccmsg_setmaxsize(&conn->ccmsg, 2048);
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff ISC_LIST_APPEND(listener->connections, conn, link);
f9df80f4348ef68043903efa08299480324f4823Michael Graff return (ISC_R_SUCCESS);
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff cleanup:
f9df80f4348ef68043903efa08299480324f4823Michael Graff isccc_ccmsg_invalidate(&conn->ccmsg);
f9df80f4348ef68043903efa08299480324f4823Michael Graff if (conn->timer != NULL)
f9df80f4348ef68043903efa08299480324f4823Michael Graff isc_timer_detach(&conn->timer);
f9df80f4348ef68043903efa08299480324f4823Michael Graff isc_mem_put(listener->mctx, conn, sizeof(*conn));
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff return (result);
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff}
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graffstatic void
f9df80f4348ef68043903efa08299480324f4823Michael Graffcontrol_newconn(isc_task_t *task, isc_event_t *event) {
f9df80f4348ef68043903efa08299480324f4823Michael Graff isc_socket_newconnev_t *nevent = (isc_socket_newconnev_t *)event;
f9df80f4348ef68043903efa08299480324f4823Michael Graff controllistener_t *listener = event->ev_arg;
f9df80f4348ef68043903efa08299480324f4823Michael Graff isc_socket_t *sock;
f9df80f4348ef68043903efa08299480324f4823Michael Graff isc_sockaddr_t peeraddr;
f9df80f4348ef68043903efa08299480324f4823Michael Graff isc_result_t result;
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff UNUSED(task);
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff if (nevent->result != ISC_R_SUCCESS) {
f9df80f4348ef68043903efa08299480324f4823Michael Graff if (nevent->result == ISC_R_CANCELED) {
f9df80f4348ef68043903efa08299480324f4823Michael Graff isc_socket_detach(&listener->sock);
f9df80f4348ef68043903efa08299480324f4823Michael Graff listener->listening = ISC_FALSE;
f9df80f4348ef68043903efa08299480324f4823Michael Graff shutdown_listener(listener);
454bea884d271ab2f8a13e924309e6b61b2775b4Andreas Gustafsson goto cleanup;
f9df80f4348ef68043903efa08299480324f4823Michael Graff }
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff goto restart;
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff }
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff sock = nevent->newsocket;
f9df80f4348ef68043903efa08299480324f4823Michael Graff (void)isc_socket_getpeername(sock, &peeraddr);
f9df80f4348ef68043903efa08299480324f4823Michael Graff if (!address_ok(&peeraddr, listener->acl)) {
f9df80f4348ef68043903efa08299480324f4823Michael Graff char socktext[ISC_SOCKADDR_FORMATSIZE];
f9df80f4348ef68043903efa08299480324f4823Michael Graff isc_sockaddr_format(&peeraddr, socktext, sizeof(socktext));
f9df80f4348ef68043903efa08299480324f4823Michael Graff isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
f9df80f4348ef68043903efa08299480324f4823Michael Graff NS_LOGMODULE_CONTROL, ISC_LOG_WARNING,
f9df80f4348ef68043903efa08299480324f4823Michael Graff "rejected command channel message from %s",
f9df80f4348ef68043903efa08299480324f4823Michael Graff socktext);
f9df80f4348ef68043903efa08299480324f4823Michael Graff goto restart;
f9df80f4348ef68043903efa08299480324f4823Michael Graff }
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff result = newconnection(listener, sock);
f9df80f4348ef68043903efa08299480324f4823Michael Graff if (result != ISC_R_SUCCESS) {
f9df80f4348ef68043903efa08299480324f4823Michael Graff char socktext[ISC_SOCKADDR_FORMATSIZE];
f9df80f4348ef68043903efa08299480324f4823Michael Graff isc_sockaddr_format(&peeraddr, socktext, sizeof(socktext));
f9df80f4348ef68043903efa08299480324f4823Michael Graff isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
f9df80f4348ef68043903efa08299480324f4823Michael Graff NS_LOGMODULE_CONTROL, ISC_LOG_WARNING,
f9df80f4348ef68043903efa08299480324f4823Michael Graff "dropped command channel from %s: %s",
f9df80f4348ef68043903efa08299480324f4823Michael Graff socktext, isc_result_totext(result));
f9df80f4348ef68043903efa08299480324f4823Michael Graff goto restart;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff }
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff restart:
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff control_next(listener);
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff cleanup:
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff isc_event_free(&event);
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff}
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graffvoid
f9df80f4348ef68043903efa08299480324f4823Michael Graffns_controls_shutdown(ns_controls_t *controls) {
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff controllistener_t *listener;
f9df80f4348ef68043903efa08299480324f4823Michael Graff controllistener_t *next;
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff for (listener = ISC_LIST_HEAD(controls->listeners);
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff listener != NULL;
f9df80f4348ef68043903efa08299480324f4823Michael Graff listener = next)
f9df80f4348ef68043903efa08299480324f4823Michael Graff {
f9df80f4348ef68043903efa08299480324f4823Michael Graff /*
f9df80f4348ef68043903efa08299480324f4823Michael Graff * This is asynchronous. As listeners shut down, they will
f9df80f4348ef68043903efa08299480324f4823Michael Graff * call their callbacks.
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff */
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff next = ISC_LIST_NEXT(listener, link);
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff ISC_LIST_UNLINK(controls->listeners, listener, link);
f9df80f4348ef68043903efa08299480324f4823Michael Graff shutdown_listener(listener);
f9df80f4348ef68043903efa08299480324f4823Michael Graff }
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff}
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graffstatic isc_result_t
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graffcfgkeylist_find(cfg_obj_t *keylist, const char *keyname, cfg_obj_t **objp) {
f9df80f4348ef68043903efa08299480324f4823Michael Graff cfg_listelt_t *element;
f9df80f4348ef68043903efa08299480324f4823Michael Graff const char *str;
f9df80f4348ef68043903efa08299480324f4823Michael Graff cfg_obj_t *obj;
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff for (element = cfg_list_first(keylist);
f9df80f4348ef68043903efa08299480324f4823Michael Graff element != NULL;
f9df80f4348ef68043903efa08299480324f4823Michael Graff element = cfg_list_next(element))
f9df80f4348ef68043903efa08299480324f4823Michael Graff {
f9df80f4348ef68043903efa08299480324f4823Michael Graff obj = cfg_listelt_value(element);
f9df80f4348ef68043903efa08299480324f4823Michael Graff str = cfg_obj_asstring(cfg_map_getname(obj));
f9df80f4348ef68043903efa08299480324f4823Michael Graff if (strcasecmp(str, keyname) == 0)
f9df80f4348ef68043903efa08299480324f4823Michael Graff break;
f9df80f4348ef68043903efa08299480324f4823Michael Graff }
f9df80f4348ef68043903efa08299480324f4823Michael Graff if (element == NULL)
f9df80f4348ef68043903efa08299480324f4823Michael Graff return (ISC_R_NOTFOUND);
f9df80f4348ef68043903efa08299480324f4823Michael Graff obj = cfg_listelt_value(element);
f9df80f4348ef68043903efa08299480324f4823Michael Graff *objp = obj;
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff return (ISC_R_SUCCESS);
f9df80f4348ef68043903efa08299480324f4823Michael Graff}
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graffstatic isc_result_t
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graffcontrolkeylist_fromcfg(cfg_obj_t *keylist, isc_mem_t *mctx,
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff controlkeylist_t *keyids)
f9df80f4348ef68043903efa08299480324f4823Michael Graff{
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff cfg_listelt_t *element;
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff char *newstr = NULL;
f9df80f4348ef68043903efa08299480324f4823Michael Graff const char *str;
f9df80f4348ef68043903efa08299480324f4823Michael Graff cfg_obj_t *obj;
f9df80f4348ef68043903efa08299480324f4823Michael Graff controlkey_t *key = NULL;
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff for (element = cfg_list_first(keylist);
f9df80f4348ef68043903efa08299480324f4823Michael Graff element != NULL;
e223094b2248afa2697c531f75e6f84855638becMichael Graff element = cfg_list_next(element))
e223094b2248afa2697c531f75e6f84855638becMichael Graff {
e223094b2248afa2697c531f75e6f84855638becMichael Graff obj = cfg_listelt_value(element);
e223094b2248afa2697c531f75e6f84855638becMichael Graff str = cfg_obj_asstring(obj);
e223094b2248afa2697c531f75e6f84855638becMichael Graff newstr = isc_mem_strdup(mctx, str);
e223094b2248afa2697c531f75e6f84855638becMichael Graff if (newstr == NULL)
e223094b2248afa2697c531f75e6f84855638becMichael Graff goto cleanup;
e223094b2248afa2697c531f75e6f84855638becMichael Graff key = isc_mem_get(mctx, sizeof(*key));
bd3ccd1c388bd914e6283c8d398c2d926c9005a3Michael Graff if (key == NULL)
e223094b2248afa2697c531f75e6f84855638becMichael Graff goto cleanup;
e223094b2248afa2697c531f75e6f84855638becMichael Graff key->keyname = newstr;
e223094b2248afa2697c531f75e6f84855638becMichael Graff key->secret.base = NULL;
e223094b2248afa2697c531f75e6f84855638becMichael Graff key->secret.length = 0;
e223094b2248afa2697c531f75e6f84855638becMichael Graff ISC_LINK_INIT(key, link);
e223094b2248afa2697c531f75e6f84855638becMichael Graff ISC_LIST_APPEND(*keyids, key, link);
e223094b2248afa2697c531f75e6f84855638becMichael Graff key = NULL;
e223094b2248afa2697c531f75e6f84855638becMichael Graff newstr = NULL;
e223094b2248afa2697c531f75e6f84855638becMichael Graff }
e223094b2248afa2697c531f75e6f84855638becMichael Graff return (ISC_R_SUCCESS);
e223094b2248afa2697c531f75e6f84855638becMichael Graff
e223094b2248afa2697c531f75e6f84855638becMichael Graff cleanup:
e223094b2248afa2697c531f75e6f84855638becMichael Graff if (newstr != NULL)
e223094b2248afa2697c531f75e6f84855638becMichael Graff isc_mem_free(mctx, newstr);
e223094b2248afa2697c531f75e6f84855638becMichael Graff if (key != NULL)
e223094b2248afa2697c531f75e6f84855638becMichael Graff isc_mem_put(mctx, key, sizeof(*key));
e223094b2248afa2697c531f75e6f84855638becMichael Graff free_controlkeylist(keyids, mctx);
e223094b2248afa2697c531f75e6f84855638becMichael Graff return (ISC_R_NOMEMORY);
e223094b2248afa2697c531f75e6f84855638becMichael Graff}
e223094b2248afa2697c531f75e6f84855638becMichael Graff
e223094b2248afa2697c531f75e6f84855638becMichael Graffstatic void
e223094b2248afa2697c531f75e6f84855638becMichael Graffregister_keys(cfg_obj_t *control, cfg_obj_t *keylist,
e223094b2248afa2697c531f75e6f84855638becMichael Graff controlkeylist_t *keyids, isc_mem_t *mctx, const char *socktext)
e223094b2248afa2697c531f75e6f84855638becMichael Graff{
e223094b2248afa2697c531f75e6f84855638becMichael Graff controlkey_t *keyid, *next;
e223094b2248afa2697c531f75e6f84855638becMichael Graff cfg_obj_t *keydef;
e223094b2248afa2697c531f75e6f84855638becMichael Graff char secret[1024];
e223094b2248afa2697c531f75e6f84855638becMichael Graff isc_buffer_t b;
e223094b2248afa2697c531f75e6f84855638becMichael Graff isc_result_t result;
e223094b2248afa2697c531f75e6f84855638becMichael Graff
e223094b2248afa2697c531f75e6f84855638becMichael Graff /*
e223094b2248afa2697c531f75e6f84855638becMichael Graff * Find the keys corresponding to the keyids used by this listener.
e223094b2248afa2697c531f75e6f84855638becMichael Graff */
e223094b2248afa2697c531f75e6f84855638becMichael Graff for (keyid = ISC_LIST_HEAD(*keyids); keyid != NULL; keyid = next) {
e223094b2248afa2697c531f75e6f84855638becMichael Graff next = ISC_LIST_NEXT(keyid, link);
e223094b2248afa2697c531f75e6f84855638becMichael Graff
e223094b2248afa2697c531f75e6f84855638becMichael Graff result = cfgkeylist_find(keylist, keyid->keyname, &keydef);
e223094b2248afa2697c531f75e6f84855638becMichael Graff if (result != ISC_R_SUCCESS) {
e223094b2248afa2697c531f75e6f84855638becMichael Graff cfg_obj_log(control, ns_g_lctx, ISC_LOG_WARNING,
e223094b2248afa2697c531f75e6f84855638becMichael Graff "couldn't find key '%s' for use with "
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff "command channel %s",
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff keyid->keyname, socktext);
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff ISC_LIST_UNLINK(*keyids, keyid, link);
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff free_controlkey(keyid, mctx);
e223094b2248afa2697c531f75e6f84855638becMichael Graff } else {
e223094b2248afa2697c531f75e6f84855638becMichael Graff cfg_obj_t *algobj = NULL;
b02262cbcd550c63f85df76edc6fff556ea5e95dMichael Graff cfg_obj_t *secretobj = NULL;
e223094b2248afa2697c531f75e6f84855638becMichael Graff char *algstr = NULL;
e223094b2248afa2697c531f75e6f84855638becMichael Graff char *secretstr = NULL;
e223094b2248afa2697c531f75e6f84855638becMichael Graff
e223094b2248afa2697c531f75e6f84855638becMichael Graff (void)cfg_map_get(keydef, "algorithm", &algobj);
e223094b2248afa2697c531f75e6f84855638becMichael Graff (void)cfg_map_get(keydef, "secret", &secretobj);
e223094b2248afa2697c531f75e6f84855638becMichael Graff INSIST(algobj != NULL && secretobj != NULL);
e223094b2248afa2697c531f75e6f84855638becMichael Graff
e223094b2248afa2697c531f75e6f84855638becMichael Graff algstr = cfg_obj_asstring(algobj);
e223094b2248afa2697c531f75e6f84855638becMichael Graff secretstr = cfg_obj_asstring(secretobj);
e223094b2248afa2697c531f75e6f84855638becMichael Graff
e223094b2248afa2697c531f75e6f84855638becMichael Graff if (ns_config_getkeyalgorithm(algstr, NULL) !=
e223094b2248afa2697c531f75e6f84855638becMichael Graff ISC_R_SUCCESS)
e223094b2248afa2697c531f75e6f84855638becMichael Graff {
e223094b2248afa2697c531f75e6f84855638becMichael Graff cfg_obj_log(control, ns_g_lctx,
e223094b2248afa2697c531f75e6f84855638becMichael Graff ISC_LOG_WARNING,
e223094b2248afa2697c531f75e6f84855638becMichael Graff "unsupported algorithm '%s' in "
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff "key '%s' for use with command "
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff "channel %s",
e223094b2248afa2697c531f75e6f84855638becMichael Graff algstr, keyid->keyname, socktext);
e223094b2248afa2697c531f75e6f84855638becMichael Graff ISC_LIST_UNLINK(*keyids, keyid, link);
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff free_controlkey(keyid, mctx);
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff continue;
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff }
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff isc_buffer_init(&b, secret, sizeof(secret));
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff result = isc_base64_decodestring(secretstr, &b);
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff if (result != ISC_R_SUCCESS) {
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff cfg_obj_log(keydef, ns_g_lctx, ISC_LOG_WARNING,
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff "secret for key '%s' on "
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff "command channel %s: %s",
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff keyid->keyname, socktext,
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff isc_result_totext(result));
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff ISC_LIST_UNLINK(*keyids, keyid, link);
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff free_controlkey(keyid, mctx);
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff continue;
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff }
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff keyid->secret.length = isc_buffer_usedlength(&b);
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff keyid->secret.base = isc_mem_get(mctx,
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff keyid->secret.length);
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff if (keyid->secret.base == NULL) {
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff cfg_obj_log(keydef, ns_g_lctx, ISC_LOG_WARNING,
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff "couldn't register key '%s': "
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff "out of memory", keyid->keyname);
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff ISC_LIST_UNLINK(*keyids, keyid, link);
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff free_controlkey(keyid, mctx);
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff break;
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff }
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff memcpy(keyid->secret.base, isc_buffer_base(&b),
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff keyid->secret.length);
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff }
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff }
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff}
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff#define CHECK(x) \
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff do { \
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff result = (x); \
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff if (result != ISC_R_SUCCESS) \
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff goto cleanup; \
e223094b2248afa2697c531f75e6f84855638becMichael Graff } while (0)
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graffstatic isc_result_t
d68838693666ba930ec4143f848c18bff2bfc244Michael Graffget_rndckey(isc_mem_t *mctx, controlkeylist_t *keyids) {
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff isc_result_t result;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff cfg_parser_t *pctx = NULL;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff cfg_obj_t *config = NULL;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff cfg_obj_t *key = NULL;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff cfg_obj_t *algobj = NULL;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff cfg_obj_t *secretobj = NULL;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff char *algstr = NULL;
e223094b2248afa2697c531f75e6f84855638becMichael Graff char *secretstr = NULL;
e223094b2248afa2697c531f75e6f84855638becMichael Graff controlkey_t *keyid = NULL;
e223094b2248afa2697c531f75e6f84855638becMichael Graff char secret[1024];
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff isc_buffer_t b;
e223094b2248afa2697c531f75e6f84855638becMichael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff CHECK(cfg_parser_create(mctx, ns_g_lctx, &pctx));
e223094b2248afa2697c531f75e6f84855638becMichael Graff CHECK(cfg_parse_file(pctx, ns_g_keyfile, &cfg_type_rndckey, &config));
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff CHECK(cfg_map_get(config, "key", &key));
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff keyid = isc_mem_get(mctx, sizeof(*keyid));
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff if (keyid == NULL)
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff CHECK(ISC_R_NOMEMORY);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff keyid->keyname = isc_mem_strdup(mctx,
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff cfg_obj_asstring(cfg_map_getname(key)));
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff keyid->secret.base = NULL;
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff keyid->secret.length = 0;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff ISC_LINK_INIT(keyid, link);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff if (keyid->keyname == NULL)
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff CHECK(ISC_R_NOMEMORY);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff CHECK(cfg_check_key(key, ns_g_lctx));
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff (void)cfg_map_get(key, "algorithm", &algobj);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff (void)cfg_map_get(key, "secret", &secretobj);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff INSIST(algobj != NULL && secretobj != NULL);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
e223094b2248afa2697c531f75e6f84855638becMichael Graff algstr = cfg_obj_asstring(algobj);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff secretstr = cfg_obj_asstring(secretobj);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff if (ns_config_getkeyalgorithm(algstr, NULL) != ISC_R_SUCCESS) {
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff cfg_obj_log(key, ns_g_lctx,
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff ISC_LOG_WARNING,
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff "unsupported algorithm '%s' in "
e223094b2248afa2697c531f75e6f84855638becMichael Graff "key '%s' for use with command "
e223094b2248afa2697c531f75e6f84855638becMichael Graff "channel",
e223094b2248afa2697c531f75e6f84855638becMichael Graff algstr, keyid->keyname);
e223094b2248afa2697c531f75e6f84855638becMichael Graff goto cleanup;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff }
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff isc_buffer_init(&b, secret, sizeof(secret));
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff result = isc_base64_decodestring(secretstr, &b);
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff if (result != ISC_R_SUCCESS) {
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff cfg_obj_log(key, ns_g_lctx, ISC_LOG_WARNING,
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff "secret for key '%s' on command channel: %s",
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff keyid->keyname, isc_result_totext(result));
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff CHECK(result);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff }
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff keyid->secret.length = isc_buffer_usedlength(&b);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff keyid->secret.base = isc_mem_get(mctx,
e223094b2248afa2697c531f75e6f84855638becMichael Graff keyid->secret.length);
e223094b2248afa2697c531f75e6f84855638becMichael Graff if (keyid->secret.base == NULL) {
e223094b2248afa2697c531f75e6f84855638becMichael Graff cfg_obj_log(key, ns_g_lctx, ISC_LOG_WARNING,
e223094b2248afa2697c531f75e6f84855638becMichael Graff "couldn't register key '%s': "
e223094b2248afa2697c531f75e6f84855638becMichael Graff "out of memory", keyid->keyname);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff CHECK(ISC_R_NOMEMORY);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff }
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff memcpy(keyid->secret.base, isc_buffer_base(&b),
e223094b2248afa2697c531f75e6f84855638becMichael Graff keyid->secret.length);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff ISC_LIST_APPEND(*keyids, keyid, link);
e223094b2248afa2697c531f75e6f84855638becMichael Graff keyid = NULL;
e223094b2248afa2697c531f75e6f84855638becMichael Graff result = ISC_R_SUCCESS;
e223094b2248afa2697c531f75e6f84855638becMichael Graff
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff cleanup:
e223094b2248afa2697c531f75e6f84855638becMichael Graff if (keyid != NULL)
e223094b2248afa2697c531f75e6f84855638becMichael Graff free_controlkey(keyid, mctx);
e223094b2248afa2697c531f75e6f84855638becMichael Graff if (config != NULL)
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff cfg_obj_destroy(pctx, &config);
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff if (pctx != NULL)
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff cfg_parser_destroy(&pctx);
e223094b2248afa2697c531f75e6f84855638becMichael Graff return (result);
e223094b2248afa2697c531f75e6f84855638becMichael Graff}
e223094b2248afa2697c531f75e6f84855638becMichael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graffstatic void
d68838693666ba930ec4143f848c18bff2bfc244Michael Graffget_key_info(cfg_obj_t *config, cfg_obj_t *control,
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff cfg_obj_t **global_keylistp, cfg_obj_t **control_keylistp)
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff{
e223094b2248afa2697c531f75e6f84855638becMichael Graff cfg_obj_t *control_keylist = NULL;
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff cfg_obj_t *global_keylist = NULL;
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff
e223094b2248afa2697c531f75e6f84855638becMichael Graff REQUIRE(global_keylistp != NULL && *global_keylistp == NULL);
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff REQUIRE(control_keylistp != NULL && *control_keylistp == NULL);
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff control_keylist = cfg_tuple_get(control, "keys");
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff if (!cfg_obj_isvoid(control_keylist) &&
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff cfg_list_first(control_keylist) != NULL)
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff cfg_map_get(config, "key", &global_keylist);
e223094b2248afa2697c531f75e6f84855638becMichael Graff
e223094b2248afa2697c531f75e6f84855638becMichael Graff *global_keylistp = global_keylist;
e223094b2248afa2697c531f75e6f84855638becMichael Graff *control_keylistp = control_keylist;
e223094b2248afa2697c531f75e6f84855638becMichael Graff}
e223094b2248afa2697c531f75e6f84855638becMichael Graff
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graffstatic void
e223094b2248afa2697c531f75e6f84855638becMichael Graffupdate_listener(ns_controls_t *cp,
e223094b2248afa2697c531f75e6f84855638becMichael Graff controllistener_t **listenerp, cfg_obj_t *control,
e223094b2248afa2697c531f75e6f84855638becMichael Graff cfg_obj_t *config, isc_sockaddr_t *addr,
e223094b2248afa2697c531f75e6f84855638becMichael Graff ns_aclconfctx_t *aclconfctx, const char *socktext)
e223094b2248afa2697c531f75e6f84855638becMichael Graff{
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff controllistener_t *listener;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff cfg_obj_t *allow;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff cfg_obj_t *global_keylist = NULL;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff cfg_obj_t *control_keylist = NULL;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff dns_acl_t *new_acl = NULL;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff controlkeylist_t keys;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff isc_result_t result = ISC_R_SUCCESS;
e223094b2248afa2697c531f75e6f84855638becMichael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff for (listener = ISC_LIST_HEAD(cp->listeners);
e223094b2248afa2697c531f75e6f84855638becMichael Graff listener != NULL;
e223094b2248afa2697c531f75e6f84855638becMichael Graff listener = ISC_LIST_NEXT(listener, link))
1d11db66fa23e276074858091407734de40584acMichael Graff if (isc_sockaddr_equal(addr, &listener->address))
e223094b2248afa2697c531f75e6f84855638becMichael Graff break;
e223094b2248afa2697c531f75e6f84855638becMichael Graff
e223094b2248afa2697c531f75e6f84855638becMichael Graff if (listener == NULL) {
e223094b2248afa2697c531f75e6f84855638becMichael Graff *listenerp = NULL;
e223094b2248afa2697c531f75e6f84855638becMichael Graff return;
e223094b2248afa2697c531f75e6f84855638becMichael Graff }
e223094b2248afa2697c531f75e6f84855638becMichael Graff
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff /*
e223094b2248afa2697c531f75e6f84855638becMichael Graff * There is already a listener for this sockaddr.
e223094b2248afa2697c531f75e6f84855638becMichael Graff * Update the access list and key information.
e223094b2248afa2697c531f75e6f84855638becMichael Graff *
e223094b2248afa2697c531f75e6f84855638becMichael Graff * First try to deal with the key situation. There are a few
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff * possibilities:
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff * (a) It had an explicit keylist and still has an explicit keylist.
e223094b2248afa2697c531f75e6f84855638becMichael Graff * (b) It had an automagic key and now has an explicit keylist.
e223094b2248afa2697c531f75e6f84855638becMichael Graff * (c) It had an explicit keylist and now needs an automagic key.
e223094b2248afa2697c531f75e6f84855638becMichael Graff * (d) It has an automagic key and still needs the automagic key.
e223094b2248afa2697c531f75e6f84855638becMichael Graff *
e223094b2248afa2697c531f75e6f84855638becMichael Graff * (c) and (d) are the annoying ones. The caller needs to know
e223094b2248afa2697c531f75e6f84855638becMichael Graff * that it should use the automagic configuration for key information
e223094b2248afa2697c531f75e6f84855638becMichael Graff * in place of the named.conf configuration.
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff *
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff * XXXDCL There is one other hazard that has not been dealt with,
e223094b2248afa2697c531f75e6f84855638becMichael Graff * the problem that if a key change is being caused by a control
e223094b2248afa2697c531f75e6f84855638becMichael Graff * channel reload, then the response will be with the new key
e223094b2248afa2697c531f75e6f84855638becMichael Graff * and not able to be decrypted by the client.
e223094b2248afa2697c531f75e6f84855638becMichael Graff */
e223094b2248afa2697c531f75e6f84855638becMichael Graff get_key_info(config, control, &global_keylist, &control_keylist);
e223094b2248afa2697c531f75e6f84855638becMichael Graff
e223094b2248afa2697c531f75e6f84855638becMichael Graff if (control_keylist != NULL) {
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff INSIST(global_keylist != NULL);
e223094b2248afa2697c531f75e6f84855638becMichael Graff
e223094b2248afa2697c531f75e6f84855638becMichael Graff ISC_LIST_INIT(keys);
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff result = controlkeylist_fromcfg(control_keylist,
e223094b2248afa2697c531f75e6f84855638becMichael Graff listener->mctx, &keys);
e223094b2248afa2697c531f75e6f84855638becMichael Graff if (result) {
e223094b2248afa2697c531f75e6f84855638becMichael Graff free_controlkeylist(&listener->keys, listener->mctx);
e223094b2248afa2697c531f75e6f84855638becMichael Graff listener->keys = keys;
e223094b2248afa2697c531f75e6f84855638becMichael Graff register_keys(control, global_keylist, &listener->keys,
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff listener->mctx, socktext);
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff }
e223094b2248afa2697c531f75e6f84855638becMichael Graff } else {
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff free_controlkeylist(&listener->keys, listener->mctx);
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff result = get_rndckey(listener->mctx, &listener->keys);
e223094b2248afa2697c531f75e6f84855638becMichael Graff }
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff if (result != ISC_R_SUCCESS && global_keylist != NULL)
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff /*
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff * This message might be a little misleading since the
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff * "new keys" might in fact be identical to the old ones,
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff * but tracking whether they are identical just for the
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff * sake of avoiding this message would be too much trouble.
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff */
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff cfg_obj_log(control, ns_g_lctx, ISC_LOG_WARNING,
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff "couldn't install new keys for "
e223094b2248afa2697c531f75e6f84855638becMichael Graff "command channel %s: %s",
e223094b2248afa2697c531f75e6f84855638becMichael Graff socktext, isc_result_totext(result));
e223094b2248afa2697c531f75e6f84855638becMichael Graff
e223094b2248afa2697c531f75e6f84855638becMichael Graff
e223094b2248afa2697c531f75e6f84855638becMichael Graff /*
e223094b2248afa2697c531f75e6f84855638becMichael Graff * Now, keep the old access list unless a new one can be made.
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff */
e223094b2248afa2697c531f75e6f84855638becMichael Graff if (control != NULL) {
e223094b2248afa2697c531f75e6f84855638becMichael Graff allow = cfg_tuple_get(control, "allow");
e223094b2248afa2697c531f75e6f84855638becMichael Graff result = ns_acl_fromconfig(allow, config, aclconfctx,
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff listener->mctx, &new_acl);
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff } else {
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff result = dns_acl_any(listener->mctx, &new_acl);
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff }
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff if (result == ISC_R_SUCCESS) {
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff dns_acl_detach(&listener->acl);
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff dns_acl_attach(new_acl, &listener->acl);
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff dns_acl_detach(&new_acl);
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff } else
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff /* XXXDCL say the old acl is still used? */
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff cfg_obj_log(control, ns_g_lctx, ISC_LOG_WARNING,
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff "couldn't install new acl for "
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff "command channel %s: %s",
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff socktext, isc_result_totext(result));
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff *listenerp = listener;
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff}
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graffstatic void
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graffadd_listener(ns_controls_t *cp, controllistener_t **listenerp,
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff cfg_obj_t *control, cfg_obj_t *config, isc_sockaddr_t *addr,
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff ns_aclconfctx_t *aclconfctx, const char *socktext)
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff{
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff isc_mem_t *mctx = cp->server->mctx;
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff controllistener_t *listener;
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff cfg_obj_t *allow;
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff cfg_obj_t *global_keylist = NULL;
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff cfg_obj_t *control_keylist = NULL;
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff dns_acl_t *new_acl = NULL;
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff isc_result_t result = ISC_R_SUCCESS;
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff listener = isc_mem_get(mctx, sizeof(*listener));
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff if (listener == NULL)
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff result = ISC_R_NOMEMORY;
e223094b2248afa2697c531f75e6f84855638becMichael Graff
e223094b2248afa2697c531f75e6f84855638becMichael Graff if (result == ISC_R_SUCCESS) {
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff listener->controls = cp;
e223094b2248afa2697c531f75e6f84855638becMichael Graff listener->mctx = mctx;
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff listener->task = cp->server->task;
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff listener->address = *addr;
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff listener->sock = NULL;
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff listener->listening = ISC_FALSE;
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff listener->exiting = ISC_FALSE;
e223094b2248afa2697c531f75e6f84855638becMichael Graff listener->acl = NULL;
e223094b2248afa2697c531f75e6f84855638becMichael Graff ISC_LINK_INIT(listener, link);
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff ISC_LIST_INIT(listener->keys);
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff ISC_LIST_INIT(listener->connections);
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff /*
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff * Make the acl.
e223094b2248afa2697c531f75e6f84855638becMichael Graff */
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff if (control != NULL) {
e223094b2248afa2697c531f75e6f84855638becMichael Graff allow = cfg_tuple_get(control, "allow");
e223094b2248afa2697c531f75e6f84855638becMichael Graff result = ns_acl_fromconfig(allow, config, aclconfctx,
e223094b2248afa2697c531f75e6f84855638becMichael Graff mctx, &new_acl);
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff } else {
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff result = dns_acl_any(mctx, &new_acl);
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff }
e223094b2248afa2697c531f75e6f84855638becMichael Graff }
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff if (result == ISC_R_SUCCESS) {
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff dns_acl_attach(new_acl, &listener->acl);
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff dns_acl_detach(&new_acl);
e223094b2248afa2697c531f75e6f84855638becMichael Graff
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff if (config != NULL)
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff get_key_info(config, control, &global_keylist,
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff &control_keylist);
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff if (control_keylist != NULL) {
e223094b2248afa2697c531f75e6f84855638becMichael Graff result = controlkeylist_fromcfg(control_keylist,
e223094b2248afa2697c531f75e6f84855638becMichael Graff listener->mctx,
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff &listener->keys);
e223094b2248afa2697c531f75e6f84855638becMichael Graff if (result == ISC_R_SUCCESS)
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff register_keys(control, global_keylist,
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff &listener->keys,
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff listener->mctx, socktext);
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff } else
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff result = get_rndckey(mctx, &listener->keys);
e223094b2248afa2697c531f75e6f84855638becMichael Graff
e223094b2248afa2697c531f75e6f84855638becMichael Graff if (result != ISC_R_SUCCESS && control != NULL)
e223094b2248afa2697c531f75e6f84855638becMichael Graff cfg_obj_log(control, ns_g_lctx, ISC_LOG_WARNING,
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff "couldn't install keys for "
d49555e76c5d02943fdd6606113aebf2317390d5Michael Graff "command channel %s: %s",
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff socktext, isc_result_totext(result));
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff }
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff if (result == ISC_R_SUCCESS) {
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff int pf = isc_sockaddr_pf(&listener->address);
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff if ((pf == AF_INET && isc_net_probeipv4() != ISC_R_SUCCESS) ||
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff (pf == AF_INET6 && isc_net_probeipv6() != ISC_R_SUCCESS))
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff result = ISC_R_FAMILYNOSUPPORT;
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff }
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff if (result == ISC_R_SUCCESS)
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff result = isc_socket_create(ns_g_socketmgr,
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff isc_sockaddr_pf(&listener->address),
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff isc_sockettype_tcp,
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff &listener->sock);
e223094b2248afa2697c531f75e6f84855638becMichael Graff
e223094b2248afa2697c531f75e6f84855638becMichael Graff if (result == ISC_R_SUCCESS)
e223094b2248afa2697c531f75e6f84855638becMichael Graff result = isc_socket_bind(listener->sock,
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff &listener->address);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff if (result == ISC_R_SUCCESS)
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff result = control_listen(listener);
f9df80f4348ef68043903efa08299480324f4823Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff if (result == ISC_R_SUCCESS)
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff result = control_accept(listener);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff if (result == ISC_R_SUCCESS) {
f9df80f4348ef68043903efa08299480324f4823Michael Graff isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
f9df80f4348ef68043903efa08299480324f4823Michael Graff NS_LOGMODULE_CONTROL, ISC_LOG_NOTICE,
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff "command channel listening on %s", socktext);
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff *listenerp = listener;
f9df80f4348ef68043903efa08299480324f4823Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff } else {
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff if (listener != NULL) {
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff listener->exiting = ISC_TRUE;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff free_listener(listener);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff }
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff if (control != NULL)
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff cfg_obj_log(control, ns_g_lctx, ISC_LOG_WARNING,
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff "couldn't add command channel %s: %s",
b02262cbcd550c63f85df76edc6fff556ea5e95dMichael Graff socktext, isc_result_totext(result));
e223094b2248afa2697c531f75e6f84855638becMichael Graff else
e223094b2248afa2697c531f75e6f84855638becMichael Graff isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
e223094b2248afa2697c531f75e6f84855638becMichael Graff NS_LOGMODULE_CONTROL, ISC_LOG_NOTICE,
e223094b2248afa2697c531f75e6f84855638becMichael Graff "couldn't add command channel %s: %s",
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff socktext, isc_result_totext(result));
d49555e76c5d02943fdd6606113aebf2317390d5Michael Graff
d49555e76c5d02943fdd6606113aebf2317390d5Michael Graff *listenerp = NULL;
d49555e76c5d02943fdd6606113aebf2317390d5Michael Graff }
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff /* XXXDCL return error results? fail hard? */
d49555e76c5d02943fdd6606113aebf2317390d5Michael Graff}
d49555e76c5d02943fdd6606113aebf2317390d5Michael Graff
d49555e76c5d02943fdd6606113aebf2317390d5Michael Graffisc_result_t
d49555e76c5d02943fdd6606113aebf2317390d5Michael Graffns_controls_configure(ns_controls_t *cp, cfg_obj_t *config,
d49555e76c5d02943fdd6606113aebf2317390d5Michael Graff ns_aclconfctx_t *aclconfctx)
d49555e76c5d02943fdd6606113aebf2317390d5Michael Graff{
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff controllistener_t *listener;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff controllistenerlist_t new_listeners;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff cfg_obj_t *controlslist = NULL;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff cfg_listelt_t *element, *element2;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff char socktext[ISC_SOCKADDR_FORMATSIZE];
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff ISC_LIST_INIT(new_listeners);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff /*
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff * Get the list of named.conf 'controls' statements.
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff */
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff (void)cfg_map_get(config, "controls", &controlslist);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff /*
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff * Run through the new control channel list, noting sockets that
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff * are already being listened on and moving them to the new list.
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff *
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff * Identifying duplicate addr/port combinations is left to either
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff * the underlying config code, or to the bind attempt getting an
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff * address-in-use error.
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff */
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff if (controlslist != NULL) {
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff for (element = cfg_list_first(controlslist);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff element != NULL;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff element = cfg_list_next(element)) {
f9df80f4348ef68043903efa08299480324f4823Michael Graff cfg_obj_t *controls;
f9df80f4348ef68043903efa08299480324f4823Michael Graff cfg_obj_t *inetcontrols = NULL;
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff controls = cfg_listelt_value(element);
f9df80f4348ef68043903efa08299480324f4823Michael Graff (void)cfg_map_get(controls, "inet", &inetcontrols);
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff if (inetcontrols == NULL)
1d7987f4227c838f7fa790ad57255d3df3332ccaMichael Graff continue;
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff for (element2 = cfg_list_first(inetcontrols);
f9df80f4348ef68043903efa08299480324f4823Michael Graff element2 != NULL;
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff element2 = cfg_list_next(element2)) {
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff cfg_obj_t *control;
f9df80f4348ef68043903efa08299480324f4823Michael Graff cfg_obj_t *obj;
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff isc_sockaddr_t *addr;
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff /*
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff * The parser handles BIND 8 configuration file
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff * syntax, so it allows unix phrases as well
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff * inet phrases with no keys{} clause.
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff *
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff * "unix" phrases have been reported as
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff * unsupported by the parser.
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff */
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff control = cfg_listelt_value(element2);
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff
1d7987f4227c838f7fa790ad57255d3df3332ccaMichael Graff obj = cfg_tuple_get(control, "address");
1d7987f4227c838f7fa790ad57255d3df3332ccaMichael Graff addr = cfg_obj_assockaddr(obj);
1d7987f4227c838f7fa790ad57255d3df3332ccaMichael Graff if (isc_sockaddr_getport(addr) == 0)
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff isc_sockaddr_setport(addr,
1d7987f4227c838f7fa790ad57255d3df3332ccaMichael Graff NS_CONTROL_PORT);
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff isc_sockaddr_format(addr, socktext,
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff sizeof(socktext));
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff isc_log_write(ns_g_lctx,
ddd035637d92035a0d9e2bc32a7e2c9cc8a99d3fMichael Graff NS_LOGCATEGORY_GENERAL,
ddd035637d92035a0d9e2bc32a7e2c9cc8a99d3fMichael Graff NS_LOGMODULE_CONTROL,
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff ISC_LOG_DEBUG(9),
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff "processing control channel %s",
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff socktext);
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff update_listener(cp, &listener, control, config,
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff addr, aclconfctx, socktext);
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff if (listener != NULL)
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff /*
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff * Remove the listener from the old
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff * list, so it won't be shut down.
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff */
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff ISC_LIST_UNLINK(cp->listeners,
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff listener, link);
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff else
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff /*
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff * This is a new listener.
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff */
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff add_listener(cp, &listener, control,
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff config, addr, aclconfctx,
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff socktext);
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff if (listener != NULL)
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff ISC_LIST_APPEND(new_listeners,
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff listener, link);
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff }
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff }
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff } else {
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff int i;
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff for (i = 0 ; i < 2; i++) {
f9df80f4348ef68043903efa08299480324f4823Michael Graff isc_sockaddr_t addr;
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff if (i == 1) {
f9df80f4348ef68043903efa08299480324f4823Michael Graff if (isc_net_probeipv4() != ISC_R_SUCCESS)
f9df80f4348ef68043903efa08299480324f4823Michael Graff continue;
f9df80f4348ef68043903efa08299480324f4823Michael Graff isc_sockaddr_any(&addr);
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff } else {
f9df80f4348ef68043903efa08299480324f4823Michael Graff if (isc_net_probeipv6() != ISC_R_SUCCESS)
f9df80f4348ef68043903efa08299480324f4823Michael Graff continue;
f9df80f4348ef68043903efa08299480324f4823Michael Graff isc_sockaddr_any6(&addr);
f9df80f4348ef68043903efa08299480324f4823Michael Graff }
f9df80f4348ef68043903efa08299480324f4823Michael Graff isc_sockaddr_setport(&addr, NS_CONTROL_PORT);
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff isc_sockaddr_format(&addr, socktext, sizeof(socktext));
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff update_listener(cp, &listener, NULL, NULL,
f9df80f4348ef68043903efa08299480324f4823Michael Graff &addr, NULL, socktext);
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff if (listener != NULL)
f9df80f4348ef68043903efa08299480324f4823Michael Graff /*
f9df80f4348ef68043903efa08299480324f4823Michael Graff * Remove the listener from the old
f9df80f4348ef68043903efa08299480324f4823Michael Graff * list, so it won't be shut down.
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff */
f9df80f4348ef68043903efa08299480324f4823Michael Graff ISC_LIST_UNLINK(cp->listeners,
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff listener, link);
f9df80f4348ef68043903efa08299480324f4823Michael Graff else
f9df80f4348ef68043903efa08299480324f4823Michael Graff /*
f9df80f4348ef68043903efa08299480324f4823Michael Graff * This is a new listener.
f9df80f4348ef68043903efa08299480324f4823Michael Graff */
f9df80f4348ef68043903efa08299480324f4823Michael Graff add_listener(cp, &listener, NULL, NULL,
f9df80f4348ef68043903efa08299480324f4823Michael Graff &addr, NULL, socktext);
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff if (listener != NULL)
f9df80f4348ef68043903efa08299480324f4823Michael Graff ISC_LIST_APPEND(new_listeners,
a920f559c3689f52731519a9d5169ad5814866edMichael Graff listener, link);
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff }
f9df80f4348ef68043903efa08299480324f4823Michael Graff }
a920f559c3689f52731519a9d5169ad5814866edMichael Graff
1d7987f4227c838f7fa790ad57255d3df3332ccaMichael Graff /*
1d7987f4227c838f7fa790ad57255d3df3332ccaMichael Graff * ns_control_shutdown() will stop whatever is on the global
1d7987f4227c838f7fa790ad57255d3df3332ccaMichael Graff * listeners list, which currently only has whatever sockaddrs
1d7987f4227c838f7fa790ad57255d3df3332ccaMichael Graff * were in the previous configuration (if any) that do not
1d7987f4227c838f7fa790ad57255d3df3332ccaMichael Graff * remain in the current configuration.
d49555e76c5d02943fdd6606113aebf2317390d5Michael Graff */
d49555e76c5d02943fdd6606113aebf2317390d5Michael Graff ns_controls_shutdown(cp);
d49555e76c5d02943fdd6606113aebf2317390d5Michael Graff
d49555e76c5d02943fdd6606113aebf2317390d5Michael Graff /*
a920f559c3689f52731519a9d5169ad5814866edMichael Graff * Put all of the valid listeners on the listeners list.
f9df80f4348ef68043903efa08299480324f4823Michael Graff * Anything already on listeners in the process of shutting
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff * down will be taken care of by listen_done().
a920f559c3689f52731519a9d5169ad5814866edMichael Graff */
a920f559c3689f52731519a9d5169ad5814866edMichael Graff ISC_LIST_APPENDLIST(cp->listeners, new_listeners, link);
a920f559c3689f52731519a9d5169ad5814866edMichael Graff return (ISC_R_SUCCESS);
1d7987f4227c838f7fa790ad57255d3df3332ccaMichael Graff}
1d7987f4227c838f7fa790ad57255d3df3332ccaMichael Graff
1d7987f4227c838f7fa790ad57255d3df3332ccaMichael Graffisc_result_t
1d7987f4227c838f7fa790ad57255d3df3332ccaMichael Graffns_controls_create(ns_server_t *server, ns_controls_t **ctrlsp) {
1d7987f4227c838f7fa790ad57255d3df3332ccaMichael Graff isc_mem_t *mctx = server->mctx;
1d7987f4227c838f7fa790ad57255d3df3332ccaMichael Graff ns_controls_t *controls = isc_mem_get(mctx, sizeof(*controls));
1d7987f4227c838f7fa790ad57255d3df3332ccaMichael Graff if (controls == NULL)
1d7987f4227c838f7fa790ad57255d3df3332ccaMichael Graff return (ISC_R_NOMEMORY);
41cc03374dc7fd58d3b099d6c921f192a7bbb5f7Michael Graff controls->server = server;
1d7987f4227c838f7fa790ad57255d3df3332ccaMichael Graff ISC_LIST_INIT(controls->listeners);
bfbf3f2d770dc093ac5c74d5fd716ac9521e8715Michael Graff *ctrlsp = controls;
1d7987f4227c838f7fa790ad57255d3df3332ccaMichael Graff return (ISC_R_SUCCESS);
bfbf3f2d770dc093ac5c74d5fd716ac9521e8715Michael Graff}
bfbf3f2d770dc093ac5c74d5fd716ac9521e8715Michael Graff
823e45c1273512a8048cd5e7e57f31f58c964f7fMichael Graffvoid
823e45c1273512a8048cd5e7e57f31f58c964f7fMichael Graffns_controls_destroy(ns_controls_t **ctrlsp) {
1d7987f4227c838f7fa790ad57255d3df3332ccaMichael Graff ns_controls_t *controls = *ctrlsp;
1d7987f4227c838f7fa790ad57255d3df3332ccaMichael Graff
1d7987f4227c838f7fa790ad57255d3df3332ccaMichael Graff REQUIRE(ISC_LIST_EMPTY(controls->listeners));
1d7987f4227c838f7fa790ad57255d3df3332ccaMichael Graff
1d7987f4227c838f7fa790ad57255d3df3332ccaMichael Graff isc_mem_put(controls->server->mctx, controls, sizeof(*controls));
d49555e76c5d02943fdd6606113aebf2317390d5Michael Graff *ctrlsp = NULL;
d49555e76c5d02943fdd6606113aebf2317390d5Michael Graff}
d49555e76c5d02943fdd6606113aebf2317390d5Michael Graff