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.
* 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
#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>
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;
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));
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));
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++;
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;
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;
}
}
}
+
+ 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;
}
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;
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;
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);
- 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>
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
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
- 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>
<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>
* 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
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;
* 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>
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
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 }
};
};
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 }
};
};
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
* 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>
/* 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);
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 */