dns_zonestat_level_t statlevel;
int xmlrc;
dns_xfrin_t *xfr = NULL;
- bool is_running, is_deferred, is_pending;
+ bool is_running, is_deferred, is_presoa, is_pending;
bool needs_refresh;
bool is_first_data_received, is_ixfr;
unsigned int nmsg = 0;
}
result = dns_zone_getxfr(zone, &xfr, &is_running, &is_deferred,
- &is_pending, &needs_refresh);
+ &is_presoa, &is_pending, &needs_refresh);
if (result != ISC_R_SUCCESS) {
result = ISC_R_SUCCESS;
goto cleanup;
}
- if (!is_running && !is_deferred && !is_pending && !needs_refresh) {
+ if (!is_running && !is_deferred && !is_presoa && !is_pending &&
+ !needs_refresh)
+ {
/* No ongoing/queued transfer. */
goto cleanup;
}
TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR xfr_state));
} else if (is_deferred) {
TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR "Deferred"));
+ } else if (is_presoa) {
+ TRY0(xmlTextWriterWriteString(writer,
+ ISC_XMLCHAR "Refresh SOA"));
} else if (is_pending) {
TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR "Pending"));
} else if (needs_refresh) {
TRY0(xmlTextWriterEndElement(writer));
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "soatransport"));
- if (is_running) {
- transport_type = dns_xfrin_getsoatransporttype(xfr);
+ if (is_running || is_presoa) {
+ if (is_running) {
+ transport_type = dns_xfrin_getsoatransporttype(xfr);
+ } else {
+ transport_type = dns_zone_getrequesttransporttype(zone);
+ }
if (transport_type == DNS_TRANSPORT_UDP) {
TRY0(xmlTextWriterWriteString(writer,
ISC_XMLCHAR "UDP"));
dns_transport_type_t transport_type;
dns_zonestat_level_t statlevel;
dns_xfrin_t *xfr = NULL;
- bool is_running, is_deferred, is_pending;
+ bool is_running, is_deferred, is_presoa, is_pending;
bool needs_refresh;
bool is_first_data_received, is_ixfr;
unsigned int nmsg = 0;
}
result = dns_zone_getxfr(zone, &xfr, &is_running, &is_deferred,
- &is_pending, &needs_refresh);
+ &is_presoa, &is_pending, &needs_refresh);
if (result != ISC_R_SUCCESS) {
result = ISC_R_SUCCESS;
goto cleanup;
}
- if (!is_running && !is_deferred && !is_pending && !needs_refresh) {
+ if (!is_running && !is_deferred && !is_presoa && !is_pending &&
+ !needs_refresh)
+ {
/* No ongoing/queued transfer. */
goto cleanup;
}
} else if (is_deferred) {
json_object_object_add(xfrinobj, "state",
json_object_new_string("Deferred"));
+ } else if (is_presoa) {
+ json_object_object_add(xfrinobj, "state",
+ json_object_new_string("Refresh SOA"));
} else if (is_pending) {
json_object_object_add(xfrinobj, "state",
json_object_new_string("Pending"));
json_object_new_string("-"));
}
- if (is_running) {
- transport_type = dns_xfrin_getsoatransporttype(xfr);
+ if (is_running || is_presoa) {
+ if (is_running) {
+ transport_type = dns_xfrin_getsoatransporttype(xfr);
+ } else {
+ transport_type = dns_zone_getrequesttransporttype(zone);
+ }
+
if (transport_type == DNS_TRANSPORT_UDP) {
json_object_object_add(xfrinobj, "soatransport",
json_object_new_string("UDP"));
hasn't started yet.
``Pending``
- The zone is flagged for a refresh, but the process is
- in waiting state because of rate-limiting, see
- :any:`serial-query-rate`.
+ The zone is flagged for a refresh, but the process is currently
+ in the queue and will start shortly, or is in a waiting state
+ because of rate-limiting, see :any:`serial-query-rate`.
+
+ ``Refresh SOA``
+ Sending a refresh SOA query to get the zone serial number, then
+ initiate a zone transfer, if necessary. If this step is successful,
+ the ``SOA Query`` and ``Got SOA`` states will be skipped.
+ Otherwise, the zone transfer procedure can still be initiated,
+ and the SOA request will be attempted using the same transport as
+ the zone transfer.
``Deferred``
The zone is going to be refreshed, but the process was
``SOA Transport`` (``soatransport``)
Text string. This is the transport protocol in use for the
- SOA request. Possible values are: ``UDP``, ``TCP``, ``TLS``, ``None``.
+ SOA query. Note, that this value can potentially change during the
+ process. For example, when the transfer is in the ``Refresh SOA``
+ state, the ``SOA Transport`` of the ongoing query can be shown as ``UDP``.
+ If that query fails or times out, it then can be retried using another
+ transport, or the transfer process can be initiated in "SOA before" mode,
+ where the SOA query will be attempted using the same transport as the zone
+ transfer. See the description of the ``State`` field for more information.
+ Possible values are: ``UDP``, ``TCP``, ``TLS``, ``None``.
``Transport`` (``transport``)
Text string. This is the transport protocol in use for the
* \li 'zone' to be a valid zone.
*/
+dns_transport_type_t
+dns_zone_getrequesttransporttype(dns_zone_t *zone);
+/*%<
+ * Get the transport type used for the SOA query to the current primary server
+ * before an ongoing incoming zone transfer is lanunched. When the transfer is
+ * already running, this information should be retrieved from the xfrin object
+ * instead, using the dns_xfrin_gettransporttype() function.
+ *
+ * Requires:
+ * \li 'zone' to be a valid zone.
+ */
+
void
dns_zone_setnotifytype(dns_zone_t *zone, dns_notifytype_t notifytype);
/*%<
isc_result_t
dns_zone_getxfr(dns_zone_t *zone, dns_xfrin_t **xfrp, bool *is_running,
- bool *is_deferred, bool *is_pending, bool *needs_refresh);
+ bool *is_deferred, bool *is_presoa, bool *is_pending,
+ bool *needs_refresh);
/*%<
* Returns the xfrin associated with the zone (if any) with the current
* transfer states (as booleans). When no longer needed, the returned xfrin
*\li 'xfrp' to be non NULL and '*xfrp' to be NULL.
*\li 'is_running' to be non NULL.
*\li 'is_deferred' to be non NULL.
+ *\li 'is_presoa' to be non NULL.
*\li 'is_pending' to be non NULL.
*\li 'needs_refresh' to be non NULL.
*
}
}
+/*
+ * Get the transport type used for the SOA query to the current primary server
+ * before an ongoing incoming zone transfer.
+ *
+ * Requires:
+ * The zone is locked by the caller.
+ */
+static dns_transport_type_t
+get_request_transport_type(dns_zone_t *zone) {
+ dns_transport_type_t transport_type = DNS_TRANSPORT_NONE;
+
+ if (zone->transport != NULL) {
+ transport_type = dns_transport_get_type(zone->transport);
+ } else {
+ transport_type = (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEVC))
+ ? DNS_TRANSPORT_TCP
+ : DNS_TRANSPORT_UDP;
+
+ /* Check if the peer is forced to always use TCP. */
+ if (transport_type != DNS_TRANSPORT_TCP) {
+ isc_result_t result;
+ isc_sockaddr_t primaryaddr;
+ isc_netaddr_t primaryip;
+ dns_peer_t *peer = NULL;
+
+ primaryaddr = dns_remote_curraddr(&zone->primaries);
+ isc_netaddr_fromsockaddr(&primaryip, &primaryaddr);
+ result = dns_peerlist_peerbyaddr(zone->view->peers,
+ &primaryip, &peer);
+ if (result == ISC_R_SUCCESS && peer != NULL) {
+ bool usetcp;
+ result = dns_peer_getforcetcp(peer, &usetcp);
+ if (result == ISC_R_SUCCESS && usetcp) {
+ transport_type = DNS_TRANSPORT_TCP;
+ }
+ }
+ }
+ }
+
+ return (transport_type);
+}
+
+dns_transport_type_t
+dns_zone_getrequesttransporttype(dns_zone_t *zone) {
+ dns_transport_type_t transport_type;
+
+ REQUIRE(DNS_ZONE_VALID(zone));
+
+ LOCK_ZONE(zone);
+ transport_type = get_request_transport_type(zone);
+ UNLOCK_ZONE(zone);
+
+ return (transport_type);
+}
+
/*
* This event callback is called when a zone has received
* any necessary zone transfer quota. This is the time
"zone transfer: %s",
isc_result_totext(result));
}
-
- if (result == ISC_R_SUCCESS && xfrtype != dns_rdatatype_soa) {
- soa_transport_type = DNS_TRANSPORT_TLS;
- }
}
LOCK_ZONE(zone);
- if (soa_transport_type == DNS_TRANSPORT_NONE &&
- xfrtype != dns_rdatatype_soa)
- {
- soa_transport_type = (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEVC))
- ? DNS_TRANSPORT_TCP
- : DNS_TRANSPORT_UDP;
-
- /* Check if the peer is forced to always use TCP. */
- if (soa_transport_type != DNS_TRANSPORT_TCP && peer != NULL) {
- bool usetcp;
- result = dns_peer_getforcetcp(peer, &usetcp);
- if (result == ISC_R_SUCCESS && usetcp) {
- soa_transport_type = DNS_TRANSPORT_TCP;
- }
- }
+ if (xfrtype != dns_rdatatype_soa) {
+ /*
+ * If 'xfrtype' is dns_rdatatype_soa, then the SOA query will be
+ * performed by xfrin, otherwise, the SOA request performed by
+ * soa_query() was successful and we should inform the xfrin
+ * about the transport type used for that query, so that the
+ * information can be presented in the statistics channel.
+ */
+ soa_transport_type = get_request_transport_type(zone);
}
-
sourceaddr = zone->sourceaddr;
UNLOCK_ZONE(zone);
isc_result_t
dns_zone_getxfr(dns_zone_t *zone, dns_xfrin_t **xfrp, bool *is_running,
- bool *is_deferred, bool *is_pending, bool *needs_refresh) {
+ bool *is_deferred, bool *is_presoa, bool *is_pending,
+ bool *needs_refresh) {
REQUIRE(DNS_ZONE_VALID(zone));
REQUIRE(xfrp != NULL && *xfrp == NULL);
return (ISC_R_NOTFOUND);
}
+ /* Reset. */
+ *is_running = false;
+ *is_deferred = false;
+ *is_presoa = false;
+ *is_pending = false;
+
RWLOCK(&zone->zmgr->rwlock, isc_rwlocktype_read);
LOCK_ZONE(zone);
if (zone->xfr != NULL) {
}
if (zone->statelist == &zone->zmgr->xfrin_in_progress) {
*is_running = true;
- *is_deferred = false;
- *is_pending = false;
} else if (zone->statelist == &zone->zmgr->waiting_for_xfrin) {
- *is_running = false;
*is_deferred = true;
- *is_pending = false;
} else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH)) {
- *is_running = false;
- *is_deferred = false;
- *is_pending = true;
- } else {
- *is_running = false;
- *is_deferred = false;
- *is_pending = false;
+ if (zone->request != NULL) {
+ *is_presoa = true;
+ } else {
+ *is_pending = true;
+ }
}
*needs_refresh = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDREFRESH);
UNLOCK_ZONE(zone);