mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-09-01 06:55:30 +00:00
187. [func] isc_ratelimter_enqueue() has an additional arguement
'task'. checkpoint zone maintence / notify work.
This commit is contained in:
174
lib/dns/zone.c
174
lib/dns/zone.c
@@ -15,7 +15,7 @@
|
|||||||
* SOFTWARE.
|
* SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* $Id: zone.c,v 1.117 2000/05/18 02:59:16 marka Exp $ */
|
/* $Id: zone.c,v 1.118 2000/05/18 04:43:00 marka Exp $ */
|
||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
|
||||||
@@ -48,9 +48,6 @@
|
|||||||
#include <dns/xfrin.h>
|
#include <dns/xfrin.h>
|
||||||
#include <dns/zone.h>
|
#include <dns/zone.h>
|
||||||
|
|
||||||
/* XXX remove once config changes are in place */
|
|
||||||
#define dns_zone_uptodate(x) zone_log(x, me, ISC_LOG_INFO, "dns_zone_uptodate")
|
|
||||||
|
|
||||||
#define ZONE_MAGIC 0x5a4f4e45U /* ZONE */
|
#define ZONE_MAGIC 0x5a4f4e45U /* ZONE */
|
||||||
#define NOTIFY_MAGIC 0x4e746679U /* Ntfy */
|
#define NOTIFY_MAGIC 0x4e746679U /* Ntfy */
|
||||||
|
|
||||||
@@ -223,7 +220,7 @@ static void zone_expire(dns_zone_t *zone);
|
|||||||
static isc_result_t zone_replacedb(dns_zone_t *zone, dns_db_t *db,
|
static isc_result_t zone_replacedb(dns_zone_t *zone, dns_db_t *db,
|
||||||
isc_boolean_t dump);
|
isc_boolean_t dump);
|
||||||
static isc_result_t default_journal(dns_zone_t *zone);
|
static isc_result_t default_journal(dns_zone_t *zone);
|
||||||
static void xfrdone(dns_zone_t *zone, isc_result_t result);
|
static void zone_xfrdone(dns_zone_t *zone, isc_result_t result);
|
||||||
static void zone_shutdown(isc_task_t *, isc_event_t *);
|
static void zone_shutdown(isc_task_t *, isc_event_t *);
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
@@ -1264,7 +1261,8 @@ dns_zone_maintenance(dns_zone_t *zone) {
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
(void) zone_settimer(zone, now); /*XXX*/
|
if (!DNS_ZONE_FLAG(zone, DNS_ZONE_F_EXITING))
|
||||||
|
(void) zone_settimer(zone, now);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -1303,6 +1301,9 @@ dns_zone_refresh(dns_zone_t *zone) {
|
|||||||
|
|
||||||
isc_stdtime_get(&now);
|
isc_stdtime_get(&now);
|
||||||
|
|
||||||
|
if (DNS_ZONE_FLAG(zone, DNS_ZONE_F_EXITING))
|
||||||
|
return;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set DNS_ZONE_F_REFRESH so that there is only one refresh operation
|
* Set DNS_ZONE_F_REFRESH so that there is only one refresh operation
|
||||||
* in progress at the one time.
|
* in progress at the one time.
|
||||||
@@ -1454,6 +1455,22 @@ dns_zone_setrefresh(dns_zone_t *zone, isc_uint32_t refresh,
|
|||||||
zone->retry = retry;
|
zone->retry = retry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static isc_boolean_t
|
||||||
|
notify_isqueued(dns_zone_t *zone, dns_name_t *name, isc_sockaddr_t *addr) {
|
||||||
|
notify_t *notify;
|
||||||
|
|
||||||
|
for (notify = ISC_LIST_HEAD(zone->notifies);
|
||||||
|
notify != NULL;
|
||||||
|
notify = ISC_LIST_NEXT(notify, link)) {
|
||||||
|
if (name != NULL && dns_name_dynamic(¬ify->ns) &&
|
||||||
|
dns_name_equal(name, ¬ify->ns))
|
||||||
|
return (ISC_TRUE);
|
||||||
|
if (addr != NULL && isc_sockaddr_equal(addr, ¬ify->dst))
|
||||||
|
return (ISC_TRUE);
|
||||||
|
}
|
||||||
|
return (ISC_FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
notify_destroy(notify_t *notify) {
|
notify_destroy(notify_t *notify) {
|
||||||
isc_mem_t *mctx;
|
isc_mem_t *mctx;
|
||||||
@@ -1495,6 +1512,7 @@ notify_create(isc_mem_t *mctx, notify_t **notifyp) {
|
|||||||
notify->zone = NULL;
|
notify->zone = NULL;
|
||||||
notify->find = NULL;
|
notify->find = NULL;
|
||||||
notify->request = NULL;
|
notify->request = NULL;
|
||||||
|
isc_sockaddr_any(¬ify->dst);
|
||||||
dns_name_init(¬ify->ns, NULL);
|
dns_name_init(¬ify->ns, NULL);
|
||||||
ISC_LINK_INIT(notify, link);
|
ISC_LINK_INIT(notify, link);
|
||||||
notify->magic = NOTIFY_MAGIC;
|
notify->magic = NOTIFY_MAGIC;
|
||||||
@@ -1585,8 +1603,9 @@ notify_send_queue(notify_t *notify) {
|
|||||||
if (e == NULL)
|
if (e == NULL)
|
||||||
return (ISC_R_NOMEMORY);
|
return (ISC_R_NOMEMORY);
|
||||||
e->ev_arg = notify;
|
e->ev_arg = notify;
|
||||||
e->ev_sender = notify;
|
e->ev_sender = NULL;
|
||||||
result = isc_ratelimiter_enqueue(notify->zone->zmgr->rl, &e);
|
result = isc_ratelimiter_enqueue(notify->zone->zmgr->rl,
|
||||||
|
notify->zone->task, &e);
|
||||||
if (result != ISC_R_SUCCESS)
|
if (result != ISC_R_SUCCESS)
|
||||||
isc_event_free(&e);
|
isc_event_free(&e);
|
||||||
return (result);
|
return (result);
|
||||||
@@ -1645,11 +1664,14 @@ notify_send(notify_t *notify) {
|
|||||||
if (result != ISC_R_SUCCESS)
|
if (result != ISC_R_SUCCESS)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ai = ISC_LIST_HEAD(notify->find->list);
|
for (ai = ISC_LIST_HEAD(notify->find->list);
|
||||||
while (ai != NULL) {
|
ai != NULL;
|
||||||
|
ai = ISC_LIST_NEXT(ai, publink)) {
|
||||||
dst = *ai->sockaddr;
|
dst = *ai->sockaddr;
|
||||||
if (isc_sockaddr_getport(&dst) == 0)
|
if (isc_sockaddr_getport(&dst) == 0)
|
||||||
isc_sockaddr_setport(&dst, 53); /* XXX */
|
isc_sockaddr_setport(&dst, 53); /* XXX */
|
||||||
|
if (notify_isqueued(notify->zone, NULL, &dst))
|
||||||
|
continue;
|
||||||
new = NULL;
|
new = NULL;
|
||||||
result = notify_create(notify->mctx, &new);
|
result = notify_create(notify->mctx, &new);
|
||||||
if (result != ISC_R_SUCCESS)
|
if (result != ISC_R_SUCCESS)
|
||||||
@@ -1661,7 +1683,6 @@ notify_send(notify_t *notify) {
|
|||||||
if (result != ISC_R_SUCCESS)
|
if (result != ISC_R_SUCCESS)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
new = NULL;
|
new = NULL;
|
||||||
ai = ISC_LIST_NEXT(ai, publink);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
@@ -1675,7 +1696,6 @@ void
|
|||||||
dns_zone_notify(dns_zone_t *zone) {
|
dns_zone_notify(dns_zone_t *zone) {
|
||||||
dns_dbnode_t *node = NULL;
|
dns_dbnode_t *node = NULL;
|
||||||
dns_dbversion_t *version = NULL;
|
dns_dbversion_t *version = NULL;
|
||||||
dns_message_t *message = NULL;
|
|
||||||
dns_name_t *origin = NULL;
|
dns_name_t *origin = NULL;
|
||||||
dns_name_t master;
|
dns_name_t master;
|
||||||
dns_rdata_ns_t ns;
|
dns_rdata_ns_t ns;
|
||||||
@@ -1686,49 +1706,48 @@ dns_zone_notify(dns_zone_t *zone) {
|
|||||||
isc_result_t result;
|
isc_result_t result;
|
||||||
notify_t *notify = NULL;
|
notify_t *notify = NULL;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
isc_sockaddr_t dst;
|
||||||
|
isc_boolean_t isqueued;
|
||||||
|
|
||||||
REQUIRE(DNS_ZONE_VALID(zone));
|
REQUIRE(DNS_ZONE_VALID(zone));
|
||||||
|
|
||||||
if (!DNS_ZONE_OPTION(zone, DNS_ZONE_O_NOTIFY)) {
|
|
||||||
LOCK(&zone->lock);
|
|
||||||
zone->flags &= ~DNS_ZONE_F_NEEDNOTIFY;
|
|
||||||
UNLOCK(&zone->lock);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
origin = &zone->origin;
|
|
||||||
|
|
||||||
result = notify_createmessage(zone, &message);
|
|
||||||
if (result != ISC_R_SUCCESS)
|
|
||||||
return;
|
|
||||||
|
|
||||||
LOCK(&zone->lock);
|
LOCK(&zone->lock);
|
||||||
zone->flags &= ~DNS_ZONE_F_NEEDNOTIFY;
|
zone->flags &= ~DNS_ZONE_F_NEEDNOTIFY;
|
||||||
UNLOCK(&zone->lock);
|
UNLOCK(&zone->lock);
|
||||||
|
|
||||||
|
if (!DNS_ZONE_OPTION(zone, DNS_ZONE_O_NOTIFY)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
origin = &zone->origin;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Enqueue notify request.
|
* Enqueue notify request.
|
||||||
*/
|
*/
|
||||||
|
LOCK(&zone->lock);
|
||||||
for (i = 0; i < zone->notifycnt; i++) {
|
for (i = 0; i < zone->notifycnt; i++) {
|
||||||
|
dst = zone->notify[i];
|
||||||
|
if (isc_sockaddr_getport(&dst) == 0)
|
||||||
|
isc_sockaddr_setport(&dst, 53); /* XXX */
|
||||||
|
if (notify_isqueued(zone, NULL, &dst))
|
||||||
|
continue;
|
||||||
result = notify_create(zone->mctx, ¬ify);
|
result = notify_create(zone->mctx, ¬ify);
|
||||||
if (result != ISC_R_SUCCESS)
|
if (result != ISC_R_SUCCESS) {
|
||||||
goto cleanup0;
|
UNLOCK(&zone->lock);
|
||||||
dns_zone_attach(zone, ¬ify->zone);
|
return;
|
||||||
notify->dst = zone->notify[i];
|
}
|
||||||
if (isc_sockaddr_getport(¬ify->dst) == 0)
|
zone_attach(zone, ¬ify->zone);
|
||||||
isc_sockaddr_setport(¬ify->dst, 53); /* XXX */
|
notify->dst = dst;
|
||||||
LOCK(&zone->lock);
|
|
||||||
ISC_LIST_APPEND(zone->notifies, notify, link);
|
ISC_LIST_APPEND(zone->notifies, notify, link);
|
||||||
UNLOCK(&zone->lock);
|
|
||||||
result = notify_send_queue(notify);
|
result = notify_send_queue(notify);
|
||||||
if (result != ISC_R_SUCCESS) {
|
if (result != ISC_R_SUCCESS) {
|
||||||
LOCK(&zone->lock);
|
|
||||||
notify_destroy(notify);
|
notify_destroy(notify);
|
||||||
UNLOCK(&zone->lock);
|
UNLOCK(&zone->lock);
|
||||||
goto cleanup0;
|
return;
|
||||||
}
|
}
|
||||||
notify = NULL;
|
notify = NULL;
|
||||||
}
|
}
|
||||||
|
UNLOCK(&zone->lock);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Process NS RRset to generate notifies.
|
* Process NS RRset to generate notifies.
|
||||||
@@ -1789,6 +1808,11 @@ dns_zone_notify(dns_zone_t *zone) {
|
|||||||
result = dns_rdataset_next(&nsrdset);
|
result = dns_rdataset_next(&nsrdset);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
LOCK(&zone->lock);
|
||||||
|
isqueued = notify_isqueued(zone, &ns.name, NULL);
|
||||||
|
UNLOCK(&zone->lock);
|
||||||
|
if (isqueued)
|
||||||
|
continue;
|
||||||
result = notify_create(zone->mctx, ¬ify);
|
result = notify_create(zone->mctx, ¬ify);
|
||||||
if (result != ISC_R_SUCCESS) {
|
if (result != ISC_R_SUCCESS) {
|
||||||
dns_rdata_freestruct(&ns);
|
dns_rdata_freestruct(&ns);
|
||||||
@@ -1819,8 +1843,6 @@ dns_zone_notify(dns_zone_t *zone) {
|
|||||||
dns_db_detachnode(zone->db, &node);
|
dns_db_detachnode(zone->db, &node);
|
||||||
cleanup1:
|
cleanup1:
|
||||||
dns_db_closeversion(zone->db, &version, ISC_FALSE);
|
dns_db_closeversion(zone->db, &version, ISC_FALSE);
|
||||||
cleanup0:
|
|
||||||
dns_message_destroy(&message);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/***
|
/***
|
||||||
@@ -1835,9 +1857,7 @@ refresh_callback(isc_task_t *task, isc_event_t *event) {
|
|||||||
dns_message_t *msg = NULL;
|
dns_message_t *msg = NULL;
|
||||||
isc_uint32_t soacnt, cnamecnt, soacount, nscount;
|
isc_uint32_t soacnt, cnamecnt, soacount, nscount;
|
||||||
isc_stdtime_t now;
|
isc_stdtime_t now;
|
||||||
char *master;
|
char master[ISC_SOCKADDR_FORMATSIZE];
|
||||||
isc_buffer_t masterbuf;
|
|
||||||
char mastermem[256];
|
|
||||||
dns_rdataset_t *rdataset;
|
dns_rdataset_t *rdataset;
|
||||||
dns_rdata_t rdata;
|
dns_rdata_t rdata;
|
||||||
dns_rdata_soa_t soa;
|
dns_rdata_soa_t soa;
|
||||||
@@ -1855,12 +1875,9 @@ refresh_callback(isc_task_t *task, isc_event_t *event) {
|
|||||||
* if timeout log and next master;
|
* if timeout log and next master;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
isc_buffer_init(&masterbuf, mastermem, sizeof(mastermem));
|
isc_sockaddr_format(&zone->masteraddr, master, sizeof(master));
|
||||||
result = isc_sockaddr_totext(&zone->masteraddr, &masterbuf);
|
|
||||||
if (result == ISC_R_SUCCESS)
|
isc_stdtime_get(&now);
|
||||||
master = (char *) masterbuf.base;
|
|
||||||
else
|
|
||||||
master = "<UNKNOWN>";
|
|
||||||
|
|
||||||
if (revent->result != ISC_R_SUCCESS) {
|
if (revent->result != ISC_R_SUCCESS) {
|
||||||
zone_log(zone, me, ISC_LOG_INFO, "failure for %s: %s",
|
zone_log(zone, me, ISC_LOG_INFO, "failure for %s: %s",
|
||||||
@@ -1991,7 +2008,18 @@ refresh_callback(isc_task_t *task, isc_event_t *event) {
|
|||||||
dns_request_destroy(&zone->request);
|
dns_request_destroy(&zone->request);
|
||||||
queue_xfrin(zone);
|
queue_xfrin(zone);
|
||||||
} else if (isc_serial_eq(soa.serial, zone->serial)) {
|
} else if (isc_serial_eq(soa.serial, zone->serial)) {
|
||||||
dns_zone_uptodate(zone);
|
if (zone->dbname != NULL) {
|
||||||
|
isc_time_t t;
|
||||||
|
isc_time_set(&t, now, 0);
|
||||||
|
result = isc_file_settime(zone->dbname, &t);
|
||||||
|
if (result != ISC_R_SUCCESS)
|
||||||
|
zone_log(zone, me, ISC_LOG_ERROR,
|
||||||
|
"isc_file_settime(%s): %s",
|
||||||
|
zone->dbname,
|
||||||
|
dns_result_totext(result));
|
||||||
|
}
|
||||||
|
zone->refreshtime = now + zone->refresh;
|
||||||
|
zone->expiretime = now + zone->expire;
|
||||||
goto next_master;
|
goto next_master;
|
||||||
} else {
|
} else {
|
||||||
ZONE_LOG(1, "ahead");
|
ZONE_LOG(1, "ahead");
|
||||||
@@ -2009,7 +2037,6 @@ refresh_callback(isc_task_t *task, isc_event_t *event) {
|
|||||||
if (zone->curmaster >= zone->masterscnt) {
|
if (zone->curmaster >= zone->masterscnt) {
|
||||||
zone->flags &= ~DNS_ZONE_F_REFRESH;
|
zone->flags &= ~DNS_ZONE_F_REFRESH;
|
||||||
|
|
||||||
isc_stdtime_get(&now);
|
|
||||||
zone_settimer(zone, now);
|
zone_settimer(zone, now);
|
||||||
UNLOCK(&zone->lock);
|
UNLOCK(&zone->lock);
|
||||||
return;
|
return;
|
||||||
@@ -2028,6 +2055,11 @@ queue_soa_query(dns_zone_t *zone) {
|
|||||||
|
|
||||||
DNS_ENTER;
|
DNS_ENTER;
|
||||||
|
|
||||||
|
if (DNS_ZONE_FLAG(zone, DNS_ZONE_F_EXITING)) {
|
||||||
|
cancel_refresh(zone);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
e = isc_event_allocate(zone->mctx, NULL, DNS_EVENT_ZONE,
|
e = isc_event_allocate(zone->mctx, NULL, DNS_EVENT_ZONE,
|
||||||
soa_query, zone, sizeof(isc_event_t));
|
soa_query, zone, sizeof(isc_event_t));
|
||||||
if (e == NULL) {
|
if (e == NULL) {
|
||||||
@@ -2039,8 +2071,8 @@ queue_soa_query(dns_zone_t *zone) {
|
|||||||
* until the event is delivered.
|
* until the event is delivered.
|
||||||
*/
|
*/
|
||||||
e->ev_arg = zone;
|
e->ev_arg = zone;
|
||||||
e->ev_sender = zone;
|
e->ev_sender = NULL;
|
||||||
result = isc_ratelimiter_enqueue(zone->zmgr->rl, &e);
|
result = isc_ratelimiter_enqueue(zone->zmgr->rl, zone->task, &e);
|
||||||
if (result != ISC_R_SUCCESS) {
|
if (result != ISC_R_SUCCESS) {
|
||||||
dns_zone_detach(&dummy);
|
dns_zone_detach(&dummy);
|
||||||
isc_event_free(&e);
|
isc_event_free(&e);
|
||||||
@@ -2147,6 +2179,7 @@ static void
|
|||||||
zone_shutdown(isc_task_t *task, isc_event_t *event) {
|
zone_shutdown(isc_task_t *task, isc_event_t *event) {
|
||||||
dns_zone_t *zone = (dns_zone_t *) event->ev_arg;
|
dns_zone_t *zone = (dns_zone_t *) event->ev_arg;
|
||||||
notify_t *notify;
|
notify_t *notify;
|
||||||
|
isc_result_t result;
|
||||||
|
|
||||||
UNUSED(task);
|
UNUSED(task);
|
||||||
REQUIRE(DNS_ZONE_VALID(zone));
|
REQUIRE(DNS_ZONE_VALID(zone));
|
||||||
@@ -2183,6 +2216,12 @@ zone_shutdown(isc_task_t *task, isc_event_t *event) {
|
|||||||
dns_request_cancel(notify->request);
|
dns_request_cancel(notify->request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (zone->timer != NULL) {
|
||||||
|
result = isc_timer_reset(zone->timer, isc_timertype_inactive,
|
||||||
|
NULL, NULL, ISC_TRUE);
|
||||||
|
RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
if (zone->view != NULL)
|
if (zone->view != NULL)
|
||||||
dns_view_weakdetach(&zone->view);
|
dns_view_weakdetach(&zone->view);
|
||||||
|
|
||||||
@@ -3022,8 +3061,8 @@ zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
xfrdone(dns_zone_t *zone, isc_result_t result) {
|
zone_xfrdone(dns_zone_t *zone, isc_result_t result) {
|
||||||
const char me[] = "xfrdone";
|
const char me[] = "zone_xfrdone";
|
||||||
isc_stdtime_t now;
|
isc_stdtime_t now;
|
||||||
isc_boolean_t again = ISC_FALSE;
|
isc_boolean_t again = ISC_FALSE;
|
||||||
|
|
||||||
@@ -3039,13 +3078,30 @@ xfrdone(dns_zone_t *zone, isc_result_t result) {
|
|||||||
switch (result) {
|
switch (result) {
|
||||||
case ISC_R_SUCCESS:
|
case ISC_R_SUCCESS:
|
||||||
zone->flags |= DNS_ZONE_F_NEEDNOTIFY;
|
zone->flags |= DNS_ZONE_F_NEEDNOTIFY;
|
||||||
/* FALLTHROUGH */
|
|
||||||
case DNS_R_UPTODATE:
|
case DNS_R_UPTODATE:
|
||||||
|
/*
|
||||||
|
* This is not neccessary if we just performed a AXFR
|
||||||
|
* however it is necessary for an IXFR / UPTODATE and
|
||||||
|
* won't hurt with an AXFR.
|
||||||
|
*/
|
||||||
|
if (zone->dbname != NULL) {
|
||||||
|
isc_time_t t;
|
||||||
|
isc_time_set(&t, now, 0);
|
||||||
|
result = isc_file_settime(zone->dbname, &t);
|
||||||
|
if (result != ISC_R_SUCCESS)
|
||||||
|
zone_log(zone, me, ISC_LOG_ERROR,
|
||||||
|
"isc_file_settime(%s): %s",
|
||||||
|
zone->dbname,
|
||||||
|
dns_result_totext(result));
|
||||||
|
}
|
||||||
if (DNS_ZONE_FLAG(zone, DNS_ZONE_F_NEEDREFRESH)) {
|
if (DNS_ZONE_FLAG(zone, DNS_ZONE_F_NEEDREFRESH)) {
|
||||||
zone->flags &= ~DNS_ZONE_F_NEEDREFRESH;
|
zone->flags &= ~DNS_ZONE_F_NEEDREFRESH;
|
||||||
zone->refreshtime = now;
|
zone->refreshtime = now;
|
||||||
} else
|
zone->expire = now + zone->expire;
|
||||||
|
} else {
|
||||||
zone->refreshtime = now + zone->refresh;
|
zone->refreshtime = now + zone->refresh;
|
||||||
|
zone->expire = now + zone->expire;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -3213,7 +3269,7 @@ got_transfer_quota(isc_task_t *task, isc_event_t *event) {
|
|||||||
result = dns_xfrin_create(zone, xfrtype, &zone->masteraddr,
|
result = dns_xfrin_create(zone, xfrtype, &zone->masteraddr,
|
||||||
tsigkey, zone->mctx,
|
tsigkey, zone->mctx,
|
||||||
zone->zmgr->timermgr, zone->zmgr->socketmgr,
|
zone->zmgr->timermgr, zone->zmgr->socketmgr,
|
||||||
zone->task, xfrdone, &zone->xfr);
|
zone->task, zone_xfrdone, &zone->xfr);
|
||||||
cleanup:
|
cleanup:
|
||||||
/*
|
/*
|
||||||
* Any failure in this function is handled like a failed
|
* Any failure in this function is handled like a failed
|
||||||
@@ -3221,7 +3277,7 @@ got_transfer_quota(isc_task_t *task, isc_event_t *event) {
|
|||||||
* zmgr->xfrin_in_progress.
|
* zmgr->xfrin_in_progress.
|
||||||
*/
|
*/
|
||||||
if (result != ISC_R_SUCCESS)
|
if (result != ISC_R_SUCCESS)
|
||||||
xfrdone(zone, result);
|
zone_xfrdone(zone, result);
|
||||||
|
|
||||||
isc_event_free(&event);
|
isc_event_free(&event);
|
||||||
|
|
||||||
@@ -3293,8 +3349,8 @@ dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
|
|||||||
&zmgr->rl);
|
&zmgr->rl);
|
||||||
if (result != ISC_R_SUCCESS)
|
if (result != ISC_R_SUCCESS)
|
||||||
goto free_task;
|
goto free_task;
|
||||||
/* 100 refresh queries / notifies per second. */
|
/* 20 refresh queries / notifies per second. */
|
||||||
isc_interval_set(&interval, 0, 1000000000/10);
|
isc_interval_set(&interval, 0, 1000000000/2);
|
||||||
result = isc_ratelimiter_setinterval(zmgr->rl, &interval);
|
result = isc_ratelimiter_setinterval(zmgr->rl, &interval);
|
||||||
RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
||||||
isc_ratelimiter_setpertic(zmgr->rl, 10);
|
isc_ratelimiter_setpertic(zmgr->rl, 10);
|
||||||
@@ -3518,7 +3574,7 @@ zmgr_resume_xfrs(dns_zonemgr_t *zmgr) {
|
|||||||
*
|
*
|
||||||
* Returns:
|
* Returns:
|
||||||
* ISC_R_SUCCESS There was enough quota and we attempted to
|
* ISC_R_SUCCESS There was enough quota and we attempted to
|
||||||
* start a transfer. xfrdone() has been or will
|
* start a transfer. zone_xfrdone() has been or will
|
||||||
* be called.
|
* be called.
|
||||||
* ISC_R_QUOTA Not enough quota.
|
* ISC_R_QUOTA Not enough quota.
|
||||||
* Others Failure.
|
* Others Failure.
|
||||||
|
@@ -67,16 +67,23 @@ isc_ratelimiter_setpertic(isc_ratelimiter_t *rl, isc_uint32_t perint);
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
isc_result_t
|
isc_result_t
|
||||||
isc_ratelimiter_enqueue(isc_ratelimiter_t *rl, isc_event_t **eventp);
|
isc_ratelimiter_enqueue(isc_ratelimiter_t *rl, isc_task_t *task,
|
||||||
|
isc_event_t **eventp);
|
||||||
/*
|
/*
|
||||||
* Queue an event for rate-limited execution. This is similar
|
* Queue an event for rate-limited execution. This is similar
|
||||||
* to doing an isc_task_send() to the rate limiter's task, except
|
* to doing an isc_task_send() to the 'task', except that the
|
||||||
* that the execution may be delayed to achieve the desired rate
|
* execution may be delayed to achieve the desired rate of
|
||||||
* of execution.
|
* execution.
|
||||||
|
*
|
||||||
|
* '(*eventp)->ev_sender' is used to hold the task. The caller
|
||||||
|
* must ensure that the task exists until the event is delivered.
|
||||||
*
|
*
|
||||||
* Requires:
|
* Requires:
|
||||||
* An interval has been set by calling
|
* An interval has been set by calling
|
||||||
* isc_ratelimiter_setinterval().
|
* isc_ratelimiter_setinterval().
|
||||||
|
*
|
||||||
|
* 'task' to be non NULL.
|
||||||
|
* '(*eventp)->ev_sender' to be NULL.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@@ -122,27 +122,37 @@ isc_ratelimiter_setpertic(isc_ratelimiter_t *rl, isc_uint32_t pertic) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
isc_result_t
|
isc_result_t
|
||||||
isc_ratelimiter_enqueue(isc_ratelimiter_t *rl, isc_event_t **eventp) {
|
isc_ratelimiter_enqueue(isc_ratelimiter_t *rl, isc_task_t *task,
|
||||||
|
isc_event_t **eventp)
|
||||||
|
{
|
||||||
isc_result_t result = ISC_R_SUCCESS;
|
isc_result_t result = ISC_R_SUCCESS;
|
||||||
INSIST(eventp != NULL && *eventp != NULL);
|
isc_event_t *ev;
|
||||||
|
|
||||||
|
REQUIRE(eventp != NULL && *eventp != NULL);
|
||||||
|
REQUIRE(task != NULL);
|
||||||
|
ev = *eventp;
|
||||||
|
REQUIRE(ev->ev_sender == NULL);
|
||||||
|
|
||||||
LOCK(&rl->lock);
|
LOCK(&rl->lock);
|
||||||
if (rl->state == isc_ratelimiter_ratelimited) {
|
if (rl->state == isc_ratelimiter_ratelimited) {
|
||||||
isc_event_t *ev = *eventp;
|
isc_event_t *ev = *eventp;
|
||||||
|
ev->ev_sender = task;
|
||||||
ISC_LIST_APPEND(rl->pending, ev, ev_link);
|
ISC_LIST_APPEND(rl->pending, ev, ev_link);
|
||||||
*eventp = NULL;
|
*eventp = NULL;
|
||||||
} else if (rl->state == isc_ratelimiter_worklimited) {
|
} else if (rl->state == isc_ratelimiter_worklimited) {
|
||||||
result = isc_timer_reset(rl->timer, isc_timertype_ticker, NULL,
|
result = isc_timer_reset(rl->timer, isc_timertype_ticker, NULL,
|
||||||
&rl->interval, ISC_FALSE);
|
&rl->interval, ISC_FALSE);
|
||||||
if (result == ISC_R_SUCCESS)
|
if (result == ISC_R_SUCCESS) {
|
||||||
|
ev->ev_sender = task;
|
||||||
rl->state = isc_ratelimiter_ratelimited;
|
rl->state = isc_ratelimiter_ratelimited;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
INSIST(rl->state == isc_ratelimiter_shuttingdown);
|
INSIST(rl->state == isc_ratelimiter_shuttingdown);
|
||||||
result = ISC_R_SHUTTINGDOWN;
|
result = ISC_R_SHUTTINGDOWN;
|
||||||
}
|
}
|
||||||
UNLOCK(&rl->lock);
|
UNLOCK(&rl->lock);
|
||||||
if (*eventp != NULL)
|
if (*eventp != NULL && result == ISC_R_SUCCESS)
|
||||||
isc_task_send(rl->task, eventp);
|
isc_task_send(task, eventp);
|
||||||
ENSURE(*eventp == NULL);
|
|
||||||
return (result);
|
return (result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -179,8 +189,10 @@ ratelimiter_tick(isc_task_t *task, isc_event_t *event) {
|
|||||||
pertic = 0; /* Force the loop to exit. */
|
pertic = 0; /* Force the loop to exit. */
|
||||||
}
|
}
|
||||||
UNLOCK(&rl->lock);
|
UNLOCK(&rl->lock);
|
||||||
if (p != NULL)
|
if (p != NULL) {
|
||||||
isc_task_send(rl->task, &p);
|
isc_task_t *evtask = p->ev_sender;
|
||||||
|
isc_task_send(evtask, &p);
|
||||||
|
}
|
||||||
INSIST(p == NULL);
|
INSIST(p == NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -188,6 +200,7 @@ ratelimiter_tick(isc_task_t *task, isc_event_t *event) {
|
|||||||
void
|
void
|
||||||
isc_ratelimiter_shutdown(isc_ratelimiter_t *rl) {
|
isc_ratelimiter_shutdown(isc_ratelimiter_t *rl) {
|
||||||
isc_event_t *ev;
|
isc_event_t *ev;
|
||||||
|
isc_task_t *task;
|
||||||
LOCK(&rl->lock);
|
LOCK(&rl->lock);
|
||||||
rl->state = isc_ratelimiter_shuttingdown;
|
rl->state = isc_ratelimiter_shuttingdown;
|
||||||
(void) isc_timer_reset(rl->timer, isc_timertype_inactive,
|
(void) isc_timer_reset(rl->timer, isc_timertype_inactive,
|
||||||
@@ -195,7 +208,8 @@ isc_ratelimiter_shutdown(isc_ratelimiter_t *rl) {
|
|||||||
while ((ev = ISC_LIST_HEAD(rl->pending)) != NULL) {
|
while ((ev = ISC_LIST_HEAD(rl->pending)) != NULL) {
|
||||||
ISC_LIST_UNLINK(rl->pending, ev, ev_link);
|
ISC_LIST_UNLINK(rl->pending, ev, ev_link);
|
||||||
ev->ev_attributes |= ISC_EVENTATTR_CANCELED;
|
ev->ev_attributes |= ISC_EVENTATTR_CANCELED;
|
||||||
isc_task_send(rl->task, &ev);
|
task = ev->ev_sender;
|
||||||
|
isc_task_send(task, &ev);
|
||||||
}
|
}
|
||||||
UNLOCK(&rl->lock);
|
UNLOCK(&rl->lock);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user