grep "records in zone (4) exceeds max-records (3)" ns3/named.run > /dev/null || ret=1
[ $ret = 0 ] || { echo I:failed; status=1; }
+#
+# Add client library tests here
+#
+n=`expr $n + 1`
+echo "I:check that dns_client_update handles prerequisite NXDOMAIN failure ($n)"
+$SAMPLEUPDATE -P 5300 -a 10.53.0.1 -a 10.53.0.2 -p "nxdomain exists.sample" \
+ add "nxdomain-exists.sample 0 in a 1.2.3.4" > update.out.test$n 2>&1
+$SAMPLEUPDATE -P 5300 -a 10.53.0.2 -p "nxdomain exists.sample" \
+ add "check-nxdomain-exists.sample 0 in a 1.2.3.4" > update.out.check$n 2>&1
+$DIG +tcp @10.53.0.1 -p 5300 a nxdomain-exists.sample > dig.out.ns1.test$n
+$DIG +tcp @10.53.0.2 -p 5300 a nxdomain-exists.sample > dig.out.ns2.test$n
+$DIG +tcp @10.53.0.2 -p 5300 a check-nxdomain-exists.sample > check.out.ns2.test$n
+grep "update failed: YXDOMAIN" update.out.test$n > /dev/null || ret=1
+grep "update succeeded" update.out.check$n > /dev/null || ret=1
+grep "status: NXDOMAIN" dig.out.ns1.test$n > /dev/null || ret=1
+grep "status: NXDOMAIN" dig.out.ns2.test$n > /dev/null || ret=1
+grep "status: NOERROR" check.out.ns2.test$n > /dev/null || ret=1
+[ $ret = 0 ] || { echo I:failed; status=1; }
+
+n=`expr $n + 1`
+echo "I:check that dns_client_update handles prerequisite YXDOMAIN failure ($n)"
+$SAMPLEUPDATE -P 5300 -a 10.53.0.1 -a 10.53.0.2 -p "yxdomain nxdomain.sample" \
+ add "yxdomain-nxdomain.sample 0 in a 1.2.3.4" > update.out.test$n 2>&1
+$SAMPLEUPDATE -P 5300 -a 10.53.0.2 -p "yxdomain nxdomain.sample" \
+ add "check-yxdomain-nxdomain.sample 0 in a 1.2.3.4" > update.out.check$n 2>&1
+$DIG +tcp @10.53.0.1 -p 5300 a nxdomain-exists.sample > dig.out.ns1.test$n
+$DIG +tcp @10.53.0.2 -p 5300 a nxdomain-exists.sample > dig.out.ns2.test$n
+$DIG +tcp @10.53.0.2 -p 5300 a check-nxdomain-exists.sample > check.out.ns2.test$n
+grep "update failed: NXDOMAIN" update.out.test$n > /dev/null || ret=1
+grep "update succeeded" update.out.check$n > /dev/null || ret=1
+grep "status: NXDOMAIN" dig.out.ns1.test$n > /dev/null || ret=1
+grep "status: NXDOMAIN" dig.out.ns2.test$n > /dev/null || ret=1
+grep "status: NOERROR" check.out.ns2.test$n > /dev/null || ret=1
+[ $ret = 0 ] || { echo I:failed; status=1; }
+
+n=`expr $n + 1`
+echo "I:check that dns_client_update handles prerequisite NXRRSET failure ($n)"
+$SAMPLEUPDATE -P 5300 -a 10.53.0.1 -a 10.53.0.2 -p "nxrrset exists.sample TXT This RRset exists." \
+ add "nxrrset-exists.sample 0 in a 1.2.3.4" > update.out.test$n 2>&1
+$SAMPLEUPDATE -P 5300 -a 10.53.0.2 -p "nxrrset exists.sample TXT This RRset exists." \
+ add "check-nxrrset-exists.sample 0 in a 1.2.3.4" > update.out.check$n 2>&1
+$DIG +tcp @10.53.0.1 -p 5300 a nxrrset-exists.sample > dig.out.ns1.test$n
+$DIG +tcp @10.53.0.2 -p 5300 a nxrrset-exists.sample > dig.out.ns2.test$n
+$DIG +tcp @10.53.0.2 -p 5300 a check-nxrrset-exists.sample > check.out.ns2.test$n
+grep "update failed: YXRRSET" update.out.test$n > /dev/null || ret=1
+grep "update succeeded" update.out.check$n > /dev/null || ret=1
+grep "status: NXDOMAIN" dig.out.ns1.test$n > /dev/null || ret=1
+grep "status: NXDOMAIN" dig.out.ns2.test$n > /dev/null || ret=1
+grep "status: NOERROR" check.out.ns2.test$n > /dev/null || ret=1
+[ $ret = 0 ] || { echo I:failed; status=1; }
+
+n=`expr $n + 1`
+echo "I:check that dns_client_update handles prerequisite YXRRSET failure ($n)"
+$SAMPLEUPDATE -P 5300 -a 10.53.0.1 -a 10.53.0.2 -p "yxrrset no-txt.sample TXT" \
+ add "yxrrset-nxrrset.sample 0 in a 1.2.3.4" > update.out.test$n 2>&1
+$SAMPLEUPDATE -P 5300 -a 10.53.0.2 -p "yxrrset no-txt.sample TXT" \
+ add "check-yxrrset-nxrrset.sample 0 in a 1.2.3.4" > update.out.check$n 2>&1
+$DIG +tcp @10.53.0.1 -p 5300 a yxrrset-nxrrset.sample > dig.out.ns1.test$n
+$DIG +tcp @10.53.0.2 -p 5300 a yxrrset-nxrrset.sample > dig.out.ns2.test$n
+$DIG +tcp @10.53.0.2 -p 5300 a check-yxrrset-nxrrset.sample > check.out.ns2.test$n
+grep "update failed: NXRRSET" update.out.test$n > /dev/null || ret=1
+grep "update succeeded" update.out.check$n > /dev/null || ret=1
+grep "status: NXDOMAIN" dig.out.ns1.test$n > /dev/null || ret=1
+grep "status: NXDOMAIN" dig.out.ns2.test$n > /dev/null || ret=1
+grep "status: NOERROR" check.out.ns2.test$n > /dev/null || ret=1
+[ $ret = 0 ] || { echo I:failed; status=1; }
+
+#
+# End client library tests here
+#
+
echo "I:exit status: $status"
[ $status -eq 0 ] || exit 1
static isc_bufferlist_t usedbuffers;
static ISC_LIST(dns_rdatalist_t) usedrdatalists;
+static const char *port = "53";
+
static void setup_tsec(char *keyfile, isc_mem_t *mctx);
static void update_addordelete(isc_mem_t *mctx, char *cmdline,
isc_boolean_t isdelete, dns_name_t *name);
exit(1);
}
+static isc_boolean_t
+addserver(const char *server, isc_sockaddrlist_t *list,
+ isc_sockaddr_t *sockaddr)
+{
+ struct addrinfo hints, *res;
+ int gaierror;
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_DGRAM;
+ hints.ai_protocol = IPPROTO_UDP;
+#ifdef AI_NUMERICHOST
+ hints.ai_flags |= AI_NUMERICHOST;
+#endif
+#ifdef AI_NUMERICSERV
+ hints.ai_flags |= AI_NUMERICSERV;
+#endif
+ gaierror = getaddrinfo(server, port, &hints, &res);
+ if (gaierror != 0) {
+ fprintf(stderr, "getaddrinfo(%s) failed: %s\n",
+ server, gai_strerror(gaierror));
+ return (ISC_FALSE);
+ }
+ INSIST(res->ai_addrlen <= sizeof(sockaddr->type));
+ memmove(&sockaddr->type, res->ai_addr, res->ai_addrlen);
+ freeaddrinfo(res);
+ sockaddr->length = (unsigned int)res->ai_addrlen;
+ ISC_LINK_INIT(sockaddr, link);
+ ISC_LIST_APPEND(*list, sockaddr, link);
+ return (ISC_TRUE);
+}
+
int
main(int argc, char *argv[]) {
int ch;
- struct addrinfo hints, *res;
- int gaierror;
dns_client_t *client = NULL;
char *zonenamestr = NULL;
char *keyfilename = NULL;
char *prereqstr = NULL;
- isc_sockaddrlist_t auth_servers;
- char *auth_server = NULL;
- char *recursive_server = NULL;
- isc_sockaddr_t sa_auth, sa_recursive;
+ isc_sockaddr_t sa_auth[10], sa_recursive[10];
+ unsigned int nsa_auth = 0, nsa_recursive = 0;
isc_sockaddrlist_t rec_servers;
+ isc_sockaddrlist_t auth_servers;
isc_result_t result;
isc_boolean_t isdelete;
isc_buffer_t b, *buf;
dns_namelist_t updatelist, prereqlist, *prereqlistp = NULL;
isc_mem_t *umctx = NULL;
- while ((ch = isc_commandline_parse(argc, argv, "a:k:p:r:z:")) != EOF) {
+ ISC_LIST_INIT(auth_servers);
+ ISC_LIST_INIT(rec_servers);
+
+ while ((ch = isc_commandline_parse(argc, argv, "a:k:p:P:r:z:")) != EOF) {
switch (ch) {
case 'k':
keyfilename = isc_commandline_argument;
break;
case 'a':
- auth_server = isc_commandline_argument;
+ if (nsa_auth < sizeof(sa_auth)/sizeof(*sa_auth) &&
+ addserver(isc_commandline_argument, &auth_servers,
+ &sa_auth[nsa_auth]))
+ nsa_auth++;
break;
case 'p':
prereqstr = isc_commandline_argument;
break;
+ case 'P':
+ port = isc_commandline_argument;
+ break;
case 'r':
- recursive_server = isc_commandline_argument;
+ if (nsa_recursive <
+ sizeof(sa_recursive)/sizeof(*sa_recursive) &&
+ addserver(isc_commandline_argument, &rec_servers,
+ &sa_recursive[nsa_recursive]))
+ nsa_recursive++;
break;
case 'z':
zonenamestr = isc_commandline_argument;
exit(1);
}
- if (auth_server == NULL && recursive_server == NULL) {
- fprintf(stderr, "authoritative or recursive server "
+ if (ISC_LIST_HEAD(auth_servers) == NULL &&
+ ISC_LIST_HEAD(rec_servers) == NULL) {
+ fprintf(stderr, "authoritative or recursive servers "
"must be specified\n");
usage();
}
ISC_LIST_INIT(usedbuffers);
ISC_LIST_INIT(usedrdatalists);
ISC_LIST_INIT(prereqlist);
- ISC_LIST_INIT(auth_servers);
isc_lib_register();
result = dns_lib_init();
if (result != ISC_R_SUCCESS) {
exit(1);
}
- /* Set the authoritative server */
- if (auth_server != NULL) {
- memset(&hints, 0, sizeof(hints));
- hints.ai_family = AF_UNSPEC;
- hints.ai_socktype = SOCK_DGRAM;
- hints.ai_protocol = IPPROTO_UDP;
-#ifdef AI_NUMERICHOST
- hints.ai_flags = AI_NUMERICHOST;
-#endif
- gaierror = getaddrinfo(auth_server, "53", &hints, &res);
- if (gaierror != 0) {
- fprintf(stderr, "getaddrinfo failed: %s\n",
- gai_strerror(gaierror));
- exit(1);
- }
- INSIST(res->ai_addrlen <= sizeof(sa_auth.type));
- memmove(&sa_auth.type, res->ai_addr, res->ai_addrlen);
- freeaddrinfo(res);
- sa_auth.length = (unsigned int)res->ai_addrlen;
- ISC_LINK_INIT(&sa_auth, link);
-
- ISC_LIST_APPEND(auth_servers, &sa_auth, link);
- }
-
- /* Set the recursive server */
- if (recursive_server != NULL) {
- memset(&hints, 0, sizeof(hints));
- hints.ai_family = AF_UNSPEC;
- hints.ai_socktype = SOCK_DGRAM;
- hints.ai_protocol = IPPROTO_UDP;
-#ifdef AI_NUMERICHOST
- hints.ai_flags = AI_NUMERICHOST;
-#endif
- gaierror = getaddrinfo(recursive_server, "53", &hints, &res);
- if (gaierror != 0) {
- fprintf(stderr, "getaddrinfo failed: %s\n",
- gai_strerror(gaierror));
- exit(1);
- }
- INSIST(res->ai_addrlen <= sizeof(sa_recursive.type));
- memmove(&sa_recursive.type, res->ai_addr, res->ai_addrlen);
- freeaddrinfo(res);
- sa_recursive.length = (unsigned int)res->ai_addrlen;
- ISC_LINK_INIT(&sa_recursive, link);
- ISC_LIST_INIT(rec_servers);
- ISC_LIST_APPEND(rec_servers, &sa_recursive, link);
- result = dns_client_setservers(client, dns_rdataclass_in,
- NULL, &rec_servers);
- if (result != ISC_R_SUCCESS) {
- fprintf(stderr, "set server failed: %d\n", result);
- exit(1);
- }
- }
-
/* Construct zone name */
zname = NULL;
if (zonenamestr != NULL) {
result = dns_client_update(client,
default_rdataclass, /* XXX: fixed */
zname, prereqlistp, &updatelist,
- (auth_server == NULL) ? NULL :
- &auth_servers, tsec, 0);
+ (ISC_LIST_HEAD(auth_servers) == NULL) ?
+ NULL : &auth_servers, tsec, 0);
if (result != ISC_R_SUCCESS) {
fprintf(stderr,
"update failed: %s\n", dns_result_totext(result));