]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
1680. [func] rndc: the source address can now be specified.
authorMark Andrews <marka@isc.org>
Fri, 23 Jul 2004 04:15:27 +0000 (04:15 +0000)
committerMark Andrews <marka@isc.org>
Fri, 23 Jul 2004 04:15:27 +0000 (04:15 +0000)
CHANGES
bin/rndc/rndc.c
bin/rndc/rndc.conf.docbook
bin/rndc/rndc.docbook
lib/isccfg/include/isccfg/grammar.h
lib/isccfg/namedconf.c
lib/isccfg/parser.c

diff --git a/CHANGES b/CHANGES
index 2d07ffd4071b07cc55df633456e5d59b8315c61b..792a9d40e26beaa18582d3ba33bde375d58fd551 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -25,7 +25,7 @@
 1681.  [bug]           Only set SO_REUSEADDR when a port is specified in
                        isc_socket_bind(). [RT #11742]
 
-1680.  [placeholder]   rt11697
+1680.  [func]          rndc: the source address can now be specified.
 
 1679.  [bug]           When there was a single nameserver with multiple
                        addresses for a zone not all addresses were tried.
index 37bfd8d33c4fcf3b20114f92c47b935661073a60..38f24efa8f9bf5732e16330af9253f1c0001a8b5 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: rndc.c,v 1.97 2004/06/18 04:38:46 marka Exp $ */
+/* $Id: rndc.c,v 1.98 2004/07/23 04:15:23 marka Exp $ */
 
 /*
  * Principal Author: DCL
@@ -30,6 +30,7 @@
 #include <isc/commandline.h>
 #include <isc/file.h>
 #include <isc/log.h>
+#include <isc/net.h>
 #include <isc/mem.h>
 #include <isc/random.h>
 #include <isc/socket.h>
@@ -64,6 +65,8 @@ static const char *admin_keyfile;
 static const char *version = VERSION;
 static const char *servername = NULL;
 static isc_sockaddr_t serveraddrs[SERVERADDRS];
+static isc_sockaddr_t local4, local6;
+static isc_boolean_t local4set = ISC_FALSE, local6set = ISC_FALSE;
 static int nserveraddrs;
 static int currentaddr = 0;
 static unsigned int remoteport = 0;
@@ -169,10 +172,12 @@ rndc_recvdone(isc_task_t *task, isc_event_t *event) {
 
        if (ccmsg.result == ISC_R_EOF)
                fatal("connection to remote host closed\n"
-                     "This may indicate that the remote server is using "
-                     "an older version of \n"
-                     "the command protocol, this host is not authorized "
-                     "to connect,\nor the key is invalid.");
+                     "This may indicate that\n"
+                     "* the remote server is using an older version of"
+                     " the command protocol,\n"
+                     "* this host is not authorized to connect,\n"
+                     "* the clocks are not syncronized, or\n"
+                     "* the key is invalid.");
 
        if (ccmsg.result != ISC_R_SUCCESS)
                fatal("recv failed: %s", isc_result_totext(ccmsg.result));
@@ -228,10 +233,12 @@ rndc_recvnonce(isc_task_t *task, isc_event_t *event) {
 
        if (ccmsg.result == ISC_R_EOF)
                fatal("connection to remote host closed\n"
-                     "This may indicate that the remote server is using "
-                     "an older version of \n"
-                     "the command protocol, this host is not authorized "
-                     "to connect,\nor the key is invalid.");
+                     "This may indicate that\n"
+                     "* the remote server is using an older version of"
+                     " the command protocol,\n"
+                     "* this host is not authorized to connect,\n"
+                     "* the clocks are not syncronized, or\n"
+                     "* the key is invalid.");
 
        if (ccmsg.result != ISC_R_SUCCESS)
                fatal("recv failed: %s", isc_result_totext(ccmsg.result));
@@ -357,6 +364,16 @@ rndc_startconnect(isc_sockaddr_t *addr, isc_task_t *task) {
        DO("create socket", isc_socket_create(socketmgr,
                                              isc_sockaddr_pf(addr),
                                              isc_sockettype_tcp, &sock));
+       switch (isc_sockaddr_pf(addr)) {
+       case AF_INET:
+               DO("bind socket", isc_socket_bind(sock, &local4));
+               break;
+       case AF_INET6:
+               DO("bind socket", isc_socket_bind(sock, &local6));
+               break;
+       default:
+               break;
+       }
        DO("connect", isc_socket_connect(sock, addr, task, rndc_connected,
                                         NULL));
        connects++;
@@ -387,6 +404,7 @@ parse_config(isc_mem_t *mctx, isc_log_t *log, const char *keyname,
        cfg_obj_t *secretobj = NULL;
        cfg_obj_t *algorithmobj = NULL;
        cfg_obj_t *config = NULL;
+       cfg_obj_t *address = NULL;
        cfg_listelt_t *elt;
        const char *secretstr;
        const char *algorithm;
@@ -524,10 +542,9 @@ parse_config(isc_mem_t *mctx, isc_log_t *log, const char *keyname,
                     element != NULL;
                     element = cfg_list_next(element))
                {
-
-                       cfg_obj_t *address = cfg_listelt_value(element);
                        isc_sockaddr_t sa;
 
+                       address = cfg_listelt_value(element);
                        if (!cfg_obj_issockaddr(address)) {
                                unsigned int myport;
                                const char *name;
@@ -567,6 +584,41 @@ parse_config(isc_mem_t *mctx, isc_log_t *log, const char *keyname,
                        }
                }
        }
+
+       if (!local4set && server != NULL) {
+               address = NULL;
+               cfg_map_get(server, "source-address", &address);
+               if (address != NULL) {
+                       local4 = *cfg_obj_assockaddr(address);
+                       local4set = ISC_TRUE;
+               }
+       }
+       if (!local4set && options != NULL) {
+               address = NULL;
+               cfg_map_get(options, "default-source-address", &address);
+               if (address != NULL) {
+                       local4 = *cfg_obj_assockaddr(address);
+                       local4set = ISC_TRUE;
+               }
+       }
+
+       if (!local6set && server != NULL) {
+               address = NULL;
+               cfg_map_get(server, "source-address-v6", &address);
+               if (address != NULL) {
+                       local6 = *cfg_obj_assockaddr(address);
+                       local6set = ISC_TRUE;
+               }
+       }
+       if (!local6set && options != NULL) {
+               address = NULL;
+               cfg_map_get(options, "default-source-address-v6", &address);
+               if (address != NULL) {
+                       local6 = *cfg_obj_assockaddr(address);
+                       local6set = ISC_TRUE;
+               }
+       }
+
        *configp = config;
 }
 
@@ -582,6 +634,8 @@ main(int argc, char **argv) {
        cfg_parser_t *pctx = NULL;
        cfg_obj_t *config = NULL;
        const char *keyname = NULL;
+       struct in_addr in;
+       struct in6_addr in6;
        char *p;
        size_t argslen;
        int ch;
@@ -595,13 +649,28 @@ main(int argc, char **argv) {
        admin_conffile = RNDC_CONFFILE;
        admin_keyfile = RNDC_KEYFILE;
 
+       isc_sockaddr_any(&local4);
+       isc_sockaddr_any6(&local6);
+
        result = isc_app_start();
        if (result != ISC_R_SUCCESS)
                fatal("isc_app_start() failed: %s", isc_result_totext(result));
 
-       while ((ch = isc_commandline_parse(argc, argv, "c:k:Mmp:s:Vy:"))
+       while ((ch = isc_commandline_parse(argc, argv, "b:c:k:Mmp:s:Vy:"))
               != -1) {
                switch (ch) {
+               case 'b':
+                       if (inet_pton(AF_INET, isc_commandline_argument,
+                                     &in) == 1) {
+                               isc_sockaddr_fromin(&local4, &in, 0);
+                               local4set = ISC_TRUE;
+                       } else if (inet_pton(AF_INET6, isc_commandline_argument,
+                                            &in6) == 1) {
+                               isc_sockaddr_fromin6(&local6, &in6, 0);
+                               local6set = ISC_TRUE;
+                       }
+                       break;
+
                case 'c':
                        admin_conffile = isc_commandline_argument;
                        break;
@@ -628,15 +697,19 @@ main(int argc, char **argv) {
                case 's':
                        servername = isc_commandline_argument;
                        break;
+
                case 'V':
                        verbose = ISC_TRUE;
                        break;
+
                case 'y':
                        keyname = isc_commandline_argument;
                        break;
                case '?':
                        usage(0);
                        break;
+
                default:
                        fatal("unexpected error parsing command arguments: "
                              "got %c\n", ch);
index 58a910ee2266cb5867d97deabbdcb13baf3a724c..1d486eae120cd3f7a7fbbc2d8a6964bdeabaa606 100644 (file)
@@ -16,7 +16,7 @@
  - PERFORMANCE OF THIS SOFTWARE.
 -->
 
-<!-- $Id: rndc.conf.docbook,v 1.7 2004/06/18 04:38:47 marka Exp $ -->
+<!-- $Id: rndc.conf.docbook,v 1.8 2004/07/23 04:15:23 marka Exp $ -->
 
 <refentry>
   <refentryinfo>
@@ -67,7 +67,7 @@
        and a key statement.
     </para>
     <para>
-        The <option>options</option> statement contains three clauses.
+        The <option>options</option> statement contains five clauses.
        The <option>default-server</option> clause is followed by the
        name or address of a name server.  This host will be used when
        no name server is given as an argument to
        line, and no <option>port</option> clause is found in a
        matching <option>server</option> statement, this default port
        will be used to connect.
+       The <option>default-source-address</option> and
+       <option>default-source-address-v6</option> clauses which
+       can be used to set the IPv4 and IPv6 source addresses
+       respectively.
     </para>
     <para>
        After the <option>server</option> keyword, the server
@@ -95,6 +99,9 @@
        specifies the port to connect to.  If an <option>addresses</option>
        clause is supplied these addresses will be used instead of
        the server name.  Each address can take a optional port.
+       If an <option>source-address</option> or <option>source-address-v6</option>
+       of supplied then these will be used to specify the IPv4 and IPv6
+       source addresses respectively. 
     </para>
     <para>
         The <option>key</option> statement begins with an identifying
index 6ddb40b2c308a60d9343df6c5aab42c10e678954..f54e59781cccf977ca87295454a384e8b3bdb131 100644 (file)
@@ -16,7 +16,7 @@
  - PERFORMANCE OF THIS SOFTWARE.
 -->
 
-<!-- $Id: rndc.docbook,v 1.9 2004/06/03 02:22:33 marka Exp $ -->
+<!-- $Id: rndc.docbook,v 1.10 2004/07/23 04:15:25 marka Exp $ -->
 
 <refentry>
   <refentryinfo>
@@ -37,6 +37,7 @@
   <refsynopsisdiv>
     <cmdsynopsis>
       <command>rndc</command>
+      <arg><option>-b <replaceable class="parameter">source-address</replaceable></option></arg>
       <arg><option>-c <replaceable class="parameter">config-file</replaceable></option></arg>
       <arg><option>-k <replaceable class="parameter">key-file</replaceable></option></arg>
       <arg><option>-s <replaceable class="parameter">server</replaceable></option></arg>
     <title>OPTIONS</title>
 
     <variablelist>
+      <varlistentry>
+        <term>-b <replaceable class="parameter">source-address</replaceable></term>
+       <listitem>
+         <para>
+             Use <replaceable class="parameter">source-address</replaceable>
+             as the source address for the connection to the server.
+             Multiple instances are permitted to allow setting of both
+             the IPv4 and IPv6 source addresses.
+         </para>
+       </listitem>
+      </varlistentry>
+
       <varlistentry>
         <term>-c <replaceable class="parameter">config-file</replaceable></term>
        <listitem>
index 5431e7e093f79382599e0b31825bbdafb0335dbc..74b2bb5528ed47e2efef2f5d4318511bd5e5be8e 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: grammar.h,v 1.4 2004/03/05 05:12:27 marka Exp $ */
+/* $Id: grammar.h,v 1.5 2004/07/23 04:15:27 marka Exp $ */
 
 #ifndef ISCCFG_GRAMMAR_H
 #define ISCCFG_GRAMMAR_H 1
@@ -248,6 +248,10 @@ LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_astring;
 LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_ustring;
 LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_sockaddr;
 LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_netaddr;
+LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_netaddr4;
+LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_netaddr4wild;
+LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_netaddr6;
+LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_netaddr6wild;
 LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_netprefix;
 LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_void;
 LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_token;
index 9059656f7bf67a817ad07f803ad2753257121a12..391118d4946e23629de3ca0117261a097ad86dc4 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: namedconf.c,v 1.35 2004/06/18 04:38:45 marka Exp $ */
+/* $Id: namedconf.c,v 1.36 2004/07/23 04:15:26 marka Exp $ */
 
 #include <config.h>
 
@@ -1680,7 +1680,9 @@ lwres_clausesets[] = {
        NULL
 };
 static cfg_type_t cfg_type_lwres = {
-       "lwres", cfg_parse_map, cfg_print_map, cfg_doc_map, &cfg_rep_map, lwres_clausesets };
+       "lwres", cfg_parse_map, cfg_print_map, cfg_doc_map, &cfg_rep_map,
+       lwres_clausesets
+};
 
 /*
  * rndc
@@ -1688,9 +1690,11 @@ static cfg_type_t cfg_type_lwres = {
 
 static cfg_clausedef_t
 rndcconf_options_clauses[] = {
-       { "default-server", &cfg_type_astring, 0 },
        { "default-key", &cfg_type_astring, 0 },
        { "default-port", &cfg_type_uint32, 0 },
+       { "default-server", &cfg_type_astring, 0 },
+       { "default-source-address", &cfg_type_netaddr4wild, 0 },
+       { "default-source-address-v6", &cfg_type_netaddr6wild, 0 },
        { NULL, NULL, 0 }
 };
 
@@ -1701,14 +1705,16 @@ rndcconf_options_clausesets[] = {
 };
 
 static cfg_type_t cfg_type_rndcconf_options = {
-       "rndcconf_options", cfg_parse_map, cfg_print_map, cfg_doc_map, &cfg_rep_map,
-       rndcconf_options_clausesets
+       "rndcconf_options", cfg_parse_map, cfg_print_map, cfg_doc_map,
+       &cfg_rep_map, rndcconf_options_clausesets
 };
 
 static cfg_clausedef_t
 rndcconf_server_clauses[] = {
        { "key", &cfg_type_astring, 0 },
        { "port", &cfg_type_uint32, 0 },
+       { "source-address", &cfg_type_netaddr4wild, 0 },
+       { "source-address-v6", &cfg_type_netaddr6wild, 0 },
        { "addresses", &cfg_type_bracketed_sockaddrnameportlist, 0 },
        { NULL, NULL, 0 }
 };
@@ -1720,8 +1726,8 @@ rndcconf_server_clausesets[] = {
 };
 
 static cfg_type_t cfg_type_rndcconf_server = {
-       "rndcconf_server", cfg_parse_named_map, cfg_print_map, cfg_doc_map, &cfg_rep_map,
-       rndcconf_server_clausesets
+       "rndcconf_server", cfg_parse_named_map, cfg_print_map, cfg_doc_map,
+       &cfg_rep_map, rndcconf_server_clausesets
 };
 
 static cfg_clausedef_t
index 14223142ba4b837d6dab07cb287e13fce6b1e774..3fbda9bff4f114ec3d9a53b6bfdfc4103f8ec75e 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: parser.c,v 1.113 2004/05/15 03:37:34 jinmei Exp $ */
+/* $Id: parser.c,v 1.114 2004/07/23 04:15:26 marka Exp $ */
 
 #include <config.h>
 
