From 64e56a9704e7dbe7579b7f1dbc71e0bf57028975 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Sur=C3=BD?= Date: Thu, 22 Oct 2020 12:32:18 +0200 Subject: [PATCH] Postpone the isc_app_shutdown() after rndc response has been sent When `rndc stop` is received, the isc_app_shutdown() was being called before response to the rndc client has been sent; as the isc_app_shutdown() also tears down the netmgr, the message was never sent and rndc would complain about connection being interrupted in the middle of the transaction. We now postpone the shutdown after the rndc response has been sent. --- bin/named/control.c | 6 ++---- bin/named/controlconf.c | 27 +++++++++++++++++++-------- 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/bin/named/control.c b/bin/named/control.c index 3320a8fe9d..55a469925d 100644 --- a/bin/named/control.c +++ b/bin/named/control.c @@ -183,8 +183,7 @@ named_control_docommand(isccc_sexpr_t *message, bool readonly, /* Do not flush master files */ named_server_flushonshutdown(named_g_server, false); named_os_shutdownmsg(cmdline, *text); - isc_app_shutdown(); - result = ISC_R_SUCCESS; + result = ISC_R_SHUTTINGDOWN; } else if (command_compare(command, NAMED_COMMAND_STOP)) { /* * "stop" is the same as "halt" except it does @@ -201,8 +200,7 @@ named_control_docommand(isccc_sexpr_t *message, bool readonly, #endif /* ifdef HAVE_LIBSCF */ named_server_flushonshutdown(named_g_server, true); named_os_shutdownmsg(cmdline, *text); - isc_app_shutdown(); - result = ISC_R_SUCCESS; + result = ISC_R_SHUTTINGDOWN; } else if (command_compare(command, NAMED_COMMAND_ADDZONE) || command_compare(command, NAMED_COMMAND_MODZONE)) { diff --git a/bin/named/controlconf.c b/bin/named/controlconf.c index 4bfa6af4c1..871cb459b7 100644 --- a/bin/named/controlconf.c +++ b/bin/named/controlconf.c @@ -14,6 +14,7 @@ #include #include +#include #include #include #include @@ -225,6 +226,11 @@ control_senddone(isc_nmhandle_t *handle, isc_result_t result, void *arg) { conn->sending = false; + if (conn->result == ISC_R_SHUTTINGDOWN) { + isc_app_shutdown(); + goto cleanup_sendhandle; + } + if (atomic_load_acquire(&listener->controls->shuttingdown) || result == ISC_R_CANCELED) { @@ -284,12 +290,12 @@ conn_cleanup(controlconnection_t *conn) { } static void -control_respond(isc_nmhandle_t *handle, isc_result_t result, void *arg) { - controlconnection_t *conn = (controlconnection_t *)arg; +control_respond(isc_nmhandle_t *handle, controlconnection_t *conn) { controllistener_t *listener = conn->listener; isccc_sexpr_t *data = NULL; isc_buffer_t b; isc_region_t r; + isc_result_t result; result = isccc_cc_createresponse(conn->request, conn->now, conn->now + 60, &conn->response); @@ -297,17 +303,22 @@ control_respond(isc_nmhandle_t *handle, isc_result_t result, void *arg) { goto cleanup; } + if (conn->result == ISC_R_SHUTTINGDOWN) { + result = ISC_R_SUCCESS; + } else { + result = conn->result; + } + data = isccc_alist_lookup(conn->response, "_data"); if (data != NULL) { - if (isccc_cc_defineuint32(data, "result", conn->result) == NULL) - { + if (isccc_cc_defineuint32(data, "result", result) == NULL) { goto cleanup; } } - if (conn->result != ISC_R_SUCCESS) { + if (result != ISC_R_SUCCESS) { if (data != NULL) { - const char *estr = isc_result_totext(conn->result); + const char *estr = isc_result_totext(result); if (isccc_cc_definestring(data, "err", estr) == NULL) { goto cleanup; } @@ -380,7 +391,7 @@ control_command(isc_task_t *task, isc_event_t *event) { conn->result = named_control_docommand(conn->request, listener->readonly, &conn->text); - control_respond(conn->cmdhandle, conn->result, conn); + control_respond(conn->cmdhandle, conn); done: isc_event_free(&event); @@ -521,7 +532,7 @@ control_recvmessage(isc_nmhandle_t *handle, isc_result_t result, void *arg) { isc_nonce_buf(&conn->nonce, sizeof(conn->nonce)); } conn->result = ISC_R_SUCCESS; - control_respond(handle, result, conn); + control_respond(handle, conn); return; }