isc_result_t
isc_nm_listentcpdns(isc_nm_t *mgr, isc_nmiface_t *iface,
- isc_nm_recv_cb_t cb, void *arg,
- size_t extrahandlesize, int backlog,
- isc_quota_t *quota,
- isc_nmsocket_t **sockp);
+ isc_nm_recv_cb_t cb, void *cbarg,
+ isc_nm_cb_t accept_cb, void *accept_cbarg,
+ size_t extrahandlesize, int backlog, isc_quota_t *quota,
+ isc_nmsocket_t **sockp);
/*%<
* Start listening for DNS messages over the TCP interface 'iface', using
* net manager 'mgr'.
* When a complete DNS message is received on the socket, 'cb' will be
* called with 'cbarg' as its argument.
*
+ * When a new TCP connection is accepted, 'accept_cb' will be called
+ * with 'accept_cbarg' 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).
isc__nm_readcb_t rcb;
void *rcbarg;
+
+ isc__nm_cb_t accept_cb;
+ void *accept_cbarg;
};
bool
}
/*
- * Accept callback for TCP-DNS connection
+ * Accept callback for TCP-DNS connection.
*/
static void
dnslisten_acceptcb(isc_nmhandle_t *handle, isc_result_t result, void *cbarg) {
return;
}
+ if (dnslistensock->accept_cb.accept != NULL) {
+ dnslistensock->accept_cb.accept(handle, ISC_R_SUCCESS,
+ dnslistensock->accept_cbarg);
+ }
+
/* We need to create a 'wrapper' dnssocket for this connection */
dnssock = isc_mem_get(handle->sock->mgr->mctx, sizeof(*dnssock));
- isc__nmsocket_init(dnssock, handle->sock->mgr,
- isc_nm_tcpdnssocket);
+ isc__nmsocket_init(dnssock, handle->sock->mgr, isc_nm_tcpdnssocket);
/* We need to copy read callbacks from outer socket */
dnssock->rcb.recv = dnslistensock->rcb.recv;
isc_result_t
isc_nm_listentcpdns(isc_nm_t *mgr, isc_nmiface_t *iface,
isc_nm_recv_cb_t cb, void *cbarg,
- size_t extrahandlesize, int backlog,
- isc_quota_t *quota,
+ isc_nm_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 */
dnslistensock->iface = iface;
dnslistensock->rcb.recv = cb;
dnslistensock->rcbarg = cbarg;
+ dnslistensock->accept_cb.accept = accept_cb;
+ dnslistensock->accept_cbarg = accept_cbarg;
dnslistensock->extrahandlesize = extrahandlesize;
/* We set dnslistensock->outer to a true listening socket */
}
if (isc_nmhandle_is_stream(handle)) {
client->attributes |= NS_CLIENTATTR_TCP;
- unsigned int curr_tcpquota =
- isc_quota_getused(&client->sctx->tcpquota);
- ns_stats_update_if_greater(client->sctx->nsstats,
- ns_statscounter_tcphighwater,
- curr_tcpquota);
}
INSIST(client->recursionquota == NULL);
isc_task_unpause(client->task);
}
+void
+ns__client_tcpconn(isc_nmhandle_t *handle, isc_result_t result, void *arg) {
+ ns_server_t *sctx = (ns_server_t *) arg;
+ unsigned int tcpquota;
+
+ UNUSED(handle);
+ UNUSED(result);
+
+ tcpquota = isc_quota_getused(&sctx->tcpquota);
+ ns_stats_update_if_greater(sctx->nsstats,
+ ns_statscounter_tcphighwater,
+ tcpquota);
+}
+
static void
get_clientmctx(ns_clientmgr_t *manager, isc_mem_t **mctxp) {
isc_mem_t *clientmctx;
ns_client_addopt(ns_client_t *client, dns_message_t *message,
dns_rdataset_t **opt);
-/*
+/*%<
* Get a client object from the inactive queue, or create one, as needed.
* (Not intended for use outside this module and associated tests.)
*/
void
ns__client_request(isc_nmhandle_t *handle, isc_region_t *region, void *arg);
-/*
+/*%<
* Handle client requests.
* (Not intended for use outside this module and associated tests.)
*/
+ void
+ ns__client_tcpconn(isc_nmhandle_t *handle, isc_result_t result, void *arg);
+
+ /*%<
+ * Called every time a TCP connection is establish. This is used for
+ * updating TCP statistics.
+ */
+
dns_rdataset_t *
ns_client_newrdataset(ns_client_t *client);
static isc_result_t
ns_interface_listentcp(ns_interface_t *ifp) {
- unsigned int tcpquota;
isc_result_t result;
result = isc_nm_listentcpdns(ifp->mgr->nm,
(isc_nmiface_t *) &ifp->addr,
ns__client_request, ifp,
+ ns__client_tcpconn, ifp->mgr->sctx,
sizeof(ns_client_t),
ifp->mgr->backlog,
&ifp->mgr->sctx->tcpquota,
}
/*
- * We update tcp-highwater stats here, since named itself adds to
- * the TCP quota when starting, as it ensures that at least one
- * client will be created for every interface it is listening to.
+ * We call this now to update the tcp-highwater statistic:
+ * this is necessary because we are adding to the TCP quota just
+ * by listening.
*/
- tcpquota = isc_quota_getused(&ifp->mgr->sctx->tcpquota);
- ns_stats_update_if_greater(ifp->mgr->sctx->nsstats,
- ns_statscounter_tcphighwater,
- tcpquota);
+ ns__client_tcpconn(NULL, ISC_R_SUCCESS, ifp->mgr->sctx);
#if 0
#ifndef ISC_ALLOW_MAPPED