- add support for TCP backlog, using the value provided by config.
- don't attach to TCP client quota for listening sockets, only
connected sockets.
echo_i "TCP high-water: check initial statistics ($n)"
ret=0
refresh_tcp_stats
-assert_int_equal "${TCP_CUR}" 1 "current TCP clients count" || ret=1
+assert_int_equal "${TCP_CUR}" 0 "current TCP clients count" || ret=1
if [ $ret != 0 ]; then echo_i "failed"; fi
status=$((status + ret))
isc_result_t
isc_nm_listentcp(isc_nm_t *mgr, isc_nmiface_t *iface,
isc_nm_cb_t cb, void *cbarg,
- size_t extrahandlesize, isc_quota_t *quota,
+ size_t extrahandlesize, int backlog,
+ isc_quota_t *quota,
isc_nmsocket_t **sockp);
/*%<
* Start listening for raw messages over the TCP interface 'iface', using
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, isc_quota_t *quota,
+ size_t extrahandlesize, int backlog,
+ isc_quota_t *quota,
isc_nmsocket_t **sockp);
/*%<
* Start listening for DNS messages over the TCP interface 'iface', using
isc_nmsocket_type type;
isc_nm_t *mgr;
isc_nmsocket_t *parent;
+
+ /*
+ * quota is the TCP client, attached when a TCP connection
+ * is established. pquota is a non-attached pointer to the
+ * TCP client quota, stored in listening sockets but only
+ * attached in connected sockets.
+ */
isc_quota_t *quota;
+ isc_quota_t *pquota;
bool overquota;
+
+ /*
+ * TCP read timeout timer.
+ */
uv_timer_t timer;
bool timer_initialized;
uint64_t read_timeout;
/*% extra data allocated at the end of each isc_nmhandle_t */
size_t extrahandlesize;
+ /*% TCP backlog */
+ int backlog;
+
/*% libuv data */
uv_os_sock_t fd;
union uv_any_handle uv_handle;
isc_quota_detach(&sock->quota);
}
+ sock->pquota = NULL;
+
if (sock->timer_initialized) {
uv_close((uv_handle_t *)&sock->timer, NULL);
sock->timer_initialized = false;
isc_result_t
isc_nm_listentcp(isc_nm_t *mgr, isc_nmiface_t *iface,
isc_nm_cb_t cb, void *cbarg,
- size_t extrahandlesize, isc_quota_t *quota,
+ size_t extrahandlesize, int backlog,
+ isc_quota_t *quota,
isc_nmsocket_t **sockp)
{
isc__netievent_tcplisten_t *ievent = NULL;
nsock->rcb.accept = cb;
nsock->rcbarg = cbarg;
nsock->extrahandlesize = extrahandlesize;
+ nsock->backlog = backlog;
if (quota != NULL) {
/*
- * We need to force it to make sure we get it attached.
- * An example failure mode would be server under attack
- * reconfiguring interfaces - that might cause weak attach
- * to fail and leave this listening socket without limits.
- * We can ignore the result.
+ * We don't attach to quota, just assign - to avoid
+ * increasing quota unnecesarily.
*/
- isc_quota_force(quota, &nsock->quota);
+ nsock->pquota = quota;
}
nsock->tid = isc_random_uniform(mgr->nworkers);
}
uv_tcp_bind(&sock->uv_handle.tcp, &sock->iface->addr.type.sa, 0);
- r = uv_listen((uv_stream_t *) &sock->uv_handle.tcp, 10,
+ r = uv_listen((uv_stream_t *) &sock->uv_handle.tcp, sock->backlog,
tcp_connection_cb);
if (r != 0) {
return;
SIGNAL(&sock->cond);
UNLOCK(&sock->lock);
- if (sock->quota != NULL) {
- isc_quota_detach(&sock->quota);
- }
+ sock->pquota = NULL;
isc_nmsocket_detach(&sock);
}
return (ISC_R_CANCELED);
}
- if (ssock->quota != NULL) {
- result = isc_quota_attach(ssock->quota, "a);
+ if (ssock->pquota != NULL) {
+ result = isc_quota_attach(ssock->pquota, "a);
if (result != ISC_R_SUCCESS) {
return (result);
}
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, isc_quota_t *quota,
+ size_t extrahandlesize, int backlog,
+ isc_quota_t *quota,
isc_nmsocket_t **sockp)
{
/* A 'wrapper' socket object with outer set to true TCP socket */
/* We set dnslistensock->outer to a true listening socket */
result = isc_nm_listentcp(mgr, iface, dnslisten_acceptcb,
- dnslistensock, extrahandlesize,
+ dnslistensock, extrahandlesize, backlog,
quota, &dnslistensock->outer);
atomic_store(&dnslistensock->listening, true);
(isc_nmiface_t *) &ifp->addr,
ns__client_request, ifp,
sizeof(ns_client_t),
+ ifp->mgr->backlog,
&ifp->mgr->sctx->tcpquota,
&ifp->tcplistensocket);
if (result != ISC_R_SUCCESS) {