@@ -1766,14 +1766,21 @@ cfg_print_rawaddr(cfg_printer_t *pctx, isc_netaddr_t *na) {
 
 /* netaddr */
 
+static unsigned int netaddr_flags = CFG_ADDR_V4OK | CFG_ADDR_V6OK;
+static unsigned int netaddr4_flags = CFG_ADDR_V4OK;
+static unsigned int netaddr4wild_flags = CFG_ADDR_V4OK | CFG_ADDR_WILDOK;
+static unsigned int netaddr6_flags = CFG_ADDR_V6OK;
+static unsigned int netaddr6wild_flags = CFG_ADDR_V6OK | CFG_ADDR_WILDOK;
+
 static isc_result_t
 parse_netaddr(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
        isc_result_t result;
        cfg_obj_t *obj = NULL;
        isc_netaddr_t netaddr;
-       UNUSED(type);
+       unsigned int flags = *(const unsigned int *)type->of;
+
        CHECK(cfg_create_obj(pctx, type, &obj));
-       CHECK(cfg_parse_rawaddr(pctx, CFG_ADDR_V4OK | CFG_ADDR_V6OK, &netaddr));
+       CHECK(cfg_parse_rawaddr(pctx, flags, &netaddr));
        isc_sockaddr_fromnetaddr(&obj->value.sockaddr, &netaddr, 0);
        *ret = obj;
        return (ISC_R_SUCCESS);
@@ -1782,9 +1789,57 @@ parse_netaddr(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
        return (result);
 }
 
+static void
+cfg_doc_netaddr(cfg_printer_t *pctx, const cfg_type_t *type) {
+       const unsigned int *flagp = type->of;
+       int n = 0;
+       if (*flagp != CFG_ADDR_V4OK && *flagp != CFG_ADDR_V6OK)
+               cfg_print_chars(pctx, "( ", 2);
+       if (*flagp & CFG_ADDR_V4OK) {
+               if (n != 0)
+                       cfg_print_chars(pctx, " | ", 3);
+               cfg_print_cstr(pctx, "<ipv4_address>");
+               n++;
+       }
+       if (*flagp & CFG_ADDR_V6OK) {
+               if (n != 0)
+                       cfg_print_chars(pctx, " | ", 3);
+               cfg_print_cstr(pctx, "<ipv6_address>");
+               n++;                    
+       }
+       if (*flagp & CFG_ADDR_WILDOK) {
+               if (n != 0)
+                       cfg_print_chars(pctx, " | ", 3);
+               cfg_print_chars(pctx, "*", 1);
+               n++;
+       }
+       if (*flagp != CFG_ADDR_V4OK && *flagp != CFG_ADDR_V6OK)
+               cfg_print_chars(pctx, " )", 2);
+}
+
 cfg_type_t cfg_type_netaddr = {
-       "netaddr", parse_netaddr, cfg_print_sockaddr, cfg_doc_terminal,
-       &cfg_rep_sockaddr, NULL
+       "netaddr", parse_netaddr, cfg_print_sockaddr, cfg_doc_netaddr,
+       &cfg_rep_sockaddr, &netaddr_flags
+};
+
+cfg_type_t cfg_type_netaddr4 = {
+       "netaddr4", parse_netaddr, cfg_print_sockaddr, cfg_doc_netaddr,
+       &cfg_rep_sockaddr, &netaddr4_flags
+};
+
+cfg_type_t cfg_type_netaddr4wild = {
+       "netaddr4wild", parse_netaddr, cfg_print_sockaddr, cfg_doc_netaddr,
+       &cfg_rep_sockaddr, &netaddr4wild_flags
+};
+
+cfg_type_t cfg_type_netaddr6 = {
+       "netaddr6", parse_netaddr, cfg_print_sockaddr, cfg_doc_netaddr,
+       &cfg_rep_sockaddr, &netaddr6_flags
+};
+
+cfg_type_t cfg_type_netaddr6wild = {
+       "netaddr6wild", parse_netaddr, cfg_print_sockaddr, cfg_doc_netaddr,
+       &cfg_rep_sockaddr, &netaddr6wild_flags
 };
 
 /* netprefix */