]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
1515. [func] Allow transfer source to be set in a server statement.
authorTatuya JINMEI 神明達哉 <jinmei@isc.org>
Thu, 25 Sep 2003 18:16:50 +0000 (18:16 +0000)
committerTatuya JINMEI 神明達哉 <jinmei@isc.org>
Thu, 25 Sep 2003 18:16:50 +0000 (18:16 +0000)
[RT #6496]

implemented by marka, reviewed and documented by jinmei.
Notes:
  lib/dns/zone.c had to be modified manually.
  ARM html files were not regenerated (yet).

CHANGES
bin/named/server.c
doc/arm/Bv9ARM-book.xml
lib/bind9/check.c
lib/dns/include/dns/peer.h
lib/dns/peer.c
lib/dns/zone.c
lib/isccfg/namedconf.c

diff --git a/CHANGES b/CHANGES
index c1a8d34b2446676a41003853ad1dfba18a548226..9a715f35a44ef80e7669481e7a71e25f4e742625 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,6 @@
+1515.  [func]          Allow transfer source to be set in a server statement.
+                       [RT #6496]
+
 1514.  [bug]           named: isc_hash_destroy() was being called to early.
                        [RT #9160]
 
index d63fd4ed769c7f43210751656b1cdf6c62c265b1..66350a7325ed464623441ba40990d3e32ba2ac4f 100644 (file)
@@ -15,7 +15,7 @@
  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: server.c,v 1.403 2003/09/19 12:39:47 marka Exp $ */
+/* $Id: server.c,v 1.404 2003/09/25 18:16:43 jinmei Exp $ */
 
 #include <config.h>
 
@@ -553,6 +553,18 @@ configure_peer(cfg_obj_t *cpeer, isc_mem_t *mctx, dns_peer_t **peerp) {
                if (result != ISC_R_SUCCESS)
                        goto cleanup;
        }
+
+       obj = NULL;
+       if (isc_sockaddr_pf(sa) == AF_INET)
+               (void)cfg_map_get(cpeer, "transfer-source", &obj);
+       else
+               (void)cfg_map_get(cpeer, "transfer-source-v6", &obj);
+       if (obj != NULL) {
+               result = dns_peer_settransfersource(peer,
+                                                   cfg_obj_assockaddr(obj));
+               if (result != ISC_R_SUCCESS)
+                       goto cleanup;
+       }
        *peerp = peer;
        return (ISC_R_SUCCESS);
 
index 3d2f903525945d9285cc1e2962157c40dec25483..b054a14eb3e13629c40eca1747db04f403cf1222 100644 (file)
@@ -2,7 +2,7 @@
 <!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.0//EN"
                "http://www.oasis-open.org/docbook/xml/4.0/docbookx.dtd">
 
-<!-- File: $Id: Bv9ARM-book.xml,v 1.229 2003/09/23 07:11:40 marka Exp $ -->
+<!-- File: $Id: Bv9ARM-book.xml,v 1.230 2003/09/25 18:16:45 jinmei Exp $ -->
 
 <book>
 <title>BIND 9 Administrator Reference Manual</title>
@@ -4247,6 +4247,8 @@ to be incremented, and may additionally cause the
     <optional> transfers <replaceable>number</replaceable> ; </optional>
     <optional> transfer-format <replaceable>( one-answer | many-answers )</replaceable> ; ]</optional>
     <optional> keys <replaceable>{ string ; <optional> string ; <optional>...</optional></optional> }</replaceable> ; </optional>
+    <optional> transfer-source (<replaceable>ip4_addr</replaceable> | <constant>*</constant>) <optional>port <replaceable>ip_port</replaceable></optional> ; </optional>
+    <optional> transfer-source-v6 (<replaceable>ip6_addr</replaceable> | <constant>*</constant>) <optional>port <replaceable>ip_port</replaceable></optional> ; </optional>
 };
 </programlisting>
 
@@ -4328,6 +4330,18 @@ to be signed by this key.</para>
 allows for multiple keys, only a single key per server is currently
 supported.</para>
 
+<para>The <command>transfer-source</command> and
+<command>transfer-source-v6</command> clauses specify the IPv4 and IPv6 source
+address to be used for zone transfer with the remote server, respectively.
+For an IPv4 remote server, only <command>transfer-source</command> can
+be specified.
+Similarly, for an IPv6 remote server, only
+<command>transfer-source-v6</command> can be specified.
+Form more details, see the description of
+<command>transfer-source</command> and
+<command>transfer-source-v6</command> in
+<xref linkend="zone_transfers"/>.</para>
+
 </sect2>
 
 <sect2><title><command>trusted-keys</command> Statement Grammar</title>
index e82c371442853a3e94feff7fa6b615bc73d4899c..f90b57a1d987a61677adb5e6ab388fdfcbea083d 100644 (file)
@@ -15,7 +15,7 @@
  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: check.c,v 1.40 2003/09/19 12:39:48 marka Exp $ */
+/* $Id: check.c,v 1.41 2003/09/25 18:16:47 jinmei Exp $ */
 
 #include <config.h>
 
@@ -806,10 +806,30 @@ check_servers(cfg_obj_t *servers, isc_log_t *logctx) {
        cfg_obj_t *v1, *v2;
        isc_sockaddr_t *s1, *s2;
        isc_netaddr_t na;
+       cfg_obj_t *ts;
+       char buf[128];
+       const char *xfr;
+       isc_buffer_t target;
 
        for (e1 = cfg_list_first(servers); e1 != NULL; e1 = cfg_list_next(e1)) {
                v1 = cfg_listelt_value(e1);
                s1 = cfg_obj_assockaddr(cfg_map_getname(v1));
+               ts = NULL;
+               if (isc_sockaddr_pf(s1) == AF_INET)
+                       xfr = "transfer-source-v6";
+               else
+                       xfr = "transfer-source";
+               (void)cfg_map_get(v1, xfr, &ts);
+               if (ts != NULL) {
+                       isc_netaddr_fromsockaddr(&na, s1);
+                       isc_buffer_init(&target, buf, sizeof(buf) - 1);
+                       RUNTIME_CHECK(isc_netaddr_totext(&na, &target)
+                                     == ISC_R_SUCCESS);
+                       buf[isc_buffer_usedlength(&target)] = '\0';
+                       cfg_obj_log(v1, logctx, ISC_LOG_ERROR,
+                                   "server '%s': %s not valid", buf, xfr);
+                       result = ISC_R_FAILURE;
+               }
                e2 = e1;
                while ((e2 = cfg_list_next(e2)) != NULL) {
                        v2 = cfg_listelt_value(e2);
@@ -817,8 +837,6 @@ check_servers(cfg_obj_t *servers, isc_log_t *logctx) {
                        if (isc_sockaddr_eqaddr(s1, s2)) {
                                const char *file = cfg_obj_file(v1);
                                unsigned int line = cfg_obj_line(v1);
-                               isc_buffer_t target;
-                               char buf[128];
 
                                if (file == NULL)
                                        file = "<unknown file>";
index d5d47df92f654cec18ea909dd65a68ede74365f0..0a27421475e347c2d63adb71473dc0b4da1916ac 100644 (file)
@@ -15,7 +15,7 @@
  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: peer.h,v 1.18 2001/11/30 01:59:26 gson Exp $ */
+/* $Id: peer.h,v 1.19 2003/09/25 18:16:49 jinmei Exp $ */
 
 #ifndef DNS_PEER_H
 #define DNS_PEER_H 1
@@ -72,6 +72,7 @@ struct dns_peer {
        isc_boolean_t           request_ixfr;
        isc_boolean_t           support_edns;
        dns_name_t             *key;
+       isc_sockaddr_t         *transfer_source;
 
        isc_uint32_t            bitflags;
 
@@ -165,6 +166,12 @@ dns_peer_getkey(dns_peer_t *peer, dns_name_t **retval);
 isc_result_t
 dns_peer_setkey(dns_peer_t *peer, dns_name_t **keyval);
 
+isc_result_t
+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_LANG_ENDDECLS
 
 #endif /* DNS_PEER_H */
index 1e589cf49d9e4dde01ac92a909dc811eca1e1e97..0dc1a4fac9a45563352c336b4ab2d509c3dd2af9 100644 (file)
  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: peer.c,v 1.17 2001/11/30 01:59:14 gson Exp $ */
+/* $Id: peer.c,v 1.18 2003/09/25 18:16:47 jinmei Exp $ */
 
 #include <config.h>
 
 #include <isc/mem.h>
 #include <isc/string.h>
 #include <isc/util.h>
+#include <isc/sockaddr.h>
 
 #include <dns/bit.h>
 #include <dns/fixedname.h>
@@ -193,6 +194,7 @@ dns_peer_new(isc_mem_t *mem, isc_netaddr_t *addr, dns_peer_t **peerptr) {
        peer->provide_ixfr = ISC_FALSE;
        peer->key = NULL;
        peer->refs = 1;
+       peer->transfer_source = NULL;
 
        memset(&peer->bitflags, 0x0, sizeof(peer->bitflags));
 
@@ -256,6 +258,11 @@ peer_delete(dns_peer_t **peer) {
                isc_mem_put(mem, p->key, sizeof(dns_name_t));
        }
 
+       if (p->transfer_source != NULL) {
+               isc_mem_put(mem, p->transfer_source,
+                           sizeof(*p->transfer_source));
+       }
+
        isc_mem_put(mem, p, sizeof(*p));
 
        *peer = NULL;
@@ -482,3 +489,34 @@ dns_peer_setkeybycharp(dns_peer_t *peer, const char *keyval) {
 
        return (result);
 }
+
+isc_result_t
+dns_peer_settransfersource(dns_peer_t *peer, isc_sockaddr_t *transfer_source) {
+       REQUIRE(DNS_PEER_VALID(peer));
+
+       if (peer->transfer_source != NULL) {
+               isc_mem_put(peer->mem, peer->transfer_source,
+                           sizeof(*peer->transfer_source));
+               peer->transfer_source = NULL;
+       }
+       if (transfer_source != NULL) {
+               peer->transfer_source = isc_mem_get(peer->mem,
+                                               sizeof(*peer->transfer_source));
+               if (peer->transfer_source == NULL)
+                       return (ISC_R_NOMEMORY);
+
+               *peer->transfer_source = *transfer_source;
+       }
+       return (ISC_R_SUCCESS);
+}
+
+isc_result_t
+dns_peer_gettransfersource(dns_peer_t *peer, isc_sockaddr_t *transfer_source) {
+       REQUIRE(DNS_PEER_VALID(peer));
+       REQUIRE(transfer_source != NULL);
+
+       if (peer->transfer_source == NULL)
+               return (ISC_R_NOTFOUND);
+       *transfer_source = *peer->transfer_source;
+       return (ISC_R_SUCCESS);
+}
index b0e8b5adca07dabc9ae54e58e84c10827a1ce9f6..4c236ef5ebb3bcffb337869836ffe45bfca3a301 100644 (file)
@@ -15,7 +15,7 @@
  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: zone.c,v 1.398 2003/09/24 01:03:37 marka Exp $ */
+/* $Id: zone.c,v 1.399 2003/09/25 18:16:47 jinmei Exp $ */
 
 #include <config.h>
 
@@ -3824,6 +3824,7 @@ soa_query(isc_task_t *task, isc_event_t *event) {
        isc_uint32_t options;
        isc_boolean_t cancel = ISC_TRUE;
        int timeout;
+       isc_boolean_t have_xfrsource;
 
        REQUIRE(DNS_ZONE_VALID(zone));
 
@@ -3853,30 +3854,6 @@ soa_query(isc_task_t *task, isc_event_t *event) {
 
        zone->masteraddr = zone->masters[zone->curmaster];
 
-       switch (isc_sockaddr_pf(&zone->masteraddr)) {
-       case PF_INET:
-               if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
-                       if (isc_sockaddr_equal(&zone->altxfrsource4,
-                                              &zone->xfrsource4))
-                               goto skip_master;
-                       zone->sourceaddr = zone->altxfrsource4;
-               } else
-                       zone->sourceaddr = zone->xfrsource4;
-               break;
-       case PF_INET6:
-               if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
-                       if (isc_sockaddr_equal(&zone->altxfrsource6,
-                                              &zone->xfrsource6))
-                               goto skip_master;
-                       zone->sourceaddr = zone->altxfrsource6;
-               } else
-                       zone->sourceaddr = zone->xfrsource6;
-               break;
-       default:
-               result = ISC_R_NOTIMPLEMENTED;
-               goto cleanup;
-       }
-
        isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
        /*
         * First, look for a tsig key in the master statement, then
@@ -3897,15 +3874,45 @@ soa_query(isc_task_t *task, isc_event_t *event) {
        if (key == NULL)
                (void)dns_view_getpeertsig(zone->view, &masterip, &key);
 
+       have_xfrsource = ISC_FALSE;
        if (zone->view->peers != NULL) {
                dns_peer_t *peer = NULL;
                isc_boolean_t edns;
                result = dns_peerlist_peerbyaddr(zone->view->peers,
                                                 &masterip, &peer);
-               if (result == ISC_R_SUCCESS)
+               if (result == ISC_R_SUCCESS) {
                        result = dns_peer_getsupportedns(peer, &edns);
-               if (result == ISC_R_SUCCESS && !edns)
-                       DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
+                       if (result == ISC_R_SUCCESS && !edns)
+                               DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
+                       result = dns_peer_gettransfersource(peer,
+                                                           &zone->sourceaddr);
+                       if (result == ISC_R_SUCCESS)
+                               have_xfrsource = ISC_TRUE;
+               }
+       }
+
+       switch (isc_sockaddr_pf(&zone->masteraddr)) {
+       case PF_INET:
+               if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
+                       if (isc_sockaddr_equal(&zone->altxfrsource4,
+                                              &zone->xfrsource4))
+                               goto skip_master;
+                       zone->sourceaddr = zone->altxfrsource4;
+               } else if (!have_xfrsource)
+                       zone->sourceaddr = zone->xfrsource4;
+               break;
+       case PF_INET6:
+               if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
+                       if (isc_sockaddr_equal(&zone->altxfrsource6,
+                                              &zone->xfrsource6))
+                               goto skip_master;
+                       zone->sourceaddr = zone->altxfrsource6;
+               } else if (!have_xfrsource)
+                       zone->sourceaddr = zone->xfrsource6;
+               break;
+       default:
+               result = ISC_R_NOTIMPLEMENTED;
+               goto cleanup;
        }
 
        options = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEVC) ?
@@ -3968,6 +3975,7 @@ ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset, dns_stub_t *stub) {
        dns_tsigkey_t *key = NULL;
        dns_dbnode_t *node = NULL;
        int timeout;
+       isc_boolean_t have_xfrsource = ISC_FALSE;
 
        REQUIRE(DNS_ZONE_VALID(zone));
        REQUIRE((soardataset != NULL && stub == NULL) ||
@@ -4078,10 +4086,16 @@ ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset, dns_stub_t *stub) {
                isc_boolean_t edns;
                result = dns_peerlist_peerbyaddr(zone->view->peers,
                                                 &masterip, &peer);
-               if (result == ISC_R_SUCCESS)
+               if (result == ISC_R_SUCCESS) {
                        result = dns_peer_getsupportedns(peer, &edns);
-               if (result == ISC_R_SUCCESS && !edns)
-                       DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
+                       if (result == ISC_R_SUCCESS && !edns)
+                               DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
+                       result = dns_peer_gettransfersource(peer,
+                                                           &zone->sourceaddr);
+                       if (result == ISC_R_SUCCESS)
+                               have_xfrsource = ISC_TRUE;
+               }
+               
        }
        if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
                result = add_opt(message);
@@ -4098,13 +4112,13 @@ ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset, dns_stub_t *stub) {
        case PF_INET:
                if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC))
                        zone->sourceaddr = zone->altxfrsource4;
-               else
+               else if (!have_xfrsource)
                        zone->sourceaddr = zone->xfrsource4;
                break;
        case PF_INET6:
                if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC))
                        zone->sourceaddr = zone->altxfrsource6;
-               else
+               else if (!have_xfrsource)
                        zone->sourceaddr = zone->xfrsource6;
                break;
        default:
index 8450a23b53759b8c22a3d51372da2aadeb929ee0..82447e51e238aa62edccd8c3bad242c090c08ce3 100644 (file)
@@ -15,7 +15,7 @@
  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: namedconf.c,v 1.23 2003/09/19 12:39:49 marka Exp $ */
+/* $Id: namedconf.c,v 1.24 2003/09/25 18:16:50 jinmei Exp $ */
 
 #include <config.h>
 
@@ -824,6 +824,8 @@ server_clauses[] = {
        { "transfer-format", &cfg_type_transferformat, 0 },
        { "keys", &cfg_type_server_key_kludge, 0 },
        { "edns", &cfg_type_boolean, 0 },
+       { "transfer-source", &cfg_type_sockaddr4wild, 0 },
+       { "transfer-source-v6", &cfg_type_sockaddr6wild, 0 },
        { NULL, NULL, 0 }
 };
 static cfg_clausedef_t *
@@ -1579,8 +1581,8 @@ static cfg_type_t cfg_type_sockaddr4wild = {
 
 static unsigned int sockaddr6wild_flags = CFG_ADDR_WILDOK | CFG_ADDR_V6OK;
 static cfg_type_t cfg_type_sockaddr6wild = {
-       "v6addrportwild", cfg_parse_sockaddr, cfg_print_sockaddr, cfg_doc_sockaddr,
-       &cfg_rep_sockaddr, &sockaddr6wild_flags
+       "v6addrportwild", cfg_parse_sockaddr, cfg_print_sockaddr,
+       cfg_doc_sockaddr, &cfg_rep_sockaddr, &sockaddr6wild_flags
 };
 
 /*