2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-30 22:15:20 +00:00

lwres get-addr-by-name returns a linked list, not an array, of names. This

was needed to make adding the sortlist code, which will be checked in
in a few minutes.
This commit is contained in:
Michael Graff
2000-03-10 23:11:36 +00:00
parent 2311073ce0
commit d736db6dc5
15 changed files with 423 additions and 136 deletions

View File

@@ -351,6 +351,7 @@ client_init_aliases(client_t *client)
client->addrs[i].family = 0;
client->addrs[i].length = 0;
client->addrs[i].address = NULL;
LWRES_LINK_INIT(&client->addrs[i], link);
}
}
@@ -368,7 +369,7 @@ client_init_gabn(client_t *client)
client->gabn.aliases = client->aliases;
client->gabn.realnamelen = 0;
client->gabn.aliaslen = client->aliaslen;
client->gabn.addrs = client->addrs;
LWRES_LIST_INIT(client->gabn.addrs);
client->gabn.base = NULL;
client->gabn.baselen = 0;

View File

@@ -110,6 +110,8 @@ setup_addresses(client_t *client, dns_adbfind_t *find, unsigned int at)
addr->address, addr->family, addr->length);
client->gabn.naddrs++;
REQUIRE(!LWRES_LINK_LINKED(addr, link));
LWRES_LIST_APPEND(client->gabn.addrs, addr, link);
next:
ai = ISC_LIST_NEXT(ai, publink);
@@ -151,6 +153,7 @@ generate_reply(client_t *client)
* Run through the finds we have and wire them up to the gabn
* structure.
*/
LWRES_LIST_INIT(client->gabn.addrs);
if (client->v4find != NULL)
setup_addresses(client, client->v4find, DNS_ADBFIND_INET);
if (client->v6find != NULL)

View File

