isc_event_free(eventp);
}
+static isc_result_t
+recursionquota_attach(ns_client_t *client, bool soft_limit) {
+ isc_result_t result;
+
+ if (client->recursionquota != NULL) {
+ return (ISC_R_SUCCESS);
+ }
+
+ result = isc_quota_attach(&client->manager->sctx->recursionquota,
+ &client->recursionquota);
+ switch (result) {
+ case ISC_R_SUCCESS:
+ break;
+ case ISC_R_SOFTQUOTA:
+ if (soft_limit) {
+ /*
+ * Exceeding soft quota was allowed, so continue as if
+ * 'result' was ISC_R_SUCCESS while retaining the
+ * original result code.
+ */
+ break;
+ }
+
+ isc_quota_detach(&client->recursionquota);
+ FALLTHROUGH;
+ default:
+ return (result);
+ }
+
+ ns_stats_increment(client->manager->sctx->nsstats,
+ ns_statscounter_recursclients);
+
+ return (result);
+}
+
+static isc_result_t
+recursionquota_attach_hard(ns_client_t *client) {
+ return (recursionquota_attach(client, false));
+}
+
+static isc_result_t
+recursionquota_attach_soft(ns_client_t *client) {
+ return (recursionquota_attach(client, true));
+}
+
static void
recursionquota_detach(ns_client_t *client) {
if (client->recursionquota != NULL) {
return;
}
- if (client->recursionquota == NULL) {
- result =
- isc_quota_attach(&client->manager->sctx->recursionquota,
- &client->recursionquota);
- switch (result) {
- case ISC_R_SUCCESS:
- break;
- case ISC_R_SOFTQUOTA:
- isc_quota_detach(&client->recursionquota);
- FALLTHROUGH;
- default:
- return;
- }
+ result = recursionquota_attach_hard(client);
+ if (result != ISC_R_SUCCESS) {
+ return;
}
- ns_stats_increment(client->manager->sctx->nsstats,
- ns_statscounter_recursclients);
-
tmprdataset = ns_client_newrdataset(client);
if (!TCP(client)) {
return;
}
- if (client->recursionquota == NULL) {
- result =
- isc_quota_attach(&client->manager->sctx->recursionquota,
- &client->recursionquota);
- switch (result) {
- case ISC_R_SUCCESS:
- break;
- case ISC_R_SOFTQUOTA:
- isc_quota_detach(&client->recursionquota);
- FALLTHROUGH;
- default:
- return;
- }
+ result = recursionquota_attach_hard(client);
+ if (result != ISC_R_SUCCESS) {
+ return;
}
- ns_stats_increment(client->manager->sctx->nsstats,
- ns_statscounter_recursclients);
-
tmprdataset = ns_client_newrdataset(client);
if (!TCP(client)) {
* connection was accepted (if allowed by the TCP quota).
*/
if (client->recursionquota == NULL) {
- result =
- isc_quota_attach(&client->manager->sctx->recursionquota,
- &client->recursionquota);
+ result = recursionquota_attach_soft(client);
if (result == ISC_R_SOFTQUOTA) {
isc_stdtime_t now;
isc_stdtime_get(&now);
return (result);
}
- ns_stats_increment(client->manager->sctx->nsstats,
- ns_statscounter_recursclients);
-
/*
* Invoke the resolver.
*/
goto cleanup;
}
- ns_stats_increment(client->manager->sctx->nsstats,
- ns_statscounter_recursclients);
-
saved_qctx = isc_mem_get(client->manager->mctx, sizeof(*saved_qctx));
qctx_save(qctx, saved_qctx);
result = runasync(saved_qctx, client->manager->mctx, arg,