controlconf.c revision 368aedf188d7c7782cae8a5ce2a978be47b5a764
ca41b452ede6feaa9d8739ec3cae19389a7b0d03Bob Halley * Copyright (C) 2004-2008, 2011-2014 Internet Systems Consortium, Inc. ("ISC")
96f55bdc736f8559b3a57260db6f0e964c44070dBob Halley * Copyright (C) 2001-2003 Internet Software Consortium.
96f55bdc736f8559b3a57260db6f0e964c44070dBob Halley * Permission to use, copy, modify, and/or distribute this software for any
96f55bdc736f8559b3a57260db6f0e964c44070dBob Halley * purpose with or without fee is hereby granted, provided that the above
96f55bdc736f8559b3a57260db6f0e964c44070dBob Halley * copyright notice and this permission notice appear in all copies.
96f55bdc736f8559b3a57260db6f0e964c44070dBob Halley * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
96f55bdc736f8559b3a57260db6f0e964c44070dBob Halley * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
96f55bdc736f8559b3a57260db6f0e964c44070dBob Halley * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
96f55bdc736f8559b3a57260db6f0e964c44070dBob Halley * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
96f55bdc736f8559b3a57260db6f0e964c44070dBob Halley * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
96f55bdc736f8559b3a57260db6f0e964c44070dBob Halley * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
96f55bdc736f8559b3a57260db6f0e964c44070dBob Halley * PERFORMANCE OF THIS SOFTWARE.
96f55bdc736f8559b3a57260db6f0e964c44070dBob Halley/* $Id: controlconf.c,v 1.63 2011/12/22 08:07:48 marka Exp $ */
03dd96d177e4ed6771be7fb5f86a3a9d5f17be4eBob Halley * Note: Listeners and connections are not locked. All event handlers are
03dd96d177e4ed6771be7fb5f86a3a9d5f17be4eBob Halley * executed by the server task, and all callers of exported routines must
a829555ed724caa56b1ff7716d7eda2266491eafBob Halley * be running under the server task.
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencetypedef struct controlconnection controlconnection_t;
03dd96d177e4ed6771be7fb5f86a3a9d5f17be4eBob Halleytypedef ISC_LIST(controlconnection_t) controlconnectionlist_t;
97f1a75cf072c2cab98b4bc28c4d2491cfcd3086Bob Halleytypedef ISC_LIST(controllistener_t) controllistenerlist_t;
96f55bdc736f8559b3a57260db6f0e964c44070dBob Halleystatic void control_newconn(isc_task_t *task, isc_event_t *event);
96f55bdc736f8559b3a57260db6f0e964c44070dBob Halleystatic void control_recvmessage(isc_task_t *task, isc_event_t *event);
96f55bdc736f8559b3a57260db6f0e964c44070dBob Halleyfree_controlkey(controlkey_t *key, isc_mem_t *mctx) {
96f55bdc736f8559b3a57260db6f0e964c44070dBob Halley isc_mem_put(mctx, key->secret.base, key->secret.length);
96f55bdc736f8559b3a57260db6f0e964c44070dBob Halleyfree_controlkeylist(controlkeylist_t *keylist, isc_mem_t *mctx) {
dd324bd791a766c48d90ce9e43d1ab1446378983Bob Halley free_controlkeylist(&listener->keys, listener->mctx);
96f55bdc736f8559b3a57260db6f0e964c44070dBob Halley isc_mem_putanddetach(&listener->mctx, listener, sizeof(*listener));
96f55bdc736f8559b3a57260db6f0e964c44070dBob Halleymaybe_free_listener(controllistener_t *listener) {
96f55bdc736f8559b3a57260db6f0e964c44070dBob Halleymaybe_free_connection(controlconnection_t *conn) {
bed86971bf7eb315e9c64f75bba331917f4557cfBob Halley ISC_LIST_UNLINK(listener->connections, conn, link);
bed86971bf7eb315e9c64f75bba331917f4557cfBob Halley isc_mem_put(listener->mctx, conn, sizeof(*conn));
bed86971bf7eb315e9c64f75bba331917f4557cfBob Halley ISC_LIST_UNLINK(listener->controls->listeners, listener, link);
bed86971bf7eb315e9c64f75bba331917f4557cfBob Halley isc_sockaddr_format(&listener->address, socktext,
bed86971bf7eb315e9c64f75bba331917f4557cfBob Halley isc_socket_cleanunix(&listener->address, ISC_TRUE);
bed86971bf7eb315e9c64f75bba331917f4557cfBob Halley for (conn = ISC_LIST_HEAD(listener->connections);
bed86971bf7eb315e9c64f75bba331917f4557cfBob Halley isc_socket_cancel(listener->sock, listener->task,
96f55bdc736f8559b3a57260db6f0e964c44070dBob Halleyaddress_ok(isc_sockaddr_t *sockaddr, dns_acl_t *acl) {
97f1a75cf072c2cab98b4bc28c4d2491cfcd3086Bob Halley "isc_socket_accept() failed: %s",
bed86971bf7eb315e9c64f75bba331917f4557cfBob Halley "isc_socket_listen() failed: %s",
97f1a75cf072c2cab98b4bc28c4d2491cfcd3086Bob Halleycontrol_senddone(isc_task_t *task, isc_event_t *event) {
97f1a75cf072c2cab98b4bc28c4d2491cfcd3086Bob Halley isc_socketevent_t *sevent = (isc_socketevent_t *) event;
bed86971bf7eb315e9c64f75bba331917f4557cfBob Halley isc_socket_t *sock = (isc_socket_t *)sevent->ev_sender;
03dd96d177e4ed6771be7fb5f86a3a9d5f17be4eBob Halley isc_sockaddr_format(&peeraddr, socktext, sizeof(socktext));
e8336c458cca9289f34dc5cb58fc0b5769502649David Lawrence "error sending command response to %s: %s",
03dd96d177e4ed6771be7fb5f86a3a9d5f17be4eBob Halley result = isccc_ccmsg_readmessage(&conn->ccmsg, listener->task,
e8336c458cca9289f34dc5cb58fc0b5769502649David Lawrencestatic inline void
e8336c458cca9289f34dc5cb58fc0b5769502649David Lawrencelog_invalid(isccc_ccmsg_t *ccmsg, isc_result_t result) {
e8336c458cca9289f34dc5cb58fc0b5769502649David Lawrence (void)isc_socket_getpeername(ccmsg->sock, &peeraddr);
e8336c458cca9289f34dc5cb58fc0b5769502649David Lawrence isc_sockaddr_format(&peeraddr, socktext, sizeof(socktext));
e8336c458cca9289f34dc5cb58fc0b5769502649David Lawrence isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
03dd96d177e4ed6771be7fb5f86a3a9d5f17be4eBob Halley "invalid command from %s: %s",
03dd96d177e4ed6771be7fb5f86a3a9d5f17be4eBob Halleycontrol_recvmessage(isc_task_t *task, isc_event_t *event) {
96f55bdc736f8559b3a57260db6f0e964c44070dBob Halley /* Is the server shutting down? */
a829555ed724caa56b1ff7716d7eda2266491eafBob Halley ccregion.rstart = isc_buffer_base(&conn->ccmsg.buffer);
a829555ed724caa56b1ff7716d7eda2266491eafBob Halley ccregion.rend = isc_buffer_used(&conn->ccmsg.buffer);
a829555ed724caa56b1ff7716d7eda2266491eafBob Halley secret.rstart = isc_mem_get(listener->mctx, key->secret.length);
a829555ed724caa56b1ff7716d7eda2266491eafBob Halley memmove(secret.rstart, key->secret.base, key->secret.length);
a829555ed724caa56b1ff7716d7eda2266491eafBob Halley secret.rend = secret.rstart + key->secret.length;
97f1a75cf072c2cab98b4bc28c4d2491cfcd3086Bob Halley isc_mem_put(listener->mctx, secret.rstart, REGION_SIZE(secret));
97f1a75cf072c2cab98b4bc28c4d2491cfcd3086Bob Halley /* We shouldn't be getting a reply. */
97f1a75cf072c2cab98b4bc28c4d2491cfcd3086Bob Halley * Limit exposure to replay attacks.
97f1a75cf072c2cab98b4bc28c4d2491cfcd3086Bob Halley if (isccc_cc_lookupuint32(_ctrl, "_tim", &sent) == ISC_R_SUCCESS) {
97f1a75cf072c2cab98b4bc28c4d2491cfcd3086Bob Halley if ((sent + CLOCKSKEW) < now || (sent - CLOCKSKEW) > now) {
97f1a75cf072c2cab98b4bc28c4d2491cfcd3086Bob Halley * Expire messages that are too old.
97f1a75cf072c2cab98b4bc28c4d2491cfcd3086Bob Halley if (isccc_cc_lookupuint32(_ctrl, "_exp", &exp) == ISC_R_SUCCESS &&
96f55bdc736f8559b3a57260db6f0e964c44070dBob Halley * Duplicate suppression (required for UDP).
96f55bdc736f8559b3a57260db6f0e964c44070dBob Halley isccc_cc_cleansymtab(listener->controls->symtab, now);
goto cleanup_request;
goto cleanup_request;
goto cleanup_request;
goto cleanup_response;
goto cleanup_response;
goto cleanup_response;
goto cleanup_response;
goto cleanup_response;
static isc_result_t
return (ISC_R_NOMEMORY);
goto cleanup;
goto cleanup;
return (ISC_R_SUCCESS);
return (result);
goto cleanup;
goto restart;
socktext);
goto restart;
goto restart;
static isc_result_t
const char *str;
return (ISC_R_NOTFOUND);
return (ISC_R_SUCCESS);
static isc_result_t
const char *str;
goto cleanup;
goto cleanup;
return (ISC_R_SUCCESS);
return (ISC_R_NOMEMORY);
isc_buffer_t b;
unsigned int algtype;
#define CHECK(x) \
result = (x); \
goto cleanup; \
static isc_result_t
unsigned int algtype;
isc_buffer_t b;
return (ISC_R_FILENOTFOUND);
goto cleanup;
goto cleanup;
return (result);
* in place of the named.conf configuration.
&new_acl);
"couldn't update ownership/permission for "
&new_acl);
#ifdef ISC_PLATFORM_HAVESYSUNH
#ifndef ISC_ALLOW_MAPPED
* Get the list of named.conf 'controls' statements.
sizeof(socktext));
socktext);
&in6addr_loopback, 0);
return (ISC_R_SUCCESS);
return (ISC_R_NOMEMORY);
return (result);
return (ISC_R_SUCCESS);