named_server_retransfercommand(named_server_t *server, isc_lex_t *lex,
isc_buffer_t **text) {
isc_result_t result;
+ const char *arg = NULL;
dns_zone_t *zone = NULL;
dns_zone_t *raw = NULL;
dns_zonetype_t type;
+ bool force = false;
REQUIRE(text != NULL);
- result = zone_from_args(server, lex, NULL, &zone, NULL, text, true);
+ /* Skip the command name. */
+ (void)next_token(lex, text);
+
+ arg = next_token(lex, text);
+ if (arg != NULL && (strcmp(arg, "-force") == 0)) {
+ force = true;
+ arg = next_token(lex, text);
+ }
+
+ result = zone_from_args(server, lex, arg, &zone, NULL, text, false);
if (result != ISC_R_SUCCESS) {
return (result);
}
(type == dns_zone_redirect &&
dns_zone_getredirecttype(zone) == dns_zone_secondary))
{
+ if (force) {
+ dns_zone_stopxfr(zone);
+ }
dns_zone_forcereload(zone);
} else {
(void)putstr(text, "retransfer: inappropriate zone type: ");
.. program:: rndc
-.. option:: retransfer zone [class [view]]
+.. option:: retransfer [-force] zone [class [view]]
This command retransfers the given secondary zone from the primary server.
If the zone is configured to use ``inline-signing``, the signed
version of the zone is discarded; after the retransfer of the
unsigned version is complete, the signed version is regenerated
- with new signatures.
+ with new signatures. With the optional ``-force`` argument provided
+ if there is an ongoing zone transfer it will be aborted before a new zone
+ transfer is scheduled.
.. option:: scan
*\li 'tlsctx_cache' is a valid TLS context cache.
*/
+void
+dns_zone_stopxfr(dns_zone_t *zone);
+/*%<
+ * If 'zone' has an ongoing active transfer, stop it.
+ *
+ * Requires:
+ *\li 'zone' to be a valid zone.
+ */
+
void
dns_zone_forcereload(dns_zone_t *zone);
/*%<
break;
case ISC_R_CANCELED:
+ /*
+ * A new "retransfer" command with a "-force" argument could
+ * have canceled the current transfer in which case we should
+ * make sure to try again from the beginning.
+ */
+ if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER)) {
+ DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH);
+ again = true;
+ }
+ FALLTHROUGH;
case ISC_R_SHUTTINGDOWN:
- dns_remote_reset(&zone->primaries, false);
+ dns_remote_reset(&zone->primaries, true);
break;
default:
RWUNLOCK(&zmgr->urlock, isc_rwlocktype_write);
}
+void
+dns_zone_stopxfr(dns_zone_t *zone) {
+ dns_xfrin_t *xfr = NULL;
+
+ REQUIRE(DNS_ZONE_VALID(zone));
+
+ RWLOCK(&zone->zmgr->rwlock, isc_rwlocktype_read);
+ LOCK_ZONE(zone);
+ if (zone->statelist == &zone->zmgr->xfrin_in_progress &&
+ zone->xfr != NULL)
+ {
+ dns_xfrin_attach(zone->xfr, &xfr);
+ }
+ UNLOCK_ZONE(zone);
+ RWUNLOCK(&zone->zmgr->rwlock, isc_rwlocktype_read);
+
+ if (xfr != NULL) {
+ dns_xfrin_shutdown(xfr);
+ dns_xfrin_detach(&xfr);
+ }
+}
+
void
dns_zone_forcereload(dns_zone_t *zone) {
REQUIRE(DNS_ZONE_VALID(zone));