mirror of
https://github.com/isc-projects/bind9.git
synced 2026-05-28 04:34:54 -04:00
Merge branch '2122-netmgr-refcount-cleanup' into 'main'
Resolve "clean up netmgr reference counting" Closes #2122 See merge request isc-projects/bind9!4089
This commit is contained in:
commit
5f45cea2c5
32 changed files with 834 additions and 446 deletions
4
CHANGES
4
CHANGES
|
|
@ -1,3 +1,7 @@
|
|||
5503. [bug] Cleaned up reference counting of network manager
|
||||
handles, now using isc_nmhandle_attach() and _detach()
|
||||
instead of _ref() and _unref(). [GL #2122]
|
||||
|
||||
5502. [func] 'dig +bufsize=0' no longer disables EDNS. [GL #2054]
|
||||
|
||||
5501. [func] Log CDS/CDNSKEY publication. [GL #1748]
|
||||
|
|
|
|||
|
|
@ -67,9 +67,11 @@ struct controlkey {
|
|||
};
|
||||
|
||||
struct controlconnection {
|
||||
isc_nmhandle_t *handle;
|
||||
isc_nmhandle_t *readhandle;
|
||||
isc_nmhandle_t *sendhandle;
|
||||
isc_nmhandle_t *cmdhandle;
|
||||
isccc_ccmsg_t ccmsg;
|
||||
bool ccmsg_valid;
|
||||
bool reading;
|
||||
bool sending;
|
||||
controllistener_t *listener;
|
||||
isccc_sexpr_t *ctrl;
|
||||
|
|
@ -221,10 +223,8 @@ control_senddone(isc_nmhandle_t *handle, isc_result_t result, void *arg) {
|
|||
|
||||
conn->sending = false;
|
||||
|
||||
isc_nmhandle_unref(handle);
|
||||
|
||||
if (result == ISC_R_CANCELED) {
|
||||
return;
|
||||
if (listener->controls->shuttingdown || result == ISC_R_CANCELED) {
|
||||
goto cleanup_sendhandle;
|
||||
} else if (result != ISC_R_SUCCESS) {
|
||||
char socktext[ISC_SOCKADDR_FORMATSIZE];
|
||||
|
||||
|
|
@ -233,16 +233,31 @@ control_senddone(isc_nmhandle_t *handle, isc_result_t result, void *arg) {
|
|||
NAMED_LOGMODULE_CONTROL, ISC_LOG_WARNING,
|
||||
"error sending command response to %s: %s",
|
||||
socktext, isc_result_totext(result));
|
||||
return;
|
||||
goto cleanup_sendhandle;
|
||||
}
|
||||
|
||||
isc_nmhandle_attach(handle, &conn->readhandle);
|
||||
conn->reading = true;
|
||||
|
||||
isc_nmhandle_detach(&conn->sendhandle);
|
||||
|
||||
result = isccc_ccmsg_readmessage(&conn->ccmsg, control_recvmessage,
|
||||
conn);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
isc_nmhandle_detach(&conn->readhandle);
|
||||
conn->reading = false;
|
||||
|
||||
maybe_free_listener(listener);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
listener->listening = true;
|
||||
|
||||
return;
|
||||
|
||||
cleanup_sendhandle:
|
||||
isc_nmhandle_detach(&conn->sendhandle);
|
||||
}
|
||||
|
||||
static inline void
|
||||
|
|
@ -257,6 +272,25 @@ log_invalid(isccc_ccmsg_t *ccmsg, isc_result_t result) {
|
|||
isc_result_totext(result));
|
||||
}
|
||||
|
||||
static void
|
||||
conn_cleanup(controlconnection_t *conn) {
|
||||
controllistener_t *listener = conn->listener;
|
||||
|
||||
if (conn->response != NULL) {
|
||||
isccc_sexpr_free(&conn->response);
|
||||
}
|
||||
if (conn->request != NULL) {
|
||||
isccc_sexpr_free(&conn->request);
|
||||
}
|
||||
if (conn->secret.rstart != NULL) {
|
||||
isc_mem_put(listener->mctx, conn->secret.rstart,
|
||||
REGION_SIZE(conn->secret));
|
||||
}
|
||||
if (conn->text != NULL) {
|
||||
isc_buffer_free(&conn->text);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
control_respond(isc_nmhandle_t *handle, isc_result_t result, void *arg) {
|
||||
controlconnection_t *conn = (controlconnection_t *)arg;
|
||||
|
|
@ -324,29 +358,21 @@ control_respond(isc_nmhandle_t *handle, isc_result_t result, void *arg) {
|
|||
r.base = conn->buffer->base;
|
||||
r.length = conn->buffer->used;
|
||||
|
||||
isc_nmhandle_ref(handle);
|
||||
isc_nmhandle_attach(handle, &conn->sendhandle);
|
||||
conn->sending = true;
|
||||
result = isc_nm_send(handle, &r, control_senddone, conn);
|
||||
conn_cleanup(conn);
|
||||
|
||||
isc_nmhandle_detach(&conn->cmdhandle);
|
||||
|
||||
result = isc_nm_send(conn->sendhandle, &r, control_senddone, conn);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
isc_nmhandle_unref(handle);
|
||||
isc_nmhandle_detach(&conn->sendhandle);
|
||||
conn->sending = false;
|
||||
}
|
||||
|
||||
return;
|
||||
cleanup:
|
||||
if (conn->response != NULL) {
|
||||
isccc_sexpr_free(&conn->response);
|
||||
}
|
||||
if (conn->request != NULL) {
|
||||
isccc_sexpr_free(&conn->request);
|
||||
}
|
||||
|
||||
if (conn->secret.rstart != NULL) {
|
||||
isc_mem_put(listener->mctx, conn->secret.rstart,
|
||||
REGION_SIZE(conn->secret));
|
||||
}
|
||||
if (conn->text != NULL) {
|
||||
isc_buffer_free(&conn->text);
|
||||
}
|
||||
conn_cleanup(conn);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -356,17 +382,17 @@ control_command(isc_task_t *task, isc_event_t *event) {
|
|||
|
||||
UNUSED(task);
|
||||
|
||||
/*
|
||||
* An extra ref and two unrefs are needed here to
|
||||
* ensure the handle isn't cleaned up if we're running
|
||||
* an "rndc stop" command.
|
||||
*/
|
||||
isc_nmhandle_ref(conn->handle);
|
||||
if (listener->controls->shuttingdown) {
|
||||
isc_nmhandle_detach(&conn->cmdhandle);
|
||||
conn_cleanup(conn);
|
||||
goto done;
|
||||
}
|
||||
|
||||
conn->result = named_control_docommand(conn->request,
|
||||
listener->readonly, &conn->text);
|
||||
control_respond(conn->handle, conn->result, conn);
|
||||
isc_nmhandle_unref(conn->handle);
|
||||
isc_nmhandle_unref(conn->handle);
|
||||
control_respond(conn->cmdhandle, conn->result, conn);
|
||||
|
||||
done:
|
||||
isc_event_free(&event);
|
||||
}
|
||||
|
||||
|
|
@ -380,26 +406,21 @@ control_recvmessage(isc_nmhandle_t *handle, isc_result_t result, void *arg) {
|
|||
isccc_time_t exp;
|
||||
uint32_t nonce;
|
||||
|
||||
conn->ccmsg_valid = false;
|
||||
conn->reading = false;
|
||||
|
||||
/* Is the server shutting down? */
|
||||
if (listener->controls->shuttingdown) {
|
||||
return;
|
||||
goto cleanup_readhandle;
|
||||
}
|
||||
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
if (result == ISC_R_CANCELED) {
|
||||
/*
|
||||
* Don't bother with any more scheduled command events.
|
||||
*/
|
||||
listener->controls->shuttingdown = true;
|
||||
isc_task_purge(named_g_server->task, NULL,
|
||||
NAMED_EVENT_COMMAND, NULL);
|
||||
} else if (result != ISC_R_EOF) {
|
||||
log_invalid(&conn->ccmsg, result);
|
||||
}
|
||||
|
||||
return;
|
||||
goto cleanup_readhandle;
|
||||
}
|
||||
|
||||
for (key = ISC_LIST_HEAD(listener->keys); key != NULL;
|
||||
|
|
@ -424,7 +445,7 @@ control_recvmessage(isc_nmhandle_t *handle, isc_result_t result, void *arg) {
|
|||
REGION_SIZE(conn->secret));
|
||||
if (result != ISCCC_R_BADAUTH) {
|
||||
log_invalid(&conn->ccmsg, result);
|
||||
return;
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -496,7 +517,8 @@ control_recvmessage(isc_nmhandle_t *handle, isc_result_t result, void *arg) {
|
|||
|
||||
isc_buffer_allocate(listener->mctx, &conn->text, 2 * 2048);
|
||||
|
||||
conn->ccmsg_valid = true;
|
||||
isc_nmhandle_attach(handle, &conn->cmdhandle);
|
||||
isc_nmhandle_detach(&conn->readhandle);
|
||||
|
||||
if (conn->nonce == 0) {
|
||||
/*
|
||||
|
|
@ -513,26 +535,23 @@ control_recvmessage(isc_nmhandle_t *handle, isc_result_t result, void *arg) {
|
|||
/*
|
||||
* Trigger the command.
|
||||
*/
|
||||
isc_nmhandle_ref(handle);
|
||||
|
||||
event = isc_event_allocate(listener->mctx, conn, NAMED_EVENT_COMMAND,
|
||||
control_command, conn, sizeof(isc_event_t));
|
||||
isc_task_send(named_g_server->task, &event);
|
||||
|
||||
return;
|
||||
|
||||
cleanup:
|
||||
if (conn->response != NULL) {
|
||||
isccc_sexpr_free(&conn->response);
|
||||
}
|
||||
if (conn->request != NULL) {
|
||||
isccc_sexpr_free(&conn->request);
|
||||
}
|
||||
conn_cleanup(conn);
|
||||
|
||||
if (conn->secret.rstart != NULL) {
|
||||
isc_mem_put(listener->mctx, conn->secret.rstart,
|
||||
REGION_SIZE(conn->secret));
|
||||
}
|
||||
if (conn->text != NULL) {
|
||||
isc_buffer_free(&conn->text);
|
||||
cleanup_readhandle:
|
||||
/*
|
||||
* readhandle could be NULL if we're shutting down,
|
||||
* but if not we need to detach it.
|
||||
*/
|
||||
if (conn->readhandle != NULL) {
|
||||
isc_nmhandle_detach(&conn->readhandle);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -545,7 +564,7 @@ conn_reset(void *arg) {
|
|||
isc_buffer_free(&conn->buffer);
|
||||
}
|
||||
|
||||
if (conn->ccmsg_valid) {
|
||||
if (conn->reading) {
|
||||
isccc_ccmsg_cancelread(&conn->ccmsg);
|
||||
return;
|
||||
}
|
||||
|
|
@ -583,18 +602,11 @@ newconnection(controllistener_t *listener, isc_nmhandle_t *handle) {
|
|||
isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
|
||||
NAMED_LOGMODULE_CONTROL, ISC_LOG_DEBUG(3),
|
||||
"allocate new control connection");
|
||||
*conn = (controlconnection_t){ .handle = NULL };
|
||||
}
|
||||
|
||||
if (conn->handle == NULL) {
|
||||
isc_nmhandle_setdata(handle, conn, conn_reset, conn_put);
|
||||
} else {
|
||||
INSIST(conn->handle == handle);
|
||||
}
|
||||
|
||||
*conn = (controlconnection_t){ .handle = handle,
|
||||
.listener = listener,
|
||||
.ccmsg_valid = true,
|
||||
*conn = (controlconnection_t){ .listener = listener,
|
||||
.reading = false,
|
||||
.alg = DST_ALG_UNKNOWN };
|
||||
|
||||
isccc_ccmsg_init(listener->mctx, handle, &conn->ccmsg);
|
||||
|
|
@ -604,9 +616,14 @@ newconnection(controllistener_t *listener, isc_nmhandle_t *handle) {
|
|||
|
||||
ISC_LINK_INIT(conn, link);
|
||||
|
||||
isc_nmhandle_attach(handle, &conn->readhandle);
|
||||
conn->reading = true;
|
||||
|
||||
result = isccc_ccmsg_readmessage(&conn->ccmsg, control_recvmessage,
|
||||
conn);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
isc_nmhandle_detach(&conn->readhandle);
|
||||
conn->reading = false;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -14866,14 +14866,15 @@ named_server_zonestatus(named_server_t *server, isc_lex_t *lex,
|
|||
|
||||
/* Serial number */
|
||||
result = dns_zone_getserial(mayberaw, &serial);
|
||||
/* XXXWPK TODO this is to mirror old behavior with dns_zone_getserial */
|
||||
|
||||
/* This is to mirror old behavior with dns_zone_getserial */
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
serial = 0;
|
||||
}
|
||||
|
||||
snprintf(serbuf, sizeof(serbuf), "%u", serial);
|
||||
if (hasraw) {
|
||||
result = dns_zone_getserial(zone, &signed_serial);
|
||||
/* XXXWPK TODO ut supra */
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
serial = 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
#include <isc/log.h>
|
||||
#include <isc/mem.h>
|
||||
#include <isc/net.h>
|
||||
#include <isc/netmgr.h>
|
||||
#include <isc/print.h>
|
||||
#include <isc/random.h>
|
||||
#include <isc/refcount.h>
|
||||
|
|
@ -89,6 +90,8 @@ static uint32_t serial;
|
|||
static bool quiet = false;
|
||||
static bool showresult = false;
|
||||
static bool shuttingdown = false;
|
||||
static isc_nmhandle_t *recvdone_handle = NULL;
|
||||
static isc_nmhandle_t *recvnonce_handle = NULL;
|
||||
|
||||
static void
|
||||
rndc_startconnect(isc_sockaddr_t *addr);
|
||||
|
|
@ -288,19 +291,21 @@ get_addresses(const char *host, in_port_t port) {
|
|||
|
||||
static void
|
||||
rndc_senddone(isc_nmhandle_t *handle, isc_result_t result, void *arg) {
|
||||
UNUSED(arg);
|
||||
isc_nmhandle_t *sendhandle = (isc_nmhandle_t *)arg;
|
||||
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
fatal("send failed: %s", isc_result_totext(result));
|
||||
}
|
||||
|
||||
REQUIRE(sendhandle == handle);
|
||||
isc_nmhandle_detach(&sendhandle);
|
||||
|
||||
if (atomic_fetch_sub_release(&sends, 1) == 1 &&
|
||||
atomic_load_acquire(&recvs) == 0)
|
||||
{
|
||||
shuttingdown = true;
|
||||
isc_task_shutdown(rndc_task);
|
||||
isc_app_shutdown();
|
||||
isc_nmhandle_unref(handle);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -315,10 +320,12 @@ rndc_recvdone(isc_nmhandle_t *handle, isc_result_t result, void *arg) {
|
|||
|
||||
REQUIRE(ccmsg != NULL);
|
||||
|
||||
atomic_fetch_sub_release(&recvs, 1);
|
||||
|
||||
if (shuttingdown && (result == ISC_R_EOF || result == ISC_R_CANCELED)) {
|
||||
isc_nmhandle_unref(handle);
|
||||
atomic_fetch_sub_release(&recvs, 1);
|
||||
if (handle != NULL) {
|
||||
REQUIRE(recvdone_handle == handle);
|
||||
isc_nmhandle_detach(&recvdone_handle);
|
||||
}
|
||||
return;
|
||||
} else if (result == ISC_R_EOF) {
|
||||
fatal("connection to remote host closed.\n"
|
||||
|
|
@ -376,10 +383,13 @@ rndc_recvdone(isc_nmhandle_t *handle, isc_result_t result, void *arg) {
|
|||
|
||||
isccc_sexpr_free(&response);
|
||||
|
||||
REQUIRE(recvdone_handle == handle);
|
||||
isc_nmhandle_detach(&recvdone_handle);
|
||||
|
||||
if (atomic_load_acquire(&sends) == 0 &&
|
||||
atomic_load_acquire(&recvs) == 0) {
|
||||
atomic_fetch_sub_release(&recvs, 1) == 1)
|
||||
{
|
||||
shuttingdown = true;
|
||||
isc_nmhandle_unref(handle);
|
||||
isc_task_shutdown(rndc_task);
|
||||
isc_app_shutdown();
|
||||
}
|
||||
|
|
@ -400,10 +410,12 @@ rndc_recvnonce(isc_nmhandle_t *handle, isc_result_t result, void *arg) {
|
|||
|
||||
REQUIRE(ccmsg != NULL);
|
||||
|
||||
atomic_fetch_sub_release(&recvs, 1);
|
||||
|
||||
if (shuttingdown && result == ISC_R_EOF) {
|
||||
isc_nmhandle_unref(handle);
|
||||
atomic_fetch_sub_release(&recvs, 1);
|
||||
if (handle != NULL) {
|
||||
REQUIRE(recvnonce_handle == handle);
|
||||
isc_nmhandle_detach(&recvnonce_handle);
|
||||
}
|
||||
return;
|
||||
} else if (result == ISC_R_EOF) {
|
||||
fatal("connection to remote host closed.\n"
|
||||
|
|
@ -467,12 +479,19 @@ rndc_recvnonce(isc_nmhandle_t *handle, isc_result_t result, void *arg) {
|
|||
r.base = databuf->base;
|
||||
r.length = databuf->used;
|
||||
|
||||
isc_nmhandle_attach(handle, &recvdone_handle);
|
||||
atomic_fetch_add_relaxed(&recvs, 1);
|
||||
DO("schedule recv",
|
||||
isccc_ccmsg_readmessage(ccmsg, rndc_recvdone, ccmsg));
|
||||
atomic_fetch_add_relaxed(&recvs, 1);
|
||||
|
||||
DO("send message", isc_nm_send(handle, &r, rndc_senddone, NULL));
|
||||
isc_nmhandle_t *sendhandle = NULL;
|
||||
isc_nmhandle_attach(handle, &sendhandle);
|
||||
atomic_fetch_add_relaxed(&sends, 1);
|
||||
DO("send message", isc_nm_send(handle, &r, rndc_senddone, sendhandle));
|
||||
|
||||
REQUIRE(recvnonce_handle == handle);
|
||||
isc_nmhandle_detach(&recvnonce_handle);
|
||||
atomic_fetch_sub_release(&recvs, 1);
|
||||
|
||||
isccc_sexpr_free(&response);
|
||||
isccc_sexpr_free(&request);
|
||||
|
|
@ -488,12 +507,12 @@ rndc_connected(isc_nmhandle_t *handle, isc_result_t result, void *arg) {
|
|||
isccc_time_t now;
|
||||
isc_region_t r;
|
||||
isc_buffer_t b;
|
||||
isc_nmhandle_t *connhandle = NULL;
|
||||
|
||||
REQUIRE(ccmsg != NULL);
|
||||
|
||||
atomic_fetch_sub_release(&connects, 1);
|
||||
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
atomic_fetch_sub_release(&connects, 1);
|
||||
isc_sockaddr_format(&serveraddrs[currentaddr], socktext,
|
||||
sizeof(socktext));
|
||||
if (++currentaddr < nserveraddrs) {
|
||||
|
|
@ -507,6 +526,8 @@ rndc_connected(isc_nmhandle_t *handle, isc_result_t result, void *arg) {
|
|||
isc_result_totext(result));
|
||||
}
|
||||
|
||||
isc_nmhandle_attach(handle, &connhandle);
|
||||
|
||||
isc_stdtime_get(&now);
|
||||
DO("create message", isccc_cc_createmessage(1, NULL, NULL, ++serial,
|
||||
now, now + 60, &request));
|
||||
|
|
@ -534,14 +555,18 @@ rndc_connected(isc_nmhandle_t *handle, isc_result_t result, void *arg) {
|
|||
isccc_ccmsg_init(rndc_mctx, handle, ccmsg);
|
||||
isccc_ccmsg_setmaxsize(ccmsg, 1024 * 1024);
|
||||
|
||||
isc_nmhandle_ref(handle);
|
||||
|
||||
isc_nmhandle_attach(handle, &recvnonce_handle);
|
||||
atomic_fetch_add_relaxed(&recvs, 1);
|
||||
DO("schedule recv",
|
||||
isccc_ccmsg_readmessage(ccmsg, rndc_recvnonce, ccmsg));
|
||||
atomic_fetch_add_relaxed(&recvs, 1);
|
||||
|
||||
DO("send message", isc_nm_send(handle, &r, rndc_senddone, NULL));
|
||||
isc_nmhandle_t *sendhandle = NULL;
|
||||
isc_nmhandle_attach(handle, &sendhandle);
|
||||
atomic_fetch_add_relaxed(&sends, 1);
|
||||
DO("send message", isc_nm_send(handle, &r, rndc_senddone, sendhandle));
|
||||
|
||||
isc_nmhandle_detach(&connhandle);
|
||||
atomic_fetch_sub_release(&connects, 1);
|
||||
|
||||
isccc_sexpr_free(&request);
|
||||
}
|
||||
|
|
@ -573,11 +598,11 @@ rndc_startconnect(isc_sockaddr_t *addr) {
|
|||
ISC_UNREACHABLE();
|
||||
}
|
||||
|
||||
atomic_fetch_add_relaxed(&connects, 1);
|
||||
DO("create connection",
|
||||
isc_nm_tcpconnect(netmgr, (isc_nmiface_t *)local,
|
||||
(isc_nmiface_t *)addr, rndc_connected, &rndc_ccmsg,
|
||||
0));
|
||||
atomic_fetch_add_relaxed(&connects, 1);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -1009,7 +1034,7 @@ main(int argc, char **argv) {
|
|||
isc_mem_create(&rndc_mctx);
|
||||
netmgr = isc_nm_start(rndc_mctx, 1);
|
||||
DO("create task manager",
|
||||
isc_taskmgr_create(rndc_mctx, 1, 0, NULL, &taskmgr));
|
||||
isc_taskmgr_create(rndc_mctx, 1, 0, netmgr, &taskmgr));
|
||||
DO("create task", isc_task_create(taskmgr, 0, &rndc_task));
|
||||
isc_log_create(rndc_mctx, &log, &logconfig);
|
||||
isc_log_setcontext(log);
|
||||
|
|
@ -1068,16 +1093,18 @@ main(int argc, char **argv) {
|
|||
isc_task_detach(&rndc_task);
|
||||
isc_taskmgr_destroy(&taskmgr);
|
||||
|
||||
isc_nm_destroy(&netmgr);
|
||||
isc_nm_closedown(netmgr);
|
||||
|
||||
/*
|
||||
* Note: when TCP connections are shut down, there will be a final
|
||||
* call to the isccc callback routine with &rndc_ccmsg as its
|
||||
* argument. We therefore need to delay invalidating it until
|
||||
* after the netmgr is destroyed.
|
||||
* after the netmgr is closed down.
|
||||
*/
|
||||
isccc_ccmsg_invalidate(&rndc_ccmsg);
|
||||
|
||||
isc_nm_destroy(&netmgr);
|
||||
|
||||
isc_log_destroy(&log);
|
||||
isc_log_setcontext(NULL);
|
||||
|
||||
|
|
|
|||
|
|
@ -26,12 +26,10 @@ $DIFF ref output > /dev/null && { ret=1 ; echo_i "diff out of order failed"; }
|
|||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||
status=`expr $status + $ret`
|
||||
|
||||
# flush resolver so queries will be from others again
|
||||
$RNDCCMD 10.53.0.4 flush
|
||||
sleep 1
|
||||
|
||||
echo_i "check pipelined TCP queries using mdig"
|
||||
ret=0
|
||||
$RNDCCMD 10.53.0.4 flush
|
||||
sleep 1
|
||||
$MDIG $MDIGOPTS +noall +answer +vc -f input -b 10.53.0.4 @10.53.0.4 > raw.mdig
|
||||
awk '{ print $1 " " $5 }' < raw.mdig > output.mdig
|
||||
sort < output.mdig > output-sorted.mdig
|
||||
|
|
@ -42,6 +40,8 @@ status=`expr $status + $ret`
|
|||
|
||||
echo_i "check keep-response-order"
|
||||
ret=0
|
||||
$RNDCCMD 10.53.0.4 flush
|
||||
sleep 1
|
||||
$PIPEQUERIES -p ${PORT} ++ < inputb > rawb || ret=1
|
||||
awk '{ print $1 " " $5 }' < rawb > outputb
|
||||
$DIFF refb outputb || ret=1
|
||||
|
|
@ -50,6 +50,8 @@ status=`expr $status + $ret`
|
|||
|
||||
echo_i "check keep-response-order using mdig"
|
||||
ret=0
|
||||
$RNDCCMD 10.53.0.4 flush
|
||||
sleep 1
|
||||
$MDIG $MDIGOPTS +noall +answer +vc -f inputb -b 10.53.0.7 @10.53.0.4 > rawb.mdig
|
||||
awk '{ print $1 " " $5 }' < rawb.mdig > outputb.mdig
|
||||
$DIFF refb outputb.mdig || ret=1
|
||||
|
|
@ -58,6 +60,8 @@ status=`expr $status + $ret`
|
|||
|
||||
echo_i "check mdig -4 -6"
|
||||
ret=0
|
||||
$RNDCCMD 10.53.0.4 flush
|
||||
sleep 1
|
||||
$MDIG $MDIGOPTS -4 -6 -f input @10.53.0.4 > output46.mdig 2>&1 && ret=1
|
||||
grep "only one of -4 and -6 allowed" output46.mdig > /dev/null || ret=1
|
||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ options {
|
|||
listen-on { 10.53.0.4; };
|
||||
listen-on-v6 { none; };
|
||||
recursion yes;
|
||||
dnssec-validation yes;
|
||||
};
|
||||
|
||||
view normal {
|
||||
|
|
|
|||
|
|
@ -8,11 +8,10 @@
|
|||
# information regarding copyright ownership.
|
||||
|
||||
rm -f ns*/*.jnl
|
||||
rm -f ns*/named.conf
|
||||
rm -f ns*/named.lock
|
||||
rm -f ns*/named.memstats
|
||||
rm -f ns*/named.run
|
||||
rm -f ns*/rpz*.txt
|
||||
rm -f resolver/named.conf
|
||||
rm -f */named.conf
|
||||
rm -f */named.run
|
||||
rm -rf __pycache__
|
||||
rm -f *.status
|
||||
|
|
|
|||
|
|
@ -1,3 +1,11 @@
|
|||
logging {
|
||||
channel basic {
|
||||
file "named.run";
|
||||
severity debug 999;
|
||||
print-time yes;
|
||||
};
|
||||
category default { basic; };
|
||||
};
|
||||
key rndc_key {
|
||||
secret "1234abcd8765";
|
||||
algorithm hmac-sha256;
|
||||
|
|
|
|||
|
|
@ -1320,11 +1320,11 @@ AM_CONDITIONAL([HAVE_CMOCKA], [test "$with_cmocka" = "yes"])
|
|||
LD_WRAP_TESTS=false
|
||||
AC_MSG_CHECKING([for linker support for --wrap option])
|
||||
AX_SAVE_FLAGS([wrap])
|
||||
LDFLAGS="-Wl,-wrap,exit"
|
||||
LDFLAGS="-Wl,--wrap,exit"
|
||||
AC_RUN_IFELSE(
|
||||
[AC_LANG_PROGRAM([[#include <stdlib.h>
|
||||
void __real_exit (int status);
|
||||
void __wrap_exit (int status) { __real_exit (status); }
|
||||
void __wrap_exit (int status) { __real_exit (0); }
|
||||
]],
|
||||
[[exit (1);]])],
|
||||
[LD_WRAP_TESTS=true
|
||||
|
|
|
|||
|
|
@ -75,7 +75,10 @@ struct isc_httpd {
|
|||
isc_httpdmgr_t *mgr; /*%< our parent */
|
||||
ISC_LINK(isc_httpd_t) link;
|
||||
|
||||
isc_nmhandle_t *handle;
|
||||
isc_nmhandle_t *handle; /* Permanent pointer to handle */
|
||||
isc_nmhandle_t *readhandle; /* Waiting for a read callback */
|
||||
isc_nmhandle_t *sendhandle; /* Waiting for a send callback */
|
||||
|
||||
state_t state;
|
||||
int flags;
|
||||
|
||||
|
|
@ -636,6 +639,7 @@ new_httpd(isc_httpdmgr_t *httpdmgr, isc_nmhandle_t *handle) {
|
|||
|
||||
if (httpd->handle == NULL) {
|
||||
isc_nmhandle_setdata(handle, httpd, httpd_reset, httpd_put);
|
||||
httpd->handle = handle;
|
||||
} else {
|
||||
INSIST(httpd->handle == handle);
|
||||
}
|
||||
|
|
@ -663,10 +667,10 @@ new_httpd(isc_httpdmgr_t *httpdmgr, isc_nmhandle_t *handle) {
|
|||
ISC_LIST_APPEND(httpdmgr->running, httpd, link);
|
||||
UNLOCK(&httpdmgr->lock);
|
||||
|
||||
isc_nmhandle_ref(handle);
|
||||
isc_nmhandle_attach(handle, &httpd->readhandle);
|
||||
result = isc_nm_read(handle, httpd_request, httpdmgr);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
isc_nmhandle_unref(handle);
|
||||
isc_nmhandle_detach(&httpd->readhandle);
|
||||
}
|
||||
|
||||
return (result);
|
||||
|
|
@ -849,7 +853,7 @@ httpd_request(isc_nmhandle_t *handle, isc_result_t eresult,
|
|||
REQUIRE(httpd->state == RECV);
|
||||
|
||||
if (eresult != ISC_R_SUCCESS) {
|
||||
goto done;
|
||||
goto cleanup_readhandle;
|
||||
}
|
||||
|
||||
result = process_request(httpd, region);
|
||||
|
|
@ -858,9 +862,9 @@ httpd_request(isc_nmhandle_t *handle, isc_result_t eresult,
|
|||
/* don't unref, continue reading */
|
||||
return;
|
||||
}
|
||||
goto done;
|
||||
goto cleanup_readhandle;
|
||||
} else if (result != ISC_R_SUCCESS) {
|
||||
goto done;
|
||||
goto cleanup_readhandle;
|
||||
}
|
||||
|
||||
isc_buffer_initnull(&httpd->bodybuffer);
|
||||
|
|
@ -958,18 +962,18 @@ httpd_request(isc_nmhandle_t *handle, isc_result_t eresult,
|
|||
isc_nm_pauseread(handle);
|
||||
httpd->state = SEND;
|
||||
|
||||
isc_nmhandle_ref(handle);
|
||||
isc_nmhandle_attach(handle, &httpd->sendhandle);
|
||||
result = isc_nm_send(handle, &r, httpd_senddone, httpd);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
isc_nm_resumeread(handle);
|
||||
isc_nmhandle_unref(handle);
|
||||
isc_nmhandle_detach(&httpd->sendhandle);
|
||||
|
||||
httpd->state = RECV;
|
||||
isc_nm_resumeread(handle);
|
||||
}
|
||||
|
||||
return;
|
||||
done:
|
||||
isc_nmhandle_unref(handle);
|
||||
cleanup_readhandle:
|
||||
isc_nmhandle_detach(&httpd->readhandle);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -990,7 +994,7 @@ isc_httpdmgr_shutdown(isc_httpdmgr_t **httpdmgrp) {
|
|||
|
||||
httpd = ISC_LIST_HEAD(httpdmgr->running);
|
||||
while (httpd != NULL) {
|
||||
isc_nmhandle_unref(httpd->handle);
|
||||
isc_nm_cancelread(httpd->readhandle);
|
||||
httpd = ISC_LIST_NEXT(httpd, link);
|
||||
}
|
||||
UNLOCK(&httpdmgr->lock);
|
||||
|
|
@ -1137,9 +1141,10 @@ httpd_senddone(isc_nmhandle_t *handle, isc_result_t result, void *arg) {
|
|||
return;
|
||||
}
|
||||
|
||||
isc_nmhandle_detach(&httpd->sendhandle);
|
||||
|
||||
httpd->state = RECV;
|
||||
isc_nm_resumeread(handle);
|
||||
isc_nmhandle_unref(handle);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
|
|
|
|||
|
|
@ -110,9 +110,9 @@ isc_nmsocket_close(isc_nmsocket_t **sockp);
|
|||
*/
|
||||
|
||||
void
|
||||
isc_nmhandle_ref(isc_nmhandle_t *handle);
|
||||
isc_nmhandle_attach(isc_nmhandle_t *handle, isc_nmhandle_t **dest);
|
||||
void
|
||||
isc_nmhandle_unref(isc_nmhandle_t *handle);
|
||||
isc_nmhandle_detach(isc_nmhandle_t **handlep);
|
||||
/*%<
|
||||
* Increment/decrement the reference counter in a netmgr handle,
|
||||
* but (unlike the attach/detach functions) do not change the pointer
|
||||
|
|
@ -176,8 +176,8 @@ isc_nm_listenudp(isc_nm_t *mgr, isc_nmiface_t *iface, isc_nm_recv_cb_t cb,
|
|||
* as its argument.
|
||||
*
|
||||
* When handles are allocated for the socket, 'extrasize' additional bytes
|
||||
* will be allocated along with the handle for an associated object
|
||||
* (typically ns_client).
|
||||
* can be allocated along with the handle for an associated object, which
|
||||
* can then be freed automatically when the handle is destroyed.
|
||||
*/
|
||||
|
||||
void
|
||||
|
|
@ -196,12 +196,17 @@ isc_nm_pause(isc_nm_t *mgr);
|
|||
void
|
||||
isc_nm_resume(isc_nm_t *mgr);
|
||||
/*%<
|
||||
* Resume paused processing. It will return immediately
|
||||
* after signalling workers to resume.
|
||||
* Resume paused processing. It will return immediately after signalling
|
||||
* workers to resume.
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
isc_nm_read(isc_nmhandle_t *handle, isc_nm_recv_cb_t cb, void *cbarg);
|
||||
/*
|
||||
* Begin (or continue) reading on the socket associated with 'handle', and
|
||||
* update its recv callback to 'cb', which will be called as soon as there
|
||||
* is data to process.
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
isc_nm_pauseread(isc_nmhandle_t *handle);
|
||||
|
|
|
|||
|
|
@ -49,6 +49,20 @@
|
|||
#define ISC_NETMGR_RECVBUF_SIZE (65536)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Define NETMGR_TRACE to activate tracing of handles and sockets.
|
||||
* This will impair performance but enables us to quickly determine,
|
||||
* if netmgr resources haven't been cleaned up on shutdown, which ones
|
||||
* are still in use.
|
||||
*/
|
||||
#ifdef NETMGR_TRACE
|
||||
#define TRACE_SIZE 8
|
||||
|
||||
void
|
||||
isc__nm_dump_active(isc_nm_t *nm);
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Single network event loop worker.
|
||||
*/
|
||||
|
|
@ -104,6 +118,11 @@ struct isc_nmhandle {
|
|||
isc_sockaddr_t local;
|
||||
isc_nm_opaquecb_t doreset; /* reset extra callback, external */
|
||||
isc_nm_opaquecb_t dofree; /* free extra callback, external */
|
||||
#ifdef NETMGR_TRACE
|
||||
void *backtrace[TRACE_SIZE];
|
||||
int backtrace_size;
|
||||
LINK(isc_nmhandle_t) active_link;
|
||||
#endif
|
||||
void *opaque;
|
||||
char extra[];
|
||||
};
|
||||
|
|
@ -117,12 +136,10 @@ struct isc_nmiface {
|
|||
|
||||
typedef enum isc__netievent_type {
|
||||
netievent_udpsend,
|
||||
netievent_udprecv,
|
||||
netievent_udpstop,
|
||||
|
||||
netievent_tcpconnect,
|
||||
netievent_tcpsend,
|
||||
netievent_tcprecv,
|
||||
netievent_tcpstartread,
|
||||
netievent_tcppauseread,
|
||||
netievent_tcpchildaccept,
|
||||
|
|
@ -130,8 +147,8 @@ typedef enum isc__netievent_type {
|
|||
netievent_tcpstop,
|
||||
netievent_tcpclose,
|
||||
|
||||
netievent_tcpdnsclose,
|
||||
netievent_tcpdnssend,
|
||||
netievent_tcpdnsclose,
|
||||
|
||||
netievent_closecb,
|
||||
netievent_shutdown,
|
||||
|
|
@ -146,23 +163,8 @@ typedef enum isc__netievent_type {
|
|||
netievent_tcplisten,
|
||||
} isc__netievent_type;
|
||||
|
||||
/*
|
||||
* We have to split it because we can read and write on a socket
|
||||
* simultaneously.
|
||||
*/
|
||||
typedef union {
|
||||
isc_nm_recv_cb_t recv;
|
||||
isc_nm_accept_cb_t accept;
|
||||
} isc__nm_readcb_t;
|
||||
|
||||
typedef union {
|
||||
isc_nm_cb_t send;
|
||||
isc_nm_cb_t connect;
|
||||
} isc__nm_writecb_t;
|
||||
|
||||
typedef union {
|
||||
isc_nm_recv_cb_t recv;
|
||||
isc_nm_accept_cb_t accept;
|
||||
isc_nm_cb_t send;
|
||||
isc_nm_cb_t connect;
|
||||
} isc__nm_cb_t;
|
||||
|
|
@ -209,10 +211,10 @@ typedef isc__netievent__socket_t isc__netievent_udplisten_t;
|
|||
typedef isc__netievent__socket_t isc__netievent_udpstop_t;
|
||||
typedef isc__netievent__socket_t isc__netievent_tcpstop_t;
|
||||
typedef isc__netievent__socket_t isc__netievent_tcpclose_t;
|
||||
typedef isc__netievent__socket_t isc__netievent_tcpdnsclose_t;
|
||||
typedef isc__netievent__socket_t isc__netievent_startread_t;
|
||||
typedef isc__netievent__socket_t isc__netievent_pauseread_t;
|
||||
typedef isc__netievent__socket_t isc__netievent_closecb_t;
|
||||
typedef isc__netievent__socket_t isc__netievent_tcpdnsclose_t;
|
||||
|
||||
typedef struct isc__netievent__socket_req {
|
||||
isc__netievent_type type;
|
||||
|
|
@ -325,6 +327,10 @@ struct isc_nm {
|
|||
uint32_t idle;
|
||||
uint32_t keepalive;
|
||||
uint32_t advertised;
|
||||
|
||||
#ifdef NETMGR_TRACE
|
||||
ISC_LIST(isc_nmsocket_t) active_sockets;
|
||||
#endif
|
||||
};
|
||||
|
||||
typedef enum isc_nmsocket_type {
|
||||
|
|
@ -333,7 +339,7 @@ typedef enum isc_nmsocket_type {
|
|||
isc_nm_tcpsocket,
|
||||
isc_nm_tcplistener,
|
||||
isc_nm_tcpdnslistener,
|
||||
isc_nm_tcpdnssocket
|
||||
isc_nm_tcpdnssocket,
|
||||
} isc_nmsocket_type;
|
||||
|
||||
/*%
|
||||
|
|
@ -403,7 +409,7 @@ struct isc_nmsocket {
|
|||
isc_nmsocket_t *children;
|
||||
int nchildren;
|
||||
isc_nmiface_t *iface;
|
||||
isc_nmhandle_t *tcphandle;
|
||||
isc_nmhandle_t *statichandle;
|
||||
isc_nmhandle_t *outerhandle;
|
||||
|
||||
/*% Extra data allocated at the end of each isc_nmhandle_t */
|
||||
|
|
@ -445,7 +451,12 @@ struct isc_nmsocket {
|
|||
isc_refcount_t references;
|
||||
|
||||
/*%
|
||||
* TCPDNS socket has been set not to pipeliine.
|
||||
* Established an outgoing connection, as client not server.
|
||||
*/
|
||||
atomic_bool client;
|
||||
|
||||
/*%
|
||||
* TCPDNS socket has been set not to pipeline.
|
||||
*/
|
||||
atomic_bool sequential;
|
||||
|
||||
|
|
@ -531,11 +542,17 @@ struct isc_nmsocket {
|
|||
*/
|
||||
isc_nm_opaquecb_t closehandle_cb;
|
||||
|
||||
isc__nm_readcb_t rcb;
|
||||
void *rcbarg;
|
||||
isc_nm_recv_cb_t recv_cb;
|
||||
void *recv_cbarg;
|
||||
|
||||
isc__nm_cb_t accept_cb;
|
||||
isc_nm_accept_cb_t accept_cb;
|
||||
void *accept_cbarg;
|
||||
#ifdef NETMGR_TRACE
|
||||
void *backtrace[TRACE_SIZE];
|
||||
int backtrace_size;
|
||||
LINK(isc_nmsocket_t) active_link;
|
||||
ISC_LIST(isc_nmhandle_t) active_handles;
|
||||
#endif
|
||||
};
|
||||
|
||||
bool
|
||||
|
|
@ -686,6 +703,9 @@ isc__nm_tcp_send(isc_nmhandle_t *handle, isc_region_t *region, isc_nm_cb_t cb,
|
|||
|
||||
isc_result_t
|
||||
isc__nm_tcp_read(isc_nmhandle_t *handle, isc_nm_recv_cb_t cb, void *cbarg);
|
||||
/*
|
||||
* Back-end implementation of isc_nm_read() for TCP handles.
|
||||
*/
|
||||
|
||||
void
|
||||
isc__nm_tcp_close(isc_nmsocket_t *sock);
|
||||
|
|
@ -713,9 +733,9 @@ isc__nm_tcp_shutdown(isc_nmsocket_t *sock);
|
|||
*/
|
||||
|
||||
void
|
||||
isc__nm_tcp_cancelread(isc_nmsocket_t *sock);
|
||||
isc__nm_tcp_cancelread(isc_nmhandle_t *handle);
|
||||
/*%<
|
||||
* Stop reading on a connected socket.
|
||||
* Stop reading on a connected TCP handle.
|
||||
*/
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -33,6 +33,10 @@
|
|||
#include "netmgr-int.h"
|
||||
#include "uv-compat.h"
|
||||
|
||||
#ifdef NETMGR_TRACE
|
||||
#include <execinfo.h>
|
||||
#endif
|
||||
|
||||
/*%
|
||||
* How many isc_nmhandles and isc_nm_uvreqs will we be
|
||||
* caching for reuse in a socket.
|
||||
|
|
@ -157,6 +161,10 @@ isc_nm_start(isc_mem_t *mctx, uint32_t workers) {
|
|||
atomic_init(&mgr->paused, false);
|
||||
atomic_init(&mgr->interlocked, false);
|
||||
|
||||
#ifdef NETMGR_TRACE
|
||||
ISC_LIST_INIT(mgr->active_sockets);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Default TCP timeout values.
|
||||
* May be updated by isc_nm_tcptimeouts().
|
||||
|
|
@ -393,6 +401,7 @@ isc_nm_closedown(isc_nm_t *mgr) {
|
|||
void
|
||||
isc_nm_destroy(isc_nm_t **mgr0) {
|
||||
isc_nm_t *mgr = NULL;
|
||||
int counter = 0;
|
||||
|
||||
REQUIRE(mgr0 != NULL);
|
||||
REQUIRE(VALID_NM(*mgr0));
|
||||
|
|
@ -407,7 +416,7 @@ isc_nm_destroy(isc_nm_t **mgr0) {
|
|||
/*
|
||||
* Wait for the manager to be dereferenced elsewhere.
|
||||
*/
|
||||
while (isc_refcount_current(&mgr->references) > 1) {
|
||||
while (isc_refcount_current(&mgr->references) > 1 && counter++ < 1000) {
|
||||
/*
|
||||
* Sometimes libuv gets stuck, pausing and unpausing
|
||||
* netmgr goes over all events in async queue for all
|
||||
|
|
@ -422,6 +431,13 @@ isc_nm_destroy(isc_nm_t **mgr0) {
|
|||
usleep(10000);
|
||||
#endif /* ifdef WIN32 */
|
||||
}
|
||||
#ifdef NETMGR_TRACE
|
||||
if (!ISC_LIST_EMPTY(mgr->active_sockets)) {
|
||||
isc__nm_dump_active(mgr);
|
||||
INSIST(ISC_LIST_EMPTY(mgr->active_sockets));
|
||||
}
|
||||
#endif
|
||||
INSIST(counter <= 1000);
|
||||
|
||||
/*
|
||||
* Detach final reference.
|
||||
|
|
@ -591,6 +607,7 @@ process_queue(isc__networker_t *worker, isc_queue_t *queue) {
|
|||
uv_stop(&worker->loop);
|
||||
isc_mempool_put(worker->mgr->evpool, ievent);
|
||||
return;
|
||||
|
||||
case netievent_udplisten:
|
||||
isc__nm_async_udplisten(worker, ievent);
|
||||
break;
|
||||
|
|
@ -600,6 +617,7 @@ process_queue(isc__networker_t *worker, isc_queue_t *queue) {
|
|||
case netievent_udpsend:
|
||||
isc__nm_async_udpsend(worker, ievent);
|
||||
break;
|
||||
|
||||
case netievent_tcpconnect:
|
||||
isc__nm_async_tcpconnect(worker, ievent);
|
||||
break;
|
||||
|
|
@ -630,9 +648,11 @@ process_queue(isc__networker_t *worker, isc_queue_t *queue) {
|
|||
case netievent_tcpclose:
|
||||
isc__nm_async_tcpclose(worker, ievent);
|
||||
break;
|
||||
|
||||
case netievent_tcpdnsclose:
|
||||
isc__nm_async_tcpdnsclose(worker, ievent);
|
||||
break;
|
||||
|
||||
case netievent_closecb:
|
||||
isc__nm_async_closecb(worker, ievent);
|
||||
break;
|
||||
|
|
@ -739,11 +759,10 @@ nmsocket_cleanup(isc_nmsocket_t *sock, bool dofree) {
|
|||
isc__nm_decstats(sock->mgr, sock->statsindex[STATID_ACTIVE]);
|
||||
}
|
||||
|
||||
sock->tcphandle = NULL;
|
||||
sock->statichandle = NULL;
|
||||
|
||||
if (sock->outerhandle != NULL) {
|
||||
isc_nmhandle_unref(sock->outerhandle);
|
||||
sock->outerhandle = NULL;
|
||||
isc_nmhandle_detach(&sock->outerhandle);
|
||||
}
|
||||
|
||||
if (sock->outer != NULL) {
|
||||
|
|
@ -786,7 +805,11 @@ nmsocket_cleanup(isc_nmsocket_t *sock, bool dofree) {
|
|||
isc_mem_free(sock->mgr->mctx, sock->ah_handles);
|
||||
isc_mutex_destroy(&sock->lock);
|
||||
isc_condition_destroy(&sock->cond);
|
||||
|
||||
#ifdef NETMGR_TRACE
|
||||
LOCK(&sock->mgr->lock);
|
||||
ISC_LIST_UNLINK(sock->mgr->active_sockets, sock, active_link);
|
||||
UNLOCK(&sock->mgr->lock);
|
||||
#endif
|
||||
if (dofree) {
|
||||
isc_nm_t *mgr = sock->mgr;
|
||||
isc_mem_put(mgr->mctx, sock, sizeof(*sock));
|
||||
|
|
@ -833,7 +856,7 @@ nmsocket_maybe_destroy(isc_nmsocket_t *sock) {
|
|||
}
|
||||
}
|
||||
|
||||
if (active_handles == 0 || sock->tcphandle != NULL) {
|
||||
if (active_handles == 0 || sock->statichandle != NULL) {
|
||||
destroy = true;
|
||||
}
|
||||
|
||||
|
|
@ -944,6 +967,15 @@ isc__nmsocket_init(isc_nmsocket_t *sock, isc_nm_t *mgr, isc_nmsocket_type type,
|
|||
.inactivereqs = isc_astack_new(
|
||||
mgr->mctx, ISC_NM_REQS_STACK_SIZE) };
|
||||
|
||||
#ifdef NETMGR_TRACE
|
||||
sock->backtrace_size = backtrace(sock->backtrace, TRACE_SIZE);
|
||||
ISC_LINK_INIT(sock, active_link);
|
||||
ISC_LIST_INIT(sock->active_handles);
|
||||
LOCK(&mgr->lock);
|
||||
ISC_LIST_APPEND(mgr->active_sockets, sock, active_link);
|
||||
UNLOCK(&mgr->lock);
|
||||
#endif
|
||||
|
||||
isc_nm_attach(mgr, &sock->mgr);
|
||||
sock->uv_handle.handle.data = sock;
|
||||
|
||||
|
|
@ -997,9 +1029,9 @@ void
|
|||
isc__nmsocket_clearcb(isc_nmsocket_t *sock) {
|
||||
REQUIRE(VALID_NMSOCK(sock));
|
||||
|
||||
sock->rcb.recv = NULL;
|
||||
sock->rcbarg = NULL;
|
||||
sock->accept_cb.accept = NULL;
|
||||
sock->recv_cb = NULL;
|
||||
sock->recv_cbarg = NULL;
|
||||
sock->accept_cb = NULL;
|
||||
sock->accept_cbarg = NULL;
|
||||
}
|
||||
|
||||
|
|
@ -1032,6 +1064,9 @@ alloc_handle(isc_nmsocket_t *sock) {
|
|||
sizeof(isc_nmhandle_t) + sock->extrahandlesize);
|
||||
|
||||
*handle = (isc_nmhandle_t){ .magic = NMHANDLE_MAGIC };
|
||||
#ifdef NETMGR_TRACE
|
||||
ISC_LINK_INIT(handle, active_link);
|
||||
#endif
|
||||
isc_refcount_init(&handle->references, 1);
|
||||
|
||||
return (handle);
|
||||
|
|
@ -1051,12 +1086,16 @@ isc__nmhandle_get(isc_nmsocket_t *sock, isc_sockaddr_t *peer,
|
|||
if (handle == NULL) {
|
||||
handle = alloc_handle(sock);
|
||||
} else {
|
||||
isc_refcount_increment0(&handle->references);
|
||||
isc_refcount_init(&handle->references, 1);
|
||||
INSIST(VALID_NMHANDLE(handle));
|
||||
}
|
||||
|
||||
isc__nmsocket_attach(sock, &handle->sock);
|
||||
|
||||
#ifdef NETMGR_TRACE
|
||||
handle->backtrace_size = backtrace(handle->backtrace, TRACE_SIZE);
|
||||
#endif
|
||||
|
||||
if (peer != NULL) {
|
||||
memcpy(&handle->peer, peer, sizeof(isc_sockaddr_t));
|
||||
} else {
|
||||
|
|
@ -1097,21 +1136,35 @@ isc__nmhandle_get(isc_nmsocket_t *sock, isc_sockaddr_t *peer,
|
|||
INSIST(sock->ah_handles[pos] == NULL);
|
||||
sock->ah_handles[pos] = handle;
|
||||
handle->ah_pos = pos;
|
||||
#ifdef NETMGR_TRACE
|
||||
ISC_LIST_APPEND(sock->active_handles, handle, active_link);
|
||||
#endif
|
||||
UNLOCK(&sock->lock);
|
||||
|
||||
if (sock->type == isc_nm_tcpsocket) {
|
||||
INSIST(sock->tcphandle == NULL);
|
||||
sock->tcphandle = handle;
|
||||
if (sock->type == isc_nm_tcpsocket ||
|
||||
(sock->type == isc_nm_udpsocket && atomic_load(&sock->client)))
|
||||
{
|
||||
INSIST(sock->statichandle == NULL);
|
||||
|
||||
/*
|
||||
* statichandle must be assigned, not attached;
|
||||
* otherwise, if a handle was detached elsewhere
|
||||
* it could never reach 0 references, and the
|
||||
* handle and socket would never be freed.
|
||||
*/
|
||||
sock->statichandle = handle;
|
||||
}
|
||||
|
||||
return (handle);
|
||||
}
|
||||
|
||||
void
|
||||
isc_nmhandle_ref(isc_nmhandle_t *handle) {
|
||||
isc_nmhandle_attach(isc_nmhandle_t *handle, isc_nmhandle_t **handlep) {
|
||||
REQUIRE(VALID_NMHANDLE(handle));
|
||||
REQUIRE(handlep != NULL && *handlep == NULL);
|
||||
|
||||
isc_refcount_increment(&handle->references);
|
||||
*handlep = handle;
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
@ -1153,6 +1206,10 @@ nmhandle_deactivate(isc_nmsocket_t *sock, isc_nmhandle_t *handle) {
|
|||
INSIST(sock->ah_size > handle->ah_pos);
|
||||
INSIST(atomic_load(&sock->ah) > 0);
|
||||
|
||||
#ifdef NETMGR_TRACE
|
||||
ISC_LIST_UNLINK(sock->active_handles, handle, active_link);
|
||||
#endif
|
||||
|
||||
sock->ah_handles[handle->ah_pos] = NULL;
|
||||
handlenum = atomic_fetch_sub(&sock->ah, 1) - 1;
|
||||
sock->ah_frees[handlenum] = handle->ah_pos;
|
||||
|
|
@ -1167,14 +1224,20 @@ nmhandle_deactivate(isc_nmsocket_t *sock, isc_nmhandle_t *handle) {
|
|||
}
|
||||
|
||||
void
|
||||
isc_nmhandle_unref(isc_nmhandle_t *handle) {
|
||||
isc_nmhandle_detach(isc_nmhandle_t **handlep) {
|
||||
isc_nmsocket_t *sock = NULL;
|
||||
isc_nmhandle_t *handle = NULL;
|
||||
|
||||
REQUIRE(VALID_NMHANDLE(handle));
|
||||
REQUIRE(handlep != NULL);
|
||||
REQUIRE(VALID_NMHANDLE(*handlep));
|
||||
|
||||
handle = *handlep;
|
||||
*handlep = NULL;
|
||||
|
||||
if (isc_refcount_decrement(&handle->references) > 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* We need an acquire memory barrier here */
|
||||
(void)isc_refcount_current(&handle->references);
|
||||
|
||||
|
|
@ -1208,6 +1271,11 @@ isc_nmhandle_unref(isc_nmhandle_t *handle) {
|
|||
}
|
||||
}
|
||||
|
||||
if (handle == sock->statichandle) {
|
||||
/* statichandle is assigned, not attached. */
|
||||
sock->statichandle = NULL;
|
||||
}
|
||||
|
||||
isc__nmsocket_detach(&sock);
|
||||
}
|
||||
|
||||
|
|
@ -1309,7 +1377,7 @@ isc__nm_uvreq_put(isc__nm_uvreq_t **req0, isc_nmsocket_t *sock) {
|
|||
}
|
||||
|
||||
if (handle != NULL) {
|
||||
isc_nmhandle_unref(handle);
|
||||
isc_nmhandle_detach(&handle);
|
||||
}
|
||||
|
||||
isc__nmsocket_detach(&sock);
|
||||
|
|
@ -1353,7 +1421,7 @@ isc_nm_cancelread(isc_nmhandle_t *handle) {
|
|||
|
||||
switch (handle->sock->type) {
|
||||
case isc_nm_tcpsocket:
|
||||
isc__nm_tcp_cancelread(handle->sock);
|
||||
isc__nm_tcp_cancelread(handle);
|
||||
break;
|
||||
default:
|
||||
INSIST(0);
|
||||
|
|
@ -1553,3 +1621,79 @@ isc__nm_socket_freebind(const uv_handle_t *handle) {
|
|||
#endif
|
||||
return (result);
|
||||
}
|
||||
|
||||
#ifdef NETMGR_TRACE
|
||||
/*
|
||||
* Dump all active sockets in netmgr. We output to stderr
|
||||
* as the logger might be already shut down.
|
||||
*/
|
||||
|
||||
static const char *
|
||||
nmsocket_type_totext(isc_nmsocket_type type) {
|
||||
switch (type) {
|
||||
case isc_nm_udpsocket:
|
||||
return ("isc_nm_udpsocket");
|
||||
case isc_nm_udplistener:
|
||||
return ("isc_nm_udplistener");
|
||||
case isc_nm_tcpsocket:
|
||||
return ("isc_nm_tcpsocket");
|
||||
case isc_nm_tcplistener:
|
||||
return ("isc_nm_tcplistener");
|
||||
case isc_nm_tcpdnslistener:
|
||||
return ("isc_nm_tcpdnslistener");
|
||||
case isc_nm_tcpdnssocket:
|
||||
return ("isc_nm_tcpdnssocket");
|
||||
default:
|
||||
INSIST(0);
|
||||
ISC_UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
nmhandle_dump(isc_nmhandle_t *handle) {
|
||||
fprintf(stderr, "Active handle %p, refs %lu\n", handle,
|
||||
isc_refcount_current(&handle->references));
|
||||
fprintf(stderr, "Created by:\n");
|
||||
backtrace_symbols_fd(handle->backtrace, handle->backtrace_size,
|
||||
STDERR_FILENO);
|
||||
fprintf(stderr, "\n\n");
|
||||
}
|
||||
|
||||
static void
|
||||
nmsocket_dump(isc_nmsocket_t *sock) {
|
||||
isc_nmhandle_t *handle;
|
||||
LOCK(&sock->lock);
|
||||
fprintf(stderr, "\n=================\n");
|
||||
fprintf(stderr, "Active socket %p, type %s, refs %lu\n", sock,
|
||||
nmsocket_type_totext(sock->type),
|
||||
isc_refcount_current(&sock->references));
|
||||
fprintf(stderr, "Parent %p, listener %p\n", sock->parent,
|
||||
sock->listener);
|
||||
fprintf(stderr, "Created by:\n");
|
||||
backtrace_symbols_fd(sock->backtrace, sock->backtrace_size,
|
||||
STDERR_FILENO);
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, "Active handles:\n");
|
||||
for (handle = ISC_LIST_HEAD(sock->active_handles); handle != NULL;
|
||||
handle = ISC_LIST_NEXT(handle, active_link))
|
||||
{
|
||||
nmhandle_dump(handle);
|
||||
}
|
||||
fprintf(stderr, "\n");
|
||||
UNLOCK(&sock->lock);
|
||||
}
|
||||
|
||||
void
|
||||
isc__nm_dump_active(isc_nm_t *nm) {
|
||||
isc_nmsocket_t *sock;
|
||||
REQUIRE(VALID_NM(nm));
|
||||
LOCK(&nm->lock);
|
||||
fprintf(stderr, "Outstanding sockets\n");
|
||||
for (sock = ISC_LIST_HEAD(nm->active_sockets); sock != NULL;
|
||||
sock = ISC_LIST_NEXT(sock, active_link))
|
||||
{
|
||||
nmsocket_dump(sock);
|
||||
}
|
||||
UNLOCK(&nm->lock);
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -147,49 +147,46 @@ done:
|
|||
|
||||
static void
|
||||
tcp_connect_cb(uv_connect_t *uvreq, int status) {
|
||||
isc_result_t result;
|
||||
isc__nm_uvreq_t *req = (isc__nm_uvreq_t *)uvreq->data;
|
||||
isc_nmsocket_t *sock = NULL;
|
||||
struct sockaddr_storage ss;
|
||||
isc_nmhandle_t *handle = NULL;
|
||||
|
||||
sock = uv_handle_get_data((uv_handle_t *)uvreq->handle);
|
||||
|
||||
REQUIRE(VALID_UVREQ(req));
|
||||
|
||||
if (status == 0) {
|
||||
isc_result_t result;
|
||||
struct sockaddr_storage ss;
|
||||
isc_nmhandle_t *handle = NULL;
|
||||
|
||||
sock = uv_handle_get_data((uv_handle_t *)uvreq->handle);
|
||||
isc__nm_incstats(sock->mgr, sock->statsindex[STATID_CONNECT]);
|
||||
uv_tcp_getpeername(&sock->uv_handle.tcp, (struct sockaddr *)&ss,
|
||||
&(int){ sizeof(ss) });
|
||||
result = isc_sockaddr_fromsockaddr(&sock->peer,
|
||||
(struct sockaddr *)&ss);
|
||||
RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
||||
|
||||
handle = isc__nmhandle_get(sock, NULL, NULL);
|
||||
req->cb.connect(handle, ISC_R_SUCCESS, req->cbarg);
|
||||
|
||||
isc__nm_uvreq_put(&req, sock);
|
||||
|
||||
/*
|
||||
* The sock is now attached to the handle.
|
||||
*/
|
||||
isc__nmsocket_detach(&sock);
|
||||
|
||||
/*
|
||||
* If the connect callback wants to hold on to the handle,
|
||||
* it needs to attach to it.
|
||||
*/
|
||||
isc_nmhandle_unref(handle);
|
||||
} else {
|
||||
/*
|
||||
* TODO:
|
||||
* Handle the connect error properly and free the socket.
|
||||
*/
|
||||
if (status != 0) {
|
||||
req->cb.connect(NULL, isc__nm_uverr2result(status), req->cbarg);
|
||||
isc__nm_uvreq_put(&req, sock);
|
||||
return;
|
||||
}
|
||||
|
||||
sock = uv_handle_get_data((uv_handle_t *)uvreq->handle);
|
||||
isc__nm_incstats(sock->mgr, sock->statsindex[STATID_CONNECT]);
|
||||
uv_tcp_getpeername(&sock->uv_handle.tcp, (struct sockaddr *)&ss,
|
||||
&(int){ sizeof(ss) });
|
||||
result = isc_sockaddr_fromsockaddr(&sock->peer, (struct sockaddr *)&ss);
|
||||
RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
||||
|
||||
handle = isc__nmhandle_get(sock, NULL, NULL);
|
||||
req->cb.connect(handle, ISC_R_SUCCESS, req->cbarg);
|
||||
|
||||
isc__nm_uvreq_put(&req, sock);
|
||||
|
||||
atomic_init(&sock->client, true);
|
||||
|
||||
/*
|
||||
* The sock is now attached to the handle.
|
||||
*/
|
||||
isc__nmsocket_detach(&sock);
|
||||
|
||||
/*
|
||||
* The connect callback should have attached to the handle.
|
||||
* If it didn't, the socket will be closed now.
|
||||
*/
|
||||
isc_nmhandle_detach(&handle);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
|
|
@ -201,6 +198,8 @@ isc_nm_tcpconnect(isc_nm_t *mgr, isc_nmiface_t *local, isc_nmiface_t *peer,
|
|||
isc_result_t result = ISC_R_SUCCESS;
|
||||
|
||||
REQUIRE(VALID_NM(mgr));
|
||||
REQUIRE(local != NULL);
|
||||
REQUIRE(peer != NULL);
|
||||
|
||||
nsock = isc_mem_get(mgr->mctx, sizeof(*nsock));
|
||||
isc__nmsocket_init(nsock, mgr, isc_nm_tcpsocket, local);
|
||||
|
|
@ -211,6 +210,7 @@ isc_nm_tcpconnect(isc_nm_t *mgr, isc_nmiface_t *local, isc_nmiface_t *peer,
|
|||
req->cb.connect = cb;
|
||||
req->cbarg = cbarg;
|
||||
req->peer = peer->addr;
|
||||
req->local = local->addr;
|
||||
|
||||
ievent = isc__nm_get_ievent(mgr, netievent_tcpconnect);
|
||||
ievent->sock = nsock;
|
||||
|
|
@ -262,7 +262,7 @@ isc_nm_listentcp(isc_nm_t *mgr, isc_nmiface_t *iface,
|
|||
|
||||
nsock = isc_mem_get(mgr->mctx, sizeof(*nsock));
|
||||
isc__nmsocket_init(nsock, mgr, isc_nm_tcplistener, iface);
|
||||
nsock->accept_cb.accept = accept_cb;
|
||||
nsock->accept_cb = accept_cb;
|
||||
nsock->accept_cbarg = accept_cbarg;
|
||||
nsock->extrahandlesize = extrahandlesize;
|
||||
nsock->backlog = backlog;
|
||||
|
|
@ -434,6 +434,8 @@ isc__nm_async_tcpchildaccept(isc__networker_t *worker, isc__netievent_t *ev0) {
|
|||
struct sockaddr_storage ss;
|
||||
isc_sockaddr_t local;
|
||||
int r;
|
||||
isc_nm_accept_cb_t accept_cb;
|
||||
void *accept_cbarg;
|
||||
|
||||
REQUIRE(isc__nm_in_netthread());
|
||||
REQUIRE(ssock->type == isc_nm_tcplistener);
|
||||
|
|
@ -488,9 +490,14 @@ isc__nm_async_tcpchildaccept(isc__networker_t *worker, isc__netievent_t *ev0) {
|
|||
|
||||
handle = isc__nmhandle_get(csock, NULL, &local);
|
||||
|
||||
INSIST(ssock->accept_cb.accept != NULL);
|
||||
LOCK(&ssock->lock);
|
||||
INSIST(ssock->accept_cb != NULL);
|
||||
accept_cb = ssock->accept_cb;
|
||||
accept_cbarg = ssock->accept_cbarg;
|
||||
UNLOCK(&ssock->lock);
|
||||
|
||||
csock->read_timeout = ssock->mgr->init;
|
||||
ssock->accept_cb.accept(handle, ISC_R_SUCCESS, ssock->accept_cbarg);
|
||||
accept_cb(handle, ISC_R_SUCCESS, accept_cbarg);
|
||||
|
||||
/*
|
||||
* csock is now attached to the handle.
|
||||
|
|
@ -498,10 +505,10 @@ isc__nm_async_tcpchildaccept(isc__networker_t *worker, isc__netievent_t *ev0) {
|
|||
isc__nmsocket_detach(&csock);
|
||||
|
||||
/*
|
||||
* If the accept callback wants to hold on to the handle,
|
||||
* it needs to attach to it.
|
||||
* The accept callback should have attached to the handle.
|
||||
* If it didn't, the socket will be closed now.
|
||||
*/
|
||||
isc_nmhandle_unref(handle);
|
||||
isc_nmhandle_detach(&handle);
|
||||
return;
|
||||
|
||||
error:
|
||||
|
|
@ -583,6 +590,8 @@ tcp_listenclose_cb(uv_handle_t *handle) {
|
|||
static void
|
||||
readtimeout_cb(uv_timer_t *handle) {
|
||||
isc_nmsocket_t *sock = uv_handle_get_data((uv_handle_t *)handle);
|
||||
isc_nm_recv_cb_t cb;
|
||||
void *cbarg;
|
||||
|
||||
REQUIRE(VALID_NMSOCK(sock));
|
||||
REQUIRE(sock->tid == isc_nm_tid());
|
||||
|
|
@ -603,10 +612,15 @@ readtimeout_cb(uv_timer_t *handle) {
|
|||
if (sock->quota) {
|
||||
isc_quota_detach(&sock->quota);
|
||||
}
|
||||
if (sock->rcb.recv != NULL) {
|
||||
sock->rcb.recv(sock->tcphandle, ISC_R_TIMEDOUT, NULL,
|
||||
sock->rcbarg);
|
||||
isc__nmsocket_clearcb(sock);
|
||||
|
||||
LOCK(&sock->lock);
|
||||
cb = sock->recv_cb;
|
||||
cbarg = sock->recv_cbarg;
|
||||
isc__nmsocket_clearcb(sock);
|
||||
UNLOCK(&sock->lock);
|
||||
|
||||
if (cb != NULL) {
|
||||
cb(sock->statichandle, ISC_R_TIMEDOUT, NULL, cbarg);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -619,8 +633,11 @@ isc__nm_tcp_read(isc_nmhandle_t *handle, isc_nm_recv_cb_t cb, void *cbarg) {
|
|||
REQUIRE(VALID_NMSOCK(handle->sock));
|
||||
|
||||
sock = handle->sock;
|
||||
sock->rcb.recv = cb;
|
||||
sock->rcbarg = cbarg;
|
||||
|
||||
LOCK(&sock->lock);
|
||||
sock->recv_cb = cb;
|
||||
sock->recv_cbarg = cbarg;
|
||||
UNLOCK(&sock->lock);
|
||||
|
||||
ievent = isc__nm_get_ievent(sock->mgr, netievent_tcpstartread);
|
||||
ievent->sock = sock;
|
||||
|
|
@ -729,9 +746,12 @@ isc__nm_tcp_resumeread(isc_nmsocket_t *sock) {
|
|||
isc__netievent_startread_t *ievent = NULL;
|
||||
|
||||
REQUIRE(VALID_NMSOCK(sock));
|
||||
if (sock->rcb.recv == NULL) {
|
||||
LOCK(&sock->lock);
|
||||
if (sock->recv_cb == NULL) {
|
||||
UNLOCK(&sock->lock);
|
||||
return (ISC_R_CANCELED);
|
||||
}
|
||||
UNLOCK(&sock->lock);
|
||||
|
||||
if (!atomic_load(&sock->readpaused)) {
|
||||
return (ISC_R_SUCCESS);
|
||||
|
|
@ -757,17 +777,23 @@ isc__nm_tcp_resumeread(isc_nmsocket_t *sock) {
|
|||
static void
|
||||
read_cb(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf) {
|
||||
isc_nmsocket_t *sock = uv_handle_get_data((uv_handle_t *)stream);
|
||||
isc_nm_recv_cb_t cb;
|
||||
void *cbarg;
|
||||
|
||||
REQUIRE(VALID_NMSOCK(sock));
|
||||
REQUIRE(buf != NULL);
|
||||
|
||||
LOCK(&sock->lock);
|
||||
cb = sock->recv_cb;
|
||||
cbarg = sock->recv_cbarg;
|
||||
UNLOCK(&sock->lock);
|
||||
|
||||
if (nread >= 0) {
|
||||
isc_region_t region = { .base = (unsigned char *)buf->base,
|
||||
.length = nread };
|
||||
|
||||
if (sock->rcb.recv != NULL) {
|
||||
sock->rcb.recv(sock->tcphandle, ISC_R_SUCCESS, ®ion,
|
||||
sock->rcbarg);
|
||||
if (cb != NULL) {
|
||||
cb(sock->statichandle, ISC_R_SUCCESS, ®ion, cbarg);
|
||||
}
|
||||
|
||||
sock->read_timeout = (atomic_load(&sock->keepalive)
|
||||
|
|
@ -790,10 +816,10 @@ read_cb(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf) {
|
|||
* This might happen if the inner socket is closing. It means that
|
||||
* it's detached, so the socket will be closed.
|
||||
*/
|
||||
if (sock->rcb.recv != NULL) {
|
||||
if (cb != NULL) {
|
||||
isc__nm_incstats(sock->mgr, sock->statsindex[STATID_RECVFAIL]);
|
||||
sock->rcb.recv(sock->tcphandle, ISC_R_EOF, NULL, sock->rcbarg);
|
||||
isc__nmsocket_clearcb(sock);
|
||||
cb(sock->statichandle, ISC_R_EOF, NULL, cbarg);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -958,8 +984,7 @@ isc__nm_tcp_send(isc_nmhandle_t *handle, isc_region_t *region, isc_nm_cb_t cb,
|
|||
uvreq = isc__nm_uvreq_get(sock->mgr, sock);
|
||||
uvreq->uvbuf.base = (char *)region->base;
|
||||
uvreq->uvbuf.len = region->length;
|
||||
uvreq->handle = handle;
|
||||
isc_nmhandle_ref(uvreq->handle);
|
||||
isc_nmhandle_attach(handle, &uvreq->handle);
|
||||
uvreq->cb.send = cb;
|
||||
uvreq->cbarg = cbarg;
|
||||
|
||||
|
|
@ -1002,7 +1027,6 @@ tcp_send_cb(uv_write_t *req, int status) {
|
|||
uvreq->cb.send(uvreq->handle, result, uvreq->cbarg);
|
||||
|
||||
sock = uvreq->handle->sock;
|
||||
isc_nmhandle_unref(uvreq->handle);
|
||||
isc__nm_uvreq_put(&uvreq, sock);
|
||||
}
|
||||
|
||||
|
|
@ -1034,8 +1058,6 @@ tcp_send_direct(isc_nmsocket_t *sock, isc__nm_uvreq_t *req) {
|
|||
|
||||
REQUIRE(sock->tid == isc_nm_tid());
|
||||
REQUIRE(sock->type == isc_nm_tcpsocket);
|
||||
|
||||
isc_nmhandle_ref(req->handle);
|
||||
r = uv_write(&req->uv_req.write, &sock->uv_handle.stream, &req->uvbuf,
|
||||
1, tcp_send_cb);
|
||||
if (r < 0) {
|
||||
|
|
@ -1125,24 +1147,43 @@ void
|
|||
isc__nm_tcp_shutdown(isc_nmsocket_t *sock) {
|
||||
REQUIRE(VALID_NMSOCK(sock));
|
||||
|
||||
if (sock->type == isc_nm_tcpsocket && sock->tcphandle != NULL &&
|
||||
sock->rcb.recv != NULL)
|
||||
{
|
||||
sock->rcb.recv(sock->tcphandle, ISC_R_CANCELED, NULL,
|
||||
sock->rcbarg);
|
||||
if (sock->type == isc_nm_tcpsocket && sock->statichandle != NULL) {
|
||||
isc_nm_recv_cb_t cb;
|
||||
void *cbarg;
|
||||
|
||||
LOCK(&sock->lock);
|
||||
cb = sock->recv_cb;
|
||||
cbarg = sock->recv_cbarg;
|
||||
isc__nmsocket_clearcb(sock);
|
||||
UNLOCK(&sock->lock);
|
||||
|
||||
if (cb != NULL) {
|
||||
cb(sock->statichandle, ISC_R_CANCELED, NULL, cbarg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
isc__nm_tcp_cancelread(isc_nmsocket_t *sock) {
|
||||
REQUIRE(VALID_NMSOCK(sock));
|
||||
isc__nm_tcp_cancelread(isc_nmhandle_t *handle) {
|
||||
isc_nmsocket_t *sock = NULL;
|
||||
|
||||
if (sock->type == isc_nm_tcpsocket && sock->tcphandle != NULL &&
|
||||
sock->rcb.recv != NULL)
|
||||
{
|
||||
sock->rcb.recv(sock->tcphandle, ISC_R_CANCELED, NULL,
|
||||
sock->rcbarg);
|
||||
REQUIRE(VALID_NMHANDLE(handle));
|
||||
|
||||
sock = handle->sock;
|
||||
|
||||
REQUIRE(VALID_NMSOCK(sock));
|
||||
REQUIRE(sock->type == isc_nm_tcpsocket);
|
||||
|
||||
if (atomic_load(&sock->client)) {
|
||||
isc_nm_recv_cb_t cb;
|
||||
void *cbarg;
|
||||
|
||||
LOCK(&sock->lock);
|
||||
cb = sock->recv_cb;
|
||||
cbarg = sock->recv_cbarg;
|
||||
isc__nmsocket_clearcb(sock);
|
||||
UNLOCK(&sock->lock);
|
||||
|
||||
cb(handle, ISC_R_EOF, NULL, cbarg);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -82,7 +82,9 @@ alloc_dnsbuf(isc_nmsocket_t *sock, size_t len) {
|
|||
static void
|
||||
timer_close_cb(uv_handle_t *handle) {
|
||||
isc_nmsocket_t *sock = (isc_nmsocket_t *)uv_handle_get_data(handle);
|
||||
INSIST(VALID_NMSOCK(sock));
|
||||
|
||||
REQUIRE(VALID_NMSOCK(sock));
|
||||
|
||||
atomic_store(&sock->closed, true);
|
||||
tcpdns_close_direct(sock);
|
||||
}
|
||||
|
|
@ -94,9 +96,9 @@ dnstcp_readtimeout(uv_timer_t *timer) {
|
|||
|
||||
REQUIRE(VALID_NMSOCK(sock));
|
||||
REQUIRE(sock->tid == isc_nm_tid());
|
||||
/* Close the TCP connection, it's closing should fire 'our' closing */
|
||||
isc_nmhandle_unref(sock->outerhandle);
|
||||
sock->outerhandle = NULL;
|
||||
|
||||
/* Close the TCP connection; its closure should fire ours. */
|
||||
isc_nmhandle_detach(&sock->outerhandle);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -106,6 +108,9 @@ static isc_result_t
|
|||
dnslisten_acceptcb(isc_nmhandle_t *handle, isc_result_t result, void *cbarg) {
|
||||
isc_nmsocket_t *dnslistensock = (isc_nmsocket_t *)cbarg;
|
||||
isc_nmsocket_t *dnssock = NULL;
|
||||
isc_nmhandle_t *readhandle = NULL;
|
||||
isc_nm_accept_cb_t accept_cb;
|
||||
void *accept_cbarg;
|
||||
|
||||
REQUIRE(VALID_NMSOCK(dnslistensock));
|
||||
REQUIRE(dnslistensock->type == isc_nm_tcpdnslistener);
|
||||
|
|
@ -114,9 +119,13 @@ dnslisten_acceptcb(isc_nmhandle_t *handle, isc_result_t result, void *cbarg) {
|
|||
return (result);
|
||||
}
|
||||
|
||||
if (dnslistensock->accept_cb.accept != NULL) {
|
||||
result = dnslistensock->accept_cb.accept(
|
||||
handle, ISC_R_SUCCESS, dnslistensock->accept_cbarg);
|
||||
LOCK(&dnslistensock->lock);
|
||||
accept_cb = dnslistensock->accept_cb;
|
||||
accept_cbarg = dnslistensock->accept_cbarg;
|
||||
UNLOCK(&dnslistensock->lock);
|
||||
|
||||
if (accept_cb != NULL) {
|
||||
result = accept_cb(handle, ISC_R_SUCCESS, accept_cbarg);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
return (result);
|
||||
}
|
||||
|
|
@ -132,8 +141,7 @@ dnslisten_acceptcb(isc_nmhandle_t *handle, isc_result_t result, void *cbarg) {
|
|||
|
||||
isc__nmsocket_attach(dnssock, &dnssock->self);
|
||||
|
||||
dnssock->outerhandle = handle;
|
||||
isc_nmhandle_ref(dnssock->outerhandle);
|
||||
isc_nmhandle_attach(handle, &dnssock->outerhandle);
|
||||
|
||||
dnssock->peer = handle->sock->peer;
|
||||
dnssock->read_timeout = handle->sock->mgr->init;
|
||||
|
|
@ -147,10 +155,15 @@ dnslisten_acceptcb(isc_nmhandle_t *handle, isc_result_t result, void *cbarg) {
|
|||
uv_timer_start(&dnssock->timer, dnstcp_readtimeout,
|
||||
dnssock->read_timeout, 0);
|
||||
|
||||
isc_nmhandle_ref(handle);
|
||||
result = isc_nm_read(handle, dnslisten_readcb, dnssock);
|
||||
/*
|
||||
* Add a reference to handle to keep it from being freed by
|
||||
* the caller. It will be detached in dnslisted_readcb() when
|
||||
* the connection is closed or there is no more data to be read.
|
||||
*/
|
||||
isc_nmhandle_attach(handle, &readhandle);
|
||||
result = isc_nm_read(readhandle, dnslisten_readcb, dnssock);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
isc_nmhandle_unref(handle);
|
||||
isc_nmhandle_detach(&readhandle);
|
||||
}
|
||||
isc__nmsocket_detach(&dnssock);
|
||||
|
||||
|
|
@ -187,16 +200,42 @@ processbuffer(isc_nmsocket_t *dnssock, isc_nmhandle_t **handlep) {
|
|||
*/
|
||||
len = dnslen(dnssock->buf);
|
||||
if (len <= dnssock->buf_len - 2) {
|
||||
isc_nmhandle_t *dnshandle = isc__nmhandle_get(dnssock, NULL,
|
||||
NULL);
|
||||
isc_nmsocket_t *listener = dnssock->listener;
|
||||
isc_nmhandle_t *dnshandle = NULL;
|
||||
isc_nmsocket_t *listener = NULL;
|
||||
isc_nm_recv_cb_t cb = NULL;
|
||||
void *cbarg = NULL;
|
||||
|
||||
if (listener != NULL && listener->rcb.recv != NULL) {
|
||||
listener->rcb.recv(
|
||||
dnshandle, ISC_R_SUCCESS,
|
||||
&(isc_region_t){ .base = dnssock->buf + 2,
|
||||
.length = len },
|
||||
listener->rcbarg);
|
||||
if (atomic_load(&dnssock->client) &&
|
||||
dnssock->statichandle != NULL) {
|
||||
isc_nmhandle_attach(dnssock->statichandle, &dnshandle);
|
||||
} else {
|
||||
dnshandle = isc__nmhandle_get(dnssock, NULL, NULL);
|
||||
}
|
||||
|
||||
listener = dnssock->listener;
|
||||
if (listener != NULL) {
|
||||
LOCK(&listener->lock);
|
||||
cb = listener->recv_cb;
|
||||
cbarg = listener->recv_cbarg;
|
||||
UNLOCK(&listener->lock);
|
||||
} else if (dnssock->recv_cb != NULL) {
|
||||
LOCK(&dnssock->lock);
|
||||
cb = dnssock->recv_cb;
|
||||
cbarg = dnssock->recv_cbarg;
|
||||
/*
|
||||
* We need to clear the read callback *before*
|
||||
* calling it, because it might make another
|
||||
* call to isc_nm_read() and set up a new callback.
|
||||
*/
|
||||
isc__nmsocket_clearcb(dnssock);
|
||||
UNLOCK(&dnssock->lock);
|
||||
}
|
||||
|
||||
if (cb != NULL) {
|
||||
cb(dnshandle, ISC_R_SUCCESS,
|
||||
&(isc_region_t){ .base = dnssock->buf + 2,
|
||||
.length = len },
|
||||
cbarg);
|
||||
}
|
||||
|
||||
len += 2;
|
||||
|
|
@ -214,8 +253,8 @@ processbuffer(isc_nmsocket_t *dnssock, isc_nmhandle_t **handlep) {
|
|||
}
|
||||
|
||||
/*
|
||||
* We've got a read on our underlying socket, need to check if we have
|
||||
* a complete DNS packet and, if so - call the callback
|
||||
* We've got a read on our underlying socket. Check whether
|
||||
* we have a complete DNS packet and, if so, call the callback.
|
||||
*/
|
||||
static void
|
||||
dnslisten_readcb(isc_nmhandle_t *handle, isc_result_t eresult,
|
||||
|
|
@ -227,20 +266,18 @@ dnslisten_readcb(isc_nmhandle_t *handle, isc_result_t eresult,
|
|||
|
||||
REQUIRE(VALID_NMSOCK(dnssock));
|
||||
REQUIRE(VALID_NMHANDLE(handle));
|
||||
REQUIRE(dnssock->tid == isc_nm_tid());
|
||||
|
||||
if (region == NULL || eresult != ISC_R_SUCCESS) {
|
||||
/* Connection closed */
|
||||
isc_nmhandle_unref(handle);
|
||||
dnssock->result = eresult;
|
||||
if (dnssock->self != NULL) {
|
||||
isc__nmsocket_detach(&dnssock->self);
|
||||
}
|
||||
isc__nmsocket_clearcb(dnssock);
|
||||
if (dnssock->outerhandle != NULL) {
|
||||
isc_nmhandle_unref(dnssock->outerhandle);
|
||||
dnssock->outerhandle = NULL;
|
||||
isc_nmhandle_detach(&dnssock->outerhandle);
|
||||
}
|
||||
isc_nmhandle_detach(&handle);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -277,15 +314,21 @@ dnslisten_readcb(isc_nmhandle_t *handle, isc_result_t eresult,
|
|||
uv_timer_stop(&dnssock->timer);
|
||||
}
|
||||
|
||||
if (atomic_load(&dnssock->sequential)) {
|
||||
LOCK(&dnssock->lock);
|
||||
if (atomic_load(&dnssock->sequential) ||
|
||||
dnssock->recv_cb == NULL) {
|
||||
UNLOCK(&dnssock->lock);
|
||||
/*
|
||||
* We're in sequential mode and we processed
|
||||
* one packet, so we're done until the next read
|
||||
* completes.
|
||||
* There are two reasons we might want to pause here:
|
||||
* - We're in sequential mode and we've received
|
||||
* a whole packet, so we're done until it's been
|
||||
* processed; or
|
||||
* - We no longer have a read callback.
|
||||
*/
|
||||
isc_nm_pauseread(dnssock->outerhandle);
|
||||
done = true;
|
||||
} else {
|
||||
UNLOCK(&dnssock->lock);
|
||||
/*
|
||||
* We're pipelining, so we now resume processing
|
||||
* packets until the clients-per-connection limit
|
||||
|
|
@ -300,7 +343,7 @@ dnslisten_readcb(isc_nmhandle_t *handle, isc_result_t eresult,
|
|||
}
|
||||
}
|
||||
|
||||
isc_nmhandle_unref(dnshandle);
|
||||
isc_nmhandle_detach(&dnshandle);
|
||||
} while (!done);
|
||||
}
|
||||
|
||||
|
|
@ -314,7 +357,6 @@ isc_nm_listentcpdns(isc_nm_t *mgr, isc_nmiface_t *iface, isc_nm_recv_cb_t cb,
|
|||
void *cbarg, isc_nm_accept_cb_t accept_cb,
|
||||
void *accept_cbarg, size_t extrahandlesize, int backlog,
|
||||
isc_quota_t *quota, isc_nmsocket_t **sockp) {
|
||||
/* A 'wrapper' socket object with outer set to true TCP socket */
|
||||
isc_nmsocket_t *dnslistensock = isc_mem_get(mgr->mctx,
|
||||
sizeof(*dnslistensock));
|
||||
isc_result_t result;
|
||||
|
|
@ -322,13 +364,19 @@ isc_nm_listentcpdns(isc_nm_t *mgr, isc_nmiface_t *iface, isc_nm_recv_cb_t cb,
|
|||
REQUIRE(VALID_NM(mgr));
|
||||
|
||||
isc__nmsocket_init(dnslistensock, mgr, isc_nm_tcpdnslistener, iface);
|
||||
dnslistensock->rcb.recv = cb;
|
||||
dnslistensock->rcbarg = cbarg;
|
||||
dnslistensock->accept_cb.accept = accept_cb;
|
||||
LOCK(&dnslistensock->lock);
|
||||
dnslistensock->recv_cb = cb;
|
||||
dnslistensock->recv_cbarg = cbarg;
|
||||
dnslistensock->accept_cb = accept_cb;
|
||||
dnslistensock->accept_cbarg = accept_cbarg;
|
||||
UNLOCK(&dnslistensock->lock);
|
||||
dnslistensock->extrahandlesize = extrahandlesize;
|
||||
|
||||
/* We set dnslistensock->outer to a true listening socket */
|
||||
/*
|
||||
* dnslistensock will be a DNS 'wrapper' around a connected
|
||||
* stream. We set dnslistensock->outer to a socket listening
|
||||
* for a TCP connection.
|
||||
*/
|
||||
result = isc_nm_listentcp(mgr, iface, dnslisten_acceptcb, dnslistensock,
|
||||
extrahandlesize, backlog, quota,
|
||||
&dnslistensock->outer);
|
||||
|
|
@ -429,12 +477,11 @@ resume_processing(void *arg) {
|
|||
if (sock->timer_initialized) {
|
||||
uv_timer_stop(&sock->timer);
|
||||
}
|
||||
isc_nmhandle_unref(handle);
|
||||
isc_nmhandle_detach(&handle);
|
||||
} else if (sock->outerhandle != NULL) {
|
||||
result = isc_nm_resumeread(sock->outerhandle);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
isc_nmhandle_unref(sock->outerhandle);
|
||||
sock->outerhandle = NULL;
|
||||
isc_nmhandle_detach(&sock->outerhandle);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -464,7 +511,7 @@ resume_processing(void *arg) {
|
|||
uv_timer_stop(&sock->timer);
|
||||
}
|
||||
atomic_store(&sock->outerhandle->sock->processing, true);
|
||||
isc_nmhandle_unref(dnshandle);
|
||||
isc_nmhandle_detach(&dnshandle);
|
||||
} while (atomic_load(&sock->ah) < TCPDNS_CLIENTS_PER_CONN);
|
||||
}
|
||||
|
||||
|
|
@ -477,6 +524,7 @@ tcpdnssend_cb(isc_nmhandle_t *handle, isc_result_t result, void *cbarg) {
|
|||
req->cb.send(req->handle, result, req->cbarg);
|
||||
isc_mem_put(req->sock->mgr->mctx, req->uvbuf.base, req->uvbuf.len);
|
||||
isc__nm_uvreq_put(&req, req->handle->sock);
|
||||
isc_nmhandle_detach(&handle);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -491,12 +539,16 @@ isc__nm_async_tcpdnssend(isc__networker_t *worker, isc__netievent_t *ev0) {
|
|||
|
||||
result = ISC_R_NOTCONNECTED;
|
||||
if (atomic_load(&sock->active) && sock->outerhandle != NULL) {
|
||||
isc_nmhandle_t *sendhandle = NULL;
|
||||
isc_region_t r;
|
||||
|
||||
r.base = (unsigned char *)req->uvbuf.base;
|
||||
r.length = req->uvbuf.len;
|
||||
result = isc__nm_tcp_send(sock->outerhandle, &r, tcpdnssend_cb,
|
||||
req);
|
||||
isc_nmhandle_attach(sock->outerhandle, &sendhandle);
|
||||
result = isc_nm_send(sendhandle, &r, tcpdnssend_cb, req);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
isc_nmhandle_detach(&sendhandle);
|
||||
}
|
||||
}
|
||||
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
|
|
@ -522,8 +574,7 @@ isc__nm_tcpdns_send(isc_nmhandle_t *handle, isc_region_t *region,
|
|||
REQUIRE(sock->type == isc_nm_tcpdnssocket);
|
||||
|
||||
uvreq = isc__nm_uvreq_get(sock->mgr, sock);
|
||||
uvreq->handle = handle;
|
||||
isc_nmhandle_ref(uvreq->handle);
|
||||
isc_nmhandle_attach(handle, &uvreq->handle);
|
||||
uvreq->cb.send = cb;
|
||||
uvreq->cbarg = cbarg;
|
||||
|
||||
|
|
@ -533,13 +584,20 @@ isc__nm_tcpdns_send(isc_nmhandle_t *handle, isc_region_t *region,
|
|||
memmove(uvreq->uvbuf.base + 2, region->base, region->length);
|
||||
|
||||
if (sock->tid == isc_nm_tid()) {
|
||||
isc_result_t result;
|
||||
isc_nmhandle_t *sendhandle = NULL;
|
||||
isc_region_t r;
|
||||
|
||||
r.base = (unsigned char *)uvreq->uvbuf.base;
|
||||
r.length = uvreq->uvbuf.len;
|
||||
|
||||
return (isc__nm_tcp_send(sock->outerhandle, &r, tcpdnssend_cb,
|
||||
uvreq));
|
||||
isc_nmhandle_attach(sock->outerhandle, &sendhandle);
|
||||
result = isc_nm_send(sock->outerhandle, &r, tcpdnssend_cb,
|
||||
uvreq);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
isc_nmhandle_detach(&sendhandle);
|
||||
}
|
||||
return (result);
|
||||
} else {
|
||||
isc__netievent_tcpdnssend_t *ievent = NULL;
|
||||
|
||||
|
|
@ -579,8 +637,7 @@ tcpdns_close_direct(isc_nmsocket_t *sock) {
|
|||
*/
|
||||
if (sock->outerhandle != NULL) {
|
||||
isc__nmsocket_clearcb(sock->outerhandle->sock);
|
||||
isc_nmhandle_unref(sock->outerhandle);
|
||||
sock->outerhandle = NULL;
|
||||
isc_nmhandle_detach(&sock->outerhandle);
|
||||
}
|
||||
if (sock->listener != NULL) {
|
||||
isc__nmsocket_detach(&sock->listener);
|
||||
|
|
|
|||
|
|
@ -59,9 +59,9 @@ isc_nm_listenudp(isc_nm_t *mgr, isc_nmiface_t *iface, isc_nm_recv_cb_t cb,
|
|||
mgr->nworkers * sizeof(*nsock));
|
||||
memset(nsock->children, 0, mgr->nworkers * sizeof(*nsock));
|
||||
|
||||
INSIST(nsock->rcb.recv == NULL && nsock->rcbarg == NULL);
|
||||
nsock->rcb.recv = cb;
|
||||
nsock->rcbarg = cbarg;
|
||||
INSIST(nsock->recv_cb == NULL && nsock->recv_cbarg == NULL);
|
||||
nsock->recv_cb = cb;
|
||||
nsock->recv_cbarg = cbarg;
|
||||
nsock->extrahandlesize = extrahandlesize;
|
||||
|
||||
for (size_t i = 0; i < mgr->nworkers; i++) {
|
||||
|
|
@ -76,11 +76,11 @@ isc_nm_listenudp(isc_nm_t *mgr, isc_nmiface_t *iface, isc_nm_recv_cb_t cb,
|
|||
csock->tid = i;
|
||||
csock->extrahandlesize = extrahandlesize;
|
||||
|
||||
INSIST(csock->rcb.recv == NULL && csock->rcbarg == NULL);
|
||||
csock->rcb.recv = cb;
|
||||
csock->rcbarg = cbarg;
|
||||
INSIST(csock->recv_cb == NULL && csock->recv_cbarg == NULL);
|
||||
csock->recv_cb = cb;
|
||||
csock->recv_cbarg = cbarg;
|
||||
csock->fd = socket(family, SOCK_DGRAM, 0);
|
||||
INSIST(csock->fd >= 0);
|
||||
RUNTIME_CHECK(csock->fd >= 0);
|
||||
|
||||
/*
|
||||
* This is SO_REUSE**** hell:
|
||||
|
|
@ -159,7 +159,7 @@ udp_alloc_cb(uv_handle_t *handle, size_t size, uv_buf_t *buf) {
|
|||
}
|
||||
|
||||
/*
|
||||
* handle 'udplisten' async call - start listening on a socket.
|
||||
* Asynchronous 'udplisten' call handler: start listening on a UDP socket.
|
||||
*/
|
||||
void
|
||||
isc__nm_async_udplisten(isc__networker_t *worker, isc__netievent_t *ev0) {
|
||||
|
|
@ -223,7 +223,7 @@ isc__nm_async_udplisten(isc__networker_t *worker, isc__netievent_t *ev0) {
|
|||
}
|
||||
|
||||
static void
|
||||
udp_close_cb(uv_handle_t *handle) {
|
||||
udp_stop_cb(uv_handle_t *handle) {
|
||||
isc_nmsocket_t *sock = uv_handle_get_data(handle);
|
||||
atomic_store(&sock->closed, true);
|
||||
|
||||
|
|
@ -236,7 +236,7 @@ stop_udp_child(isc_nmsocket_t *sock) {
|
|||
REQUIRE(sock->tid == isc_nm_tid());
|
||||
|
||||
uv_udp_recv_stop(&sock->uv_handle.udp);
|
||||
uv_close((uv_handle_t *)&sock->uv_handle.udp, udp_close_cb);
|
||||
uv_close((uv_handle_t *)&sock->uv_handle.udp, udp_stop_cb);
|
||||
|
||||
isc__nm_incstats(sock->mgr, sock->statsindex[STATID_CLOSE]);
|
||||
|
||||
|
|
@ -311,7 +311,7 @@ isc__nm_udp_stoplistening(isc_nmsocket_t *sock) {
|
|||
}
|
||||
|
||||
/*
|
||||
* handle 'udpstop' async call - stop listening on a socket.
|
||||
* Asynchronous 'udpstop' call handler: stop listening on a UDP socket.
|
||||
*/
|
||||
void
|
||||
isc__nm_async_udpstop(isc__networker_t *worker, isc__netievent_t *ev0) {
|
||||
|
|
@ -360,6 +360,8 @@ udp_recv_cb(uv_udp_t *handle, ssize_t nrecv, const uv_buf_t *buf,
|
|||
isc_region_t region;
|
||||
uint32_t maxudp;
|
||||
bool free_buf = true;
|
||||
isc_nm_recv_cb_t cb;
|
||||
void *cbarg;
|
||||
|
||||
/*
|
||||
* Even though destruction of the socket can only happen from the
|
||||
|
|
@ -375,9 +377,9 @@ udp_recv_cb(uv_udp_t *handle, ssize_t nrecv, const uv_buf_t *buf,
|
|||
#endif
|
||||
|
||||
/*
|
||||
* Three reasons to return now without processing:
|
||||
* - If addr == NULL that's the end of stream - we can
|
||||
* free the buffer and bail.
|
||||
* Three possible reasons to return now without processing:
|
||||
* - If addr == NULL, in which case it's the end of stream;
|
||||
* we can free the buffer and bail.
|
||||
* - If we're simulating a firewall blocking UDP packets
|
||||
* bigger than 'maxudp' bytes for testing purposes.
|
||||
* - If the socket is no longer active.
|
||||
|
|
@ -399,8 +401,18 @@ udp_recv_cb(uv_udp_t *handle, ssize_t nrecv, const uv_buf_t *buf,
|
|||
region.base = (unsigned char *)buf->base;
|
||||
region.length = nrecv;
|
||||
|
||||
INSIST(sock->rcb.recv != NULL);
|
||||
sock->rcb.recv(nmhandle, ISC_R_SUCCESS, ®ion, sock->rcbarg);
|
||||
/*
|
||||
* In tcp.c and tcpdns.c, this would need to be locked
|
||||
* by sock->lock because callbacks may be set to NULL
|
||||
* unexpectedly when the connection drops, but that isn't
|
||||
* a factor in the UDP case.
|
||||
*/
|
||||
INSIST(sock->recv_cb != NULL);
|
||||
cb = sock->recv_cb;
|
||||
cbarg = sock->recv_cbarg;
|
||||
|
||||
cb(nmhandle, ISC_R_SUCCESS, ®ion, cbarg);
|
||||
|
||||
if (free_buf) {
|
||||
isc__nm_free_uvbuf(sock, buf);
|
||||
}
|
||||
|
|
@ -414,24 +426,24 @@ udp_recv_cb(uv_udp_t *handle, ssize_t nrecv, const uv_buf_t *buf,
|
|||
* If the recv callback wants to hold on to the handle,
|
||||
* it needs to attach to it.
|
||||
*/
|
||||
isc_nmhandle_unref(nmhandle);
|
||||
isc_nmhandle_detach(&nmhandle);
|
||||
}
|
||||
|
||||
/*
|
||||
* isc__nm_udp_send sends buf to a peer on a socket.
|
||||
* It tries to find a proper sibling/child socket so that we won't have
|
||||
* to jump to another thread.
|
||||
* Send the data in 'region' to a peer via a UDP socket. We try to find
|
||||
* a proper sibling/child socket so that we won't have to jump to another
|
||||
* thread.
|
||||
*/
|
||||
isc_result_t
|
||||
isc__nm_udp_send(isc_nmhandle_t *handle, isc_region_t *region, isc_nm_cb_t cb,
|
||||
void *cbarg) {
|
||||
isc_nmsocket_t *psock = NULL, *rsock = NULL;
|
||||
isc_nmsocket_t *sock = handle->sock;
|
||||
isc_nmsocket_t *psock = NULL, *rsock = sock;
|
||||
isc_sockaddr_t *peer = &handle->peer;
|
||||
isc__netievent_udpsend_t *ievent = NULL;
|
||||
isc__nm_uvreq_t *uvreq = NULL;
|
||||
int ntid;
|
||||
uint32_t maxudp = atomic_load(&sock->mgr->maxudp);
|
||||
int ntid;
|
||||
|
||||
/*
|
||||
* We're simulating a firewall blocking UDP packets bigger than
|
||||
|
|
@ -442,16 +454,16 @@ isc__nm_udp_send(isc_nmhandle_t *handle, isc_region_t *region, isc_nm_cb_t cb,
|
|||
* we need to do so here.
|
||||
*/
|
||||
if (maxudp != 0 && region->length > maxudp) {
|
||||
isc_nmhandle_unref(handle);
|
||||
isc_nmhandle_detach(&handle);
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
if (sock->type == isc_nm_udpsocket) {
|
||||
if (sock->type == isc_nm_udpsocket && !atomic_load(&sock->client)) {
|
||||
INSIST(sock->parent != NULL);
|
||||
psock = sock->parent;
|
||||
} else if (sock->type == isc_nm_udplistener) {
|
||||
psock = sock;
|
||||
} else {
|
||||
} else if (!atomic_load(&sock->client)) {
|
||||
INSIST(0);
|
||||
ISC_UNREACHABLE();
|
||||
}
|
||||
|
|
@ -467,20 +479,22 @@ isc__nm_udp_send(isc_nmhandle_t *handle, isc_region_t *region, isc_nm_cb_t cb,
|
|||
*/
|
||||
if (isc__nm_in_netthread()) {
|
||||
ntid = isc_nm_tid();
|
||||
} else if (sock->type == isc_nm_udpsocket) {
|
||||
} else if (sock->type == isc_nm_udpsocket &&
|
||||
!atomic_load(&sock->client)) {
|
||||
ntid = sock->tid;
|
||||
} else {
|
||||
ntid = (int)isc_random_uniform(sock->nchildren);
|
||||
}
|
||||
|
||||
rsock = &psock->children[ntid];
|
||||
if (psock != NULL) {
|
||||
rsock = &psock->children[ntid];
|
||||
}
|
||||
|
||||
uvreq = isc__nm_uvreq_get(sock->mgr, sock);
|
||||
uvreq->uvbuf.base = (char *)region->base;
|
||||
uvreq->uvbuf.len = region->length;
|
||||
|
||||
uvreq->handle = handle;
|
||||
isc_nmhandle_ref(uvreq->handle);
|
||||
isc_nmhandle_attach(handle, &uvreq->handle);
|
||||
|
||||
uvreq->cb.send = cb;
|
||||
uvreq->cbarg = cbarg;
|
||||
|
|
@ -507,7 +521,7 @@ isc__nm_udp_send(isc_nmhandle_t *handle, isc_region_t *region, isc_nm_cb_t cb,
|
|||
}
|
||||
|
||||
/*
|
||||
* handle 'udpsend' async event - send a packet on the socket
|
||||
* Asynchronous 'udpsend' event handler: send a packet on a UDP socket.
|
||||
*/
|
||||
void
|
||||
isc__nm_async_udpsend(isc__networker_t *worker, isc__netievent_t *ev0) {
|
||||
|
|
@ -524,9 +538,6 @@ isc__nm_async_udpsend(isc__networker_t *worker, isc__netievent_t *ev0) {
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* udp_send_cb - callback
|
||||
*/
|
||||
static void
|
||||
udp_send_cb(uv_udp_send_t *req, int status) {
|
||||
isc_result_t result = ISC_R_SUCCESS;
|
||||
|
|
@ -542,7 +553,6 @@ udp_send_cb(uv_udp_send_t *req, int status) {
|
|||
}
|
||||
|
||||
uvreq->cb.send(uvreq->handle, result, uvreq->cbarg);
|
||||
isc_nmhandle_unref(uvreq->handle);
|
||||
isc__nm_uvreq_put(&uvreq, uvreq->sock);
|
||||
}
|
||||
|
||||
|
|
@ -553,6 +563,7 @@ udp_send_cb(uv_udp_send_t *req, int status) {
|
|||
static isc_result_t
|
||||
udp_send_direct(isc_nmsocket_t *sock, isc__nm_uvreq_t *req,
|
||||
isc_sockaddr_t *peer) {
|
||||
const struct sockaddr *sa = NULL;
|
||||
int rv;
|
||||
|
||||
REQUIRE(sock->tid == isc_nm_tid());
|
||||
|
|
@ -561,9 +572,10 @@ udp_send_direct(isc_nmsocket_t *sock, isc__nm_uvreq_t *req,
|
|||
if (!isc__nmsocket_active(sock)) {
|
||||
return (ISC_R_CANCELED);
|
||||
}
|
||||
isc_nmhandle_ref(req->handle);
|
||||
|
||||
sa = atomic_load(&sock->connected) ? NULL : &peer->type.sa;
|
||||
rv = uv_udp_send(&req->uv_req.udp_send, &sock->uv_handle.udp,
|
||||
&req->uvbuf, 1, &peer->type.sa, udp_send_cb);
|
||||
&req->uvbuf, 1, sa, udp_send_cb);
|
||||
if (rv < 0) {
|
||||
isc__nm_incstats(req->sock->mgr,
|
||||
req->sock->statsindex[STATID_SENDFAIL]);
|
||||
|
|
|
|||
|
|
@ -436,15 +436,15 @@ isc_netaddr_setzone
|
|||
isc_netaddr_totext
|
||||
isc_netaddr_unspec
|
||||
isc_netscope_pton
|
||||
isc_nmhandle_attach
|
||||
isc_nmhandle_detach
|
||||
isc_nmhandle_getdata
|
||||
isc_nmhandle_getextra
|
||||
isc_nmhandle_is_stream
|
||||
isc_nmhandle_netmgr
|
||||
isc_nmhandle_localaddr
|
||||
isc_nmhandle_peeraddr
|
||||
isc_nmhandle_ref
|
||||
isc_nmhandle_setdata
|
||||
isc_nmhandle_unref
|
||||
isc_nm_cancelread
|
||||
isc_nm_closedown
|
||||
isc_nm_destroy
|
||||
|
|
|
|||
|
|
@ -108,7 +108,6 @@ recv_data(isc_nmhandle_t *handle, isc_result_t eresult, isc_region_t *region,
|
|||
done:
|
||||
isc_nm_pauseread(handle);
|
||||
ccmsg->cb(handle, ccmsg->result, ccmsg->cbarg);
|
||||
isc_nmhandle_unref(handle);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -149,18 +148,14 @@ isccc_ccmsg_readmessage(isccc_ccmsg_t *ccmsg, isc_nm_cb_t cb, void *cbarg) {
|
|||
ccmsg->result = ISC_R_UNEXPECTED; /* unknown right now */
|
||||
ccmsg->length_received = false;
|
||||
|
||||
isc_nmhandle_ref(ccmsg->handle);
|
||||
if (ccmsg->reading) {
|
||||
result = isc_nm_resumeread(ccmsg->handle);
|
||||
} else {
|
||||
result = isc_nm_read(ccmsg->handle, recv_data, ccmsg);
|
||||
ccmsg->reading = true;
|
||||
}
|
||||
if (result == ISC_R_CANCELED) {
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
ccmsg->reading = false;
|
||||
} else if (result != ISC_R_SUCCESS) {
|
||||
ccmsg->reading = false;
|
||||
isc_nmhandle_unref(ccmsg->handle);
|
||||
}
|
||||
|
||||
return (result);
|
||||
|
|
@ -172,6 +167,7 @@ isccc_ccmsg_cancelread(isccc_ccmsg_t *ccmsg) {
|
|||
|
||||
if (ccmsg->reading) {
|
||||
isc_nm_cancelread(ccmsg->handle);
|
||||
ccmsg->reading = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -58,7 +58,9 @@ void
|
|||
isccc_ccmsg_init(isc_mem_t *mctx, isc_nmhandle_t *handle, isccc_ccmsg_t *ccmsg);
|
||||
/*%
|
||||
* Associate a cc message state with a given memory context and
|
||||
* netmgr handle.
|
||||
* netmgr handle. (Note that the caller must hold a reference to
|
||||
* the handle during asynchronous ccmsg operations; the ccmsg code
|
||||
* does not hold the reference itself.)
|
||||
*
|
||||
* Requires:
|
||||
*
|
||||
|
|
|
|||
|
|
@ -275,7 +275,7 @@ static void
|
|||
client_senddone(isc_nmhandle_t *handle, isc_result_t result, void *cbarg) {
|
||||
ns_client_t *client = cbarg;
|
||||
|
||||
REQUIRE(client->handle == handle);
|
||||
REQUIRE(client->sendhandle == handle);
|
||||
|
||||
CTRACE("senddone");
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
|
|
@ -284,7 +284,7 @@ client_senddone(isc_nmhandle_t *handle, isc_result_t result, void *cbarg) {
|
|||
"send failed: %s", isc_result_totext(result));
|
||||
}
|
||||
|
||||
isc_nmhandle_unref(handle);
|
||||
isc_nmhandle_detach(&client->sendhandle);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -325,13 +325,18 @@ client_allocsendbuf(ns_client_t *client, isc_buffer_t *buffer,
|
|||
|
||||
static isc_result_t
|
||||
client_sendpkg(ns_client_t *client, isc_buffer_t *buffer) {
|
||||
isc_result_t result;
|
||||
isc_region_t r;
|
||||
|
||||
REQUIRE(client->sendhandle == NULL);
|
||||
|
||||
isc_buffer_usedregion(buffer, &r);
|
||||
|
||||
INSIST(client->handle != NULL);
|
||||
|
||||
return (isc_nm_send(client->handle, &r, client_senddone, client));
|
||||
isc_nmhandle_attach(client->handle, &client->sendhandle);
|
||||
result = isc_nm_send(client->handle, &r, client_senddone, client);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
isc_nmhandle_detach(&client->sendhandle);
|
||||
}
|
||||
return (result);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -383,7 +388,6 @@ done:
|
|||
}
|
||||
|
||||
ns_client_drop(client, result);
|
||||
isc_nmhandle_unref(client->handle);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -405,17 +409,13 @@ ns_client_send(ns_client_t *client) {
|
|||
isc_region_t zr;
|
||||
#endif /* HAVE_DNSTAP */
|
||||
|
||||
REQUIRE(NS_CLIENT_VALID(client));
|
||||
|
||||
/*
|
||||
* XXXWPK TODO
|
||||
* Delay the response according to the -T delay option
|
||||
*/
|
||||
|
||||
REQUIRE(NS_CLIENT_VALID(client));
|
||||
/*
|
||||
* We need to do it to make sure the client and handle
|
||||
* won't disappear from under us with client_senddone.
|
||||
*/
|
||||
|
||||
env = ns_interfacemgr_getaclenv(client->manager->interface->mgr);
|
||||
|
||||
CTRACE("send");
|
||||
|
|
@ -591,12 +591,7 @@ renderend:
|
|||
|
||||
respsize = isc_buffer_usedlength(&buffer);
|
||||
|
||||
isc_nmhandle_ref(client->handle);
|
||||
result = client_sendpkg(client, &buffer);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
/* We won't get a callback to clean it up */
|
||||
isc_nmhandle_unref(client->handle);
|
||||
}
|
||||
|
||||
switch (isc_sockaddr_pf(&client->peeraddr)) {
|
||||
case AF_INET:
|
||||
|
|
@ -626,12 +621,7 @@ renderend:
|
|||
|
||||
respsize = isc_buffer_usedlength(&buffer);
|
||||
|
||||
isc_nmhandle_ref(client->handle);
|
||||
result = client_sendpkg(client, &buffer);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
/* We won't get a callback to clean it up */
|
||||
isc_nmhandle_unref(client->handle);
|
||||
}
|
||||
|
||||
switch (isc_sockaddr_pf(&client->peeraddr)) {
|
||||
case AF_INET:
|
||||
|
|
@ -1683,6 +1673,7 @@ ns__client_request(isc_nmhandle_t *handle, isc_result_t eresult,
|
|||
ns__client_put_cb);
|
||||
client->handle = handle;
|
||||
}
|
||||
|
||||
if (isc_nmhandle_is_stream(handle)) {
|
||||
client->attributes |= NS_CLIENTATTR_TCP;
|
||||
}
|
||||
|
|
@ -1697,8 +1688,7 @@ ns__client_request(isc_nmhandle_t *handle, isc_result_t eresult,
|
|||
isc_buffer_add(&tbuffer, region->length);
|
||||
buffer = &tbuffer;
|
||||
|
||||
client->peeraddr = isc_nmhandle_peeraddr(client->handle);
|
||||
|
||||
client->peeraddr = isc_nmhandle_peeraddr(handle);
|
||||
client->peeraddr_valid = true;
|
||||
|
||||
reqsize = isc_buffer_usedlength(buffer);
|
||||
|
|
@ -1968,8 +1958,7 @@ ns__client_request(isc_nmhandle_t *handle, isc_result_t eresult,
|
|||
isc_netaddr_fromsockaddr(&client->destaddr,
|
||||
&client->manager->interface->addr);
|
||||
} else {
|
||||
isc_sockaddr_t sockaddr =
|
||||
isc_nmhandle_localaddr(client->handle);
|
||||
isc_sockaddr_t sockaddr = isc_nmhandle_localaddr(handle);
|
||||
isc_netaddr_fromsockaddr(&client->destaddr, &sockaddr);
|
||||
}
|
||||
|
||||
|
|
@ -2174,8 +2163,7 @@ ns__client_request(isc_nmhandle_t *handle, isc_result_t eresult,
|
|||
&client->requesttime, NULL, buffer);
|
||||
#endif /* HAVE_DNSTAP */
|
||||
|
||||
isc_nmhandle_ref(client->handle);
|
||||
ns_query_start(client);
|
||||
ns_query_start(client, handle);
|
||||
break;
|
||||
case dns_opcode_update:
|
||||
CTRACE("update");
|
||||
|
|
@ -2185,14 +2173,12 @@ ns__client_request(isc_nmhandle_t *handle, isc_result_t eresult,
|
|||
&client->requesttime, NULL, buffer);
|
||||
#endif /* HAVE_DNSTAP */
|
||||
ns_client_settimeout(client, 60);
|
||||
isc_nmhandle_ref(client->handle);
|
||||
ns_update_start(client, sigresult);
|
||||
ns_update_start(client, handle, sigresult);
|
||||
break;
|
||||
case dns_opcode_notify:
|
||||
CTRACE("notify");
|
||||
ns_client_settimeout(client, 60);
|
||||
isc_nmhandle_ref(client->handle);
|
||||
ns_notify_start(client);
|
||||
ns_notify_start(client, handle);
|
||||
break;
|
||||
case dns_opcode_iquery:
|
||||
CTRACE("iquery");
|
||||
|
|
|
|||
|
|
@ -183,14 +183,19 @@ struct ns_client {
|
|||
isc_task_t * task;
|
||||
dns_view_t * view;
|
||||
dns_dispatch_t * dispatch;
|
||||
isc_nmhandle_t * handle;
|
||||
unsigned char * tcpbuf;
|
||||
dns_message_t * message;
|
||||
unsigned char * sendbuf;
|
||||
dns_rdataset_t * opt;
|
||||
uint16_t udpsize;
|
||||
uint16_t extflags;
|
||||
int16_t ednsversion; /* -1 noedns */
|
||||
isc_nmhandle_t * handle; /* Permanent pointer to handle */
|
||||
isc_nmhandle_t * sendhandle; /* Waiting for send callback */
|
||||
isc_nmhandle_t * reqhandle; /* Waiting for request callback
|
||||
(query, update, notify) */
|
||||
isc_nmhandle_t *fetchhandle; /* Waiting for recursive fetch */
|
||||
isc_nmhandle_t *updatehandle; /* Waiting for update callback */
|
||||
unsigned char * tcpbuf;
|
||||
dns_message_t * message;
|
||||
unsigned char * sendbuf;
|
||||
dns_rdataset_t *opt;
|
||||
uint16_t udpsize;
|
||||
uint16_t extflags;
|
||||
int16_t ednsversion; /* -1 noedns */
|
||||
void (*cleanup)(ns_client_t *);
|
||||
void (*shutdown)(void *arg, isc_result_t result);
|
||||
void * shutdown_arg;
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@
|
|||
***/
|
||||
|
||||
void
|
||||
ns_notify_start(ns_client_t *client);
|
||||
ns_notify_start(ns_client_t *client, isc_nmhandle_t *handle);
|
||||
|
||||
/*%<
|
||||
* Examines the incoming message to determine appropriate zone.
|
||||
|
|
|
|||
|
|
@ -209,7 +209,7 @@ void
|
|||
ns_query_free(ns_client_t *client);
|
||||
|
||||
void
|
||||
ns_query_start(ns_client_t *client);
|
||||
ns_query_start(ns_client_t *client, isc_nmhandle_t *handle);
|
||||
|
||||
void
|
||||
ns_query_cancel(ns_client_t *client);
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@
|
|||
***/
|
||||
|
||||
void
|
||||
ns_update_start(ns_client_t *client, isc_result_t sigresult);
|
||||
ns_update_start(ns_client_t *client, isc_nmhandle_t *handle,
|
||||
isc_result_t sigresult);
|
||||
|
||||
#endif /* NS_UPDATE_H */
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ respond(ns_client_t *client, isc_result_t result) {
|
|||
}
|
||||
if (msg_result != ISC_R_SUCCESS) {
|
||||
ns_client_drop(client, msg_result);
|
||||
isc_nmhandle_unref(client->handle);
|
||||
isc_nmhandle_detach(&client->reqhandle);
|
||||
return;
|
||||
}
|
||||
message->rcode = rcode;
|
||||
|
|
@ -65,11 +65,11 @@ respond(ns_client_t *client, isc_result_t result) {
|
|||
}
|
||||
|
||||
ns_client_send(client);
|
||||
isc_nmhandle_unref(client->handle);
|
||||
isc_nmhandle_detach(&client->reqhandle);
|
||||
}
|
||||
|
||||
void
|
||||
ns_notify_start(ns_client_t *client) {
|
||||
ns_notify_start(ns_client_t *client, isc_nmhandle_t *handle) {
|
||||
dns_message_t *request = client->message;
|
||||
isc_result_t result;
|
||||
dns_name_t *zonename;
|
||||
|
|
@ -79,6 +79,11 @@ ns_notify_start(ns_client_t *client) {
|
|||
char tsigbuf[DNS_NAME_FORMATSIZE * 2 + sizeof(": TSIG '' ()")];
|
||||
dns_tsigkey_t *tsigkey;
|
||||
|
||||
/*
|
||||
* Attach to the request handle
|
||||
*/
|
||||
isc_nmhandle_attach(handle, &client->reqhandle);
|
||||
|
||||
/*
|
||||
* Interpret the question section.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -550,7 +550,7 @@ query_send(ns_client_t *client) {
|
|||
|
||||
inc_stats(client, counter);
|
||||
ns_client_send(client);
|
||||
isc_nmhandle_unref(client->handle);
|
||||
isc_nmhandle_detach(&client->reqhandle);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -577,7 +577,7 @@ query_error(ns_client_t *client, isc_result_t result, int line) {
|
|||
log_queryerror(client, result, line, loglevel);
|
||||
|
||||
ns_client_error(client, result);
|
||||
isc_nmhandle_unref(client->handle);
|
||||
isc_nmhandle_detach(&client->reqhandle);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -590,7 +590,7 @@ query_next(ns_client_t *client, isc_result_t result) {
|
|||
inc_stats(client, ns_statscounter_failure);
|
||||
}
|
||||
ns_client_drop(client, result);
|
||||
isc_nmhandle_unref(client->handle);
|
||||
isc_nmhandle_detach(&client->reqhandle);
|
||||
}
|
||||
|
||||
static inline void
|
||||
|
|
@ -2475,7 +2475,7 @@ prefetch_done(isc_task_t *task, isc_event_t *event) {
|
|||
}
|
||||
|
||||
free_devent(client, &event, &devent);
|
||||
isc_nmhandle_unref(client->handle);
|
||||
isc_nmhandle_detach(&client->fetchhandle);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -2518,7 +2518,7 @@ query_prefetch(ns_client_t *client, dns_name_t *qname,
|
|||
peeraddr = NULL;
|
||||
}
|
||||
|
||||
isc_nmhandle_ref(client->handle);
|
||||
isc_nmhandle_attach(client->handle, &client->fetchhandle);
|
||||
options = client->query.fetchoptions | DNS_FETCHOPT_PREFETCH;
|
||||
result = dns_resolver_createfetch(
|
||||
client->view->resolver, qname, rdataset->type, NULL, NULL, NULL,
|
||||
|
|
@ -2527,7 +2527,7 @@ query_prefetch(ns_client_t *client, dns_name_t *qname,
|
|||
&client->query.prefetch);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
ns_client_putrdataset(client, &tmprdataset);
|
||||
isc_nmhandle_unref(client->handle);
|
||||
isc_nmhandle_detach(&client->fetchhandle);
|
||||
}
|
||||
|
||||
dns_rdataset_clearprefetch(rdataset);
|
||||
|
|
@ -2732,7 +2732,7 @@ query_rpzfetch(ns_client_t *client, dns_name_t *qname, dns_rdatatype_t type) {
|
|||
}
|
||||
|
||||
options = client->query.fetchoptions;
|
||||
isc_nmhandle_ref(client->handle);
|
||||
isc_nmhandle_attach(client->handle, &client->fetchhandle);
|
||||
result = dns_resolver_createfetch(
|
||||
client->view->resolver, qname, type, NULL, NULL, NULL, peeraddr,
|
||||
client->message->id, options, 0, NULL, client->task,
|
||||
|
|
@ -2740,7 +2740,7 @@ query_rpzfetch(ns_client_t *client, dns_name_t *qname, dns_rdatatype_t type) {
|
|||
&client->query.prefetch);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
ns_client_putrdataset(client, &tmprdataset);
|
||||
isc_nmhandle_unref(client->handle);
|
||||
isc_nmhandle_detach(&client->fetchhandle);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -5703,6 +5703,8 @@ fetch_callback(isc_task_t *task, isc_event_t *event) {
|
|||
}
|
||||
UNLOCK(&client->manager->reclock);
|
||||
|
||||
isc_nmhandle_detach(&client->fetchhandle);
|
||||
|
||||
client->query.attributes &= ~NS_QUERYATTR_RECURSING;
|
||||
client->state = NS_CLIENTSTATE_WORKING;
|
||||
|
||||
|
|
@ -5748,7 +5750,6 @@ fetch_callback(isc_task_t *task, isc_event_t *event) {
|
|||
}
|
||||
|
||||
dns_resolver_destroyfetch(&fetch);
|
||||
isc_nmhandle_unref(client->handle);
|
||||
}
|
||||
|
||||
/*%
|
||||
|
|
@ -5940,14 +5941,14 @@ ns_query_recurse(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qname,
|
|||
peeraddr = &client->peeraddr;
|
||||
}
|
||||
|
||||
isc_nmhandle_ref(client->handle);
|
||||
isc_nmhandle_attach(client->handle, &client->fetchhandle);
|
||||
result = dns_resolver_createfetch(
|
||||
client->view->resolver, qname, qtype, qdomain, nameservers,
|
||||
NULL, peeraddr, client->message->id, client->query.fetchoptions,
|
||||
0, NULL, client->task, fetch_callback, client, rdataset,
|
||||
sigrdataset, &client->query.fetch);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
isc_nmhandle_unref(client->handle);
|
||||
isc_nmhandle_detach(&client->fetchhandle);
|
||||
ns_client_putrdataset(client, &rdataset);
|
||||
if (sigrdataset != NULL) {
|
||||
ns_client_putrdataset(client, &sigrdataset);
|
||||
|
|
@ -11108,7 +11109,7 @@ log_queryerror(ns_client_t *client, isc_result_t result, int line, int level) {
|
|||
}
|
||||
|
||||
void
|
||||
ns_query_start(ns_client_t *client) {
|
||||
ns_query_start(ns_client_t *client, isc_nmhandle_t *handle) {
|
||||
isc_result_t result;
|
||||
dns_message_t *message;
|
||||
dns_rdataset_t *rdataset;
|
||||
|
|
@ -11118,6 +11119,11 @@ ns_query_start(ns_client_t *client) {
|
|||
|
||||
REQUIRE(NS_CLIENT_VALID(client));
|
||||
|
||||
/*
|
||||
* Attach to the request handle
|
||||
*/
|
||||
isc_nmhandle_attach(handle, &client->reqhandle);
|
||||
|
||||
message = client->message;
|
||||
saved_extflags = client->extflags;
|
||||
saved_flags = client->message->flags;
|
||||
|
|
|
|||
|
|
@ -32,7 +32,8 @@ notify_test_SOURCES = \
|
|||
|
||||
notify_test_LDFLAGS = \
|
||||
$(LDFLAGS) \
|
||||
-Wl,--wrap=isc_nmhandle_unref
|
||||
-Wl,--wrap=isc_nmhandle_attach \
|
||||
-Wl,--wrap=isc_nmhandle_detach
|
||||
|
||||
query_test_SOURCES = \
|
||||
query_test.c \
|
||||
|
|
@ -40,7 +41,7 @@ query_test_SOURCES = \
|
|||
|
||||
query_test_LDFLAGS = \
|
||||
$(LDFLAGS) \
|
||||
-Wl,--wrap=isc_nmhandle_unref
|
||||
-Wl,--wrap=isc_nmhandle_detach
|
||||
|
||||
endif
|
||||
|
||||
|
|
|
|||
|
|
@ -86,6 +86,7 @@ static void
|
|||
notify_start(void **state) {
|
||||
isc_result_t result;
|
||||
ns_client_t *client = NULL;
|
||||
isc_nmhandle_t *handle = NULL;
|
||||
dns_message_t *nmsg = NULL;
|
||||
unsigned char ndata[4096];
|
||||
isc_buffer_t nbuf;
|
||||
|
|
@ -130,13 +131,16 @@ notify_start(void **state) {
|
|||
client->message = nmsg;
|
||||
nmsg = NULL;
|
||||
client->sendcb = check_response;
|
||||
ns_notify_start(client);
|
||||
ns_notify_start(client, client->handle);
|
||||
|
||||
/*
|
||||
* Clean up
|
||||
*/
|
||||
ns_test_cleanup_zone();
|
||||
isc_nmhandle_unref(client->handle);
|
||||
|
||||
handle = client->handle;
|
||||
isc_nmhandle_detach(&client->handle);
|
||||
isc_nmhandle_detach(&handle);
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
|||
|
|
@ -78,10 +78,32 @@ atomic_uint_fast32_t client_refs[32];
|
|||
atomic_uintptr_t client_addrs[32];
|
||||
|
||||
void
|
||||
__wrap_isc_nmhandle_unref(isc_nmhandle_t *handle);
|
||||
__wrap_isc_nmhandle_attach(isc_nmhandle_t *source, isc_nmhandle_t **targetp);
|
||||
void
|
||||
__wrap_isc_nmhandle_detach(isc_nmhandle_t **handlep);
|
||||
|
||||
void
|
||||
__wrap_isc_nmhandle_unref(isc_nmhandle_t *handle) {
|
||||
__wrap_isc_nmhandle_attach(isc_nmhandle_t *source, isc_nmhandle_t **targetp) {
|
||||
ns_client_t *client = (ns_client_t *)source;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 32; i++) {
|
||||
if (atomic_load(&client_addrs[i]) == (uintptr_t)client) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
INSIST(i < 32);
|
||||
INSIST(atomic_load(&client_refs[i]) > 0);
|
||||
|
||||
atomic_fetch_add(&client_refs[i], 1);
|
||||
|
||||
*targetp = source;
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
__wrap_isc_nmhandle_detach(isc_nmhandle_t **handlep) {
|
||||
isc_nmhandle_t *handle = *handlep;
|
||||
ns_client_t *client = (ns_client_t *)handle;
|
||||
int i;
|
||||
|
||||
|
|
@ -90,7 +112,7 @@ __wrap_isc_nmhandle_unref(isc_nmhandle_t *handle) {
|
|||
break;
|
||||
}
|
||||
}
|
||||
REQUIRE(i < 32);
|
||||
INSIST(i < 32);
|
||||
|
||||
if (atomic_fetch_sub(&client_refs[i], 1) == 1) {
|
||||
dns_view_detach(&client->view);
|
||||
|
|
@ -99,6 +121,8 @@ __wrap_isc_nmhandle_unref(isc_nmhandle_t *handle) {
|
|||
ns__client_put_cb(client);
|
||||
isc_mem_put(mctx, client, sizeof(ns_client_t));
|
||||
}
|
||||
|
||||
*handlep = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -743,11 +767,13 @@ create_qctx_for_client(ns_client_t *client, query_ctx_t **qctxp) {
|
|||
saved_hook_table = ns__hook_table;
|
||||
ns__hook_table = query_hooks;
|
||||
|
||||
ns_query_start(client);
|
||||
ns_query_start(client, client->handle);
|
||||
|
||||
ns__hook_table = saved_hook_table;
|
||||
ns_hooktable_free(mctx, (void **)&query_hooks);
|
||||
|
||||
isc_nmhandle_detach(&client->reqhandle);
|
||||
|
||||
if (*qctxp == NULL) {
|
||||
return (ISC_R_NOMEMORY);
|
||||
} else {
|
||||
|
|
@ -760,6 +786,7 @@ ns_test_qctx_create(const ns_test_qctx_create_params_t *params,
|
|||
query_ctx_t **qctxp) {
|
||||
ns_client_t *client = NULL;
|
||||
isc_result_t result;
|
||||
isc_nmhandle_t *handle = NULL;
|
||||
|
||||
REQUIRE(params != NULL);
|
||||
REQUIRE(params->qname != NULL);
|
||||
|
|
@ -810,17 +837,19 @@ ns_test_qctx_create(const ns_test_qctx_create_params_t *params,
|
|||
}
|
||||
|
||||
/*
|
||||
* Reference count for "client" is now at 2, so decrement it in order
|
||||
* for it to drop to zero when "qctx" gets destroyed.
|
||||
* The reference count for "client" is now at 2, so we need to
|
||||
* decrement it in order for it to drop to zero when "qctx" gets
|
||||
* destroyed.
|
||||
*/
|
||||
isc_nmhandle_unref(client->handle);
|
||||
handle = client->handle;
|
||||
isc_nmhandle_detach(&handle);
|
||||
|
||||
return (ISC_R_SUCCESS);
|
||||
|
||||
destroy_query:
|
||||
dns_message_destroy(&client->message);
|
||||
detach_client:
|
||||
isc_nmhandle_unref(client->handle);
|
||||
isc_nmhandle_detach(&client->handle);
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
|
@ -842,7 +871,7 @@ ns_test_qctx_destroy(query_ctx_t **qctxp) {
|
|||
dns_db_detach(&qctx->db);
|
||||
}
|
||||
if (qctx->client != NULL) {
|
||||
isc_nmhandle_unref(qctx->client->handle);
|
||||
isc_nmhandle_detach(&qctx->client->handle);
|
||||
}
|
||||
|
||||
isc_mem_put(mctx, qctx, sizeof(*qctx));
|
||||
|
|
|
|||
|
|
@ -26,15 +26,22 @@
|
|||
#include <ns/client.h>
|
||||
|
||||
/*
|
||||
* This overrides calls to isc_nmhandle_unref(), sending them to
|
||||
* __wrap_isc_nmhandle_unref(), when libtool is in use and LD_WRAP
|
||||
* can't be used.
|
||||
* This overrides calls to isc_nmhandle_attach/detach(), sending them to
|
||||
* __wrap_isc_nmhandle_attach/detach() instead, when libtool is in use
|
||||
* and LD_WRAP can't be used.
|
||||
*/
|
||||
|
||||
void
|
||||
__wrap_isc_nmhandle_attach(isc_nmhandle_t *source, isc_nmhandle_t **targetp);
|
||||
extern void
|
||||
__wrap_isc_nmhandle_unref(isc_nmhandle_t *handle);
|
||||
__wrap_isc_nmhandle_detach(isc_nmhandle_t **handlep);
|
||||
|
||||
void
|
||||
isc_nmhandle_unref(isc_nmhandle_t *handle) {
|
||||
__wrap_isc_nmhandle_unref(handle);
|
||||
isc_nmhandle_attach(isc_nmhandle_t *source, isc_nmhandle_t **targetp) {
|
||||
__wrap_isc_nmhandle_attach(source, targetp);
|
||||
}
|
||||
|
||||
void
|
||||
isc_nmhandle_detach(isc_nmhandle_t **handlep) {
|
||||
__wrap_isc_nmhandle_detach(handlep);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1567,7 +1567,7 @@ send_update_event(ns_client_t *client, dns_zone_t *zone) {
|
|||
client->nupdates++;
|
||||
event->ev_arg = client;
|
||||
|
||||
isc_nmhandle_ref(client->handle);
|
||||
isc_nmhandle_attach(client->handle, &client->updatehandle);
|
||||
dns_zone_gettask(zone, &zonetask);
|
||||
isc_task_send(zonetask, ISC_EVENT_PTR(&event));
|
||||
|
||||
|
|
@ -1585,7 +1585,6 @@ respond(ns_client_t *client, isc_result_t result) {
|
|||
client->message->rcode = dns_result_torcode(result);
|
||||
|
||||
ns_client_send(client);
|
||||
isc_nmhandle_unref(client->handle);
|
||||
return;
|
||||
|
||||
msg_failure:
|
||||
|
|
@ -1594,17 +1593,23 @@ msg_failure:
|
|||
"could not create update response message: %s",
|
||||
isc_result_totext(msg_result));
|
||||
ns_client_drop(client, msg_result);
|
||||
isc_nmhandle_unref(client->handle);
|
||||
isc_nmhandle_detach(&client->reqhandle);
|
||||
}
|
||||
|
||||
void
|
||||
ns_update_start(ns_client_t *client, isc_result_t sigresult) {
|
||||
ns_update_start(ns_client_t *client, isc_nmhandle_t *handle,
|
||||
isc_result_t sigresult) {
|
||||
dns_message_t *request = client->message;
|
||||
isc_result_t result;
|
||||
dns_name_t *zonename;
|
||||
dns_rdataset_t *zone_rdataset;
|
||||
dns_zone_t *zone = NULL, *raw = NULL;
|
||||
|
||||
/*
|
||||
* Attach to the request handle
|
||||
*/
|
||||
isc_nmhandle_attach(handle, &client->reqhandle);
|
||||
|
||||
/*
|
||||
* Interpret the zone section.
|
||||
*/
|
||||
|
|
@ -1673,6 +1678,8 @@ ns_update_start(ns_client_t *client, isc_result_t sigresult) {
|
|||
default:
|
||||
FAILC(DNS_R_NOTAUTH, "not authoritative for update zone");
|
||||
}
|
||||
|
||||
isc_nmhandle_detach(&client->reqhandle);
|
||||
return;
|
||||
|
||||
failure:
|
||||
|
|
@ -1690,6 +1697,7 @@ failure:
|
|||
if (zone != NULL) {
|
||||
dns_zone_detach(&zone);
|
||||
}
|
||||
isc_nmhandle_detach(&client->reqhandle);
|
||||
}
|
||||
|
||||
/*%
|
||||
|
|
@ -3497,6 +3505,7 @@ common:
|
|||
}
|
||||
uev->ev_type = DNS_EVENT_UPDATEDONE;
|
||||
uev->ev_action = updatedone_action;
|
||||
|
||||
isc_task_send(client->task, &event);
|
||||
|
||||
INSIST(ver == NULL);
|
||||
|
|
@ -3510,8 +3519,9 @@ updatedone_action(isc_task_t *task, isc_event_t *event) {
|
|||
|
||||
UNUSED(task);
|
||||
|
||||
INSIST(event->ev_type == DNS_EVENT_UPDATEDONE);
|
||||
INSIST(task == client->task);
|
||||
REQUIRE(event->ev_type == DNS_EVENT_UPDATEDONE);
|
||||
REQUIRE(task == client->task);
|
||||
REQUIRE(client->updatehandle == client->handle);
|
||||
|
||||
INSIST(client->nupdates > 0);
|
||||
switch (uev->result) {
|
||||
|
|
@ -3528,16 +3538,18 @@ updatedone_action(isc_task_t *task, isc_event_t *event) {
|
|||
if (uev->zone != NULL) {
|
||||
dns_zone_detach(&uev->zone);
|
||||
}
|
||||
|
||||
client->nupdates--;
|
||||
|
||||
respond(client, uev->result);
|
||||
|
||||
isc_event_free(&event);
|
||||
isc_nmhandle_unref(client->handle);
|
||||
isc_nmhandle_detach(&client->updatehandle);
|
||||
}
|
||||
|
||||
/*%
|
||||
* Update forwarding support.
|
||||
*/
|
||||
|
||||
static void
|
||||
forward_fail(isc_task_t *task, isc_event_t *event) {
|
||||
ns_client_t *client = (ns_client_t *)event->ev_arg;
|
||||
|
|
@ -3548,7 +3560,7 @@ forward_fail(isc_task_t *task, isc_event_t *event) {
|
|||
client->nupdates--;
|
||||
respond(client, DNS_R_SERVFAIL);
|
||||
isc_event_free(&event);
|
||||
isc_nmhandle_unref(client->handle);
|
||||
isc_nmhandle_detach(&client->updatehandle);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -3568,6 +3580,7 @@ forward_callback(void *arg, isc_result_t result, dns_message_t *answer) {
|
|||
uev->answer = answer;
|
||||
inc_stats(client, zone, ns_statscounter_updaterespfwd);
|
||||
}
|
||||
|
||||
isc_task_send(client->task, ISC_EVENT_PTR(&uev));
|
||||
dns_zone_detach(&zone);
|
||||
}
|
||||
|
|
@ -3584,7 +3597,7 @@ forward_done(isc_task_t *task, isc_event_t *event) {
|
|||
ns_client_sendraw(client, uev->answer);
|
||||
dns_message_destroy(&uev->answer);
|
||||
isc_event_free(&event);
|
||||
isc_nmhandle_unref(client->handle);
|
||||
isc_nmhandle_detach(&client->updatehandle);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -3636,7 +3649,7 @@ send_forward_event(ns_client_t *client, dns_zone_t *zone) {
|
|||
namebuf, classbuf);
|
||||
|
||||
dns_zone_gettask(zone, &zonetask);
|
||||
isc_nmhandle_ref(client->handle);
|
||||
isc_nmhandle_attach(client->handle, &client->updatehandle);
|
||||
isc_task_send(zonetask, ISC_EVENT_PTR(&event));
|
||||
|
||||
if (event != NULL) {
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@
|
|||
#include <isc/mem.h>
|
||||
#include <isc/print.h>
|
||||
#include <isc/stats.h>
|
||||
#include <isc/timer.h>
|
||||
#include <isc/util.h>
|
||||
|
||||
#include <dns/db.h>
|
||||
|
|
@ -34,7 +33,6 @@
|
|||
#include <dns/rriterator.h>
|
||||
#include <dns/soa.h>
|
||||
#include <dns/stats.h>
|
||||
#include <dns/timer.h>
|
||||
#include <dns/tsig.h>
|
||||
#include <dns/view.h>
|
||||
#include <dns/zone.h>
|
||||
|
|
@ -1192,7 +1190,7 @@ failure:
|
|||
NS_LOGMODULE_XFER_OUT, ISC_LOG_DEBUG(3),
|
||||
"zone transfer setup failed");
|
||||
ns_client_error(client, result);
|
||||
isc_nmhandle_unref(client->handle);
|
||||
isc_nmhandle_detach(&client->reqhandle);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1276,11 +1274,6 @@ xfrout_ctx_create(isc_mem_t *mctx, ns_client_t *client, unsigned int id,
|
|||
xfr->txmem = mem;
|
||||
xfr->txmemlen = len;
|
||||
|
||||
#if 0
|
||||
CHECK(dns_timer_setidle(xfr->client->timer,
|
||||
maxtime,idletime,false));
|
||||
#endif /* if 0 */
|
||||
|
||||
/*
|
||||
* Register a shutdown callback with the client, so that we
|
||||
* can stop the transfer immediately when the client task
|
||||
|
|
@ -1572,15 +1565,17 @@ sendstream(xfrout_ctx_t *xfr) {
|
|||
xfrout_log(xfr, ISC_LOG_DEBUG(8),
|
||||
"sending TCP message of %d bytes", used.length);
|
||||
|
||||
CHECK(isc_nm_send(xfr->client->handle, &used, xfrout_senddone,
|
||||
xfr));
|
||||
isc_nmhandle_attach(xfr->client->handle,
|
||||
&xfr->client->sendhandle);
|
||||
CHECK(isc_nm_send(xfr->client->sendhandle, &used,
|
||||
xfrout_senddone, xfr));
|
||||
xfr->sends++;
|
||||
xfr->cbytes = used.length;
|
||||
} else {
|
||||
xfrout_log(xfr, ISC_LOG_DEBUG(8), "sending IXFR UDP response");
|
||||
ns_client_send(xfr->client);
|
||||
xfr->stream->methods->pause(xfr->stream);
|
||||
isc_nmhandle_unref(xfr->client->handle);
|
||||
isc_nmhandle_detach(&xfr->client->reqhandle);
|
||||
xfrout_ctx_destroy(&xfr);
|
||||
return;
|
||||
}
|
||||
|
|
@ -1623,6 +1618,10 @@ failure:
|
|||
return;
|
||||
}
|
||||
|
||||
if (xfr->client->sendhandle != NULL) {
|
||||
isc_nmhandle_detach(&xfr->client->sendhandle);
|
||||
}
|
||||
|
||||
xfrout_fail(xfr, result, "sending zone data");
|
||||
}
|
||||
|
||||
|
|
@ -1675,6 +1674,8 @@ xfrout_senddone(isc_nmhandle_t *handle, isc_result_t result, void *arg) {
|
|||
xfr->sends--;
|
||||
INSIST(xfr->sends == 0);
|
||||
|
||||
isc_nmhandle_detach(&xfr->client->sendhandle);
|
||||
|
||||
/*
|
||||
* Update transfer statistics if sending succeeded, accounting for the
|
||||
* two-byte TCP length prefix included in the number of bytes sent.
|
||||
|
|
@ -1684,10 +1685,6 @@ xfrout_senddone(isc_nmhandle_t *handle, isc_result_t result, void *arg) {
|
|||
xfr->stats.nbytes += xfr->cbytes;
|
||||
}
|
||||
|
||||
#if 0
|
||||
(void)isc_timer_touch(xfr->client->timer);
|
||||
#endif /* if 0 */
|
||||
|
||||
if (xfr->shuttingdown) {
|
||||
xfrout_maybe_destroy(xfr);
|
||||
} else if (result != ISC_R_SUCCESS) {
|
||||
|
|
@ -1716,9 +1713,12 @@ xfrout_senddone(isc_nmhandle_t *handle, isc_result_t result, void *arg) {
|
|||
(unsigned int)(msecs % 1000), (unsigned int)persec,
|
||||
xfr->end_serial);
|
||||
|
||||
/*
|
||||
* We're done, unreference the handle and destroy the xfr
|
||||
* context.
|
||||
*/
|
||||
isc_nmhandle_detach(&xfr->client->reqhandle);
|
||||
xfrout_ctx_destroy(&xfr);
|
||||
/* We're done, unreference the handle */
|
||||
isc_nmhandle_unref(handle);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1732,23 +1732,11 @@ xfrout_fail(xfrout_ctx_t *xfr, isc_result_t result, const char *msg) {
|
|||
|
||||
static void
|
||||
xfrout_maybe_destroy(xfrout_ctx_t *xfr) {
|
||||
INSIST(xfr->shuttingdown);
|
||||
#if 0
|
||||
if (xfr->sends > 0) {
|
||||
/*
|
||||
* If we are currently sending, cancel it and wait for
|
||||
* cancel event before destroying the context.
|
||||
*/
|
||||
isc_socket_cancel(xfr->client->tcpsocket,xfr->client->task,
|
||||
ISC_SOCKCANCEL_SEND);
|
||||
} else {
|
||||
#endif /* if 0 */
|
||||
REQUIRE(xfr->shuttingdown);
|
||||
|
||||
ns_client_drop(xfr->client, ISC_R_CANCELED);
|
||||
isc_nmhandle_unref(xfr->client->handle);
|
||||
isc_nmhandle_detach(&xfr->client->reqhandle);
|
||||
xfrout_ctx_destroy(&xfr);
|
||||
#if 0
|
||||
}
|
||||
#endif /* if 0 */
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
|||
Loading…
Reference in a new issue