2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-30 05:57:52 +00:00

Expose the SOA query transport type used before/during XFR

Add a new field in the incoming zone transfers section of the
statistics channel to show the transport used for the SOA request.

When the transfer is started beginning from the XFRST_SOAQUERY state,
it means that the SOA query will be performed by xfrin itself, using
the same transport. Otherwise, it means that the SOA query was already
performed by other means (e.g. by zone.c:soa_query()), and, in that
case, we use the SOA query transport type information passed by the
'soa_transport_type' argument, when the xfrin object was created.
This commit is contained in:
Aram Sargsyan 2023-08-23 10:46:44 +00:00
parent 2eb8afde52
commit 8e2273afce
6 changed files with 153 additions and 28 deletions

View File

@ -923,6 +923,7 @@
<th>Additional Refresh Queued</th>
<th>Local Address</th>
<th>Remote Address</th>
<th>SOA Transport</th>
<th>Transport</th>
<th>TSIG Key Name</th>
<th>Duration (s)</th>
@ -949,6 +950,7 @@
<td><xsl:value-of select="refreshqueued"/></td>
<td><xsl:value-of select="localaddr"/></td>
<td><xsl:value-of select="remoteaddr"/></td>
<td><xsl:value-of select="soatransport"/></td>
<td><xsl:value-of select="transport"/></td>
<td><xsl:value-of select="tsigkeyname"/></td>
<td><xsl:value-of select="duration"/></td>

View File

