From 2a3e99550d09824a18aaf9968f3f37406b42293f Mon Sep 17 00:00:00 2001 From: Mark Andrews Date: Wed, 7 Jun 2000 02:40:42 +0000 Subject: [PATCH] 240. [func] databases now come in three flavours: zone, cache and stub. Add stubs zones support checkpoint. notify_t -> dns_notify_t --- lib/dns/zone.c | 532 ++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 500 insertions(+), 32 deletions(-) diff --git a/lib/dns/zone.c b/lib/dns/zone.c index bc2c4be729..4ce83774ce 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -15,7 +15,7 @@ * SOFTWARE. */ -/* $Id: zone.c,v 1.142 2000/06/05 21:54:28 gson Exp $ */ +/* $Id: zone.c,v 1.143 2000/06/07 02:40:42 marka Exp $ */ #include @@ -51,11 +51,14 @@ #define ZONE_MAGIC 0x5a4f4e45U /* ZONE */ #define NOTIFY_MAGIC 0x4e746679U /* Ntfy */ +#define STUB_MAGIC 0x53747562U /* Stub */ #define DNS_ZONE_VALID(zone) \ ISC_MAGIC_VALID(zone, ZONE_MAGIC) #define DNS_NOTIFY_VALID(notify) \ ISC_MAGIC_VALID(notify, NOTIFY_MAGIC) +#define DNS_STUB_VALID(stub) \ + ISC_MAGIC_VALID(stub, STUB_MAGIC) #define RANGE(a, b, c) (((a) < (b)) ? (b) : ((a) < (c) ? (a) : (c))) @@ -78,7 +81,8 @@ #define MAX_XFER_TIME (2*3600) /* Documented default is 2 hours */ -typedef struct notify notify_t; +typedef struct dns_notify dns_notify_t; +typedef struct dns_stub dns_stub_t; struct dns_zone { /* Unlocked */ @@ -129,7 +133,7 @@ struct dns_zone { dns_acl_t *query_acl; dns_acl_t *xfr_acl; dns_severity_t check_names; - ISC_LIST(notify_t) notifies; + ISC_LIST(dns_notify_t) notifies; dns_request_t *request; isc_uint32_t maxxfrin; isc_uint32_t maxxfrout; @@ -156,7 +160,7 @@ struct dns_zone { /* XXX MPA these may need to go back into zone.h */ #define DNS_ZONE_F_REFRESH 0x00000001U /* refresh check in progress */ #define DNS_ZONE_F_NEEDDUMP 0x00000002U /* zone need consolidation */ -/* #define DNS_ZONE_F_UNUSED 0x00000004U */ /* unused */ +#define DNS_ZONE_F_USEVC 0x00000004U /* use tcp for refresh query */ /* #define DNS_ZONE_F_UNUSED 0x00000008U */ /* unused */ /* #define DNS_ZONE_F_UNUSED 0x00000010U */ /* unused */ #define DNS_ZONE_F_LOADED 0x00000020U /* database has loaded */ @@ -199,7 +203,7 @@ struct dns_zonemgr { /* * Hold notify state. */ -struct notify { +struct dns_notify { isc_int32_t magic; isc_mem_t *mctx; dns_zone_t *zone; @@ -207,7 +211,21 @@ struct notify { dns_request_t *request; dns_name_t ns; isc_sockaddr_t dst; - ISC_LINK(notify_t) link; + ISC_LINK(dns_notify_t) link; +}; + +/* + * dns_stub holds state while performing a 'stub' transfer. + * 'db' is the zone's 'db' or a new one if this is the initial + * transfer. + */ + +struct dns_stub { + isc_int32_t magic; + isc_mem_t *mctx; + dns_zone_t *zone; + dns_db_t *db; + dns_dbversion_t *version; }; static isc_result_t zone_settimer(dns_zone_t *, isc_stdtime_t); @@ -232,12 +250,15 @@ static void dns_zonemgr_dbdestroyed(isc_task_t *task, isc_event_t *event); #endif static void refresh_callback(isc_task_t *, isc_event_t *); +static void stub_callback(isc_task_t *, isc_event_t *); static void queue_soa_query(dns_zone_t *zone); static void soa_query(isc_task_t *, isc_event_t *); +static void ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset, + dns_stub_t *stub); static int message_count(dns_message_t *msg, dns_section_t section, dns_rdatatype_t type); -static void notify_find_address(notify_t *notify); -static void notify_send(notify_t *notify); +static void notify_find_address(dns_notify_t *notify); +static void notify_send(dns_notify_t *notify); static isc_result_t notify_createmessage(dns_zone_t *zone, dns_message_t **messagep); static void notify_done(isc_task_t *task, isc_event_t *event); @@ -628,9 +649,10 @@ dns_zone_load(dns_zone_t *zone) { goto cleanup; result = dns_db_create(zone->mctx, zone->db_type, - &zone->origin, - ISC_FALSE, zone->rdclass, - zone->db_argc, zone->db_argv, &db); + &zone->origin, (zone->type == dns_zone_stub) ? + dns_dbtype_stub : dns_dbtype_zone, + zone->rdclass, zone->db_argc, zone->db_argv, + &db); if (result != ISC_R_SUCCESS) goto cleanup; @@ -643,7 +665,8 @@ dns_zone_load(dns_zone_t *zone) { * XXX better error feedback to log. */ if (result != ISC_R_SUCCESS) { - if (zone->type == dns_zone_slave) { + if (zone->type == dns_zone_slave || + zone->type == dns_zone_stub) { zone_log(zone, me, ISC_LOG_INFO, "no database file"); /* Mark the zone for immediate refresh. */ @@ -1539,7 +1562,7 @@ dns_zone_setrefresh(dns_zone_t *zone, isc_uint32_t refresh, static isc_boolean_t notify_isqueued(dns_zone_t *zone, dns_name_t *name, isc_sockaddr_t *addr) { - notify_t *notify; + dns_notify_t *notify; for (notify = ISC_LIST_HEAD(zone->notifies); notify != NULL; @@ -1556,7 +1579,7 @@ notify_isqueued(dns_zone_t *zone, dns_name_t *name, isc_sockaddr_t *addr) { } static void -notify_destroy(notify_t *notify) { +notify_destroy(dns_notify_t *notify) { isc_mem_t *mctx; /* @@ -1581,8 +1604,8 @@ notify_destroy(notify_t *notify) { } static isc_result_t -notify_create(isc_mem_t *mctx, notify_t **notifyp) { - notify_t *notify; +notify_create(isc_mem_t *mctx, dns_notify_t **notifyp) { + dns_notify_t *notify; REQUIRE(notifyp != NULL && *notifyp == NULL); @@ -1608,7 +1631,7 @@ notify_create(isc_mem_t *mctx, notify_t **notifyp) { */ static void process_adb_event(isc_task_t *task, isc_event_t *ev) { - notify_t *notify; + dns_notify_t *notify; isc_eventtype_t result; dns_zone_t *zone = NULL; @@ -1638,7 +1661,7 @@ process_adb_event(isc_task_t *task, isc_event_t *ev) { } static void -notify_find_address(notify_t *notify) { +notify_find_address(dns_notify_t *notify) { isc_result_t result; unsigned int options; dns_zone_t *zone = NULL; @@ -1679,7 +1702,7 @@ notify_find_address(notify_t *notify) { static isc_result_t -notify_send_queue(notify_t *notify) { +notify_send_queue(dns_notify_t *notify) { isc_event_t *e; isc_result_t result; @@ -1700,7 +1723,7 @@ notify_send_queue(notify_t *notify) { static void notify_send_toaddr(isc_task_t *task, isc_event_t *event) { - notify_t *notify; + dns_notify_t *notify; isc_result_t result; dns_message_t *message = NULL; dns_zone_t *zone = NULL; @@ -1754,12 +1777,12 @@ notify_send_toaddr(isc_task_t *task, isc_event_t *event) { } static void -notify_send(notify_t *notify) { +notify_send(dns_notify_t *notify) { dns_adbaddrinfo_t *ai; isc_sockaddr_t dst; isc_result_t result; dns_message_t *message = NULL; - notify_t *new = NULL; + dns_notify_t *new = NULL; /* * Zone lock held by caller. @@ -1808,7 +1831,7 @@ dns_zone_notify(dns_zone_t *zone) { dns_rdataset_t nsrdset; dns_rdataset_t soardset; isc_result_t result; - notify_t *notify = NULL; + dns_notify_t *notify = NULL; unsigned int i; isc_sockaddr_t dst; isc_boolean_t isqueued; @@ -1948,6 +1971,256 @@ dns_zone_notify(dns_zone_t *zone) { *** Private ***/ +static void +stub_callback(isc_task_t *task, isc_event_t *event) { + const char me[] = "stub_callback"; + dns_requestevent_t *revent = (dns_requestevent_t *)event; + dns_stub_t *stub = NULL; + dns_message_t *msg = NULL; + dns_zone_t *zone = NULL; + char master[ISC_SOCKADDR_FORMATSIZE]; + isc_uint32_t nscnt, cnamecnt; + isc_result_t result; + isc_stdtime_t now; + dns_rdata_ns_t ns; + dns_rdataset_t *nsrdataset = NULL; + dns_rdataset_t *rdataset = NULL; + dns_dbnode_t *node = NULL; + dns_rdata_t rdata; + + stub = revent->ev_arg; + INSIST(DNS_STUB_VALID(stub)); + + UNUSED(task); + + /* XXX add test for exiting */ + + dns_zone_iattach(stub->zone, &zone); + + DNS_ENTER; + + isc_stdtime_get(&now); + + if (revent->result != ISC_R_SUCCESS) { + zone_log(zone, me, ISC_LOG_INFO, "failure for %s: %s", + master, dns_result_totext(revent->result)); + goto next_master; + } + + result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg); + if (result != ISC_R_SUCCESS) + goto next_master; + result = dns_request_getresponse(revent->request, msg, ISC_FALSE); + if (result != ISC_R_SUCCESS) + goto next_master; + + /* + * Unexpected rcode. + */ + if (msg->rcode != dns_rcode_noerror) { + char rcode[128]; + isc_buffer_t rb; + + isc_buffer_init(&rb, rcode, sizeof(rcode)); + dns_rcode_totext(msg->rcode, &rb); + + zone_log(zone, me, ISC_LOG_INFO, + "unexpected rcode (%.*s) from %s", + rb.used, rcode, master); + goto next_master; + } + + if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) { + if (dns_request_usedtcp(revent->request)) { + /* XXX log failure */ + goto next_master; + } + LOCK(&zone->lock); + zone->flags |= DNS_ZONE_F_USEVC; + UNLOCK(&zone->lock); + goto same_master; + } + + /* + * if non-auth log and next master; + */ + if ((msg->flags & DNS_MESSAGEFLAG_AA) == 0) { + zone_log(zone, me, ISC_LOG_INFO, + "non-authorative answer from %s", master); + goto next_master; + } + + cnamecnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_cname); + nscnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_ns); + + if (cnamecnt != 0) { + zone_log(zone, me, ISC_LOG_INFO, + "found unexpected CNAME %s", master); + goto next_master; + } + + if (nscnt == 0) { + zone_log(zone, me, ISC_LOG_INFO, + "no NS records from %s", master); + goto next_master; + } + + result = dns_message_findname(msg, DNS_SECTION_ANSWER, &zone->origin, + dns_rdatatype_ns, dns_rdatatype_none, + NULL, &nsrdataset); + if (result != ISC_R_SUCCESS) { + zone_log(zone, me, ISC_LOG_INFO, + "unable to get ns records from %s", master); + goto next_master; + } + result = dns_db_findnode(stub->db, &zone->origin, ISC_TRUE, &node); + if (result != ISC_R_SUCCESS) { + zone_log(zone, me, ISC_LOG_INFO, + "dns_db_findnode failed: %s", + dns_result_totext(result)); + goto next_master; + } + /* + * Add NS rdataset. + */ + result = dns_db_addrdataset(stub->db, node, stub->version, now, + nsrdataset, 0, NULL); + dns_db_detachnode(stub->db, &node); + if (result != ISC_R_SUCCESS) { + zone_log(zone, me, ISC_LOG_INFO, + "dns_db_addrdataset failed: %s", + dns_result_totext(result)); + goto next_master; + } + /* + * Add glue rdatasets. + */ + for (result = dns_rdataset_first(nsrdataset); + result == ISC_R_SUCCESS; + result = dns_rdataset_next(nsrdataset)) { + dns_rdataset_current(nsrdataset, &rdata); + result = dns_rdata_tostruct(&rdata, &ns, NULL); + RUNTIME_CHECK(result == ISC_R_SUCCESS); + if (!dns_name_issubdomain(&ns.name, &zone->origin)) { + result = dns_rdataset_next(nsrdataset); + continue; + } + rdataset = NULL; + result = dns_message_findname(msg, DNS_SECTION_ADDITIONAL, + &ns.name, dns_rdatatype_a6, + dns_rdatatype_none, NULL, + &rdataset); + if (result == ISC_R_SUCCESS) { + result = dns_db_findnode(stub->db, &ns.name, + ISC_TRUE, &node); + if (result != ISC_R_SUCCESS) + goto next_master; + result = dns_db_addrdataset(stub->db, node, + stub->version, now, + rdataset, 0, NULL); + dns_db_detachnode(stub->db, &node); + if (result != ISC_R_SUCCESS) + goto next_master; + } + rdataset = NULL; + result = dns_message_findname(msg, DNS_SECTION_ADDITIONAL, + &ns.name, dns_rdatatype_aaaa, + dns_rdatatype_none, NULL, + &rdataset); + if (result == ISC_R_SUCCESS) { + result = dns_db_findnode(stub->db, &ns.name, + ISC_TRUE, &node); + if (result != ISC_R_SUCCESS) + goto next_master; + result = dns_db_addrdataset(stub->db, node, + stub->version, now, + rdataset, 0, NULL); + dns_db_detachnode(stub->db, &node); + if (result != ISC_R_SUCCESS) + goto next_master; + } + rdataset = NULL; + result = dns_message_findname(msg, DNS_SECTION_ADDITIONAL, + &ns.name, dns_rdatatype_a, + dns_rdatatype_none, NULL, + &rdataset); + if (result == ISC_R_SUCCESS) { + result = dns_db_findnode(stub->db, &ns.name, + ISC_TRUE, &node); + if (result != ISC_R_SUCCESS) + goto next_master; + result = dns_db_addrdataset(stub->db, node, + stub->version, now, + rdataset, 0, NULL); + dns_db_detachnode(stub->db, &node); + if (result != ISC_R_SUCCESS) + goto next_master; + } + } + if (result != ISC_R_NOMORE) + goto next_master; + dns_db_closeversion(stub->db, &stub->version, ISC_TRUE); + LOCK(&zone->lock); + if (zone->db == NULL) + dns_db_attach(stub->db, &zone->db); + UNLOCK(&zone->lock); + dns_db_detach(&stub->db); + + if (zone->dbname != NULL) + dns_zone_dump(zone); + + dns_message_destroy(&msg); + isc_event_free(&event); + dns_request_destroy(&zone->request); + goto free_stub; + + next_master: + if (stub->version != NULL) + dns_db_closeversion(stub->db, &stub->version, ISC_FALSE); + if (node != NULL) + dns_db_detachnode(stub->db, &node); + if (stub->db != NULL) + dns_db_detach(&stub->db); + if (msg != NULL) + dns_message_destroy(&msg); + LOCK(&zone->lock); + isc_event_free(&event); + dns_request_destroy(&zone->request); + zone->curmaster++; + if (zone->curmaster >= zone->masterscnt) { + zone->flags &= ~DNS_ZONE_F_REFRESH; + + zone_settimer(zone, now); + UNLOCK(&zone->lock); + return; + } + UNLOCK(&zone->lock); + queue_soa_query(zone); + goto free_stub; + + same_master: + if (msg != NULL) + dns_message_destroy(&msg); + isc_event_free(&event); + LOCK(&zone->lock); + dns_request_destroy(&zone->request); + UNLOCK(&zone->lock); + ns_query(zone, NULL, stub); + goto detach; + + + free_stub: + stub->magic = 0; + dns_zone_idetach(&stub->zone); + INSIST(stub->db == NULL); + INSIST(stub->version == NULL); + isc_mem_put(stub->mctx, stub, sizeof(*stub)); + + detach: + dns_zone_idetach(&zone); + return; +} + static void refresh_callback(isc_task_t *task, isc_event_t *event) { const char me[] = "refresh_callback"; @@ -2011,10 +2284,23 @@ refresh_callback(isc_task_t *task, isc_event_t *event) { * If truncated punt to zone transfer which will query again. */ if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) { - zone_log(zone, me, ISC_LOG_INFO, - "truncated UDP answer initiating TCP zone xfer %s", - master); - goto tcp_transfer; + if (zone->type == dns_zone_slave) { + zone_log(zone, me, ISC_LOG_INFO, + "truncated UDP answer initiating " + "TCP zone xfer %s", + master); + goto tcp_transfer; + } else { + INSIST(zone->type == dns_zone_stub); + if (dns_request_usedtcp(revent->request)) { + /* XXX log failure */ + goto next_master; + } + LOCK(&zone->lock); + zone->flags |= DNS_ZONE_F_USEVC; + UNLOCK(&zone->lock); + goto same_master; + } } /* @@ -2095,7 +2381,6 @@ refresh_callback(isc_task_t *task, isc_event_t *event) { } serial = soa.serial; - dns_message_destroy(&msg); zone_log(zone, me, ISC_LOG_DEBUG(1), "Serial: new %u, old %u", serial, zone->serial); @@ -2104,7 +2389,14 @@ refresh_callback(isc_task_t *task, isc_event_t *event) { tcp_transfer: isc_event_free(&event); dns_request_destroy(&zone->request); - queue_xfrin(zone); + if (zone->type == dns_zone_slave) { + queue_xfrin(zone); + } else { + INSIST(zone->type == dns_zone_stub); + ns_query(zone, rdataset, NULL); + } + if (msg != NULL) + dns_message_destroy(&msg); } else if (isc_serial_eq(soa.serial, zone->serial)) { if (zone->dbname != NULL) { isc_time_t t; @@ -2123,6 +2415,8 @@ refresh_callback(isc_task_t *task, isc_event_t *event) { ZONE_LOG(1, "ahead"); goto next_master; } + if (msg != NULL) + dns_message_destroy(&msg); return; next_master: @@ -2145,6 +2439,16 @@ refresh_callback(isc_task_t *task, isc_event_t *event) { UNLOCK(&zone->lock); queue_soa_query(zone); return; + + same_master: + if (msg != NULL) + dns_message_destroy(&msg); + LOCK(&zone->lock); + isc_event_free(&event); + dns_request_destroy(&zone->request); + UNLOCK(&zone->lock); + queue_soa_query(zone); + return; } static void @@ -2196,6 +2500,7 @@ soa_query(isc_task_t *task, isc_event_t *event) { dns_peer_t *peer = NULL; dns_name_t *keyname = NULL; dns_tsigkey_t *key = NULL; + isc_uint32_t options; REQUIRE(DNS_ZONE_VALID(zone)); @@ -2262,8 +2567,10 @@ soa_query(isc_task_t *task, isc_event_t *event) { zone->view->dynamickeys); } + options = DNS_ZONE_FLAG(zone, DNS_ZONE_F_USEVC) ? + DNS_REQUESTOPT_TCP : 0; result = dns_request_create(zone->view->requestmgr, message, - &zone->masteraddr, 0, key, + &zone->masteraddr, options, key, 15 /* XXX */, zone->task, refresh_callback, zone, &zone->request); if (result != ISC_R_SUCCESS) { @@ -2290,6 +2597,167 @@ soa_query(isc_task_t *task, isc_event_t *event) { return; } +static void +ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset, dns_stub_t *stub) { + const char me[] = "ns_query"; + isc_result_t result; + dns_message_t *message = NULL; + dns_name_t *qname = NULL; + dns_rdataset_t *qrdataset = NULL; + isc_netaddr_t masterip; + dns_peer_t *peer = NULL; + dns_name_t *keyname = NULL; + dns_tsigkey_t *key = NULL; + dns_dbnode_t *node = NULL; + isc_uint32_t options; + + REQUIRE(DNS_ZONE_VALID(zone)); + REQUIRE((soardataset != NULL && stub == NULL) || + (soardataset == NULL && stub != NULL)); + REQUIRE(stub == NULL || DNS_STUB_VALID(stub)); + + DNS_ENTER; + + if (stub == NULL) { + stub = isc_mem_get(zone->mctx, sizeof *stub); + if (stub == NULL) + goto cleanup; + stub->magic = STUB_MAGIC; + stub->mctx = zone->mctx; + stub->zone = NULL; + stub->db = NULL; + stub->version = NULL; + + /* Attach so that zone won't disappear under us. */ + dns_zone_iattach(zone, &stub->zone); + + if (zone->db != NULL) + dns_db_attach(zone->db, &stub->db); + else { + result = dns_db_create(zone->mctx, "rbt", + &zone->origin, dns_dbtype_stub, + zone->rdclass, + zone->db_argc, zone->db_argv, + &stub->db); + if (result != ISC_R_SUCCESS) { + zone_log(zone, me, ISC_LOG_INFO, + "dns_db_create failed: %s", + dns_result_totext(result)); + goto cleanup; + } + } + + dns_db_newversion(stub->db, &stub->version); + + result = dns_db_findnode(stub->db, &zone->origin, ISC_TRUE, + &node); + if (result != ISC_R_SUCCESS) { + zone_log(zone, me, ISC_LOG_INFO, + "dns_db_findnode failed: %s", + dns_result_totext(result)); + goto cleanup; + } + + result = dns_db_addrdataset(stub->db, node, stub->version, 0, + soardataset, 0, NULL); + dns_db_detachnode(stub->db, &node); + if (result != ISC_R_SUCCESS) { + zone_log(zone, me, ISC_LOG_INFO, + "dns_db_addrdataset failed: %s", + dns_result_totext(result)); + goto cleanup; + } + + } + + /* + * XXX Optimisation: Create message when zone is setup and reuse. + */ + result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTRENDER, + &message); + if (result != ISC_R_SUCCESS) + goto cleanup; + + message->opcode = dns_opcode_query; + message->rdclass = zone->rdclass; + + result = dns_message_gettempname(message, &qname); + if (result != ISC_R_SUCCESS) + goto cleanup; + + result = dns_message_gettemprdataset(message, &qrdataset); + if (result != ISC_R_SUCCESS) + goto cleanup; + + /* + * Make question. + */ + dns_name_init(qname, NULL); + dns_name_clone(&zone->origin, qname); + dns_rdataset_init(qrdataset); + dns_rdataset_makequestion(qrdataset, zone->rdclass, dns_rdatatype_ns); + ISC_LIST_APPEND(qname->list, qrdataset, link); + dns_message_addname(message, qname, DNS_SECTION_QUESTION); + qname = NULL; + qrdataset = NULL; + + LOCK(&zone->lock); + INSIST(zone->masterscnt > 0); + INSIST(zone->curmaster < zone->masterscnt); + zone->masteraddr = zone->masters[zone->curmaster]; + UNLOCK(&zone->lock); + + if (isc_sockaddr_getport(&zone->masteraddr) == 0) + isc_sockaddr_setport(&zone->masteraddr, 53); /* XXX */ + + isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr); + result = dns_peerlist_peerbyaddr(zone->view->peers, + &masterip, &peer); + if (result == ISC_R_SUCCESS && + dns_peer_getkey(peer, &keyname) == ISC_R_SUCCESS) + { + result = dns_tsigkey_find(&key, keyname, NULL, + zone->view->statickeys); + if (result == ISC_R_NOTFOUND) + (void) dns_tsigkey_find(&key, keyname, NULL, + zone->view->dynamickeys); + } + + options = DNS_ZONE_FLAG(zone, DNS_ZONE_F_USEVC) ? + DNS_REQUESTOPT_TCP : 0; + result = dns_request_create(zone->view->requestmgr, message, + &zone->masteraddr, options, key, + 15 /* XXX */, zone->task, + stub_callback, stub, &zone->request); + if (result != ISC_R_SUCCESS) { + zone_log(zone, me, ISC_LOG_DEBUG(1), + "dns_request_create failed: %s", + dns_result_totext(result)); + goto cleanup; + } + dns_message_destroy(&message); + return; + + cleanup: + if (stub != NULL) { + stub->magic = 0; + if (stub->version != NULL) + dns_db_closeversion(stub->db, &stub->version, + ISC_FALSE); + if (stub->db != NULL) + dns_db_detach(&stub->db); + isc_mem_put(stub->mctx, stub, sizeof(*stub)); + } + if (qname != NULL) + dns_message_puttempname(message, &qname); + if (qrdataset != NULL) + dns_message_puttemprdataset(message, &qrdataset); + if (message != NULL) + dns_message_destroy(&message); + cancel_refresh(zone); + return; +} + /* * Handle the control event. Note that although this event causes the zone * to shut down, it is not a shutdown event in the sense of the task library. @@ -2297,7 +2765,7 @@ soa_query(isc_task_t *task, isc_event_t *event) { static void zone_shutdown(isc_task_t *task, isc_event_t *event) { dns_zone_t *zone = (dns_zone_t *) event->ev_arg; - notify_t *notify; + dns_notify_t *notify; isc_result_t result; UNUSED(task); @@ -2995,7 +3463,7 @@ record_serial() { static void notify_done(isc_task_t *task, isc_event_t *event) { const char me[] = "notify_done"; - notify_t *notify; + dns_notify_t *notify; dns_zone_t *zone = NULL; UNUSED(task);