@@ -158,6 +158,7 @@ static void
test_gabn(char *target)
{
lwres_gabnresponse_t *res;
lwres_addr_t *addr;
int ret;
unsigned int i;
char outbuf[64];
@@ -180,15 +181,19 @@ test_gabn(char *target)
for (i = 0 ; i < res->naliases ; i++)
printf("\t(%u, %s)\n", res->aliaslen[i], res->aliases[i]);
printf("%u addresses:\n", res->naddrs);
addr = LWRES_LIST_HEAD(res->addrs);
for (i = 0 ; i < res->naddrs ; i++) {
if (res->addrs[i].family == LWRES_ADDRTYPE_V4)
(void)inet_ntop(AF_INET, res->addrs[i].address,
INSIST(addr != NULL);
if (addr->family == LWRES_ADDRTYPE_V4)
(void)inet_ntop(AF_INET, addr->address,
outbuf, sizeof(outbuf));
else
(void)inet_ntop(AF_INET6, res->addrs[i].address,
(void)inet_ntop(AF_INET6, addr->address,
outbuf, sizeof(outbuf));
printf("\tAddr len %u family %08x %s\n",
res->addrs[i].length, res->addrs[i].family, outbuf);
addr->length, addr->family, outbuf);
addr = LWRES_LIST_NEXT(addr, link);
}
lwres_gabnresponse_free(ctx, &res);

View File

@@ -77,6 +77,11 @@ lwres_context_create(lwres_context_t **contextp, void *arg,
(void)context_connect(ctx); /* XXXMLG */
/*
* Init resolv.conf bits.
*/
lwres_conf_init(ctx);
*contextp = ctx;
return (LWRES_R_SUCCESS);
}

View File

@@ -46,6 +46,11 @@ struct lwres_context {
lwres_malloc_t malloc;
lwres_free_t free;
void *arg;
/*
* resolv.conf-like data
*/
lwres_conf_t confdata;
};
#endif /* LWRES_CONTEXT_P_H */

View File

@@ -3,7 +3,7 @@
* The Berkeley Software Design Inc. software License Agreement specifies
* the terms and conditions for redistribution.
*
* BSDI $Id: getaddrinfo.c,v 1.13 2000/02/04 06:17:22 halley Exp $
* BSDI $Id: getaddrinfo.c,v 1.14 2000/03/10 23:11:27 explorer Exp $
*/
@@ -353,11 +353,12 @@ add_ipv4(const char *hostname, int flags, struct addrinfo **aip,
struct addrinfo *ai;
lwres_context_t *lwrctx = NULL;
lwres_gabnresponse_t *by = NULL;
int i;
lwres_addr_t *addr;
lwres_result_t lwres;
int result = 0;
i = lwres_context_create(&lwrctx, NULL, NULL, NULL);
if (i != 0)
lwres = lwres_context_create(&lwrctx, NULL, NULL, NULL);
if (lwres != 0)
ERR(EAI_FAIL);
if (hostname == NULL && (flags & AI_PASSIVE) == 0) {
if ((ai = ai_clone(*aip, AF_INET)) == NULL) {
@@ -371,7 +372,8 @@ add_ipv4(const char *hostname, int flags, struct addrinfo **aip,
memcpy(&SIN(ai->ai_addr)->sin_addr, v4_loop, 4);
} else if (lwres_getaddrsbyname(lwrctx, hostname,
LWRES_ADDRTYPE_V4, &by) == 0) {
for (i = 0; i < by->naddrs; i++) {
addr = LWRES_LIST_HEAD(by->addrs);
while (addr != NULL) {
ai = ai_clone(*aip, AF_INET);
if (ai == NULL) {
lwres_freeaddrinfo(*aip);
@@ -381,9 +383,10 @@ add_ipv4(const char *hostname, int flags, struct addrinfo **aip,
ai->ai_socktype = socktype;
SIN(ai->ai_addr)->sin_port = port;
memcpy(&SIN(ai->ai_addr)->sin_addr,
by->addrs[i].address, 4);
addr->address, 4);
if (flags & AI_CANONNAME)
ai->ai_canonname = strdup(by->realname);
addr = LWRES_LIST_NEXT(addr, link);
}
}
cleanup:
@@ -403,12 +406,14 @@ add_ipv6(const char *hostname, int flags, struct addrinfo **aip,
struct addrinfo *ai;
lwres_context_t *lwrctx = NULL;
lwres_gabnresponse_t *by = NULL;
int i;
lwres_addr_t *addr;
lwres_result_t lwres;
int result = 0;
i = lwres_context_create(&lwrctx, NULL, NULL, NULL);
if (i != 0)
lwres = lwres_context_create(&lwrctx, NULL, NULL, NULL);
if (lwres != 0)
ERR(EAI_FAIL);
if (hostname == NULL && (flags & AI_PASSIVE) == 0) {
if ((ai = ai_clone(*aip, AF_INET6)) == NULL) {
lwres_freeaddrinfo(*aip);
@@ -421,7 +426,8 @@ add_ipv6(const char *hostname, int flags, struct addrinfo **aip,
memcpy(&SIN6(ai->ai_addr)->sin6_addr, v6_loop, 16);
} else if (lwres_getaddrsbyname(lwrctx, hostname,
LWRES_ADDRTYPE_V6, &by) == 0) {
for (i = 0; i < by->naddrs; i++) {
addr = LWRES_LIST_HEAD(by->addrs);
while (addr != NULL) {
if ((ai = ai_clone(*aip, AF_INET6)) == NULL) {
lwres_freeaddrinfo(*aip);
ERR(EAI_MEMORY);
@@ -430,9 +436,10 @@ add_ipv6(const char *hostname, int flags, struct addrinfo **aip,
ai->ai_socktype = socktype;
SIN6(ai->ai_addr)->sin6_port = port;
memcpy(&SIN6(ai->ai_addr)->sin6_addr,
by->addrs[i].address, 16);
addr->address, 16);
if (flags & AI_CANONNAME)
ai->ai_canonname = strdup(by->realname);
addr = LWRES_LIST_NEXT(addr, link);
}
}
cleanup:

View File

@@ -680,9 +680,11 @@ hostfromaddr(lwres_gnbaresponse_t *addr, int af, const void *src) {
}
static struct hostent *
hostfromname(lwres_gabnresponse_t *name, int af) {
hostfromname(lwres_gabnresponse_t *name, int af)
{
struct hostent *he;
int i;
lwres_addr_t *addr;
he = malloc(sizeof *he);
if (he == NULL)
@@ -718,11 +720,15 @@ hostfromname(lwres_gabnresponse_t *name, int af) {
/* copy addresses */
he->h_addr_list = malloc(sizeof(char *) * (name->naddrs + 1));
for (i = 0 ; i < name->naddrs; i++) {
addr = LWRES_LIST_HEAD(name->addrs);
i = 0;
while (addr != NULL) {
he->h_addr_list[i] = malloc(he->h_length);
if (he->h_addr_list[i] == NULL)
goto cleanup;
memcpy(he->h_addr_list[i], name->addrs[i].address, he->h_length);
memcpy(he->h_addr_list[i], addr->address, he->h_length);
addr = LWRES_LIST_NEXT(addr, link);
i++;
}
he->h_addr_list[i] = NULL;
return (he);

View File

@@ -21,7 +21,7 @@ top_srcdir = @top_srcdir@
# Only list headers that are to be installed!
#
HEADERS = context.h lwbuffer.h lwpacket.h lwres.h netdb.h result.h \
int.h lang.h net.h ipv6.h platform.h
int.h lang.h list.h net.h ipv6.h platform.h
SUBDIRS =
TARGETS =

View File

@@ -0,0 +1,116 @@
/*
* Copyright (C) 1997, 1999, 2000 Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
* CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
* SOFTWARE.
*/
#ifndef LWRES_LIST_H
#define LWRES_LIST_H 1
#define LWRES_LIST(type) struct { type *head, *tail; }
#define LWRES_LIST_INIT(list) \
do { (list).head = NULL; (list).tail = NULL; } while (0)
#define LWRES_LINK(type) struct { type *prev, *next; }
#define LWRES_LINK_INIT(elt, link) \
do { \
(elt)->link.prev = (void *)(-1); \
(elt)->link.next = (void *)(-1); \
} while (0)
#define LWRES_LINK_LINKED(elt, link) ((void *)((elt)->link.prev) != (void *)(-1))
#define LWRES_LIST_HEAD(list) ((list).head)
#define LWRES_LIST_TAIL(list) ((list).tail)
#define LWRES_LIST_EMPTY(list) LWRES_TF((list).head == NULL)
#define LWRES_LIST_PREPEND(list, elt, link) \
do { \
if ((list).head != NULL) \
(list).head->link.prev = (elt); \
else \
(list).tail = (elt); \
(elt)->link.prev = NULL; \
(elt)->link.next = (list).head; \
(list).head = (elt); \
} while (0)
#define LWRES_LIST_APPEND(list, elt, link) \
do { \
if ((list).tail != NULL) \
(list).tail->link.next = (elt); \
else \
(list).head = (elt); \
(elt)->link.prev = (list).tail; \
(elt)->link.next = NULL; \
(list).tail = (elt); \
} while (0)
#define LWRES_LIST_UNLINK(list, elt, link) \
do { \
if ((elt)->link.next != NULL) \
(elt)->link.next->link.prev = (elt)->link.prev; \
else \
(list).tail = (elt)->link.prev; \
if ((elt)->link.prev != NULL) \
(elt)->link.prev->link.next = (elt)->link.next; \
else \
(list).head = (elt)->link.next; \
(elt)->link.prev = (void *)(-1); \
(elt)->link.next = (void *)(-1); \
} while (0)
#define LWRES_LIST_PREV(elt, link) ((elt)->link.prev)
#define LWRES_LIST_NEXT(elt, link) ((elt)->link.next)
#define LWRES_LIST_INSERTBEFORE(list, before, elt, link) \
do { \
if ((before)->link.prev == NULL) \
LWRES_LIST_PREPEND(list, elt, link); \
else { \
(elt)->link.prev = (before)->link.prev; \
(before)->link.prev = (elt); \
(elt)->link.prev->link.next = (elt); \
(elt)->link.next = (before); \
} \
} while (0)
#define LWRES_LIST_INSERTAFTER(list, after, elt, link) \
do { \
if ((after)->link.next == NULL) \
LWRES_LIST_APPEND(list, elt, link); \
else { \
(elt)->link.next = (after)->link.next; \
(after)->link.next = (elt); \
(elt)->link.next->link.prev = (elt); \
(elt)->link.prev = (after); \
} \
} while (0)
#define LWRES_LIST_APPENDLIST(list1, list2, link) \
do { \
if (LWRES_LIST_EMPTY(list1)) \
(list1) = (list2); \
else if (!LWRES_LIST_EMPTY(list2)) { \
(list1).tail->link.next = (list2).head; \
(list2).head->link.prev = (list1).tail; \
(list1).tail = (list2).tail; \
} \
(list2).head = NULL; \
(list2).tail = NULL; \
} while (0)
#define LWRES_LIST_ENQUEUE(list, elt, link) LWRES_LIST_APPEND(list, elt, link)
#define LWRES_LIST_DEQUEUE(list, elt, link) LWRES_LIST_UNLINK(list, elt, link)
#endif /* LWRES_LIST_H */

View File

@@ -24,6 +24,7 @@
#include <lwres/context.h>
#include <lwres/int.h>
#include <lwres/lang.h>
#include <lwres/list.h>
#include <lwres/lwpacket.h>
#include <lwres/result.h>
@@ -117,11 +118,15 @@ typedef struct {
*/
#define LWRES_OPCODE_GETADDRSBYNAME 0x00010001U
typedef struct {
typedef struct lwres_addr lwres_addr_t;
typedef LWRES_LIST(lwres_addr_t) lwres_addrlist_t;
struct lwres_addr {
lwres_uint32_t family;
lwres_uint16_t length;
const unsigned char *address;
} lwres_addr_t;
LWRES_LINK(lwres_addr_t) link;
};
typedef struct {
/* public */
@@ -138,7 +143,7 @@ typedef struct {
char **aliases;
lwres_uint16_t realnamelen;
lwres_uint16_t *aliaslen;
lwres_addr_t *addrs;
lwres_addrlist_t addrs;
/* if base != NULL, it will be freed when this structure is freed. */
void *base;
size_t baselen;
@@ -196,8 +201,6 @@ typedef struct {
lwres_uint8_t no_tld_query; /* non-zero if 'options no_tld_query' */
} lwres_conf_t;
#define LWRES_ADDRTYPE_V4 0x00000001U /* ipv4 */
#define LWRES_ADDRTYPE_V6 0x00000002U /* ipv6 */
@@ -386,7 +389,7 @@ lwres_noopresponse_free(lwres_context_t *ctx, lwres_noopresponse_t **structp);
*/
lwres_result_t
lwres_conf_parse(const char *filename, lwres_conf_t *confdata);
lwres_conf_parse(lwres_context_t *ctx, const char *filename);
/*
* parses a resolv.conf-format file and puts the results into *confdata;
*
@@ -400,7 +403,7 @@ lwres_conf_parse(const char *filename, lwres_conf_t *confdata);
*/
void
lwres_conf_free(lwres_conf_t *confdata);
lwres_conf_free(lwres_context_t *ctx);
/*
* Returns the data in confdata to the system.
*
@@ -410,27 +413,34 @@ lwres_conf_free(lwres_conf_t *confdata);
*/
lwres_result_t
lwres_conf_print(FILE *fp, lwres_conf_t *confdata);
lwres_conf_print(lwres_context_t *ctx, FILE *fp);
/*
* Prints a resolv.conf-format of confdata output to fp.
*/
void
lwres_conf_init(lwres_context_t *ctx, lwres_conf_t *confdata);
lwres_conf_init(lwres_context_t *ctx);
/*
* sets all internal fields to a default state. Used to initialize a new
* lwres_conf_t structure (not reset a used on).
*/
void
lwres_conf_clear(lwres_conf_t *confdata);
lwres_conf_clear(lwres_context_t *ctx);
/*
* frees all internally allocated memory in confdata. Uses the memory
* routines supplies by ctx (so that should probably be the same value as
* given to lwres_conf_parse()).
*/
lwres_conf_t *
lwres_conf_get(lwres_context_t *ctx);
/*
* returns a pointer to the current config structure.
* Be extremely cautions in modifying the contents of this structure; it
* needs an API to return the various bits of data, walk lists, etc.
*/
/*
* Helper functions
*/
@@ -450,9 +460,6 @@ lwres_getnamebyaddr(lwres_context_t *ctx, lwres_uint32_t addrtype,
lwres_uint16_t addrlen, const unsigned char *addr,
lwres_gnbaresponse_t **structp);
LWRES_LANG_ENDDECLS
#endif /* LWRES_LWRES_H */

View File

@@ -21,14 +21,14 @@
typedef unsigned int lwres_result_t;
#define LWRES_R_SUCCESS 0
#define LWRES_R_NOMEMORY -1
#define LWRES_R_TIMEOUT -2
#define LWRES_R_NOTFOUND -3
#define LWRES_R_UNEXPECTEDEND -4 /* unexpected end of input */
#define LWRES_R_FAILURE -5 /* generic failure */
#define LWRES_R_IOERROR -6
#define LWRES_R_NOTIMPLEMENTED -7
#define LWRES_R_UNEXPECTED -8
#define LWRES_R_TRAILINGDATA -9
#define LWRES_R_NOMEMORY 1
#define LWRES_R_TIMEOUT 2
#define LWRES_R_NOTFOUND 3
#define LWRES_R_UNEXPECTEDEND 4 /* unexpected end of input */
#define LWRES_R_FAILURE 5 /* generic failure */
#define LWRES_R_IOERROR 6
#define LWRES_R_NOTIMPLEMENTED 7
#define LWRES_R_UNEXPECTED 8
#define LWRES_R_TRAILINGDATA 9
#endif /* LWRES_RESULT_H */

View File

@@ -70,23 +70,19 @@ extern const char *lwres_net_ntop(int af, const void *src, char *dst,
size_t size);
static lwres_result_t
lwres_conf_parsenameserver(lwres_context_t *ctx, FILE *fp,
lwres_conf_t *confdata);
lwres_conf_parsenameserver(lwres_context_t *ctx, FILE *fp);
static lwres_result_t
lwres_conf_parsedomain(lwres_context_t *ctx, FILE *fp, lwres_conf_t *confdata);
lwres_conf_parsedomain(lwres_context_t *ctx, FILE *fp);
static lwres_result_t
lwres_conf_parsesearch(lwres_context_t *ctx, FILE *fp,
lwres_conf_t *confdata);
lwres_conf_parsesearch(lwres_context_t *ctx, FILE *fp);
static lwres_result_t
lwres_conf_parsesortlist(lwres_context_t *ctx, FILE *fp,
lwres_conf_t *confdata);
lwres_conf_parsesortlist(lwres_context_t *ctx, FILE *fp);
static lwres_result_t
lwres_conf_parseoption(lwres_context_t *ctx, FILE *fp,
lwres_conf_t *confdata);
lwres_conf_parseoption(lwres_context_t *ctx, FILE *fp);
static void
lwres_resetaddr(lwres_context_t *ctx, lwres_addr_t *addr, int freeit);
@@ -162,20 +158,20 @@ lwres_strdup(lwres_context_t *ctx, const char *str)
}
void
lwres_conf_init(lwres_context_t *ctx, lwres_conf_t *confdata)
lwres_conf_init(lwres_context_t *ctx)
{
int i;
lwres_conf_t *confdata;
REQUIRE(ctx != NULL);
REQUIRE(confdata != NULL);
confdata = &ctx->confdata;
confdata->lwctx = ctx;
confdata->nsnext = 0;
confdata->domainname = NULL;
confdata->searchnxt = 0;
confdata->sortlistnxt = 0;
confdata->resdebug = 0;
confdata->ndots = 0;
confdata->ndots = 1;
confdata->no_tld_query = 0;
for (i = 0 ; i < LWRES_CONFMAXNAMESERVERS ; i++)
@@ -191,12 +187,13 @@ lwres_conf_init(lwres_context_t *ctx, lwres_conf_t *confdata)
}
void
lwres_conf_clear(lwres_conf_t *confdata)
lwres_conf_clear(lwres_context_t *ctx)
{
int i;
lwres_context_t *ctx;
lwres_conf_t *confdata;
ctx = confdata->lwctx;
REQUIRE(ctx != NULL);
confdata = &ctx->confdata;
for (i = 0 ; i < confdata->nsnext ; i++)
lwres_resetaddr(ctx, &confdata->nameservers[i], 1);
@@ -225,16 +222,18 @@ lwres_conf_clear(lwres_conf_t *confdata)
confdata->searchnxt = 0;
confdata->sortlistnxt = 0;
confdata->resdebug = 0;
confdata->ndots = 0;
confdata->ndots = 1;
confdata->no_tld_query = 0;
}
static lwres_result_t
lwres_conf_parsenameserver(lwres_context_t *ctx, FILE *fp,
lwres_conf_t *confdata)
lwres_conf_parsenameserver(lwres_context_t *ctx, FILE *fp)
{
char word[LWRES_CONFMAXLINELEN];
int res;
lwres_conf_t *confdata;
confdata = &ctx->confdata;
if (confdata->nsnext == LWRES_CONFMAXNAMESERVERS)
return (LWRES_R_FAILURE);
@@ -254,10 +253,13 @@ lwres_conf_parsenameserver(lwres_context_t *ctx, FILE *fp,
}
static lwres_result_t
lwres_conf_parsedomain(lwres_context_t *ctx, FILE *fp, lwres_conf_t *confdata)
lwres_conf_parsedomain(lwres_context_t *ctx, FILE *fp)
{
char word[LWRES_CONFMAXLINELEN];
int res, i;
lwres_conf_t *confdata;
confdata = &ctx->confdata;
res = getword(fp, word, sizeof(word));
if (strlen(word) == 0)
@@ -288,11 +290,13 @@ lwres_conf_parsedomain(lwres_context_t *ctx, FILE *fp, lwres_conf_t *confdata)
}
static lwres_result_t
lwres_conf_parsesearch(lwres_context_t *ctx, FILE *fp,
lwres_conf_t *confdata)
lwres_conf_parsesearch(lwres_context_t *ctx, FILE *fp)
{
int idx, delim;
char word[LWRES_CONFMAXLINELEN];
lwres_conf_t *confdata;
confdata = &ctx->confdata;
if (confdata->domainname != NULL) {
/* search and domain are mutually exclusive */
@@ -360,12 +364,14 @@ lwres_create_addr(lwres_context_t *ctx, const char *buffer, lwres_addr_t *addr)
}
static lwres_result_t
lwres_conf_parsesortlist(lwres_context_t *ctx, FILE *fp,
lwres_conf_t *confdata)
lwres_conf_parsesortlist(lwres_context_t *ctx, FILE *fp)
{
int delim, res, idx;
char word[LWRES_CONFMAXLINELEN];
char *p;
lwres_conf_t *confdata;
confdata = &ctx->confdata;
delim = getword(fp, word, sizeof(word));
if (strlen(word) == 0)
@@ -404,17 +410,16 @@ lwres_conf_parsesortlist(lwres_context_t *ctx, FILE *fp,
}
static lwres_result_t
lwres_conf_parseoption(lwres_context_t *ctx, FILE *fp,
lwres_conf_t *confdata)
lwres_conf_parseoption(lwres_context_t *ctx, FILE *fp)
{
int delim;
long ndots;
char *p;
char word[LWRES_CONFMAXLINELEN];
lwres_conf_t *confdata;
UNUSED(ctx);
REQUIRE(confdata != NULL);
REQUIRE(ctx != NULL);
confdata = &ctx->confdata;
delim = getword(fp, word, sizeof(word));
if (strlen(word) == 0)
@@ -442,20 +447,21 @@ lwres_conf_parseoption(lwres_context_t *ctx, FILE *fp,
}
lwres_result_t
lwres_conf_parse(const char *filename, lwres_conf_t *confdata)
lwres_conf_parse(lwres_context_t *ctx, const char *filename)
{
FILE *fp = NULL;
char word[256];
int delim;
lwres_result_t rval;
lwres_context_t *ctx;
lwres_conf_t *confdata;
REQUIRE(ctx != NULL);
confdata = &ctx->confdata;
REQUIRE(filename != NULL);
REQUIRE(strlen(filename) > 0);
REQUIRE(confdata != NULL);
ctx = confdata->lwctx;
rval = LWRES_R_FAILURE; /* Make compiler happy. */
errno = 0;
if ((fp = fopen(filename, "r")) == NULL)
@@ -469,15 +475,15 @@ lwres_conf_parse(const char *filename, lwres_conf_t *confdata)
}
if (strcmp(word, "nameserver") == 0)
rval = lwres_conf_parsenameserver(ctx, fp, confdata);
rval = lwres_conf_parsenameserver(ctx, fp);
else if (strcmp(word, "domain") == 0)
rval = lwres_conf_parsedomain(ctx, fp, confdata);
rval = lwres_conf_parsedomain(ctx, fp);
else if (strcmp(word, "search") == 0)
rval = lwres_conf_parsesearch(ctx, fp, confdata);
rval = lwres_conf_parsesearch(ctx, fp);
else if (strcmp(word, "sortlist") == 0)
rval = lwres_conf_parsesortlist(ctx, fp, confdata);
rval = lwres_conf_parsesortlist(ctx, fp);
else if (strcmp(word, "option") == 0)
rval = lwres_conf_parseoption(ctx, fp, confdata);
rval = lwres_conf_parseoption(ctx, fp);
} while (rval == LWRES_R_SUCCESS);
fclose(fp);
@@ -486,11 +492,15 @@ lwres_conf_parse(const char *filename, lwres_conf_t *confdata)
}
lwres_result_t
lwres_conf_print(FILE *fp, lwres_conf_t *confdata)
lwres_conf_print(lwres_context_t *ctx, FILE *fp)
{
int i;
char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"];
const char *p;
lwres_conf_t *confdata;
REQUIRE(ctx != NULL);
confdata = &ctx->confdata;
REQUIRE(confdata->nsnext <= LWRES_CONFMAXNAMESERVERS);
@@ -553,3 +563,11 @@ lwres_conf_print(FILE *fp, lwres_conf_t *confdata)
return (LWRES_R_SUCCESS);
}
lwres_conf_t *
lwres_conf_get(lwres_context_t *ctx)
{
REQUIRE(ctx != NULL);
return (&ctx->confdata);
}

View File

@@ -100,6 +100,7 @@ lwres_gabnresponse_render(lwres_context_t *ctx, lwres_gabnresponse_t *req,
int ret;
size_t payload_length;
lwres_uint16_t datalen;
lwres_addr_t *addr;
int x;
REQUIRE(ctx != NULL);
@@ -108,17 +109,22 @@ lwres_gabnresponse_render(lwres_context_t *ctx, lwres_gabnresponse_t *req,
REQUIRE(b != NULL);
/* naliases, naddrs */
payload_length = sizeof(lwres_uint16_t) * 2;
payload_length = 2 * 2;
/* real name encoding */
payload_length += 2 + req->realnamelen + 1;
/* each alias */
for (x = 0 ; x < req->naliases ; x++)
payload_length += 2 + req->aliaslen[x] + 1;
/* each address */
for (x = 0 ; x < req->naddrs ; x++) {
payload_length += sizeof(lwres_uint32_t) + sizeof(lwres_uint16_t);
payload_length += req->addrs[x].length;
x = 0;
addr = LWRES_LIST_HEAD(req->addrs);
while (addr != NULL) {
payload_length += 4 + 2;
payload_length += addr->length;
addr = LWRES_LIST_NEXT(addr, link);
x++;
}
INSIST(x == req->naddrs);
buflen = LWRES_LWPACKET_LENGTH + payload_length;
buf = CTXMALLOC(buflen);
@@ -163,14 +169,14 @@ lwres_gabnresponse_render(lwres_context_t *ctx, lwres_gabnresponse_t *req,
}
/* encode the addresses */
for (x = 0 ; x < req->naddrs ; x++) {
datalen = req->addrs[x].length + sizeof(lwres_uint16_t)
+ sizeof(lwres_uint32_t);
addr = LWRES_LIST_HEAD(req->addrs);
while (addr != NULL) {
datalen = addr->length + 2 + 4;
INSIST(SPACE_OK(b, datalen));
lwres_buffer_putuint32(b, req->addrs[x].family);
lwres_buffer_putuint16(b, req->addrs[x].length);
lwres_buffer_putmem(b, req->addrs[x].address,
req->addrs[x].length);
lwres_buffer_putuint32(b, addr->family);
lwres_buffer_putuint16(b, addr->length);
lwres_buffer_putmem(b, addr->address, addr->length);
addr = LWRES_LIST_NEXT(addr, link);
}
INSIST(LWRES_BUFFER_AVAILABLECOUNT(b) == 0);
@@ -228,11 +234,13 @@ lwres_result_t
lwres_gabnresponse_parse(lwres_context_t *ctx, lwres_buffer_t *b,
lwres_lwpacket_t *pkt, lwres_gabnresponse_t **structp)
{
int ret;
lwres_result_t ret;
unsigned int x;
lwres_uint16_t naliases;
lwres_uint16_t naddrs;
lwres_gabnresponse_t *gabn;
lwres_addrlist_t addrlist;
lwres_addr_t *addr;
REQUIRE(ctx != NULL);
REQUIRE(pkt != NULL);
@@ -257,7 +265,7 @@ lwres_gabnresponse_parse(lwres_context_t *ctx, lwres_buffer_t *b,
return (LWRES_R_NOMEMORY);
gabn->aliases = NULL;
gabn->aliaslen = NULL;
gabn->addrs = NULL;
LWRES_LIST_INIT(gabn->addrs);
gabn->base = NULL;
gabn->naliases = naliases;
@@ -277,12 +285,15 @@ lwres_gabnresponse_parse(lwres_context_t *ctx, lwres_buffer_t *b,
}
}
if (naddrs > 0) {
gabn->addrs = CTXMALLOC(sizeof(lwres_addr_t) * naddrs);
if (gabn->addrs == NULL) {
LWRES_LIST_INIT(addrlist);
for (x = 0 ; x < naddrs ; x++) {
addr = CTXMALLOC(sizeof(lwres_addr_t));
if (addr == NULL) {
ret = LWRES_R_NOMEMORY;
goto out;
}
LWRES_LINK_INIT(addr, link);
LWRES_LIST_APPEND(addrlist, addr, link);
}
/*
@@ -303,14 +314,23 @@ lwres_gabnresponse_parse(lwres_context_t *ctx, lwres_buffer_t *b,
}
/*
* Pull off the addresses.
* Pull off the addresses. We already strung the linked list
* up above.
*/
addr = LWRES_LIST_HEAD(addrlist);
for (x = 0 ; x < gabn->naddrs ; x++) {
ret = lwres_addr_parse(b, &gabn->addrs[x]);
INSIST(addr != NULL);
ret = lwres_addr_parse(b, addr);
if (ret != LWRES_R_SUCCESS)
goto out;
addr = LWRES_LIST_NEXT(addr, link);
}
/*
* Do the sortlist thing here. XXXMLG
*/
gabn->addrs = addrlist;
if (LWRES_BUFFER_REMAINING(b) != 0) {
ret = LWRES_R_TRAILINGDATA;
goto out;
@@ -326,8 +346,12 @@ lwres_gabnresponse_parse(lwres_context_t *ctx, lwres_buffer_t *b,
if (gabn->aliaslen != NULL)
CTXFREE(gabn->aliaslen,
sizeof(lwres_uint16_t) * naliases);
if (gabn->addrs != NULL)
CTXFREE(gabn->addrs, sizeof(lwres_addr_t) * naddrs);
addr = LWRES_LIST_HEAD(addrlist);
while (addr != NULL) {
LWRES_LIST_UNLINK(addrlist, addr, link);
CTXFREE(addr, sizeof(lwres_addr_t));
addr = LWRES_LIST_HEAD(addrlist);
}
CTXFREE(gabn, sizeof(lwres_gabnresponse_t));
}
@@ -352,6 +376,7 @@ void
lwres_gabnresponse_free(lwres_context_t *ctx, lwres_gabnresponse_t **structp)
{
lwres_gabnresponse_t *gabn;
lwres_addr_t *addr;
REQUIRE(ctx != NULL);
REQUIRE(structp != NULL && *structp != NULL);
@@ -363,8 +388,12 @@ lwres_gabnresponse_free(lwres_context_t *ctx, lwres_gabnresponse_t **structp)
CTXFREE(gabn->aliases, sizeof(char *) * gabn->naliases);
CTXFREE(gabn->aliaslen, sizeof(lwres_uint16_t) * gabn->naliases);
}
if (gabn->naddrs > 0)
CTXFREE(gabn->addrs, sizeof(lwres_addr_t) * gabn->naddrs);
addr = LWRES_LIST_HEAD(gabn->addrs);
while (addr != NULL) {
LWRES_LIST_UNLINK(gabn->addrs, addr, link);
CTXFREE(addr, sizeof(lwres_addr_t));
addr = LWRES_LIST_HEAD(gabn->addrs);
}
if (gabn->base != NULL)
CTXFREE(gabn->base, gabn->baselen);
CTXFREE(gabn, sizeof(lwres_gabnresponse_t));

View File

@@ -108,6 +108,25 @@ lwres_addr_parse(lwres_buffer_t *b, lwres_addr_t *addr)
return (LWRES_R_SUCCESS);
}
static void
count_dots(const char *name, unsigned int *ndots, unsigned int *last_was_dot)
{
const char *p;
p = name;
*ndots = 0;
*last_was_dot = 0;
while (*p != 0) {
if (*p++ == '.') {
(*ndots)++;
*last_was_dot = 1;
} else {
*last_was_dot = 0;
}
}
}
lwres_result_t
lwres_getaddrsbyname(lwres_context_t *ctx, const char *name,
lwres_uint32_t addrtypes, lwres_gabnresponse_t **structp)
@@ -120,12 +139,30 @@ lwres_getaddrsbyname(lwres_context_t *ctx, const char *name,
lwres_lwpacket_t pkt;
lwres_uint32_t serial;
char *buffer;
int current_suffix;
unsigned int ndots;
unsigned int last_was_dot;
unsigned int exact_first;
char target_name[1024];
unsigned int target_length;
unsigned int tried_exact;
unsigned int tried_search;
REQUIRE(ctx != NULL);
REQUIRE(name != NULL);
REQUIRE(addrtypes != 0);
REQUIRE(structp != NULL && *structp == NULL);
count_dots(name, &ndots, &last_was_dot);
if (last_was_dot || (ndots >= ctx->confdata.ndots))
exact_first = 1;
else
exact_first = 0;
current_suffix = 0;
tried_exact = 0;
tried_search = 0;
b_in.base = NULL;
b_out.base = NULL;
response = NULL;
@@ -138,12 +175,56 @@ lwres_getaddrsbyname(lwres_context_t *ctx, const char *name,
goto out;
}
next_suffix:
/*
* First, if the name ends in a dot, do an exact search. Lie and
* pretend we have already done a search.
*/
if (last_was_dot)
tried_search = 1;
if (tried_exact && tried_search) {
ret = LWRES_R_NOTFOUND;
goto out;
}
/*
* Try the exact search first. If this fails, try the
* search list.
*/
if (exact_first && !tried_exact) {
tried_exact = 1;
target_length = strlen(name);
if (target_length >= sizeof(target_name))
goto next_suffix;
strcpy(target_name, name); /* strcpy is safe */
} else {
INSIST(!tried_search);
if (current_suffix >= ctx->confdata.searchnxt) {
tried_search = 1;
exact_first = 1;
goto next_suffix;
}
target_length = strlen(name)
+ strlen(ctx->confdata.search[current_suffix])
+ 1;
if (target_length >= sizeof(target_name)) {
current_suffix++;
goto next_suffix; /* XXXMLG */
}
sprintf(target_name, "%s.%s", /* sprintf is safe */
name, ctx->confdata.search[current_suffix]);
current_suffix++;
}
/*
* Set up our request and render it to a buffer.
*/
request.addrtypes = addrtypes;
request.name = (char *)name;
request.namelen = strlen(name);
request.name = target_name;
request.namelen = target_length;
pkt.flags = 0;
pkt.serial = serial;
pkt.result = 0;
@@ -184,6 +265,9 @@ lwres_getaddrsbyname(lwres_context_t *ctx, const char *name,
b_out.base = NULL;
b_out.length = 0;
if (pkt.result == LWRES_R_NOTFOUND)
goto next_suffix;
if (pkt.result != LWRES_R_SUCCESS) {
ret = pkt.result;
goto out;

View File

@@ -742,6 +742,7 @@
./lib/lwres/include/lwres/Makefile.in MAKE 2000
./lib/lwres/include/lwres/context.h C 2000
./lib/lwres/include/lwres/ipv6.h C 2000
./lib/lwres/include/lwres/list.h C 1999,2000
./lib/lwres/include/lwres/lwbuffer.h C 2000
./lib/lwres/include/lwres/lwpacket.h C 1999,2000
./lib/lwres/include/lwres/lwres.h C 2000