@ -1461,7 +1461,7 @@ xfrin_xmlrender(dns_zone_t *zone, void *arg) {
uint32_t serial;
const isc_sockaddr_t *addrp = NULL;
char addr_buf[ISC_SOCKADDR_FORMATSIZE];
const dns_transport_t *transport = NULL;
dns_transport_type_t transport_type;
xmlTextWriterPtr writer = arg;
dns_zonestat_level_t statlevel;
int xmlrc;
@ -1581,20 +1581,41 @@ xfrin_xmlrender(dns_zone_t *zone, void *arg) {
}
TRY0(xmlTextWriterEndElement(writer));
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "transport"));
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "soatransport"));
if (is_running) {
transport = dns_xfrin_gettransport(xfr);
if (transport == NULL ||
dns_transport_get_type(transport) == DNS_TRANSPORT_TCP)
{
transport_type = dns_xfrin_getsoatransporttype(xfr);
if (transport_type == DNS_TRANSPORT_UDP) {
TRY0(xmlTextWriterWriteString(writer,
ISC_XMLCHAR "UDP"));
} else if (transport_type == DNS_TRANSPORT_TCP) {
TRY0(xmlTextWriterWriteString(writer,
ISC_XMLCHAR "TCP"));
} else if (dns_transport_get_type(transport) ==
DNS_TRANSPORT_TLS)
{
} else if (transport_type == DNS_TRANSPORT_TLS) {
TRY0(xmlTextWriterWriteString(writer,
ISC_XMLCHAR "TLS"));
} else if (transport_type == DNS_TRANSPORT_NONE) {
TRY0(xmlTextWriterWriteString(writer,
ISC_XMLCHAR "None"));
} else {
/* We don't expect any other SOA transport type. */
TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR "-"));
}
} else {
TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR "-"));
}
TRY0(xmlTextWriterEndElement(writer));
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "transport"));
if (is_running) {
transport_type = dns_xfrin_gettransporttype(xfr);
if (transport_type == DNS_TRANSPORT_TCP) {
TRY0(xmlTextWriterWriteString(writer,
ISC_XMLCHAR "TCP"));
} else if (transport_type == DNS_TRANSPORT_TLS) {
TRY0(xmlTextWriterWriteString(writer,
ISC_XMLCHAR "TLS"));
} else {
/* We don't expect any other transport type. */
TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR "-"));
}
} else {
@ -2477,7 +2498,7 @@ xfrin_jsonrender(dns_zone_t *zone, void *arg) {
json_object *xfrinobj = NULL;
const isc_sockaddr_t *addrp = NULL;
char addr_buf[ISC_SOCKADDR_FORMATSIZE];
const dns_transport_t *transport = NULL;
dns_transport_type_t transport_type;
dns_zonestat_level_t statlevel;
dns_xfrin_t *xfr = NULL;
bool is_running, is_deferred, is_pending;
@ -2582,18 +2603,39 @@ xfrin_jsonrender(dns_zone_t *zone, void *arg) {
}
if (is_running) {
transport = dns_xfrin_gettransport(xfr);
if (transport == NULL ||
dns_transport_get_type(transport) == DNS_TRANSPORT_TCP)
{
transport_type = dns_xfrin_getsoatransporttype(xfr);
if (transport_type == DNS_TRANSPORT_UDP) {
json_object_object_add(xfrinobj, "soatransport",
json_object_new_string("UDP"));
} else if (transport_type == DNS_TRANSPORT_TCP) {
json_object_object_add(xfrinobj, "soatransport",
json_object_new_string("TCP"));
} else if (transport_type == DNS_TRANSPORT_TLS) {
json_object_object_add(xfrinobj, "soatransport",
json_object_new_string("TLS"));
} else if (transport_type == DNS_TRANSPORT_NONE) {
json_object_object_add(xfrinobj, "soatransport",
json_object_new_string("None"));
} else {
/* We don't expect any other SOA transport type. */
json_object_object_add(xfrinobj, "soatransport",
json_object_new_string("-"));
}
} else {
json_object_object_add(xfrinobj, "soatransport",
json_object_new_string("-"));
}
if (is_running) {
transport_type = dns_xfrin_gettransporttype(xfr);
if (transport_type == DNS_TRANSPORT_TCP) {
json_object_object_add(xfrinobj, "transport",
json_object_new_string("TCP"));
} else if (dns_transport_get_type(transport) ==
DNS_TRANSPORT_TLS)
{
} else if (transport_type == DNS_TRANSPORT_TLS) {
json_object_object_add(xfrinobj, "transport",
json_object_new_string("TLS"));
} else {
/* We don't expect any other transport type. */
json_object_object_add(xfrinobj, "transport",
json_object_new_string("-"));
}

View File

@ -7639,6 +7639,10 @@ Incoming Zone Transfers
This shows the destination address used to establish the
connection for the transfer.
``SOA Transport`` (``soatransport``)
Text string. This is the transport protocol in use for the
SOA request. Possible values are: ``UDP``, ``TCP``, ``TLS``, ``None``.
``Transport`` (``transport``)
Text string. This is the transport protocol in use for the
transfer. Possible values are: ``TCP``, ``TLS``.

View File

@ -56,6 +56,7 @@ isc_result_t
dns_xfrin_create(dns_zone_t *zone, dns_rdatatype_t xfrtype,
const isc_sockaddr_t *primaryaddr,
const isc_sockaddr_t *sourceaddr, dns_tsigkey_t *tsigkey,
dns_transport_type_t soa_transport_type,
dns_transport_t *transport, isc_tlsctx_cache_t *tlsctx_cache,
isc_mem_t *mctx, dns_xfrindone_t done, dns_xfrin_t **xfrp);
/*%<
@ -81,6 +82,13 @@ dns_xfrin_create(dns_zone_t *zone, dns_rdatatype_t xfrtype,
*
*\li If 'xfrtype' is dns_rdatatype_ixfr or dns_rdatatype_soa,
* the zone has a database.
*
*\li 'soa_transport_type' is DNS_TRANSPORT_NONE if 'xfrtype'
* is dns_rdatatype_soa (because in that case the SOA request
* will use the same transport as the XFR), or when there is no
* preceding SOA request. Otherwise, it should indicate the
* transport type used for the SOA request performed by the
* caller itself.
*/
isc_time_t
@ -160,10 +168,23 @@ dns_xfrin_getprimaryaddr(const dns_xfrin_t *xfr);
*\li const pointer to the zone transfer's primary server's socket address
*/
const dns_transport_t *
dns_xfrin_gettransport(const dns_xfrin_t *xfr);
dns_transport_type_t
dns_xfrin_gettransporttype(const dns_xfrin_t *xfr);
/*%<
* Get the trnasport of the xfrin object.
* Get the zone transfer's trnasport type of the xfrin object.
*
* Requires:
*\li 'xfr' is a valid dns_xfrin_t.
*
* Returns:
*\li const pointer to the zone transfer's transport
*
*/
dns_transport_type_t
dns_xfrin_getsoatransporttype(const dns_xfrin_t *xfr);
/*%<
* Get the SOA request's trnasport type of the xfrin object.
*
* Requires:
*\li 'xfr' is a valid dns_xfrin_t.

View File

@ -164,6 +164,7 @@ struct dns_xfrin {
dst_context_t *tsigctx; /*%< TSIG verification context */
unsigned int sincetsig; /*%< recvd since the last TSIG */
dns_transport_type_t soa_transport_type;
dns_transport_t *transport;
dns_xfrindone_t done;
@ -206,6 +207,7 @@ xfrin_create(isc_mem_t *mctx, dns_zone_t *zone, dns_db_t *db,
dns_name_t *zonename, dns_rdataclass_t rdclass,
dns_rdatatype_t reqtype, const isc_sockaddr_t *primaryaddr,
const isc_sockaddr_t *sourceaddr, dns_tsigkey_t *tsigkey,
dns_transport_type_t soa_transport_type,
dns_transport_t *transport, isc_tlsctx_cache_t *tlsctx_cache,
dns_xfrin_t **xfrp);
@ -700,6 +702,7 @@ isc_result_t
dns_xfrin_create(dns_zone_t *zone, dns_rdatatype_t xfrtype,
const isc_sockaddr_t *primaryaddr,
const isc_sockaddr_t *sourceaddr, dns_tsigkey_t *tsigkey,
dns_transport_type_t soa_transport_type,
dns_transport_t *transport, isc_tlsctx_cache_t *tlsctx_cache,
isc_mem_t *mctx, dns_xfrindone_t done, dns_xfrin_t **xfrp) {
dns_name_t *zonename = dns_zone_getorigin(zone);
@ -721,8 +724,8 @@ dns_xfrin_create(dns_zone_t *zone, dns_rdatatype_t xfrtype,
}
xfrin_create(mctx, zone, db, zonename, dns_zone_getclass(zone), xfrtype,
primaryaddr, sourceaddr, tsigkey, transport, tlsctx_cache,
&xfr);
primaryaddr, sourceaddr, tsigkey, soa_transport_type,
transport, tlsctx_cache, &xfr);
if (db != NULL) {
xfr->zone_had_db = true;
@ -854,11 +857,22 @@ dns_xfrin_getprimaryaddr(const dns_xfrin_t *xfr) {
return (&xfr->primaryaddr);
}
const dns_transport_t *
dns_xfrin_gettransport(const dns_xfrin_t *xfr) {
dns_transport_type_t
dns_xfrin_gettransporttype(const dns_xfrin_t *xfr) {
REQUIRE(VALID_XFRIN(xfr));
return (xfr->transport);
if (xfr->transport != NULL) {
return (dns_transport_get_type(xfr->transport));
}
return (DNS_TRANSPORT_TCP);
}
dns_transport_type_t
dns_xfrin_getsoatransporttype(const dns_xfrin_t *xfr) {
REQUIRE(VALID_XFRIN(xfr));
return (xfr->soa_transport_type);
}
const dns_name_t *
@ -965,6 +979,7 @@ xfrin_create(isc_mem_t *mctx, dns_zone_t *zone, dns_db_t *db,
dns_name_t *zonename, dns_rdataclass_t rdclass,
dns_rdatatype_t reqtype, const isc_sockaddr_t *primaryaddr,
const isc_sockaddr_t *sourceaddr, dns_tsigkey_t *tsigkey,
dns_transport_type_t soa_transport_type,
dns_transport_t *transport, isc_tlsctx_cache_t *tlsctx_cache,
dns_xfrin_t **xfrp) {
dns_xfrin_t *xfr = NULL;
@ -977,6 +992,7 @@ xfrin_create(isc_mem_t *mctx, dns_zone_t *zone, dns_db_t *db,
.maxrecords = dns_zone_getmaxrecords(zone),
.primaryaddr = *primaryaddr,
.sourceaddr = *sourceaddr,
.soa_transport_type = soa_transport_type,
.firstsoa = DNS_RDATA_INIT,
.edns = true,
.magic = XFRIN_MAGIC,
@ -1082,6 +1098,23 @@ xfrin_start(dns_xfrin_t *xfr) {
LIBDNS_XFRIN_START(xfr, xfr->info);
/*
* If the transfer is started when the 'state' is XFRST_SOAQUERY, it
* means the SOA query will be performed by xfrin. A transfer could also
* be initiated starting from the XFRST_INITIALSOA state, which means
* that the SOA query was already performed by other means (e.g. by
* zone.c:soa_query()), or that it's a transfer without a preceding
* SOA request, and 'soa_transport_type' is already correctly
* set by the creator of the xfrin.
*/
if (atomic_load(&xfr->state) == XFRST_SOAQUERY) {
/*
* The "SOA before" mode is used, where the SOA request is
* using the same transport as the XFR.
*/
xfr->soa_transport_type = dns_xfrin_gettransporttype(xfr);
}
/* Set the maximum timer */
isc_interval_set(&interval, dns_zone_getmaxxfrin(xfr->zone), 0);
isc_timer_start(xfr->max_time_timer, isc_timertype_once, &interval);

View File

@ -17616,6 +17616,7 @@ got_transfer_quota(void *arg) {
isc_sockaddr_t primaryaddr;
isc_sockaddr_t sourceaddr;
isc_time_t now;
dns_transport_type_t soa_transport_type = DNS_TRANSPORT_NONE;
const char *soa_before = "";
bool loaded;
isc_tlsctx_cache_t *zmgr_tlsctx_cache = NULL;
@ -17742,11 +17743,33 @@ got_transfer_quota(void *arg) {
"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;
}
}
}
sourceaddr = zone->sourceaddr;
UNLOCK_ZONE(zone);
INSIST(isc_sockaddr_pf(&primaryaddr) == isc_sockaddr_pf(&sourceaddr));
if (zone->xfr != NULL) {
@ -17756,9 +17779,9 @@ got_transfer_quota(void *arg) {
zmgr_tlsctx_attach(zone->zmgr, &zmgr_tlsctx_cache);
result = dns_xfrin_create(zone, xfrtype, &primaryaddr, &sourceaddr,
zone->tsigkey, zone->transport,
zmgr_tlsctx_cache, zone->mctx, zone_xfrdone,
&zone->xfr);
zone->tsigkey, soa_transport_type,
zone->transport, zmgr_tlsctx_cache,
zone->mctx, zone_xfrdone, &zone->xfr);
isc_tlsctx_cache_detach(&zmgr_tlsctx_cache);