mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-31 22:45:39 +00:00
Abort incoming zone transfers on server shutdown. To support
this, zone transfers now use the zone's task, the zone holds a pointer to any zone transfer in progress, and the zone now registers a shutdown callback.
This commit is contained in:
@@ -26,15 +26,55 @@
|
|||||||
* Incoming zone transfers (AXFR + IXFR).
|
* Incoming zone transfers (AXFR + IXFR).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/***
|
||||||
|
*** Imports
|
||||||
|
***/
|
||||||
|
|
||||||
|
#include <isc/lang.h>
|
||||||
#include <dns/types.h>
|
#include <dns/types.h>
|
||||||
|
|
||||||
|
/***
|
||||||
|
*** Types
|
||||||
|
***/
|
||||||
|
|
||||||
|
typedef struct dns_xfrin_ctx dns_xfrin_ctx_t;
|
||||||
|
|
||||||
/***
|
/***
|
||||||
*** Functions
|
*** Functions
|
||||||
***/
|
***/
|
||||||
|
|
||||||
void dns_xfrin_start(dns_zone_t *zone, isc_sockaddr_t *master,
|
ISC_LANG_BEGINDECLS
|
||||||
isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
|
|
||||||
isc_timermgr_t *timermgr, isc_socketmgr_t *socketmgr,
|
isc_result_t
|
||||||
dns_xfrindone_t done);
|
dns_xfrin_create(dns_zone_t *zone, isc_sockaddr_t *masteraddr,
|
||||||
|
isc_mem_t *mctx, isc_timermgr_t *timermgr,
|
||||||
|
isc_socketmgr_t *socketmgr, isc_task_t *task,
|
||||||
|
dns_xfrindone_t done, dns_xfrin_ctx_t **xfrp);
|
||||||
|
/*
|
||||||
|
* Attempt to start an incoming zone transfer of 'zone'
|
||||||
|
* from 'masteraddr', creating a dns_xfrin_ctx_t object to
|
||||||
|
* manage it. Attach '*xfrp' to the newly created object.
|
||||||
|
*
|
||||||
|
* Iff ISC_R_SUCCESS is returned, '*done' is guaranteed to be
|
||||||
|
* called in the context of 'task', with 'zone' and a result
|
||||||
|
* code as arguments when the transfer finishes.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void dns_xfrin_shutdown(dns_xfrin_ctx_t *xfr);
|
||||||
|
/*
|
||||||
|
* If the zone transfer 'xfr' has already finished,
|
||||||
|
* do nothing. Otherwise, abort it and cause it to call
|
||||||
|
* its done callback with a status of ISC_R_CANCELLED.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void dns_xfrin_detach(dns_xfrin_ctx_t **xfrp);
|
||||||
|
/*
|
||||||
|
* Detach a reference to a zone transfer object.
|
||||||
|
*
|
||||||
|
* (Because there is no attach() method, there can currently
|
||||||
|
* only be one reference).
|
||||||
|
*/
|
||||||
|
|
||||||
|
ISC_LANG_ENDDECLS
|
||||||
|
|
||||||
#endif /* DNS_XFRIN_H */
|
#endif /* DNS_XFRIN_H */
|
||||||
|
179
lib/dns/xfrin.c
179
lib/dns/xfrin.c
@@ -15,7 +15,7 @@
|
|||||||
* SOFTWARE.
|
* SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* $Id: xfrin.c,v 1.40 2000/01/28 01:12:01 gson Exp $ */
|
/* $Id: xfrin.c,v 1.41 2000/01/28 23:48:57 gson Exp $ */
|
||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
|
||||||
@@ -65,8 +65,6 @@
|
|||||||
if (result != DNS_R_SUCCESS) goto failure; \
|
if (result != DNS_R_SUCCESS) goto failure; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
typedef struct xfrin_ctx xfrin_ctx_t;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The states of the *XFR state machine. We handle both IXFR and AXFR
|
* The states of the *XFR state machine. We handle both IXFR and AXFR
|
||||||
* with a single integrated state machine because they cannot be distinguished
|
* with a single integrated state machine because they cannot be distinguished
|
||||||
@@ -90,10 +88,12 @@ typedef enum {
|
|||||||
* Incoming zone transfer context.
|
* Incoming zone transfer context.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct xfrin_ctx {
|
struct dns_xfrin_ctx {
|
||||||
isc_mem_t *mctx;
|
isc_mem_t *mctx;
|
||||||
dns_zone_t *zone;
|
dns_zone_t *zone;
|
||||||
|
|
||||||
|
int refcount;
|
||||||
|
|
||||||
isc_task_t *task;
|
isc_task_t *task;
|
||||||
isc_timer_t *timer;
|
isc_timer_t *timer;
|
||||||
isc_socketmgr_t *socketmgr;
|
isc_socketmgr_t *socketmgr;
|
||||||
@@ -173,44 +173,43 @@ xfrin_create(isc_mem_t *mctx,
|
|||||||
isc_task_t *task,
|
isc_task_t *task,
|
||||||
isc_timermgr_t *timermgr,
|
isc_timermgr_t *timermgr,
|
||||||
isc_socketmgr_t *socketmgr,
|
isc_socketmgr_t *socketmgr,
|
||||||
dns_xfrindone_t done,
|
|
||||||
dns_name_t *zonename,
|
dns_name_t *zonename,
|
||||||
dns_rdataclass_t rdclass,
|
dns_rdataclass_t rdclass,
|
||||||
dns_rdatatype_t reqtype,
|
dns_rdatatype_t reqtype,
|
||||||
isc_sockaddr_t *masteraddr,
|
isc_sockaddr_t *masteraddr,
|
||||||
dns_tsigkey_t *tsigkey,
|
dns_tsigkey_t *tsigkey,
|
||||||
xfrin_ctx_t **xfrp);
|
dns_xfrin_ctx_t **xfrp);
|
||||||
|
|
||||||
static isc_result_t axfr_init(xfrin_ctx_t *xfr);
|
static isc_result_t axfr_init(dns_xfrin_ctx_t *xfr);
|
||||||
static isc_result_t axfr_makedb(xfrin_ctx_t *xfr, dns_db_t **dbp);
|
static isc_result_t axfr_makedb(dns_xfrin_ctx_t *xfr, dns_db_t **dbp);
|
||||||
static isc_result_t axfr_putdata(xfrin_ctx_t *xfr, dns_diffop_t op,
|
static isc_result_t axfr_putdata(dns_xfrin_ctx_t *xfr, dns_diffop_t op,
|
||||||
dns_name_t *name, dns_ttl_t ttl,
|
dns_name_t *name, dns_ttl_t ttl,
|
||||||
dns_rdata_t *rdata);
|
dns_rdata_t *rdata);
|
||||||
static isc_result_t axfr_apply(xfrin_ctx_t *xfr);
|
static isc_result_t axfr_apply(dns_xfrin_ctx_t *xfr);
|
||||||
static isc_result_t axfr_commit(xfrin_ctx_t *xfr);
|
static isc_result_t axfr_commit(dns_xfrin_ctx_t *xfr);
|
||||||
|
|
||||||
static isc_result_t ixfr_init(xfrin_ctx_t *xfr);
|
static isc_result_t ixfr_init(dns_xfrin_ctx_t *xfr);
|
||||||
static isc_result_t ixfr_apply(xfrin_ctx_t *xfr);
|
static isc_result_t ixfr_apply(dns_xfrin_ctx_t *xfr);
|
||||||
static isc_result_t ixfr_putdata(xfrin_ctx_t *xfr, dns_diffop_t op,
|
static isc_result_t ixfr_putdata(dns_xfrin_ctx_t *xfr, dns_diffop_t op,
|
||||||
dns_name_t *name, dns_ttl_t ttl,
|
dns_name_t *name, dns_ttl_t ttl,
|
||||||
dns_rdata_t *rdata);
|
dns_rdata_t *rdata);
|
||||||
static isc_result_t ixfr_commit(xfrin_ctx_t *xfr);
|
static isc_result_t ixfr_commit(dns_xfrin_ctx_t *xfr);
|
||||||
|
|
||||||
static isc_result_t xfr_rr(xfrin_ctx_t *xfr, dns_name_t *name,
|
static isc_result_t xfr_rr(dns_xfrin_ctx_t *xfr, dns_name_t *name,
|
||||||
isc_uint32_t ttl, dns_rdata_t *rdata);
|
isc_uint32_t ttl, dns_rdata_t *rdata);
|
||||||
|
|
||||||
void xfrin_start(xfrin_ctx_t *xfr);
|
static isc_result_t xfrin_start(dns_xfrin_ctx_t *xfr);
|
||||||
|
|
||||||
static void xfrin_connect_done(isc_task_t *task, isc_event_t *event);
|
static void xfrin_connect_done(isc_task_t *task, isc_event_t *event);
|
||||||
static isc_result_t xfrin_send_request(xfrin_ctx_t *xfr);
|
static isc_result_t xfrin_send_request(dns_xfrin_ctx_t *xfr);
|
||||||
static void xfrin_send_done(isc_task_t *task, isc_event_t *event);
|
static void xfrin_send_done(isc_task_t *task, isc_event_t *event);
|
||||||
static void xfrin_sendlen_done(isc_task_t *task, isc_event_t *event);
|
static void xfrin_sendlen_done(isc_task_t *task, isc_event_t *event);
|
||||||
static void xfrin_recv_done(isc_task_t *task, isc_event_t *event);
|
static void xfrin_recv_done(isc_task_t *task, isc_event_t *event);
|
||||||
static void xfrin_timeout(isc_task_t *task, isc_event_t *event);
|
static void xfrin_timeout(isc_task_t *task, isc_event_t *event);
|
||||||
|
|
||||||
static isc_boolean_t maybe_free(xfrin_ctx_t *xfr);
|
static void maybe_free(dns_xfrin_ctx_t *xfr);
|
||||||
|
|
||||||
static void xfrin_fail(xfrin_ctx_t *xfr, isc_result_t result, char *msg);
|
static void xfrin_fail(dns_xfrin_ctx_t *xfr, isc_result_t result, char *msg);
|
||||||
static isc_result_t render(dns_message_t *msg, isc_buffer_t *buf);
|
static isc_result_t render(dns_message_t *msg, isc_buffer_t *buf);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -220,7 +219,7 @@ static void
|
|||||||
xfrin_log1(int level, dns_name_t *zonename, isc_sockaddr_t *masteraddr,
|
xfrin_log1(int level, dns_name_t *zonename, isc_sockaddr_t *masteraddr,
|
||||||
const char *fmt, ...);
|
const char *fmt, ...);
|
||||||
static void
|
static void
|
||||||
xfrin_log(xfrin_ctx_t *xfr, unsigned int level, const char *fmt, ...);
|
xfrin_log(dns_xfrin_ctx_t *xfr, unsigned int level, const char *fmt, ...);
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
@@ -229,7 +228,7 @@ xfrin_log(xfrin_ctx_t *xfr, unsigned int level, const char *fmt, ...);
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
static isc_result_t
|
static isc_result_t
|
||||||
axfr_init(xfrin_ctx_t *xfr) {
|
axfr_init(dns_xfrin_ctx_t *xfr) {
|
||||||
isc_result_t result;
|
isc_result_t result;
|
||||||
xfr->is_ixfr = ISC_FALSE;
|
xfr->is_ixfr = ISC_FALSE;
|
||||||
|
|
||||||
@@ -245,7 +244,7 @@ axfr_init(xfrin_ctx_t *xfr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static isc_result_t
|
static isc_result_t
|
||||||
axfr_makedb(xfrin_ctx_t *xfr, dns_db_t **dbp) {
|
axfr_makedb(dns_xfrin_ctx_t *xfr, dns_db_t **dbp) {
|
||||||
return (dns_db_create(xfr->mctx, /* XXX */
|
return (dns_db_create(xfr->mctx, /* XXX */
|
||||||
"rbt", /* XXX guess */
|
"rbt", /* XXX guess */
|
||||||
&xfr->name,
|
&xfr->name,
|
||||||
@@ -256,7 +255,7 @@ axfr_makedb(xfrin_ctx_t *xfr, dns_db_t **dbp) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static isc_result_t
|
static isc_result_t
|
||||||
axfr_putdata(xfrin_ctx_t *xfr, dns_diffop_t op,
|
axfr_putdata(dns_xfrin_ctx_t *xfr, dns_diffop_t op,
|
||||||
dns_name_t *name, dns_ttl_t ttl, dns_rdata_t *rdata)
|
dns_name_t *name, dns_ttl_t ttl, dns_rdata_t *rdata)
|
||||||
{
|
{
|
||||||
isc_result_t result;
|
isc_result_t result;
|
||||||
@@ -273,7 +272,7 @@ axfr_putdata(xfrin_ctx_t *xfr, dns_diffop_t op,
|
|||||||
|
|
||||||
/* Store a set of AXFR RRs in the database. */
|
/* Store a set of AXFR RRs in the database. */
|
||||||
static isc_result_t
|
static isc_result_t
|
||||||
axfr_apply(xfrin_ctx_t *xfr) {
|
axfr_apply(dns_xfrin_ctx_t *xfr) {
|
||||||
isc_result_t result;
|
isc_result_t result;
|
||||||
CHECK(dns_diff_load(&xfr->diff,
|
CHECK(dns_diff_load(&xfr->diff,
|
||||||
xfr->axfr.add_func, xfr->axfr.add_private));
|
xfr->axfr.add_func, xfr->axfr.add_private));
|
||||||
@@ -285,7 +284,7 @@ axfr_apply(xfrin_ctx_t *xfr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static isc_result_t
|
static isc_result_t
|
||||||
axfr_commit(xfrin_ctx_t *xfr) {
|
axfr_commit(dns_xfrin_ctx_t *xfr) {
|
||||||
isc_result_t result;
|
isc_result_t result;
|
||||||
|
|
||||||
CHECK(axfr_apply(xfr));
|
CHECK(axfr_apply(xfr));
|
||||||
@@ -303,7 +302,7 @@ axfr_commit(xfrin_ctx_t *xfr) {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
static isc_result_t
|
static isc_result_t
|
||||||
ixfr_init(xfrin_ctx_t *xfr) {
|
ixfr_init(dns_xfrin_ctx_t *xfr) {
|
||||||
isc_result_t result;
|
isc_result_t result;
|
||||||
xfr->is_ixfr = ISC_TRUE;
|
xfr->is_ixfr = ISC_TRUE;
|
||||||
INSIST(xfr->db != NULL);
|
INSIST(xfr->db != NULL);
|
||||||
@@ -316,7 +315,7 @@ ixfr_init(xfrin_ctx_t *xfr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static isc_result_t
|
static isc_result_t
|
||||||
ixfr_putdata(xfrin_ctx_t *xfr, dns_diffop_t op,
|
ixfr_putdata(dns_xfrin_ctx_t *xfr, dns_diffop_t op,
|
||||||
dns_name_t *name, dns_ttl_t ttl, dns_rdata_t *rdata)
|
dns_name_t *name, dns_ttl_t ttl, dns_rdata_t *rdata)
|
||||||
{
|
{
|
||||||
isc_result_t result;
|
isc_result_t result;
|
||||||
@@ -333,7 +332,7 @@ ixfr_putdata(xfrin_ctx_t *xfr, dns_diffop_t op,
|
|||||||
|
|
||||||
/* Apply a set of IXFR changes to the database. */
|
/* Apply a set of IXFR changes to the database. */
|
||||||
static isc_result_t
|
static isc_result_t
|
||||||
ixfr_apply(xfrin_ctx_t *xfr) {
|
ixfr_apply(dns_xfrin_ctx_t *xfr) {
|
||||||
isc_result_t result;
|
isc_result_t result;
|
||||||
if (xfr->ver == NULL) {
|
if (xfr->ver == NULL) {
|
||||||
CHECK(dns_db_newversion(xfr->db, &xfr->ver));
|
CHECK(dns_db_newversion(xfr->db, &xfr->ver));
|
||||||
@@ -349,7 +348,7 @@ ixfr_apply(xfrin_ctx_t *xfr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static isc_result_t
|
static isc_result_t
|
||||||
ixfr_commit(xfrin_ctx_t *xfr) {
|
ixfr_commit(dns_xfrin_ctx_t *xfr) {
|
||||||
isc_result_t result;
|
isc_result_t result;
|
||||||
ixfr_apply(xfr);
|
ixfr_apply(xfr);
|
||||||
if (xfr->ver != NULL) {
|
if (xfr->ver != NULL) {
|
||||||
@@ -372,7 +371,7 @@ ixfr_commit(xfrin_ctx_t *xfr) {
|
|||||||
* state.
|
* state.
|
||||||
*/
|
*/
|
||||||
static isc_result_t
|
static isc_result_t
|
||||||
xfr_rr(xfrin_ctx_t *xfr,
|
xfr_rr(dns_xfrin_ctx_t *xfr,
|
||||||
dns_name_t *name, isc_uint32_t ttl, dns_rdata_t *rdata)
|
dns_name_t *name, isc_uint32_t ttl, dns_rdata_t *rdata)
|
||||||
{
|
{
|
||||||
isc_result_t result;
|
isc_result_t result;
|
||||||
@@ -490,19 +489,19 @@ xfr_rr(xfrin_ctx_t *xfr,
|
|||||||
return (result);
|
return (result);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
isc_result_t
|
||||||
dns_xfrin_start(dns_zone_t *zone, isc_sockaddr_t *masteraddr,
|
dns_xfrin_create(dns_zone_t *zone, isc_sockaddr_t *masteraddr,
|
||||||
isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
|
isc_mem_t *mctx, isc_timermgr_t *timermgr,
|
||||||
isc_timermgr_t *timermgr, isc_socketmgr_t *socketmgr,
|
isc_socketmgr_t *socketmgr, isc_task_t *task,
|
||||||
dns_xfrindone_t done)
|
dns_xfrindone_t done, dns_xfrin_ctx_t **xfrp)
|
||||||
{
|
{
|
||||||
dns_name_t *zonename;
|
dns_name_t *zonename;
|
||||||
isc_task_t *task;
|
dns_xfrin_ctx_t *xfr;
|
||||||
xfrin_ctx_t *xfr;
|
|
||||||
isc_result_t result;
|
isc_result_t result;
|
||||||
dns_db_t *db = NULL;
|
dns_db_t *db = NULL;
|
||||||
dns_rdatatype_t xfrtype;
|
dns_rdatatype_t xfrtype;
|
||||||
dns_tsigkey_t *key = NULL;
|
dns_tsigkey_t *key = NULL;
|
||||||
|
REQUIRE(xfrp != NULL && *xfrp == NULL);
|
||||||
|
|
||||||
zonename = dns_zone_getorigin(zone);
|
zonename = dns_zone_getorigin(zone);
|
||||||
|
|
||||||
@@ -514,10 +513,6 @@ dns_xfrin_start(dns_zone_t *zone, isc_sockaddr_t *masteraddr,
|
|||||||
else
|
else
|
||||||
CHECK(result);
|
CHECK(result);
|
||||||
|
|
||||||
task = NULL;
|
|
||||||
CHECK(isc_task_create(taskmgr, mctx, 0, &task));
|
|
||||||
isc_task_setname(task, "xfrin", zone);
|
|
||||||
|
|
||||||
if (db == NULL) {
|
if (db == NULL) {
|
||||||
xfrin_log1(ISC_LOG_DEBUG(3), zonename, masteraddr,
|
xfrin_log1(ISC_LOG_DEBUG(3), zonename, masteraddr,
|
||||||
"no database exists yet, "
|
"no database exists yet, "
|
||||||
@@ -535,34 +530,44 @@ dns_xfrin_start(dns_zone_t *zone, isc_sockaddr_t *masteraddr,
|
|||||||
task,
|
task,
|
||||||
timermgr,
|
timermgr,
|
||||||
socketmgr,
|
socketmgr,
|
||||||
done,
|
|
||||||
zonename,
|
zonename,
|
||||||
dns_zone_getclass(zone), xfrtype,
|
dns_zone_getclass(zone), xfrtype,
|
||||||
masteraddr, key, &xfr));
|
masteraddr, key, &xfr));
|
||||||
|
|
||||||
xfrin_start(xfr);
|
CHECK(xfrin_start(xfr));
|
||||||
goto cleanup;
|
|
||||||
|
xfr->done = done;
|
||||||
|
xfr->refcount++;
|
||||||
|
*xfrp = xfr;
|
||||||
|
|
||||||
failure:
|
failure:
|
||||||
if (done != NULL)
|
|
||||||
(done)(zone, result);
|
|
||||||
|
|
||||||
cleanup:
|
|
||||||
if (db != NULL)
|
if (db != NULL)
|
||||||
dns_db_detach(&db);
|
dns_db_detach(&db);
|
||||||
if (result != DNS_R_SUCCESS)
|
if (result != DNS_R_SUCCESS)
|
||||||
xfrin_log1(ISC_LOG_ERROR, zonename, masteraddr,
|
xfrin_log1(ISC_LOG_ERROR, zonename, masteraddr,
|
||||||
"zone transfer setup failed");
|
"zone transfer setup failed");
|
||||||
return;
|
return (result);
|
||||||
|
}
|
||||||
|
|
||||||
|
void dns_xfrin_shutdown(dns_xfrin_ctx_t *xfr) {
|
||||||
|
if (! xfr->shuttingdown)
|
||||||
|
xfrin_fail(xfr, ISC_R_CANCELED, "shut down");
|
||||||
|
}
|
||||||
|
|
||||||
|
void dns_xfrin_detach(dns_xfrin_ctx_t **xfrp) {
|
||||||
|
dns_xfrin_ctx_t *xfr = *xfrp;
|
||||||
|
INSIST(xfr->refcount > 0);
|
||||||
|
xfr->refcount--;
|
||||||
|
maybe_free(xfr);
|
||||||
|
*xfrp = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
xfrin_fail(xfrin_ctx_t *xfr, isc_result_t result, char *msg) {
|
xfrin_fail(dns_xfrin_ctx_t *xfr, isc_result_t result, char *msg) {
|
||||||
if (result != DNS_R_UPTODATE) {
|
if (result != DNS_R_UPTODATE) {
|
||||||
xfrin_log(xfr, ISC_LOG_ERROR, "%s: %s",
|
xfrin_log(xfr, ISC_LOG_ERROR, "%s: %s",
|
||||||
msg, isc_result_totext(result));
|
msg, isc_result_totext(result));
|
||||||
}
|
}
|
||||||
xfr->shuttingdown = ISC_TRUE;
|
|
||||||
if (xfr->connects > 0) {
|
if (xfr->connects > 0) {
|
||||||
isc_socket_cancel(xfr->socket, xfr->task,
|
isc_socket_cancel(xfr->socket, xfr->task,
|
||||||
ISC_SOCKCANCEL_CONNECT);
|
ISC_SOCKCANCEL_CONNECT);
|
||||||
@@ -572,8 +577,11 @@ xfrin_fail(xfrin_ctx_t *xfr, isc_result_t result, char *msg) {
|
|||||||
isc_socket_cancel(xfr->socket, xfr->task,
|
isc_socket_cancel(xfr->socket, xfr->task,
|
||||||
ISC_SOCKCANCEL_SEND);
|
ISC_SOCKCANCEL_SEND);
|
||||||
}
|
}
|
||||||
if (xfr->done != NULL)
|
xfr->shuttingdown = ISC_TRUE;
|
||||||
|
if (xfr->done != NULL) {
|
||||||
(xfr->done)(xfr->zone, result);
|
(xfr->done)(xfr->zone, result);
|
||||||
|
xfr->done = NULL;
|
||||||
|
}
|
||||||
maybe_free(xfr);
|
maybe_free(xfr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -584,15 +592,14 @@ xfrin_create(isc_mem_t *mctx,
|
|||||||
isc_task_t *task,
|
isc_task_t *task,
|
||||||
isc_timermgr_t *timermgr,
|
isc_timermgr_t *timermgr,
|
||||||
isc_socketmgr_t *socketmgr,
|
isc_socketmgr_t *socketmgr,
|
||||||
dns_xfrindone_t done,
|
|
||||||
dns_name_t *zonename,
|
dns_name_t *zonename,
|
||||||
dns_rdataclass_t rdclass,
|
dns_rdataclass_t rdclass,
|
||||||
dns_rdatatype_t reqtype,
|
dns_rdatatype_t reqtype,
|
||||||
isc_sockaddr_t *masteraddr,
|
isc_sockaddr_t *masteraddr,
|
||||||
dns_tsigkey_t *tsigkey,
|
dns_tsigkey_t *tsigkey,
|
||||||
xfrin_ctx_t **xfrp)
|
dns_xfrin_ctx_t **xfrp)
|
||||||
{
|
{
|
||||||
xfrin_ctx_t *xfr = NULL;
|
dns_xfrin_ctx_t *xfr = NULL;
|
||||||
isc_result_t result;
|
isc_result_t result;
|
||||||
isc_interval_t interval;
|
isc_interval_t interval;
|
||||||
|
|
||||||
@@ -600,12 +607,14 @@ xfrin_create(isc_mem_t *mctx,
|
|||||||
if (xfr == NULL)
|
if (xfr == NULL)
|
||||||
return (DNS_R_NOMEMORY);
|
return (DNS_R_NOMEMORY);
|
||||||
xfr->mctx = mctx;
|
xfr->mctx = mctx;
|
||||||
|
xfr->refcount = 0;
|
||||||
xfr->zone = NULL;
|
xfr->zone = NULL;
|
||||||
dns_zone_attach(zone, &xfr->zone);
|
dns_zone_attach(zone, &xfr->zone);
|
||||||
xfr->task = task;
|
xfr->task = NULL;
|
||||||
|
isc_task_attach(task, &xfr->task);
|
||||||
xfr->timer = NULL;
|
xfr->timer = NULL;
|
||||||
xfr->socketmgr = socketmgr;
|
xfr->socketmgr = socketmgr;
|
||||||
xfr->done = done;
|
xfr->done = NULL;
|
||||||
|
|
||||||
xfr->connects = 0;
|
xfr->connects = 0;
|
||||||
xfr->sends = 0;
|
xfr->sends = 0;
|
||||||
@@ -672,8 +681,8 @@ xfrin_create(isc_mem_t *mctx,
|
|||||||
return (result);
|
return (result);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
isc_result_t
|
||||||
xfrin_start(xfrin_ctx_t *xfr) {
|
xfrin_start(dns_xfrin_ctx_t *xfr) {
|
||||||
isc_result_t result;
|
isc_result_t result;
|
||||||
CHECK(isc_socket_create(xfr->socketmgr,
|
CHECK(isc_socket_create(xfr->socketmgr,
|
||||||
isc_sockaddr_pf(&xfr->masteraddr),
|
isc_sockaddr_pf(&xfr->masteraddr),
|
||||||
@@ -683,9 +692,10 @@ xfrin_start(xfrin_ctx_t *xfr) {
|
|||||||
CHECK(isc_socket_connect(xfr->socket, &xfr->masteraddr, xfr->task,
|
CHECK(isc_socket_connect(xfr->socket, &xfr->masteraddr, xfr->task,
|
||||||
xfrin_connect_done, xfr));
|
xfrin_connect_done, xfr));
|
||||||
xfr->connects++;
|
xfr->connects++;
|
||||||
return;
|
return (ISC_R_SUCCESS);
|
||||||
failure:
|
failure:
|
||||||
xfrin_fail(xfr, result, "setting up socket");
|
xfrin_fail(xfr, result, "setting up socket");
|
||||||
|
return (result);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* XXX the resolver could use this, too */
|
/* XXX the resolver could use this, too */
|
||||||
@@ -711,7 +721,7 @@ render(dns_message_t *msg, isc_buffer_t *buf) {
|
|||||||
static void
|
static void
|
||||||
xfrin_connect_done(isc_task_t *task, isc_event_t *event) {
|
xfrin_connect_done(isc_task_t *task, isc_event_t *event) {
|
||||||
isc_socket_connev_t *cev = (isc_socket_connev_t *) event;
|
isc_socket_connev_t *cev = (isc_socket_connev_t *) event;
|
||||||
xfrin_ctx_t *xfr = (xfrin_ctx_t *) event->arg;
|
dns_xfrin_ctx_t *xfr = (dns_xfrin_ctx_t *) event->arg;
|
||||||
isc_result_t evresult = cev->result;
|
isc_result_t evresult = cev->result;
|
||||||
isc_result_t result;
|
isc_result_t result;
|
||||||
task = task; /* Unused */
|
task = task; /* Unused */
|
||||||
@@ -719,8 +729,10 @@ xfrin_connect_done(isc_task_t *task, isc_event_t *event) {
|
|||||||
isc_event_free(&event);
|
isc_event_free(&event);
|
||||||
|
|
||||||
xfr->connects--;
|
xfr->connects--;
|
||||||
if (maybe_free(xfr))
|
if (xfr->shuttingdown) {
|
||||||
|
maybe_free(xfr);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
CHECK(evresult);
|
CHECK(evresult);
|
||||||
xfrin_log(xfr, ISC_LOG_DEBUG(3), "connected");
|
xfrin_log(xfr, ISC_LOG_DEBUG(3), "connected");
|
||||||
@@ -779,7 +791,7 @@ tuple2msgname(dns_difftuple_t *tuple, dns_message_t *msg, dns_name_t **target)
|
|||||||
* Build an *XFR request and send its length prefix.
|
* Build an *XFR request and send its length prefix.
|
||||||
*/
|
*/
|
||||||
static isc_result_t
|
static isc_result_t
|
||||||
xfrin_send_request(xfrin_ctx_t *xfr) {
|
xfrin_send_request(dns_xfrin_ctx_t *xfr) {
|
||||||
isc_result_t result;
|
isc_result_t result;
|
||||||
isc_region_t region;
|
isc_region_t region;
|
||||||
isc_region_t lregion;
|
isc_region_t lregion;
|
||||||
@@ -858,7 +870,7 @@ static void
|
|||||||
xfrin_sendlen_done(isc_task_t *task, isc_event_t *event)
|
xfrin_sendlen_done(isc_task_t *task, isc_event_t *event)
|
||||||
{
|
{
|
||||||
isc_socketevent_t *sev = (isc_socketevent_t *) event;
|
isc_socketevent_t *sev = (isc_socketevent_t *) event;
|
||||||
xfrin_ctx_t *xfr = (xfrin_ctx_t *) event->arg;
|
dns_xfrin_ctx_t *xfr = (dns_xfrin_ctx_t *) event->arg;
|
||||||
isc_result_t evresult = sev->result;
|
isc_result_t evresult = sev->result;
|
||||||
isc_result_t result;
|
isc_result_t result;
|
||||||
isc_region_t region;
|
isc_region_t region;
|
||||||
@@ -868,8 +880,10 @@ xfrin_sendlen_done(isc_task_t *task, isc_event_t *event)
|
|||||||
isc_event_free(&event);
|
isc_event_free(&event);
|
||||||
|
|
||||||
xfr->sends--;
|
xfr->sends--;
|
||||||
if (maybe_free(xfr))
|
if (xfr->shuttingdown) {
|
||||||
|
maybe_free(xfr);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
xfrin_log(xfr, ISC_LOG_DEBUG(3), "sent request length prefix");
|
xfrin_log(xfr, ISC_LOG_DEBUG(3), "sent request length prefix");
|
||||||
CHECK(evresult);
|
CHECK(evresult);
|
||||||
@@ -888,7 +902,7 @@ static void
|
|||||||
xfrin_send_done(isc_task_t *task, isc_event_t *event)
|
xfrin_send_done(isc_task_t *task, isc_event_t *event)
|
||||||
{
|
{
|
||||||
isc_socketevent_t *sev = (isc_socketevent_t *) event;
|
isc_socketevent_t *sev = (isc_socketevent_t *) event;
|
||||||
xfrin_ctx_t *xfr = (xfrin_ctx_t *) event->arg;
|
dns_xfrin_ctx_t *xfr = (dns_xfrin_ctx_t *) event->arg;
|
||||||
isc_result_t result;
|
isc_result_t result;
|
||||||
|
|
||||||
task = task; /* Unused */
|
task = task; /* Unused */
|
||||||
@@ -910,7 +924,7 @@ xfrin_send_done(isc_task_t *task, isc_event_t *event)
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
xfrin_recv_done(isc_task_t *task, isc_event_t *ev) {
|
xfrin_recv_done(isc_task_t *task, isc_event_t *ev) {
|
||||||
xfrin_ctx_t *xfr = (xfrin_ctx_t *) ev->arg;
|
dns_xfrin_ctx_t *xfr = (dns_xfrin_ctx_t *) ev->arg;
|
||||||
isc_result_t result;
|
isc_result_t result;
|
||||||
dns_message_t *msg = NULL;
|
dns_message_t *msg = NULL;
|
||||||
dns_name_t *name;
|
dns_name_t *name;
|
||||||
@@ -923,8 +937,10 @@ xfrin_recv_done(isc_task_t *task, isc_event_t *ev) {
|
|||||||
isc_event_free(&ev);
|
isc_event_free(&ev);
|
||||||
|
|
||||||
xfr->recvs--;
|
xfr->recvs--;
|
||||||
if (maybe_free(xfr))
|
if (xfr->shuttingdown) {
|
||||||
|
maybe_free(xfr);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
CHECK(tcpmsg->result);
|
CHECK(tcpmsg->result);
|
||||||
|
|
||||||
@@ -1032,13 +1048,15 @@ xfrin_recv_done(isc_task_t *task, isc_event_t *ev) {
|
|||||||
/*
|
/*
|
||||||
* Inform the caller we succeeded.
|
* Inform the caller we succeeded.
|
||||||
*/
|
*/
|
||||||
if (xfr->done != NULL)
|
if (xfr->done != NULL) {
|
||||||
(xfr->done)(xfr->zone, ISC_R_SUCCESS);
|
(xfr->done)(xfr->zone, ISC_R_SUCCESS);
|
||||||
|
xfr->done = NULL;
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
* We should have no outstanding events at this
|
* We should have no outstanding events at this
|
||||||
* point, thus maybe_free() should succeed.
|
* point, thus maybe_free() should succeed.
|
||||||
*/
|
*/
|
||||||
RUNTIME_CHECK(maybe_free(xfr) == ISC_TRUE);
|
maybe_free(xfr);
|
||||||
} else {
|
} else {
|
||||||
/* Read the next message. */
|
/* Read the next message. */
|
||||||
CHECK(dns_tcpmsg_readmessage(&xfr->tcpmsg, xfr->task,
|
CHECK(dns_tcpmsg_readmessage(&xfr->tcpmsg, xfr->task,
|
||||||
@@ -1058,18 +1076,19 @@ xfrin_recv_done(isc_task_t *task, isc_event_t *ev) {
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
xfrin_timeout(isc_task_t *task, isc_event_t *event) {
|
xfrin_timeout(isc_task_t *task, isc_event_t *event) {
|
||||||
xfrin_ctx_t *xfr = (xfrin_ctx_t *) event->arg;
|
dns_xfrin_ctx_t *xfr = (dns_xfrin_ctx_t *) event->arg;
|
||||||
task = task; /* Unused */
|
task = task; /* Unused */
|
||||||
isc_event_free(&event);
|
isc_event_free(&event);
|
||||||
/* This will log "giving up: timeout". */
|
/* This will log "giving up: timeout". */
|
||||||
xfrin_fail(xfr, ISC_R_TIMEDOUT, "giving up");
|
xfrin_fail(xfr, ISC_R_TIMEDOUT, "giving up");
|
||||||
}
|
}
|
||||||
|
|
||||||
static isc_boolean_t
|
static void
|
||||||
maybe_free(xfrin_ctx_t *xfr) {
|
maybe_free(dns_xfrin_ctx_t *xfr) {
|
||||||
if (! xfr->shuttingdown || xfr->connects != 0 ||
|
if (! xfr->shuttingdown || xfr->refcount != 0 ||
|
||||||
xfr->sends != 0 || xfr->recvs != 0)
|
xfr->connects != 0 || xfr->sends != 0 ||
|
||||||
return (ISC_FALSE);
|
xfr->recvs != 0)
|
||||||
|
return;
|
||||||
|
|
||||||
xfrin_log(xfr, ISC_LOG_INFO, "end of transfer");
|
xfrin_log(xfr, ISC_LOG_INFO, "end of transfer");
|
||||||
|
|
||||||
@@ -1080,7 +1099,7 @@ maybe_free(xfrin_ctx_t *xfr) {
|
|||||||
isc_timer_detach(&xfr->timer);
|
isc_timer_detach(&xfr->timer);
|
||||||
|
|
||||||
if (xfr->task != NULL)
|
if (xfr->task != NULL)
|
||||||
isc_task_destroy(&xfr->task);
|
isc_task_detach(&xfr->task);
|
||||||
|
|
||||||
if (xfr->lasttsig != NULL) {
|
if (xfr->lasttsig != NULL) {
|
||||||
dns_rdata_freestruct(xfr->lasttsig);
|
dns_rdata_freestruct(xfr->lasttsig);
|
||||||
@@ -1111,8 +1130,6 @@ maybe_free(xfrin_ctx_t *xfr) {
|
|||||||
dns_zone_detach(&xfr->zone);
|
dns_zone_detach(&xfr->zone);
|
||||||
|
|
||||||
isc_mem_put(xfr->mctx, xfr, sizeof(*xfr));
|
isc_mem_put(xfr->mctx, xfr, sizeof(*xfr));
|
||||||
|
|
||||||
return (ISC_TRUE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1167,7 +1184,7 @@ xfrin_log1(int level, dns_name_t *zonename, isc_sockaddr_t *masteraddr,
|
|||||||
/* Logging function for use when there is a xfin_ctx_t. */
|
/* Logging function for use when there is a xfin_ctx_t. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
xfrin_log(xfrin_ctx_t *xfr, unsigned int level, const char *fmt, ...)
|
xfrin_log(dns_xfrin_ctx_t *xfr, unsigned int level, const char *fmt, ...)
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
|
@@ -15,7 +15,7 @@
|
|||||||
* SOFTWARE.
|
* SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* $Id: zone.c,v 1.70 2000/01/28 16:10:47 bwelling Exp $ */
|
/* $Id: zone.c,v 1.71 2000/01/28 23:48:58 gson Exp $ */
|
||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
|
||||||
@@ -142,6 +142,7 @@ struct dns_zone {
|
|||||||
isc_sockaddr_t notifyfrom;
|
isc_sockaddr_t notifyfrom;
|
||||||
isc_task_t * task;
|
isc_task_t * task;
|
||||||
isc_sockaddr_t xfrsource;
|
isc_sockaddr_t xfrsource;
|
||||||
|
dns_xfrin_ctx_t * xfr;
|
||||||
/* Access Control Lists */
|
/* Access Control Lists */
|
||||||
dns_acl_t *update_acl;
|
dns_acl_t *update_acl;
|
||||||
dns_acl_t *query_acl;
|
dns_acl_t *query_acl;
|
||||||
@@ -209,11 +210,11 @@ static isc_result_t default_journal(dns_zone_t *zone);
|
|||||||
static void releasezone(dns_zonemgr_t *zmgr, dns_zone_t *zone);
|
static void releasezone(dns_zonemgr_t *zmgr, dns_zone_t *zone);
|
||||||
static void xfrin_start_temporary_kludge(dns_zone_t *zone);
|
static void xfrin_start_temporary_kludge(dns_zone_t *zone);
|
||||||
static void xfrdone(dns_zone_t *zone, isc_result_t result);
|
static void xfrdone(dns_zone_t *zone, isc_result_t result);
|
||||||
|
static void zone_shutdown(isc_task_t *, isc_event_t *);
|
||||||
#ifdef notyet
|
#ifdef notyet
|
||||||
static void refresh_callback(isc_task_t *, isc_event_t *);
|
static void refresh_callback(isc_task_t *, isc_event_t *);
|
||||||
static void soa_query(dns_zone_t *, isc_taskaction_t);
|
static void soa_query(dns_zone_t *, isc_taskaction_t);
|
||||||
static void checkservers_callback(isc_task_t *task, isc_event_t *event);
|
static void checkservers_callback(isc_task_t *task, isc_event_t *event);
|
||||||
static void zone_shutdown(isc_task_t *, isc_event_t *);
|
|
||||||
static int message_count(dns_message_t *msg, dns_section_t section,
|
static int message_count(dns_message_t *msg, dns_section_t section,
|
||||||
dns_rdatatype_t type);
|
dns_rdatatype_t type);
|
||||||
static void add_address_tocheck(dns_message_t *msg,
|
static void add_address_tocheck(dns_message_t *msg,
|
||||||
@@ -315,6 +316,7 @@ dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) {
|
|||||||
zone->idleout = DNS_DEFAULT_IDLEOUT;
|
zone->idleout = DNS_DEFAULT_IDLEOUT;
|
||||||
ISC_LIST_INIT(zone->checkservers);
|
ISC_LIST_INIT(zone->checkservers);
|
||||||
zone->xfrsource = sockaddr_any;
|
zone->xfrsource = sockaddr_any;
|
||||||
|
zone->xfr = NULL;
|
||||||
zone->maxxfrin = MAX_XFER_TIME;
|
zone->maxxfrin = MAX_XFER_TIME;
|
||||||
zone->maxxfrout = MAX_XFER_TIME;
|
zone->maxxfrout = MAX_XFER_TIME;
|
||||||
zone->diff_on_reload = ISC_FALSE;
|
zone->diff_on_reload = ISC_FALSE;
|
||||||
@@ -2130,15 +2132,16 @@ soa_query(dns_zone_t *zone, isc_taskaction_t callback) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef notyet
|
|
||||||
static void
|
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->arg;
|
dns_zone_t *zone = (dns_zone_t *) event->arg;
|
||||||
isc_event_free(&event);
|
isc_event_free(&event);
|
||||||
task = task; /* XXX */
|
UNUSED(task);
|
||||||
zone = zone; /* XXX */
|
REQUIRE(DNS_ZONE_VALID(zone));
|
||||||
|
zone_log(zone, "zone_shutdown", ISC_LOG_DEBUG(3), "shutting down");
|
||||||
|
if (zone->xfr != NULL)
|
||||||
|
dns_xfrin_shutdown(zone->xfr);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
zone_timer(isc_task_t *task, isc_event_t *event) {
|
zone_timer(isc_task_t *task, isc_event_t *event) {
|
||||||
@@ -2911,6 +2914,7 @@ xfrdone(dns_zone_t *zone, isc_result_t result) {
|
|||||||
LOCK(&zone->lock);
|
LOCK(&zone->lock);
|
||||||
INSIST((zone->flags & DNS_ZONE_F_REFRESH) != 0);
|
INSIST((zone->flags & DNS_ZONE_F_REFRESH) != 0);
|
||||||
zone->flags &= ~DNS_ZONE_F_REFRESH;
|
zone->flags &= ~DNS_ZONE_F_REFRESH;
|
||||||
|
|
||||||
switch (result) {
|
switch (result) {
|
||||||
case DNS_R_UPTODATE:
|
case DNS_R_UPTODATE:
|
||||||
case DNS_R_SUCCESS:
|
case DNS_R_SUCCESS:
|
||||||
@@ -2934,6 +2938,20 @@ xfrdone(dns_zone_t *zone, isc_result_t result) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
UNLOCK(&zone->lock);
|
UNLOCK(&zone->lock);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If creating the transfer object failed, zone->xfr is NULL.
|
||||||
|
* Otherwise, we are called as the done callback of a zone
|
||||||
|
* transfer object that just entered its shutting-down
|
||||||
|
* state. Since we are no longer responsible for shutting
|
||||||
|
* it down, we can detach our reference.
|
||||||
|
*/
|
||||||
|
if (zone->xfr != NULL)
|
||||||
|
dns_xfrin_detach(&zone->xfr);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Retry with a different server if necessary.
|
||||||
|
*/
|
||||||
if (again)
|
if (again)
|
||||||
xfrin_start_temporary_kludge(zone);
|
xfrin_start_temporary_kludge(zone);
|
||||||
}
|
}
|
||||||
@@ -2944,8 +2962,10 @@ xfrdone(dns_zone_t *zone, isc_result_t result) {
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
xfrin_start_temporary_kludge(dns_zone_t *zone) {
|
xfrin_start_temporary_kludge(dns_zone_t *zone) {
|
||||||
|
isc_result_t result;
|
||||||
isc_sockaddr_t sa;
|
isc_sockaddr_t sa;
|
||||||
in_port_t port;
|
in_port_t port;
|
||||||
|
|
||||||
if (zone->masterscnt < 1)
|
if (zone->masterscnt < 1)
|
||||||
return;
|
return;
|
||||||
port = zone->masterport;
|
port = zone->masterport;
|
||||||
@@ -2954,10 +2974,12 @@ xfrin_start_temporary_kludge(dns_zone_t *zone) {
|
|||||||
isc_sockaddr_fromin(&sa,
|
isc_sockaddr_fromin(&sa,
|
||||||
&zone->masters[zone->curmaster].type.sin.sin_addr,
|
&zone->masters[zone->curmaster].type.sin.sin_addr,
|
||||||
port);
|
port);
|
||||||
dns_xfrin_start(zone, &sa, zone->mctx,
|
result = dns_xfrin_create(zone, &sa, zone->mctx,
|
||||||
zone->zmgr->taskmgr, zone->zmgr->timermgr,
|
zone->zmgr->timermgr, zone->zmgr->socketmgr,
|
||||||
zone->zmgr->socketmgr,
|
zone->task,
|
||||||
xfrdone);
|
xfrdone, &zone->xfr);
|
||||||
|
if (result != DNS_R_SUCCESS)
|
||||||
|
xfrdone(zone, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
isc_result_t
|
isc_result_t
|
||||||
@@ -3054,18 +3076,25 @@ dns_zonemgr_managezone(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
|
|||||||
zmgr->task, zone_timer, zone,
|
zmgr->task, zone_timer, zone,
|
||||||
&zone->timer);
|
&zone->timer);
|
||||||
if (result != ISC_R_SUCCESS)
|
if (result != ISC_R_SUCCESS)
|
||||||
goto failure;
|
goto cleanup_task;
|
||||||
|
|
||||||
|
result = isc_task_onshutdown(zone->task, zone_shutdown, zone);
|
||||||
|
if (result != ISC_R_SUCCESS)
|
||||||
|
goto cleanup_timer;
|
||||||
|
|
||||||
zone->zmgr = zmgr;
|
zone->zmgr = zmgr;
|
||||||
ISC_LIST_APPEND(zmgr->zones, zone, link);
|
ISC_LIST_APPEND(zmgr->zones, zone, link);
|
||||||
|
|
||||||
goto cleanup;
|
goto unlock;
|
||||||
|
|
||||||
failure:
|
cleanup_timer:
|
||||||
|
isc_timer_detach(&zone->timer);
|
||||||
|
|
||||||
|
cleanup_task:
|
||||||
if (zone->task != NULL)
|
if (zone->task != NULL)
|
||||||
isc_task_detach(&zone->task);
|
isc_task_detach(&zone->task);
|
||||||
|
|
||||||
cleanup:
|
unlock:
|
||||||
UNLOCK(&zone->lock);
|
UNLOCK(&zone->lock);
|
||||||
RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
|
RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
|
||||||
return (result);
|
return (result);
|
||||||
|
Reference in New Issue
Block a user