mirror of
https://github.com/isc-projects/bind9.git
synced 2026-05-28 04:34:54 -04:00
[master] allow setting local addr in dns_client
3672. [func] Local address can now be specified when using dns_client API. [RT #34811]
This commit is contained in:
parent
c4004ada2a
commit
0618287859
6 changed files with 145 additions and 18 deletions
3
CHANGES
3
CHANGES
|
|
@ -1,3 +1,6 @@
|
|||
3672. [func] Local address can now be specified when using
|
||||
dns_client API. [RT #34811]
|
||||
|
||||
3671. [bug] Don't allow dnssec-importkey overwrite a existing
|
||||
non-imported private key.
|
||||
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ options {
|
|||
deny-answer-aliases { "example.org"; }
|
||||
except-from { "goodcname.example.net";
|
||||
"gooddname.example.net"; };
|
||||
allow-query {!10.53.0.8; any; };
|
||||
};
|
||||
|
||||
zone "." {
|
||||
|
|
|
|||
16
bin/tests/system/resolver/tests.sh
Normal file → Executable file
16
bin/tests/system/resolver/tests.sh
Normal file → Executable file
|
|
@ -39,6 +39,22 @@ echo "I:checking non-cachable NXDOMAIN response handling using dns_client"
|
|||
status=`expr $status + $ret`
|
||||
fi
|
||||
|
||||
if [ -x ${RESOLVE} ] ; then
|
||||
echo "I:checking that local bound address can be set (Can't query from a denied address)"
|
||||
ret=0
|
||||
${RESOLVE} -b 10.53.0.8 -p 5300 -t a -s 10.53.0.1 www.example.org 2> resolve.out || ret=1
|
||||
grep "resolution failed: failure" resolve.out > /dev/null || ret=1
|
||||
if [ $ret != 0 ]; then echo "I:failed"; fi
|
||||
status=`expr $status + $ret`
|
||||
|
||||
echo "I:checking that local bound address can be set (Can query from an allowed address)"
|
||||
ret=0
|
||||
${RESOLVE} -b 10.53.0.1 -p 5300 -t a -s 10.53.0.1 www.example.org > resolve.out || ret=1
|
||||
grep "www.example.org..*.192.0.2.1" resolve.out > /dev/null || ret=1
|
||||
if [ $ret != 0 ]; then echo "I:failed"; fi
|
||||
status=`expr $status + $ret`
|
||||
fi
|
||||
|
||||
echo "I:checking non-cachable NODATA response handling"
|
||||
ret=0
|
||||
$DIG +tcp nodata.example.net @10.53.0.1 a -p 5300 > dig.out || ret=1
|
||||
|
|
|
|||
|
|
@ -249,13 +249,14 @@ static isc_result_t send_update(updatectx_t *uctx);
|
|||
static isc_result_t
|
||||
getudpdispatch(int family, dns_dispatchmgr_t *dispatchmgr,
|
||||
isc_socketmgr_t *socketmgr, isc_taskmgr_t *taskmgr,
|
||||
isc_boolean_t is_shared, dns_dispatch_t **dispp)
|
||||
isc_boolean_t is_shared, dns_dispatch_t **dispp,
|
||||
isc_sockaddr_t *localaddr)
|
||||
{
|
||||
unsigned int attrs, attrmask;
|
||||
isc_sockaddr_t sa;
|
||||
dns_dispatch_t *disp;
|
||||
unsigned buffersize, maxbuffers, maxrequests, buckets, increment;
|
||||
isc_result_t result;
|
||||
isc_sockaddr_t anyaddr;
|
||||
|
||||
attrs = 0;
|
||||
attrs |= DNS_DISPATCHATTR_UDP;
|
||||
|
|
@ -275,7 +276,10 @@ getudpdispatch(int family, dns_dispatchmgr_t *dispatchmgr,
|
|||
attrmask |= DNS_DISPATCHATTR_IPV4;
|
||||
attrmask |= DNS_DISPATCHATTR_IPV6;
|
||||
|
||||
isc_sockaddr_anyofpf(&sa, family);
|
||||
if (localaddr == NULL) {
|
||||
localaddr = &anyaddr;
|
||||
isc_sockaddr_anyofpf(localaddr, family);
|
||||
}
|
||||
|
||||
buffersize = 4096;
|
||||
maxbuffers = is_shared ? 1000 : 8;
|
||||
|
|
@ -285,7 +289,7 @@ getudpdispatch(int family, dns_dispatchmgr_t *dispatchmgr,
|
|||
|
||||
disp = NULL;
|
||||
result = dns_dispatch_getudp(dispatchmgr, socketmgr,
|
||||
taskmgr, &sa,
|
||||
taskmgr, localaddr,
|
||||
buffersize, maxbuffers, maxrequests,
|
||||
buckets, increment,
|
||||
attrs, attrmask, &disp);
|
||||
|
|
@ -421,6 +425,19 @@ isc_result_t
|
|||
dns_client_createx(isc_mem_t *mctx, isc_appctx_t *actx, isc_taskmgr_t *taskmgr,
|
||||
isc_socketmgr_t *socketmgr, isc_timermgr_t *timermgr,
|
||||
unsigned int options, dns_client_t **clientp)
|
||||
{
|
||||
isc_result_t result;
|
||||
result = dns_client_createx2(mctx, actx, taskmgr, socketmgr, timermgr,
|
||||
options, clientp, NULL, NULL);
|
||||
return (result);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
dns_client_createx2(isc_mem_t *mctx, isc_appctx_t *actx,
|
||||
isc_taskmgr_t *taskmgr, isc_socketmgr_t *socketmgr,
|
||||
isc_timermgr_t *timermgr, unsigned int options,
|
||||
dns_client_t **clientp, isc_sockaddr_t *localaddr4,
|
||||
isc_sockaddr_t *localaddr6)
|
||||
{
|
||||
dns_client_t *client;
|
||||
isc_result_t result;
|
||||
|
|
@ -460,17 +477,27 @@ dns_client_createx(isc_mem_t *mctx, isc_appctx_t *actx, isc_taskmgr_t *taskmgr,
|
|||
goto cleanup;
|
||||
client->dispatchmgr = dispatchmgr;
|
||||
|
||||
/* TODO: whether to use dispatch v4 or v6 should be configurable */
|
||||
/*
|
||||
* If only one address family is specified, use it.
|
||||
* If neither family is specified, or if both are, use both.
|
||||
*/
|
||||
client->dispatchv4 = NULL;
|
||||
if (localaddr4 != NULL || localaddr6 == NULL) {
|
||||
result = getudpdispatch(AF_INET, dispatchmgr, socketmgr,
|
||||
taskmgr, ISC_TRUE,
|
||||
&dispatchv4, localaddr4);
|
||||
if (result == ISC_R_SUCCESS)
|
||||
client->dispatchv4 = dispatchv4;
|
||||
}
|
||||
|
||||
client->dispatchv6 = NULL;
|
||||
result = getudpdispatch(AF_INET, dispatchmgr, socketmgr,
|
||||
taskmgr, ISC_TRUE, &dispatchv4);
|
||||
if (result == ISC_R_SUCCESS)
|
||||
client->dispatchv4 = dispatchv4;
|
||||
result = getudpdispatch(AF_INET6, dispatchmgr, socketmgr,
|
||||
taskmgr, ISC_TRUE, &dispatchv6);
|
||||
if (result == ISC_R_SUCCESS)
|
||||
client->dispatchv6 = dispatchv6;
|
||||
if (localaddr6 != NULL || localaddr4 == NULL) {
|
||||
result = getudpdispatch(AF_INET6, dispatchmgr, socketmgr,
|
||||
taskmgr, ISC_TRUE,
|
||||
&dispatchv6, localaddr6);
|
||||
if (result == ISC_R_SUCCESS)
|
||||
client->dispatchv6 = dispatchv6;
|
||||
}
|
||||
|
||||
/* We need at least one of the dispatchers */
|
||||
if (dispatchv4 == NULL && dispatchv6 == NULL) {
|
||||
|
|
|
|||
|
|
@ -149,6 +149,13 @@ isc_result_t
|
|||
dns_client_createx(isc_mem_t *mctx, isc_appctx_t *actx, isc_taskmgr_t *taskmgr,
|
||||
isc_socketmgr_t *socketmgr, isc_timermgr_t *timermgr,
|
||||
unsigned int options, dns_client_t **clientp);
|
||||
|
||||
isc_result_t
|
||||
dns_client_createx2(isc_mem_t *mctx, isc_appctx_t *actx,
|
||||
isc_taskmgr_t *taskmgr, isc_socketmgr_t *socketmgr,
|
||||
isc_timermgr_t *timermgr, unsigned int options,
|
||||
dns_client_t **clientp,
|
||||
isc_sockaddr_t *localaddr4, isc_sockaddr_t *localaddr6);
|
||||
/*%<
|
||||
* Create a DNS client. These functions create a new client object with
|
||||
* minimal internal resources such as the default 'view' for the IN class and
|
||||
|
|
@ -161,6 +168,12 @@ dns_client_createx(isc_mem_t *mctx, isc_appctx_t *actx, isc_taskmgr_t *taskmgr,
|
|||
* dns_client_create() is expected to be used by an application that only needs
|
||||
* simple synchronous services or by a thread-based application.
|
||||
*
|
||||
* dns_client_createx2 takes two additional parameters, 'localaddr4' and
|
||||
* 'localaddr6', to specify the local address to use for each family. If
|
||||
* both are set to NULL, then wildcard addresses will be used for both
|
||||
* families. If only one is NULL, then the other address will be used
|
||||
* as the local address, and the other protocol family will not be used.
|
||||
*
|
||||
* If the DNS_CLIENTCREATEOPT_USECACHE flag is set in 'options',
|
||||
* dns_client_create(x) will create a cache database with the view.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -35,6 +35,10 @@
|
|||
#include <isc/mem.h>
|
||||
#include <isc/sockaddr.h>
|
||||
#include <isc/util.h>
|
||||
#include <isc/app.h>
|
||||
#include <isc/task.h>
|
||||
#include <isc/socket.h>
|
||||
#include <isc/timer.h>
|
||||
|
||||
#include <irs/resconf.h>
|
||||
#include <irs/netdb.h>
|
||||
|
|
@ -87,7 +91,7 @@ usage(void) {
|
|||
fprintf(stderr, "resolve [-t RRtype] "
|
||||
"[[-a algorithm] [-e] -k keyname -K keystring] "
|
||||
"[-S domain:serveraddr_for_domain ] [-s server_address]"
|
||||
"hostname\n");
|
||||
"[-b address[#port]] hostname\n");
|
||||
|
||||
exit(1);
|
||||
}
|
||||
|
|
@ -251,8 +255,16 @@ main(int argc, char *argv[]) {
|
|||
isc_boolean_t is_sep = ISC_FALSE;
|
||||
const char *port = "53";
|
||||
isc_mem_t *mctx = NULL;
|
||||
isc_appctx_t *actx = NULL;
|
||||
isc_taskmgr_t *taskmgr = NULL;
|
||||
isc_socketmgr_t *socketmgr = NULL;
|
||||
isc_timermgr_t *timermgr = NULL;
|
||||
struct in_addr in4;
|
||||
struct in6_addr in6;
|
||||
isc_sockaddr_t a4, a6;
|
||||
isc_sockaddr_t *addr4 = NULL, *addr6 = NULL;
|
||||
|
||||
while ((ch = getopt(argc, argv, "a:es:t:k:K:p:S:")) != -1) {
|
||||
while ((ch = getopt(argc, argv, "a:b:es:t:k:K:p:S:")) != -1) {
|
||||
switch (ch) {
|
||||
case 't':
|
||||
tr.base = optarg;
|
||||
|
|
@ -267,6 +279,29 @@ main(int argc, char *argv[]) {
|
|||
case 'a':
|
||||
algname = optarg;
|
||||
break;
|
||||
case 'b':
|
||||
if (inet_pton(AF_INET, optarg, &in4) == 1) {
|
||||
if (addr4 != NULL) {
|
||||
fprintf(stderr, "only one local "
|
||||
"address per family "
|
||||
"can be specified\n");
|
||||
exit(1);
|
||||
}
|
||||
isc_sockaddr_fromin(&a4, &in4, 0);
|
||||
addr4 = &a4;
|
||||
} else if (inet_pton(AF_INET6, optarg, &in6) == 1) {
|
||||
if (addr6 != NULL) {
|
||||
fprintf(stderr, "only one local "
|
||||
"address per family "
|
||||
"can be specified\n");
|
||||
exit(1);
|
||||
}
|
||||
isc_sockaddr_fromin6(&a6, &in6, 0);
|
||||
addr6 = &a6;
|
||||
} else {
|
||||
fprintf(stderr, "invalid address %s\n", optarg);
|
||||
exit(1);
|
||||
}
|
||||
case 'e':
|
||||
is_sep = ISC_TRUE;
|
||||
break;
|
||||
|
|
@ -334,10 +369,28 @@ main(int argc, char *argv[]) {
|
|||
exit(1);
|
||||
}
|
||||
|
||||
result = isc_appctx_create(mctx, &actx);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto cleanup;
|
||||
result = isc_app_ctxstart(actx);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto cleanup;
|
||||
result = isc_taskmgr_createinctx(mctx, actx, 1, 0, &taskmgr);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto cleanup;
|
||||
result = isc_socketmgr_createinctx(mctx, actx, &socketmgr);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto cleanup;
|
||||
result = isc_timermgr_createinctx(mctx, actx, &timermgr);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto cleanup;
|
||||
|
||||
clientopt = 0;
|
||||
result = dns_client_create(&client, clientopt);
|
||||
result = dns_client_createx2(mctx, actx, taskmgr, socketmgr, timermgr,
|
||||
clientopt, &client, addr4, addr6);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
fprintf(stderr, "dns_client_create failed: %d\n", result);
|
||||
fprintf(stderr, "dns_client_create failed: %d, %s\n", result,
|
||||
isc_result_totext(result));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
|
@ -356,10 +409,12 @@ main(int argc, char *argv[]) {
|
|||
result = dns_client_setservers(client, dns_rdataclass_in,
|
||||
NULL, nameservers);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
irs_resconf_destroy(&resconf);
|
||||
fprintf(stderr, "dns_client_setservers failed: %d\n",
|
||||
result);
|
||||
exit(1);
|
||||
}
|
||||
irs_resconf_destroy(&resconf);
|
||||
} else {
|
||||
addserver(client, server, port, NULL);
|
||||
}
|
||||
|
|
@ -390,7 +445,7 @@ main(int argc, char *argv[]) {
|
|||
fprintf(stderr, "failed to convert qname: %d\n", result);
|
||||
|
||||
/* Perform resolution */
|
||||
resopt = 0;
|
||||
resopt = DNS_CLIENTRESOPT_ALLOWRUN;
|
||||
if (keynamestr == NULL)
|
||||
resopt |= DNS_CLIENTRESOPT_NODNSSEC;
|
||||
ISC_LIST_INIT(namelist);
|
||||
|
|
@ -413,7 +468,19 @@ main(int argc, char *argv[]) {
|
|||
dns_client_freeresanswer(client, &namelist);
|
||||
|
||||
/* Cleanup */
|
||||
cleanup:
|
||||
dns_client_destroy(&client);
|
||||
|
||||
if (taskmgr != NULL)
|
||||
isc_taskmgr_destroy(&taskmgr);
|
||||
if (timermgr != NULL)
|
||||
isc_timermgr_destroy(&timermgr);
|
||||
if (socketmgr != NULL)
|
||||
isc_socketmgr_destroy(&socketmgr);
|
||||
if (actx != NULL)
|
||||
isc_appctx_destroy(&actx);
|
||||
isc_mem_detach(&mctx);
|
||||
|
||||
if (keynamestr != NULL)
|
||||
isc_mem_destroy(&keymctx);
|
||||
dns_lib_shutdown();
|
||||
|
|
|
|||
Loading…
Reference in a new issue