xfr->done = done;
- isc_refcount_init(&xfr->references, 1);
-
/*
* Set *xfrp now, before calling xfrin_start(), otherwise it's
* possible the 'done' callback could be run before *xfrp
result = xfrin_start(xfr);
if (result != ISC_R_SUCCESS) {
- atomic_store(&xfr->shuttingdown, true);
- xfr->shutdown_result = result;
- xfrin_log(xfr, ISC_LOG_ERROR, "zone transfer setup failed");
+ xfr->done = NULL;
+ xfrin_fail(xfr, result, "zone transfer setup failed");
dns_xfrin_detach(xfrp);
}
.soa_transport_type = soa_transport_type,
.firstsoa = DNS_RDATA_INIT,
.edns = true,
+ .references = 1,
.magic = XFRIN_MAGIC,
};
isc_tlsctx_cache_attach(tlsctx_cache, &xfr->tlsctx_cache);
- isc_timer_create(dns_zone_getloop(zone), xfrin_timedout, xfr,
- &xfr->max_time_timer);
- isc_timer_create(dns_zone_getloop(zone), xfrin_idledout, xfr,
- &xfr->max_idle_timer);
-
dns_zone_name(xfr->zone, xfr->info, sizeof(xfr->info));
*xfrp = xfr;
dns_xfrin_gettransporttype(xfr));
}
+ /*
+ * XXX: timeouts are hard-coded to 30 seconds; this needs to be
+ * configurable.
+ */
+ CHECK(dns_dispatch_add(xfr->disp, xfr->loop, 0, 30000,
+ &xfr->primaryaddr, xfr->transport,
+ xfr->tlsctx_cache, xfrin_connect_done,
+ xfrin_send_done, xfrin_recv_done, xfr, &xfr->id,
+ &xfr->dispentry));
+
/* Set the maximum timer */
+ if (xfr->max_time_timer == NULL) {
+ isc_timer_create(dns_zone_getloop(xfr->zone), xfrin_timedout,
+ xfr, &xfr->max_time_timer);
+ }
isc_interval_set(&interval, dns_zone_getmaxxfrin(xfr->zone), 0);
isc_timer_start(xfr->max_time_timer, isc_timertype_once, &interval);
/* Set the idle timer */
+ if (xfr->max_idle_timer == NULL) {
+ isc_timer_create(dns_zone_getloop(xfr->zone), xfrin_idledout,
+ xfr, &xfr->max_idle_timer);
+ }
isc_interval_set(&interval, dns_zone_getidlein(xfr->zone), 0);
isc_timer_start(xfr->max_idle_timer, isc_timertype_once, &interval);
/*
- * XXX: timeouts are hard-coded to 30 seconds; this needs to be
- * configurable.
+ * The connect has to be the last thing that is called before returning,
+ * as it can end synchronously and destroy the xfr object.
*/
- CHECK(dns_dispatch_add(xfr->disp, xfr->loop, 0, 30000,
- &xfr->primaryaddr, xfr->transport,
- xfr->tlsctx_cache, xfrin_connect_done,
- xfrin_send_done, xfrin_recv_done, xfr, &xfr->id,
- &xfr->dispentry));
CHECK(dns_dispatch_connect(xfr->dispentry));
return (ISC_R_SUCCESS);
}
detach:
- dns_xfrin_unref(xfr);
+ dns_xfrin_detach(&xfr);
}
/*
}
atomic_store(&xfr->shuttingdown, true);
- isc_timer_stop(xfr->max_time_timer);
- isc_timer_stop(xfr->max_idle_timer);
+
+ if (xfr->max_time_timer != NULL) {
+ isc_timer_stop(xfr->max_time_timer);
+ isc_timer_destroy(&xfr->max_time_timer);
+ }
+ if (xfr->max_idle_timer != NULL) {
+ isc_timer_stop(xfr->max_idle_timer);
+ isc_timer_destroy(&xfr->max_idle_timer);
+ }
if (xfr->shutdown_result == ISC_R_UNSET) {
xfr->shutdown_result = result;
isc_tlsctx_cache_detach(&xfr->tlsctx_cache);
}
- isc_timer_destroy(&xfr->max_idle_timer);
- isc_timer_destroy(&xfr->max_time_timer);
+ INSIST(xfr->max_time_timer == NULL);
+ INSIST(xfr->max_idle_timer == NULL);
isc_loop_detach(&xfr->loop);