Commit 2f3876d1 authored by Evan Hunt's avatar Evan Hunt Committed by Ondřej Surý
Browse files

refactor tcpquota and pipeline refs; allow special-case overrun in isc_quota

- if the TCP quota has been exceeded but there are no clients listening
  for new connections on the interface, we can now force attachment to the
  quota using isc_quota_force(), instead of carrying on with the quota not
  attached.
- the TCP client quota is now referenced via a reference-counted
  'ns_tcpconn' object, one of which is created whenever a client begins
  listening for new connections, and attached to by members of that
  client's pipeline group. when the last reference to the tcpconn
  object is detached, it is freed and the TCP quota slot is released.
- reduce code duplication by adding mark_tcp_active() function
- convert counters to stdatomic

(cherry picked from commit a8dd133d270873b736c1be9bf50ebaa074f5b38f)
(cherry picked from commit 4a8fc979)
parent a0f4a3fa
......@@ -115,6 +115,13 @@ isc_quota_attach(isc_quota_t *quota, isc_quota_t **p);
* quota if successful (ISC_R_SUCCESS or ISC_R_SOFTQUOTA).
*/
isc_result_t
isc_quota_force(isc_quota_t *quota, isc_quota_t **p);
/*%<
* Like isc_quota_attach, but will attach '*p' to the quota
* even if the hard quota has been exceeded.
*/
void
isc_quota_detach(isc_quota_t **p);
/*%<
......
......@@ -83,20 +83,36 @@ isc_quota_release(isc_quota_t *quota) {
INSIST(atomic_fetch_sub(&quota->used, 1) > 0);
}
isc_result_t
isc_quota_attach(isc_quota_t *quota, isc_quota_t **p)
{
static isc_result_t
doattach(isc_quota_t *quota, isc_quota_t **p, bool force) {
isc_result_t result;
INSIST(p != NULL && *p == NULL);
REQUIRE(p != NULL && *p == NULL);
result = isc_quota_reserve(quota);
if (result == ISC_R_SUCCESS || result == ISC_R_SOFTQUOTA)
if (result == ISC_R_SUCCESS || result == ISC_R_SOFTQUOTA) {
*p = quota;
} else if (result == ISC_R_QUOTA && force) {
/* attach anyway */
atomic_fetch_add(&quota->used, 1);
*p = quota;
result = ISC_R_SUCCESS;
}
return (result);
}
isc_result_t
isc_quota_attach(isc_quota_t *quota, isc_quota_t **p) {
return (doattach(quota, p, false));
}
isc_result_t
isc_quota_force(isc_quota_t *quota, isc_quota_t **p) {
return (doattach(quota, p, true));
}
void
isc_quota_detach(isc_quota_t **p)
{
isc_quota_detach(isc_quota_t **p) {
INSIST(p != NULL && *p != NULL);
isc_quota_release(*p);
*p = NULL;
......
......@@ -449,6 +449,7 @@ isc_portset_removerange
isc_quota_attach
isc_quota_destroy
isc_quota_detach
isc_quota_force
isc_quota_getmax
isc_quota_getsoft
isc_quota_getused
......
This diff is collapsed.
......@@ -80,6 +80,13 @@
*** Types
***/
/*% reference-counted TCP connection object */
typedef struct ns_tcpconn {
isc_refcount_t refs;
isc_quota_t *tcpquota;
bool pipelined;
} ns_tcpconn_t;
/*% nameserver client structure */
struct ns_client {
unsigned int magic;
......@@ -134,10 +141,7 @@ struct ns_client {
dns_name_t signername; /*%< [T]SIG key name */
dns_name_t *signer; /*%< NULL if not valid sig */
bool mortal; /*%< Die after handling request */
bool pipelined; /*%< TCP queries not in sequence */
isc_refcount_t *pipeline_refs;
isc_quota_t *tcpquota;
bool tcpattached;
ns_tcpconn_t *tcpconn;
isc_quota_t *recursionquota;
ns_interface_t *interface;
......
......@@ -76,11 +76,11 @@ struct ns_interface {
/*%< UDP dispatchers. */
isc_socket_t * tcpsocket; /*%< TCP socket. */
isc_dscp_t dscp; /*%< "listen-on" DSCP value */
int ntcpaccepting; /*%< Number of clients
atomic_uint_fast32_t ntcpaccepting; /*%< Number of clients
ready to accept new
TCP connections on this
interface */
int ntcpactive; /*%< Number of clients
atomic_uint_fast32_t ntcpactive; /*%< Number of clients
servicing TCP queries
(whether accepting or
connected) */
......
......@@ -423,8 +423,9 @@ ns_interface_create(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr,
* connections will be handled in parallel even though there is
* only one client initially.
*/
ifp->ntcpaccepting = 0;
ifp->ntcpactive = 0;
atomic_init(&ifp->ntcpaccepting, 0);
atomic_init(&ifp->ntcpactive, 0);
ifp->nudpdispatch = 0;
ifp->dscp = -1;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment