diff --git a/CHANGES b/CHANGES index ee880612b6..511ed8b958 100644 --- a/CHANGES +++ b/CHANGES @@ -3,7 +3,8 @@ 1878. [func] dig can now specify the EDNS version when making a query. -1868. [placeholder] rt14851 +1868. [func] edns-udp-size can now be overridden on a per + server basis. [RT #14851] 1867. [placeholder] rt14846 diff --git a/bin/named/named.conf.docbook b/bin/named/named.conf.docbook index 1534681b4a..a00cf8760b 100644 --- a/bin/named/named.conf.docbook +++ b/bin/named/named.conf.docbook @@ -17,7 +17,7 @@ - PERFORMANCE OF THIS SOFTWARE. --> - + Aug 13, 2004 @@ -102,6 +102,7 @@ masters string port integeripv4_address/prefixlen | ipv6_address/prefixlen ) { bogus boolean; edns boolean; + edns-udp-size integer; provide-ixfr boolean; request-ixfr boolean; keys server_key; diff --git a/bin/named/server.c b/bin/named/server.c index 947457b3a7..4fa3f19dc6 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: server.c,v 1.442 2005/04/29 00:36:15 marka Exp $ */ +/* $Id: server.c,v 1.443 2005/06/07 00:27:32 marka Exp $ */ /*! \file */ @@ -620,6 +620,17 @@ configure_peer(cfg_obj_t *cpeer, isc_mem_t *mctx, dns_peer_t **peerp) { if (obj != NULL) CHECK(dns_peer_setsupportedns(peer, cfg_obj_asboolean(obj))); + obj = NULL; + (void)cfg_map_get(cpeer, "edns-udp-size", &obj); + if (obj != NULL) { + isc_uint32_t udpsize = cfg_obj_asuint32(obj); + if (udpsize < 512) + udpsize = 512; + if (udpsize > 4096) + udpsize = 4096; + CHECK(dns_peer_setudpsize(peer, (isc_uint16_t)udpsize)); + } + obj = NULL; (void)cfg_map_get(cpeer, "transfers", &obj); if (obj != NULL) diff --git a/doc/arm/Bv9ARM-book.xml b/doc/arm/Bv9ARM-book.xml index 35af0efb28..ab2d0c642e 100644 --- a/doc/arm/Bv9ARM-book.xml +++ b/doc/arm/Bv9ARM-book.xml @@ -18,7 +18,7 @@ - PERFORMANCE OF THIS SOFTWARE. --> - + BIND 9 Administrator Reference Manual @@ -7181,6 +7181,7 @@ query-source-v6 address * port *; provide-ixfr yes_or_no ; request-ixfr yes_or_no ; edns yes_or_no ; + edns-udp-size number ; transfers number ; transfer-format ( one-answer | many-answers ) ; ] keys { string ; string ; ... } ; @@ -7271,10 +7272,18 @@ query-source-v6 address * port *; The edns clause determines whether - the local server - will attempt to use EDNS when communicating with the remote - server. The - default is yes. + the local server will attempt to use EDNS when communicating + with the remote server. The default is yes. + + + + The edns-udp-size option sets the EDNS UDP size + that is advertised by named when querying the remote server. + Valid values are 512 to 4096 (values outside this range will be + silently adjusted). This option is useful when you wish to + advertises a different value to this server than the value you + advertise globally, for example, when there is a firewall at the + remote site that is blocking large replies. diff --git a/doc/misc/options b/doc/misc/options index 16ff3398ac..2f6a6b3cfd 100644 --- a/doc/misc/options +++ b/doc/misc/options @@ -238,6 +238,7 @@ view { transfer-format ( many-answers | one-answer ); keys ; edns ; + edns-udp-size ; transfer-source ( | * ) [ port ( | * ) ]; transfer-source-v6 ( | * ) [ port ( @@ -407,6 +408,7 @@ server { transfer-format ( many-answers | one-answer ); keys ; edns ; + edns-udp-size ; transfer-source ( | * ) [ port ( | * ) ]; transfer-source-v6 ( | * ) [ port ( | * ) ]; }; diff --git a/lib/dns/include/dns/peer.h b/lib/dns/include/dns/peer.h index e8de6e3b9c..f9200ab9f3 100644 --- a/lib/dns/include/dns/peer.h +++ b/lib/dns/include/dns/peer.h @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: peer.h,v 1.23 2005/04/27 04:56:57 sra Exp $ */ +/* $Id: peer.h,v 1.24 2005/06/07 00:27:34 marka Exp $ */ #ifndef DNS_PEER_H #define DNS_PEER_H 1 @@ -75,6 +75,7 @@ struct dns_peer { isc_boolean_t support_edns; dns_name_t *key; isc_sockaddr_t *transfer_source; + isc_uint16_t udpsize; isc_uint32_t bitflags; @@ -178,6 +179,12 @@ dns_peer_settransfersource(dns_peer_t *peer, isc_sockaddr_t *transfer_source); isc_result_t dns_peer_gettransfersource(dns_peer_t *peer, isc_sockaddr_t *transfer_source); +isc_result_t +dns_peer_setudpsize(dns_peer_t *peer, isc_uint16_t udpsize); + +isc_result_t +dns_peer_getudpsize(dns_peer_t *peer, isc_uint16_t *udpsize); + ISC_LANG_ENDDECLS #endif /* DNS_PEER_H */ diff --git a/lib/dns/peer.c b/lib/dns/peer.c index 081398168a..6334a19f83 100644 --- a/lib/dns/peer.c +++ b/lib/dns/peer.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: peer.c,v 1.22 2005/04/27 04:56:49 sra Exp $ */ +/* $Id: peer.c,v 1.23 2005/06/07 00:27:33 marka Exp $ */ /*! \file */ @@ -40,6 +40,7 @@ #define PROVIDE_IXFR_BIT 3 #define REQUEST_IXFR_BIT 4 #define SUPPORT_EDNS_BIT 5 +#define SERVER_UDPSIZE_BIT 6 static void peerlist_delete(dns_peerlist_t **list); @@ -558,3 +559,31 @@ dns_peer_gettransfersource(dns_peer_t *peer, isc_sockaddr_t *transfer_source) { *transfer_source = *peer->transfer_source; return (ISC_R_SUCCESS); } + +isc_result_t +dns_peer_setudpsize(dns_peer_t *peer, isc_uint16_t udpsize) { + isc_boolean_t existed; + + REQUIRE(DNS_PEER_VALID(peer)); + + existed = DNS_BIT_CHECK(SERVER_UDPSIZE_BIT, &peer->bitflags); + + peer->udpsize = udpsize; + DNS_BIT_SET(SERVER_UDPSIZE_BIT, &peer->bitflags); + + return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS); +} + +isc_result_t +dns_peer_getudpsize(dns_peer_t *peer, isc_uint16_t *udpsize) { + + REQUIRE(DNS_PEER_VALID(peer)); + REQUIRE(udpsize != NULL); + + if (DNS_BIT_CHECK(SERVER_UDPSIZE_BIT, &peer->bitflags)) { + *udpsize = peer->udpsize; + return (ISC_R_SUCCESS); + } else { + return (ISC_R_NOTFOUND); + } +} diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c index f03b5dd283..ae4e4cea10 100644 --- a/lib/dns/resolver.c +++ b/lib/dns/resolver.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: resolver.c,v 1.309 2005/06/07 00:16:00 marka Exp $ */ +/* $Id: resolver.c,v 1.310 2005/06/07 00:27:33 marka Exp $ */ /*! \file */ @@ -841,7 +841,8 @@ resquery_senddone(isc_task_t *task, isc_event_t *event) { } static inline isc_result_t -fctx_addopt(dns_message_t *message, unsigned int version, dns_resolver_t *res) { +fctx_addopt(dns_message_t *message, unsigned int version, isc_uint16_t udpsize) +{ dns_rdataset_t *rdataset; dns_rdatalist_t *rdatalist; dns_rdata_t *rdata; @@ -867,7 +868,7 @@ fctx_addopt(dns_message_t *message, unsigned int version, dns_resolver_t *res) { /* * Set Maximum UDP buffer size. */ - rdatalist->rdclass = res->udpsize; + rdatalist->rdclass = udpsize; /* * Set EXTENDED-RCODE and Z to 0, DO to 1. @@ -1236,12 +1237,16 @@ resquery_send(resquery_t *query) { if ((query->addrinfo->flags & DNS_FETCHOPT_NOEDNS0) == 0) { unsigned int version = 0; /* Default version. */ unsigned int flags; + isc_uint16_t udpsize = res->udpsize; + flags = query->addrinfo->flags; if ((flags & DNS_FETCHOPT_EDNSVERSIONSET) != 0) { version = flags & DNS_FETCHOPT_EDNSVERSIONMASK; version >>= DNS_FETCHOPT_EDNSVERSIONSHIFT; } - result = fctx_addopt(fctx->qmessage, version, res); + if (peer != NULL) + (void)dns_peer_getudpsize(peer, &udpsize); + result = fctx_addopt(fctx->qmessage, version, udpsize); if (result != ISC_R_SUCCESS) { /* * We couldn't add the OPT, but we'll press on. diff --git a/lib/dns/zone.c b/lib/dns/zone.c index 344be62362..c513379613 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: zone.c,v 1.436 2005/06/04 05:32:47 jinmei Exp $ */ +/* $Id: zone.c,v 1.437 2005/06/07 00:27:33 marka Exp $ */ /*! \file */ @@ -4430,7 +4430,7 @@ create_query(dns_zone_t *zone, dns_rdatatype_t rdtype, } static isc_result_t -add_opt(dns_message_t *message) { +add_opt(dns_message_t *message, isc_uint16_t udpsize) { dns_rdataset_t *rdataset = NULL; dns_rdatalist_t *rdatalist = NULL; dns_rdata_t *rdata = NULL; @@ -4453,7 +4453,7 @@ add_opt(dns_message_t *message) { /* * Set Maximum UDP buffer size. */ - rdatalist->rdclass = SEND_BUFFER_SIZE; + rdatalist->rdclass = udpsize; /* * Set EXTENDED-RCODE, VERSION, DO and Z to 0. @@ -4500,6 +4500,7 @@ soa_query(isc_task_t *task, isc_event_t *event) { isc_boolean_t cancel = ISC_TRUE; int timeout; isc_boolean_t have_xfrsource; + isc_uint16_t udpsize = SEND_BUFFER_SIZE; REQUIRE(DNS_ZONE_VALID(zone)); @@ -4563,6 +4564,10 @@ soa_query(isc_task_t *task, isc_event_t *event) { &zone->sourceaddr); if (result == ISC_R_SUCCESS) have_xfrsource = ISC_TRUE; + if (zone->view->resolver != NULL) + udpsize = + dns_resolver_getudpsize(zone->view->resolver); + (void)dns_peer_getudpsize(peer, &udpsize); } } @@ -4594,7 +4599,7 @@ soa_query(isc_task_t *task, isc_event_t *event) { DNS_REQUESTOPT_TCP : 0; if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) { - result = add_opt(message); + result = add_opt(message, udpsize); if (result != ISC_R_SUCCESS) zone_debuglog(zone, me, 1, "unable to add opt record: %s", @@ -4653,6 +4658,7 @@ ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset, dns_stub_t *stub) { dns_dbnode_t *node = NULL; int timeout; isc_boolean_t have_xfrsource = ISC_FALSE; + isc_uint16_t udpsize = SEND_BUFFER_SIZE; REQUIRE(DNS_ZONE_VALID(zone)); REQUIRE((soardataset != NULL && stub == NULL) || @@ -4776,11 +4782,15 @@ ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset, dns_stub_t *stub) { &zone->sourceaddr); if (result == ISC_R_SUCCESS) have_xfrsource = ISC_TRUE; + if (zone->view->resolver != NULL) + udpsize = + dns_resolver_getudpsize(zone->view->resolver); + (void)dns_peer_getudpsize(peer, &udpsize); } } if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) { - result = add_opt(message); + result = add_opt(message, udpsize); if (result != ISC_R_SUCCESS) zone_debuglog(zone, me, 1, "unable to add opt record: %s", diff --git a/lib/isccfg/namedconf.c b/lib/isccfg/namedconf.c index 593eb87209..ea4f04cfd8 100644 --- a/lib/isccfg/namedconf.c +++ b/lib/isccfg/namedconf.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: namedconf.c,v 1.50 2005/05/19 04:59:05 marka Exp $ */ +/* $Id: namedconf.c,v 1.51 2005/06/07 00:27:34 marka Exp $ */ /*! \file */ @@ -907,6 +907,7 @@ server_clauses[] = { { "transfer-format", &cfg_type_transferformat, 0 }, { "keys", &cfg_type_server_key_kludge, 0 }, { "edns", &cfg_type_boolean, 0 }, + { "edns-udp-size", &cfg_type_uint32, 0 }, { "transfer-source", &cfg_type_sockaddr4wild, 0 }, { "transfer-source-v6", &cfg_type_sockaddr6wild, 0 }, { NULL, NULL, 0 }