2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-29 13:38:26 +00:00

Support for lwresd on addresses other than 127.0.0.1.

This commit is contained in:
Brian Wellington 2000-10-05 22:27:54 +00:00
parent 2a34beb5ab
commit 8f80322fb5
8 changed files with 161 additions and 35 deletions

View File

@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: lwresd.c,v 1.16 2000/10/04 23:18:55 bwelling Exp $ */
/* $Id: lwresd.c,v 1.17 2000/10/05 22:27:46 bwelling Exp $ */
/*
* Main program for the Lightweight Resolver Daemon.
@ -219,11 +219,31 @@ ns_lwresd_parseresolvconf(isc_mem_t *mctx, dns_c_ctx_t **ctxp) {
if (result != ISC_R_SUCCESS)
goto cleanup;
localhost.s_addr = htonl(INADDR_LOOPBACK);
port = lwresd_g_listenport;
if (port == 0)
port = LWRES_UDP_PORT;
if (lwc->lwnext == 0) {
localhost.s_addr = htonl(INADDR_LOOPBACK);
isc_sockaddr_fromin(&sa, &localhost, port);
} else {
if (lwc->lwservers[0].family != LWRES_ADDRTYPE_V4 &&
lwc->lwservers[0].family != LWRES_ADDRTYPE_V6)
{
result = ISC_R_FAMILYNOSUPPORT;
goto cleanup;
}
if (lwc->lwservers[0].family == LWRES_ADDRTYPE_V4) {
struct in_addr ina;
memcpy(&ina.s_addr, lwc->lwservers[0].address, 4);
isc_sockaddr_fromin(&sa, &ina, port);
} else {
struct in6_addr ina6;
memcpy(&ina6.s6_addr, lwc->lwservers[0].address, 16);
isc_sockaddr_fromin6(&sa, &ina6, port);
}
}
result = dns_c_iplist_new(mctx, 1, &locallist);
if (result != ISC_R_SUCCESS)
@ -499,9 +519,6 @@ add_listener(isc_mem_t *mctx, ns_lwreslistener_t **listenerp,
NS_LOGMODULE_LWRESD, ISC_LOG_WARNING,
"couldn't add lwres channel %s: %s",
socktext, isc_result_totext(result));
dns_view_detach(&listener->view);
*listenerp = NULL;
}
}

View File

@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: context.c,v 1.29 2000/08/22 16:20:19 gson Exp $ */
/* $Id: context.c,v 1.30 2000/10/05 22:27:47 bwelling Exp $ */
#include <config.h>
@ -46,6 +46,7 @@
#endif
lwres_uint16_t lwres_udp_port = LWRES_UDP_PORT;
const char *lwres_resolv_conf = LWRES_RESOLV_CONF;
static void *
lwres_malloc(void *, size_t);
@ -65,6 +66,7 @@ lwres_context_create(lwres_context_t **contextp, void *arg,
lwres_context_t *ctx;
REQUIRE(contextp != NULL && *contextp == NULL);
UNUSED(flags);
/*
* If we were not given anything special to use, use our own
@ -92,9 +94,6 @@ lwres_context_create(lwres_context_t **contextp, void *arg,
ctx->timeout = LWRES_DEFAULT_TIMEOUT;
ctx->serial = time(NULL); /* XXXMLG or BEW */
if ((flags & LWRES_CONTEXT_SERVERMODE) == 0)
(void)context_connect(ctx); /* XXXMLG */
/*
* Init resolv.conf bits.
*/
@ -177,19 +176,49 @@ static lwres_result_t
context_connect(lwres_context_t *ctx) {
int s;
int ret;
struct sockaddr_in localhost;
struct sockaddr_in sin;
struct sockaddr_in6 sin6;
struct sockaddr *sa;
socklen_t salen;
int flags;
int domain;
memset(&localhost, 0, sizeof(localhost));
localhost.sin_family = AF_INET;
localhost.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
localhost.sin_port = htons(lwres_udp_port);
if (ctx->confdata.lwnext != 0) {
memcpy(&ctx->address, &ctx->confdata.lwservers[0],
sizeof(lwres_addr_t));
LWRES_LINK_INIT(&ctx->address, link);
} else {
char localhost[] = "127.0.0.1";
lwres_buffer_t b;
lwres_buffer_init(&b, localhost, sizeof(localhost));
lwres_buffer_add(&b, strlen(localhost));
(void)lwres_addr_parse(&b, &ctx->address);
}
s = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (ctx->address.family == LWRES_ADDRTYPE_V4) {
memcpy(&sin.sin_addr, ctx->address.address,
sizeof(sin.sin_addr));
sin.sin_port = htons(lwres_udp_port);
sin.sin_family = AF_INET;
sa = (struct sockaddr *)&sin;
salen = sizeof(sin);
domain = PF_INET;
} else if (ctx->address.family == LWRES_ADDRTYPE_V6) {
memcpy(&sin6.sin6_addr, ctx->address.address,
sizeof(sin6.sin6_addr));
sin6.sin6_port = htons(lwres_udp_port);
sin6.sin6_family = AF_INET6;
sa = (struct sockaddr *)&sin6;
salen = sizeof(sin6);
domain = PF_INET6;
} else
return (LWRES_R_IOERROR);
s = socket(domain, SOCK_DGRAM, IPPROTO_UDP);
if (s < 0)
return (LWRES_R_IOERROR);
ret = connect(s, (struct sockaddr *)&localhost, sizeof(localhost));
ret = connect(s, sa, salen);
if (ret != 0) {
close(s);
return (LWRES_R_IOERROR);
@ -215,6 +244,14 @@ lwres_result_t
lwres_context_send(lwres_context_t *ctx,
void *sendbase, int sendlen) {
int ret;
lwres_result_t lwresult;
if (ctx->sock == -1) {
lwresult = context_connect(ctx);
if (lwresult != LWRES_R_SUCCESS)
return (lwresult);
}
ret = sendto(ctx->sock, sendbase, sendlen, 0, NULL, 0);
if (ret < 0)
return (LWRES_R_IOERROR);
@ -231,17 +268,25 @@ lwres_context_recv(lwres_context_t *ctx,
{
LWRES_SOCKADDR_LEN_T fromlen;
struct sockaddr_in sin;
struct sockaddr_in6 sin6;
struct sockaddr *sa;
int ret;
if (ctx->address.family == LWRES_ADDRTYPE_V4) {
sa = (struct sockaddr *)&sin;
fromlen = sizeof(sin);
} else {
sa = (struct sockaddr *)&sin6;
fromlen = sizeof(sin6);
}
/*
* The address of fromlen is cast to void * to shut up compiler
* warnings, namely on systems that have the sixth parameter
* prototyped as a signed int when LWRES_SOCKADDR_LEN_T is
* defined as unsigned.
*/
ret = recvfrom(ctx->sock, recvbase, recvlen, 0,
(struct sockaddr *)&sin, (void *)&fromlen);
ret = recvfrom(ctx->sock, recvbase, recvlen, 0, sa, (void *)&fromlen);
if (ret < 0)
return (LWRES_R_IOERROR);
@ -251,9 +296,19 @@ lwres_context_recv(lwres_context_t *ctx,
* wait for another packet. This can happen if an old result
* comes in, or if someone is sending us random stuff.
*/
if (sin.sin_addr.s_addr != htonl(INADDR_LOOPBACK)
if (ctx->address.family == LWRES_ADDRTYPE_V4) {
if (fromlen != sizeof(sin)
|| memcmp(&sin.sin_addr, ctx->address.address,
sizeof(sin.sin_addr)) != 0
|| sin.sin_port != htons(lwres_udp_port))
return (LWRES_R_RETRY);
} else {
if (fromlen != sizeof(sin6)
|| memcmp(&sin6.sin6_addr, ctx->address.address,
sizeof(sin6.sin6_addr)) != 0
|| sin6.sin6_port != htons(lwres_udp_port))
return (LWRES_R_RETRY);
}
if (recvd_len != NULL)
*recvd_len = ret;

View File

@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: context_p.h,v 1.10 2000/08/01 01:32:11 tale Exp $ */
/* $Id: context_p.h,v 1.11 2000/10/05 22:27:49 bwelling Exp $ */
#ifndef LWRES_CONTEXT_P_H
#define LWRES_CONTEXT_P_H 1
@ -41,6 +41,7 @@ struct lwres_context {
* For network I/O.
*/
int sock; /* socket to send on */
lwres_addr_t address; /* address to send to */
/*
* Function pointers for allocating memory.

View File

@ -19,7 +19,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: getaddrinfo.c,v 1.32 2000/09/19 21:21:59 bwelling Exp $ */
/* $Id: getaddrinfo.c,v 1.33 2000/10/05 22:27:50 bwelling Exp $ */
#include <config.h>
@ -463,7 +463,7 @@ add_ipv4(const char *hostname, int flags, struct addrinfo **aip,
lwres = lwres_context_create(&lwrctx, NULL, NULL, NULL, 0);
if (lwres != 0)
ERR(EAI_FAIL);
(void) lwres_conf_parse(lwrctx, "/etc/resolv.conf");
(void) lwres_conf_parse(lwrctx, lwres_resolv_conf);
if (hostname == NULL && (flags & AI_PASSIVE) == 0) {
ai = ai_clone(*aip, AF_INET);
if (ai == NULL) {
@ -523,7 +523,7 @@ add_ipv6(const char *hostname, int flags, struct addrinfo **aip,
lwres = lwres_context_create(&lwrctx, NULL, NULL, NULL, 0);
if (lwres != 0)
ERR(EAI_FAIL);
(void) lwres_conf_parse(lwrctx, "/etc/resolv.conf");
(void) lwres_conf_parse(lwrctx, lwres_resolv_conf);
if (hostname == NULL && (flags & AI_PASSIVE) == 0) {
ai = ai_clone(*aip, AF_INET6);

View File

@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: getipnode.c,v 1.25 2000/08/01 01:32:15 tale Exp $ */
/* $Id: getipnode.c,v 1.26 2000/10/05 22:27:51 bwelling Exp $ */
#include <config.h>
@ -166,7 +166,7 @@ lwres_getipnodebyname(const char *name, int af, int flags, int *error_num) {
*error_num = NO_RECOVERY;
goto cleanup;
}
(void) lwres_conf_parse(lwrctx, "/etc/resolv.conf");
(void) lwres_conf_parse(lwrctx, lwres_resolv_conf);
tmp_err = NO_RECOVERY;
if (have_v6 && af == AF_INET6) {
@ -279,7 +279,7 @@ lwres_getipnodebyaddr(const void *src, size_t len, int af, int *error_num) {
cp += 12;
n = lwres_context_create(&lwrctx, NULL, NULL, NULL, 0);
if (n == LWRES_R_SUCCESS)
(void) lwres_conf_parse(lwrctx, "/etc/resolv.conf");
(void) lwres_conf_parse(lwrctx, lwres_resolv_conf);
if (n == LWRES_R_SUCCESS)
n = lwres_getnamebyaddr(lwrctx, LWRES_ADDRTYPE_V4,
INADDRSZ, cp, &by);
@ -323,7 +323,7 @@ lwres_getipnodebyaddr(const void *src, size_t len, int af, int *error_num) {
n = lwres_context_create(&lwrctx, NULL, NULL, NULL, 0);
if (n == LWRES_R_SUCCESS)
(void) lwres_conf_parse(lwrctx, "/etc/resolv.conf");
(void) lwres_conf_parse(lwrctx, lwres_resolv_conf);
if (n == LWRES_R_SUCCESS)
n = lwres_getnamebyaddr(lwrctx, LWRES_ADDRTYPE_V6, IN6ADDRSZ,
src, &by);

View File

@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: getnameinfo.c,v 1.25 2000/08/01 01:32:16 tale Exp $ */
/* $Id: getnameinfo.c,v 1.26 2000/10/05 22:27:52 bwelling Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@ -255,7 +255,7 @@ lwres_getnameinfo(const struct sockaddr *sa, size_t salen, char *host,
n = lwres_context_create(&lwrctx, NULL, NULL, NULL, 0);
if (n == 0)
(void) lwres_conf_parse(lwrctx, "/etc/resolv.conf");
(void) lwres_conf_parse(lwrctx, lwres_resolv_conf);
if (n == 0)
n = lwres_getnamebyaddr(lwrctx, lwf, afd->a_addrlen,

View File

@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: lwres.h,v 1.43 2000/08/01 01:32:41 tale Exp $ */
/* $Id: lwres.h,v 1.44 2000/10/05 22:27:54 bwelling Exp $ */
#ifndef LWRES_LWRES_H
#define LWRES_LWRES_H 1
@ -80,6 +80,7 @@
#define LWRES_UDP_PORT 921 /* XXXMLG */
#define LWRES_RECVLENGTH 4096 /* XXXMLG */
#define LWRES_ADDR_MAXLEN 16 /* changing this breaks ABI */
#define LWRES_RESOLV_CONF "/etc/resolv.conf"
/*
* XXXMLG
@ -194,6 +195,7 @@ typedef struct {
*/
#define LWRES_CONFMAXNAMESERVERS 3 /* max 3 "nameserver" entries */
#define LWRES_CONFMAXLWSERVERS 1 /* max 1 "lwserver" entry */
#define LWRES_CONFMAXSEARCH 8 /* max 8 domains in "search" entry */
#define LWRES_CONFMAXLINELEN 256 /* max size of a line */
#define LWRES_CONFMAXSORTLIST 10
@ -202,6 +204,9 @@ typedef struct {
lwres_addr_t nameservers[LWRES_CONFMAXNAMESERVERS];
lwres_uint8_t nsnext; /* index for next free slot */
lwres_addr_t lwservers[LWRES_CONFMAXLWSERVERS];
lwres_uint8_t lwnext; /* index for next free slot */
char *domainname;
char *search[LWRES_CONFMAXSEARCH];
@ -232,6 +237,8 @@ LWRES_LANG_BEGINDECLS
*/
extern lwres_uint16_t lwres_udp_port;
extern const char *lwres_resolv_conf;
lwres_result_t
lwres_gabnrequest_render(lwres_context_t *ctx, lwres_gabnrequest_t *req,
lwres_lwpacket_t *pkt, lwres_buffer_t *b);

View File

@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: lwconfig.c,v 1.24 2000/08/01 01:32:20 tale Exp $ */
/* $Id: lwconfig.c,v 1.25 2000/10/05 22:27:53 bwelling Exp $ */
/***
*** Module for parsing resolv.conf files.
@ -76,6 +76,9 @@ extern const char *lwres_net_ntop(int af, const void *src, char *dst,
static lwres_result_t
lwres_conf_parsenameserver(lwres_context_t *ctx, FILE *fp);
static lwres_result_t
lwres_conf_parselwserver(lwres_context_t *ctx, FILE *fp);
static lwres_result_t
lwres_conf_parsedomain(lwres_context_t *ctx, FILE *fp);
@ -219,6 +222,7 @@ lwres_conf_init(lwres_context_t *ctx) {
confdata = &ctx->confdata;
confdata->nsnext = 0;
confdata->lwnext = 0;
confdata->domainname = NULL;
confdata->searchnxt = 0;
confdata->sortlistnxt = 0;
@ -269,6 +273,7 @@ lwres_conf_clear(lwres_context_t *ctx) {
}
confdata->nsnext = 0;
confdata->lwnext = 0;
confdata->domainname = NULL;
confdata->searchnxt = 0;
confdata->sortlistnxt = 0;
@ -305,6 +310,34 @@ lwres_conf_parsenameserver(lwres_context_t *ctx, FILE *fp) {
return (LWRES_R_SUCCESS);
}
static lwres_result_t
lwres_conf_parselwserver(lwres_context_t *ctx, FILE *fp) {
char word[LWRES_CONFMAXLINELEN];
int res;
lwres_conf_t *confdata;
confdata = &ctx->confdata;
if (confdata->lwnext == LWRES_CONFMAXLWSERVERS)
return (LWRES_R_SUCCESS);
res = getword(fp, word, sizeof(word));
if (strlen(word) == 0)
return (LWRES_R_FAILURE); /* Nothing on line. */
else if (res == ' ' || res == '\t')
res = eatwhite(fp);
if (res != EOF && res != '\n')
return (LWRES_R_FAILURE); /* Extra junk on line. */
res = lwres_create_addr(word,
&confdata->lwservers[confdata->lwnext++]);
if (res != LWRES_R_SUCCESS)
return (res);
return (LWRES_R_SUCCESS);
}
static lwres_result_t
lwres_conf_parsedomain(lwres_context_t *ctx, FILE *fp) {
char word[LWRES_CONFMAXLINELEN];
@ -544,6 +577,8 @@ lwres_conf_parse(lwres_context_t *ctx, const char *filename) {
rval = LWRES_R_SUCCESS;
else if (strcmp(word, "nameserver") == 0)
rval = lwres_conf_parsenameserver(ctx, fp);
else if (strcmp(word, "lwserver") == 0)
rval = lwres_conf_parselwserver(ctx, fp);
else if (strcmp(word, "domain") == 0)
rval = lwres_conf_parsedomain(ctx, fp);
else if (strcmp(word, "search") == 0)
@ -594,6 +629,17 @@ lwres_conf_print(lwres_context_t *ctx, FILE *fp) {
fprintf(fp, "nameserver %s\n", tmp);
}
for (i = 0 ; i < confdata->lwnext ; i++) {
af = lwresaddr2af(confdata->lwservers[i].family);
p = lwres_net_ntop(af, confdata->lwservers[i].address,
tmp, sizeof(tmp));
if (p != tmp)
return (LWRES_R_FAILURE);
fprintf(fp, "lwserver %s\n", tmp);
}
if (confdata->domainname != NULL) {
fprintf(fp, "domain %s\n", confdata->domainname);
} else if (confdata->searchnxt > 0) {