diff --git a/bin/named/controlconf.c b/bin/named/controlconf.c index 1d31f7a311..9fdf49bb7a 100644 --- a/bin/named/controlconf.c +++ b/bin/named/controlconf.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -75,8 +76,8 @@ struct controlkey { struct controlconnection { isc_socket_t * sock; isccc_ccmsg_t ccmsg; - bool ccmsg_valid; - bool sending; + bool ccmsg_valid; + bool sending; isc_timer_t * timer; isc_buffer_t * buffer; controllistener_t * listener; @@ -91,22 +92,23 @@ struct controllistener { isc_sockaddr_t address; isc_socket_t * sock; dns_acl_t * acl; - bool listening; - bool exiting; + bool listening; + bool exiting; controlkeylist_t keys; controlconnectionlist_t connections; isc_sockettype_t type; uint32_t perm; uint32_t owner; uint32_t group; - bool readonly; + bool readonly; ISC_LINK(controllistener_t) link; }; struct ns_controls { ns_server_t *server; controllistenerlist_t listeners; - bool shuttingdown; + bool shuttingdown; + isc_mutex_t symtab_lock; isccc_symtab_t *symtab; }; @@ -434,8 +436,10 @@ control_recvmessage(isc_task_t *task, isc_event_t *event) { /* * Duplicate suppression (required for UDP). */ + LOCK(&listener->controls->symtab_lock); isccc_cc_cleansymtab(listener->controls->symtab, now); result = isccc_cc_checkdup(listener->controls->symtab, request, now); + UNLOCK(&listener->controls->symtab_lock); if (result != ISC_R_SUCCESS) { if (result == ISC_R_EXISTS) result = ISCCC_R_DUPLICATE; @@ -1503,17 +1507,31 @@ ns_controls_create(ns_server_t *server, ns_controls_t **ctrlsp) { isc_result_t result; ns_controls_t *controls = isc_mem_get(mctx, sizeof(*controls)); - if (controls == NULL) + if (controls == NULL) { return (ISC_R_NOMEMORY); - controls->server = server; + } + + *controls = (ns_controls_t){ + .server = server, + }; + ISC_LIST_INIT(controls->listeners); - controls->shuttingdown = false; - controls->symtab = NULL; - result = isccc_cc_createsymtab(&controls->symtab); + + result = isc_mutex_init(&controls->symtab_lock); if (result != ISC_R_SUCCESS) { isc_mem_put(server->mctx, controls, sizeof(*controls)); return (result); } + + LOCK(&controls->symtab_lock); + result = isccc_cc_createsymtab(&controls->symtab); + UNLOCK(&controls->symtab_lock); + + if (result != ISC_R_SUCCESS) { + isc_mutex_destroy(&controls->symtab_lock); + isc_mem_put(server->mctx, controls, sizeof(*controls)); + return (result); + } *ctrlsp = controls; return (ISC_R_SUCCESS); } @@ -1524,7 +1542,10 @@ ns_controls_destroy(ns_controls_t **ctrlsp) { REQUIRE(ISC_LIST_EMPTY(controls->listeners)); + LOCK(&controls->symtab_lock); isccc_symtab_destroy(&controls->symtab); + UNLOCK(&controls->symtab_lock); + isc_mutex_destroy(&controls->symtab_lock); isc_mem_put(controls->server->mctx, controls, sizeof(*controls)); *ctrlsp = NULL; }