From efe7977c4d6fb1d45be0319fb8c42a930d8b224d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20K=C4=99pie=C5=84?= Date: Wed, 16 Aug 2017 16:01:39 +0200 Subject: [PATCH] [master] Add -4/-6 command line options to nsupdate and rndc 4691. [func] Add -4/-6 command line options to nsupdate and rndc. [RT #45632] --- CHANGES | 3 ++ bin/nsupdate/nsupdate.c | 81 ++++++++++++++++++++++-------- bin/nsupdate/nsupdate.docbook | 22 ++++++++ bin/rndc/rndc.c | 49 ++++++++++++++++-- bin/rndc/rndc.docbook | 22 ++++++++ bin/tests/system/nsupdate/tests.sh | 38 +++++++++++--- bin/tests/system/rndc/tests.sh | 16 ++++++ doc/arm/notes.xml | 7 +++ 8 files changed, 208 insertions(+), 30 deletions(-) diff --git a/CHANGES b/CHANGES index a45d476b46..ff1982dc76 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,6 @@ +4691. [func] Add -4/-6 command line options to nsupdate and rndc. + [RT #45632] + 4690. [bug] Command line options -4/-6 were handled inconsistently between tools. [RT #45632] diff --git a/bin/nsupdate/nsupdate.c b/bin/nsupdate/nsupdate.c index 70d7a55277..06e536622b 100644 --- a/bin/nsupdate/nsupdate.c +++ b/bin/nsupdate/nsupdate.c @@ -850,7 +850,7 @@ setup_system(void) { isc_result_t result; isc_sockaddr_t bind_any, bind_any6; lwres_result_t lwresult; - unsigned int attrs, attrmask; + unsigned int attrs, attrmask, flags; int i; isc_logconfig_t *logconfig = NULL; @@ -858,17 +858,6 @@ setup_system(void) { dns_result_register(); - result = isc_net_probeipv4(); - if (result == ISC_R_SUCCESS) - have_ipv4 = ISC_TRUE; - - result = isc_net_probeipv6(); - if (result == ISC_R_SUCCESS) - have_ipv6 = ISC_TRUE; - - if (!have_ipv4 && !have_ipv6) - fatal("could not find either IPv4 or IPv6"); - result = isc_log_create(gmctx, &glctx, &logconfig); check_result(result, "isc_log_create"); @@ -881,7 +870,16 @@ setup_system(void) { isc_log_setdebuglevel(glctx, logdebuglevel); - lwresult = lwres_context_create(&lwctx, gmctx, mem_alloc, mem_free, 1); + flags = LWRES_CONTEXT_SERVERMODE; + if (have_ipv4) { + flags |= LWRES_CONTEXT_USEIPV4; + } + if (have_ipv6) { + flags |= LWRES_CONTEXT_USEIPV6; + } + + lwresult = lwres_context_create(&lwctx, gmctx, mem_alloc, mem_free, + flags); if (lwresult != LWRES_R_SUCCESS) fatal("lwres_context_create failed"); @@ -909,15 +907,15 @@ setup_system(void) { if (servers == NULL) fatal("out of memory"); - if (have_ipv4) { - in.s_addr = htonl(INADDR_LOOPBACK); - isc_sockaddr_fromin(&servers[0], &in, dnsport); - } if (have_ipv6) { memset(&in6, 0, sizeof(in6)); in6.s6_addr[15] = 1; - isc_sockaddr_fromin6(&servers[(have_ipv4 ? 1 : 0)], - &in6, dnsport); + isc_sockaddr_fromin6(&servers[0], &in6, dnsport); + } + if (have_ipv4) { + in.s_addr = htonl(INADDR_LOOPBACK); + isc_sockaddr_fromin(&servers[(have_ipv6 ? 1 : 0)], + &in, dnsport); } } else { ns_total = ns_alloc = lwconf->nsnext; @@ -1034,7 +1032,7 @@ version(void) { fputs("nsupdate " VERSION "\n", stderr); } -#define PARSE_ARGS_FMT "dDML:y:ghilovk:p:Pr:R::t:Tu:V" +#define PARSE_ARGS_FMT "46dDML:y:ghilovk:p:Pr:R::t:Tu:V" static void pre_parse_args(int argc, char **argv) { @@ -1042,6 +1040,7 @@ pre_parse_args(int argc, char **argv) { int ch; char buf[100]; isc_boolean_t doexit = ISC_FALSE; + isc_boolean_t ipv4only = ISC_FALSE, ipv6only = ISC_FALSE; while ((ch = isc_commandline_parse(argc, argv, PARSE_ARGS_FMT)) != -1) { switch (ch) { @@ -1053,6 +1052,20 @@ pre_parse_args(int argc, char **argv) { ISC_MEM_DEBUGRECORD; break; + case '4': + if (ipv6only) { + fatal("only one of -4 and -6 allowed"); + } + ipv4only = ISC_TRUE; + break; + + case '6': + if (ipv4only) { + fatal("only one of -4 and -6 allowed"); + } + ipv6only = ISC_TRUE; + break; + case '?': case 'h': if (isc_commandline_option != '?') @@ -1060,7 +1073,7 @@ pre_parse_args(int argc, char **argv) { argv[0], isc_commandline_option); fprintf(stderr, "usage: nsupdate [-dDi] [-L level] [-l]" "[-g | -o | -y keyname:secret | -k keyfile] " - "[-v] [-V] [-P] [-T] [filename]\n"); + "[-v] [-V] [-P] [-T] [-4 | -6] [filename]\n"); exit(1); case 'P': @@ -1110,6 +1123,22 @@ parse_args(int argc, char **argv, isc_mem_t *mctx, isc_entropy_t **ectx) { debug("parse_args"); while ((ch = isc_commandline_parse(argc, argv, PARSE_ARGS_FMT)) != -1) { switch (ch) { + case '4': + if (have_ipv4) { + isc_net_disableipv6(); + have_ipv6 = ISC_FALSE; + } else { + fatal("can't find IPv4 networking"); + } + break; + case '6': + if (have_ipv6) { + isc_net_disableipv4(); + have_ipv4 = ISC_FALSE; + } else { + fatal("can't find IPv6 networking"); + } + break; case 'd': debugging = ISC_TRUE; break; @@ -3289,6 +3318,16 @@ main(int argc, char **argv) { isc_app_start(); + if (isc_net_probeipv4() == ISC_R_SUCCESS) { + have_ipv4 = ISC_TRUE; + } + if (isc_net_probeipv6() == ISC_R_SUCCESS) { + have_ipv6 = ISC_TRUE; + } + if (!have_ipv4 && !have_ipv6) { + fatal("could not find either IPv4 or IPv6"); + } + pre_parse_args(argc, argv); result = isc_mem_create(0, 0, &gmctx); diff --git a/bin/nsupdate/nsupdate.docbook b/bin/nsupdate/nsupdate.docbook index eaef76c38c..a74d99a0a3 100644 --- a/bin/nsupdate/nsupdate.docbook +++ b/bin/nsupdate/nsupdate.docbook @@ -71,6 +71,10 @@ + + + + filename @@ -138,6 +142,24 @@ + + -4 + + + Use IPv4 only. + + + + + + -6 + + + Use IPv6 only. + + + + -d diff --git a/bin/rndc/rndc.c b/bin/rndc/rndc.c index ad789f68f4..8dfabe075c 100644 --- a/bin/rndc/rndc.c +++ b/bin/rndc/rndc.c @@ -92,7 +92,7 @@ static void usage(int status) { fprintf(stderr, "\ Usage: %s [-b address] [-c config] [-s server] [-p port]\n\ - [-k key-file ] [-y key] [-r] [-V] command\n\ + [-k key-file ] [-y key] [-r] [-V] [-4 | -6] command\n\ \n\ command is one of the following:\n\ \n\ @@ -211,6 +211,36 @@ Version: %s\n", exit(status); } +#define CMDLINE_FLAGS "46b:c:hk:Mmp:qrs:Vy:" + +static void +preparse_args(int argc, char **argv) { + isc_boolean_t ipv4only = ISC_FALSE, ipv6only = ISC_FALSE; + int ch; + + while ((ch = isc_commandline_parse(argc, argv, CMDLINE_FLAGS)) != -1) { + switch (ch) { + case '4': + if (ipv6only) { + fatal("only one of -4 and -6 allowed"); + } + ipv4only = ISC_TRUE; + break; + case '6': + if (ipv4only) { + fatal("only one of -4 and -6 allowed"); + } + ipv6only = ISC_TRUE; + break; + default: + break; + } + } + + isc_commandline_reset = ISC_TRUE; + isc_commandline_index = 1; +} + static void get_addresses(const char *host, in_port_t port) { isc_result_t result; @@ -802,9 +832,22 @@ main(int argc, char **argv) { isc_commandline_errprint = ISC_FALSE; - while ((ch = isc_commandline_parse(argc, argv, "b:c:hk:Mmp:qrs:Vy:")) - != -1) { + preparse_args(argc, argv); + + while ((ch = isc_commandline_parse(argc, argv, CMDLINE_FLAGS)) != -1) { switch (ch) { + case '4': + if (isc_net_probeipv4() != ISC_R_SUCCESS) { + fatal("can't find IPv4 networking"); + } + isc_net_disableipv6(); + break; + case '6': + if (isc_net_probeipv6() != ISC_R_SUCCESS) { + fatal("can't find IPv6 networking"); + } + isc_net_disableipv4(); + break; case 'b': if (inet_pton(AF_INET, isc_commandline_argument, &in) == 1) { diff --git a/bin/rndc/rndc.docbook b/bin/rndc/rndc.docbook index ab29fbe519..7df47db88d 100644 --- a/bin/rndc/rndc.docbook +++ b/bin/rndc/rndc.docbook @@ -55,6 +55,10 @@ + + + + command @@ -95,6 +99,24 @@ + + -4 + + + Use IPv4 only. + + + + + + -6 + + + Use IPv6 only. + + + + -b source-address diff --git a/bin/tests/system/nsupdate/tests.sh b/bin/tests/system/nsupdate/tests.sh index 61f27e9742..707ffe156e 100755 --- a/bin/tests/system/nsupdate/tests.sh +++ b/bin/tests/system/nsupdate/tests.sh @@ -90,7 +90,7 @@ pre=`$DIG +short new.other.nil. @10.53.0.1 a -p 5300` || ret=1 ret=0 echo "I:updating zone" # nsupdate will print a ">" prompt to stdout as it gets each input line. -$NSUPDATE -l -p 5300 -k ns1/session.key > /dev/null < /dev/null < nsupdate.out 2>&1 << END && ret=1 +$NSUPDATE -4 -l -p 5300 -k ns1/session.key > nsupdate.out 2>&1 << END && ret=1 update add other.nil. 600 in ns ns3.other.nil. send END grep REFUSED nsupdate.out > /dev/null 2>&1 || ret=1 # ...but should work if an A record is inserted first: -$NSUPDATE -l -p 5300 -k ns1/session.key > nsupdate.out 2>&1 << END || ret=1 +$NSUPDATE -4 -l -p 5300 -k ns1/session.key > nsupdate.out 2>&1 << END || ret=1 update add ns4.other.nil 600 in a 10.53.0.1 send update add other.nil. 600 in ns ns4.other.nil. @@ -128,7 +128,7 @@ send END grep REFUSED nsupdate.out > /dev/null 2>&1 && ret=1 # ...or if an AAAA record does: -$NSUPDATE -l -p 5300 -k ns1/session.key > nsupdate.out 2>&1 << END || ret=1 +$NSUPDATE -4 -l -p 5300 -k ns1/session.key > nsupdate.out 2>&1 << END || ret=1 update add ns5.other.nil 600 in aaaa 2001:db8::1 send update add other.nil. 600 in ns ns5.other.nil. @@ -136,7 +136,7 @@ send END grep REFUSED nsupdate.out > /dev/null 2>&1 && ret=1 # ...or if the NS and A/AAAA are inserted together: -$NSUPDATE -l -p 5300 -k ns1/session.key > nsupdate.out 2>&1 << END || ret=1 +$NSUPDATE -4 -l -p 5300 -k ns1/session.key > nsupdate.out 2>&1 << END || ret=1 update add other.nil. 600 in ns ns6.other.nil. update add ns6.other.nil 600 in a 10.53.0.1 send @@ -457,7 +457,7 @@ $PERL ../digcomp.pl knowngood.ns1.afterstop dig.out.ns1 || ret=1 ret=0 echo "I:check that 'nsupdate -l' with a missing keyfile reports the missing file" -$NSUPDATE -l -p 5300 -k ns1/nonexistant.key 2> nsupdate.out < /dev/null +$NSUPDATE -4 -l -p 5300 -k ns1/nonexistant.key 2> nsupdate.out < /dev/null grep ns1/nonexistant.key nsupdate.out > /dev/null || ret=1 if test $ret -ne 0 then @@ -816,6 +816,32 @@ END grep "couldn't get address for 'unresolvable..': not found" nsupdate.out > /dev/null || ret=1 [ $ret = 0 ] || { echo I:failed; status=1; } +n=`expr $n + 1` +ret=0 +echo "I:check nsupdate -4 -6 ($n)" +$NSUPDATE -4 -6 < nsupdate.out-$n 2>&1 && ret=1 +server 10.53.0.3 5300 +zone delegation.test. +update del child.delegation.test. 3600 NS foo.example.net. +update del child.delegation.test. 3600 NS bar.example.net. +send +END +grep "only one of -4 and -6 allowed" nsupdate.out-$n > /dev/null 2>&1 || ret=1 +[ $ret = 0 ] || { echo I:failed; status=1; } + +n=`expr $n + 1` +ret=0 +echo "I:check nsupdate -4 with an IPv6 server address ($n)" +$NSUPDATE -4 < nsupdate.out-$n 2>&1 && ret=1 +server fd92:7065:b8e:ffff::2 5300 +zone delegation.test. +update del child.delegation.test. 3600 NS foo.example.net. +update del child.delegation.test. 3600 NS bar.example.net. +send +END +grep "address family not supported" nsupdate.out-$n > /dev/null 2>&1 || ret=1 +[ $ret = 0 ] || { echo I:failed; status=1; } + # # Add client library tests here # diff --git a/bin/tests/system/rndc/tests.sh b/bin/tests/system/rndc/tests.sh index f1bb1302f3..990ade48d3 100644 --- a/bin/tests/system/rndc/tests.sh +++ b/bin/tests/system/rndc/tests.sh @@ -639,5 +639,21 @@ grep "rndc: '' failed: failure" rndc.out.1.test$n > /dev/null if [ $ret != 0 ]; then echo "I:failed"; fi status=`expr $status + $ret` +n=`expr $n + 1` +echo "I:check rndc -4 -6 ($n)" +ret=0 +$RNDCCMD -4 -6 status > rndc.out.1.test$n 2>&1 && ret=1 +grep "only one of -4 and -6 allowed" rndc.out.1.test$n > /dev/null || ret=1 +if [ $ret != 0 ]; then echo "I:failed"; fi +status=`expr $status + $ret` + +n=`expr $n + 1` +echo "I:check rndc -4 with an IPv6 server address ($n)" +ret=0 +$RNDCCMD -4 -s fd92:7065:b8e:ffff::2 status > rndc.out.1.test$n 2>&1 && ret=1 +grep "address family not supported" rndc.out.1.test$n > /dev/null || ret=1 +if [ $ret != 0 ]; then echo "I:failed"; fi +status=`expr $status + $ret` + echo "I:exit status: $status" [ $status -eq 0 ] || exit 1 diff --git a/doc/arm/notes.xml b/doc/arm/notes.xml index 4871a1b459..3ebdde35e4 100644 --- a/doc/arm/notes.xml +++ b/doc/arm/notes.xml @@ -181,6 +181,13 @@
New Features + + + nsupdate and rndc now accept + command line options -4 and -6 + which force using only IPv4 or only IPv6, respectively. [RT #45632] + + nsec3hash -r ("rdata order") takes arguments