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].family = 0;
client->addrs[i].length = 0; client->addrs[i].length = 0;
client->addrs[i].address = NULL; 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.aliases = client->aliases;
client->gabn.realnamelen = 0; client->gabn.realnamelen = 0;
client->gabn.aliaslen = client->aliaslen; client->gabn.aliaslen = client->aliaslen;
client->gabn.addrs = client->addrs; LWRES_LIST_INIT(client->gabn.addrs);
client->gabn.base = NULL; client->gabn.base = NULL;
client->gabn.baselen = 0; 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); addr->address, addr->family, addr->length);
client->gabn.naddrs++; client->gabn.naddrs++;
REQUIRE(!LWRES_LINK_LINKED(addr, link));
LWRES_LIST_APPEND(client->gabn.addrs, addr, link);
next: next:
ai = ISC_LIST_NEXT(ai, publink); 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 * Run through the finds we have and wire them up to the gabn
* structure. * structure.
*/ */
LWRES_LIST_INIT(client->gabn.addrs);
if (client->v4find != NULL) if (client->v4find != NULL)
setup_addresses(client, client->v4find, DNS_ADBFIND_INET); setup_addresses(client, client->v4find, DNS_ADBFIND_INET);
if (client->v6find != NULL) if (client->v6find != NULL)

View File

@@ -158,6 +158,7 @@ static void
test_gabn(char *target) test_gabn(char *target)
{ {
lwres_gabnresponse_t *res; lwres_gabnresponse_t *res;
lwres_addr_t *addr;
int ret; int ret;
unsigned int i; unsigned int i;
char outbuf[64]; char outbuf[64];
@@ -180,15 +181,19 @@ test_gabn(char *target)
for (i = 0 ; i < res->naliases ; i++) for (i = 0 ; i < res->naliases ; i++)
printf("\t(%u, %s)\n", res->aliaslen[i], res->aliases[i]); printf("\t(%u, %s)\n", res->aliaslen[i], res->aliases[i]);
printf("%u addresses:\n", res->naddrs); printf("%u addresses:\n", res->naddrs);
addr = LWRES_LIST_HEAD(res->addrs);
for (i = 0 ; i < res->naddrs ; i++) { for (i = 0 ; i < res->naddrs ; i++) {
if (res->addrs[i].family == LWRES_ADDRTYPE_V4) INSIST(addr != NULL);
(void)inet_ntop(AF_INET, res->addrs[i].address,
if (addr->family == LWRES_ADDRTYPE_V4)
(void)inet_ntop(AF_INET, addr->address,
outbuf, sizeof(outbuf)); outbuf, sizeof(outbuf));
else else
(void)inet_ntop(AF_INET6, res->addrs[i].address, (void)inet_ntop(AF_INET6, addr->address,
outbuf, sizeof(outbuf)); outbuf, sizeof(outbuf));
printf("\tAddr len %u family %08x %s\n", 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); 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 */ (void)context_connect(ctx); /* XXXMLG */
/*
* Init resolv.conf bits.
*/
lwres_conf_init(ctx);
*contextp = ctx; *contextp = ctx;
return (LWRES_R_SUCCESS); return (LWRES_R_SUCCESS);
} }

View File

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

View File

@@ -3,7 +3,7 @@
* The Berkeley Software Design Inc. software License Agreement specifies * The Berkeley Software Design Inc. software License Agreement specifies
* the terms and conditions for redistribution. * 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; struct addrinfo *ai;
lwres_context_t *lwrctx = NULL; lwres_context_t *lwrctx = NULL;
lwres_gabnresponse_t *by = NULL; lwres_gabnresponse_t *by = NULL;
int i; lwres_addr_t *addr;
lwres_result_t lwres;
int result = 0; int result = 0;
i = lwres_context_create(&lwrctx, NULL, NULL, NULL); lwres = lwres_context_create(&lwrctx, NULL, NULL, NULL);
if (i != 0) if (lwres != 0)
ERR(EAI_FAIL); ERR(EAI_FAIL);
if (hostname == NULL && (flags & AI_PASSIVE) == 0) { if (hostname == NULL && (flags & AI_PASSIVE) == 0) {
if ((ai = ai_clone(*aip, AF_INET)) == NULL) { 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); memcpy(&SIN(ai->ai_addr)->sin_addr, v4_loop, 4);
} else if (lwres_getaddrsbyname(lwrctx, hostname, } else if (lwres_getaddrsbyname(lwrctx, hostname,
LWRES_ADDRTYPE_V4, &by) == 0) { 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); ai = ai_clone(*aip, AF_INET);
if (ai == NULL) { if (ai == NULL) {
lwres_freeaddrinfo(*aip); lwres_freeaddrinfo(*aip);
@@ -381,9 +383,10 @@ add_ipv4(const char *hostname, int flags, struct addrinfo **aip,
ai->ai_socktype = socktype; ai->ai_socktype = socktype;
SIN(ai->ai_addr)->sin_port = port; SIN(ai->ai_addr)->sin_port = port;
memcpy(&SIN(ai->ai_addr)->sin_addr, memcpy(&SIN(ai->ai_addr)->sin_addr,
by->addrs[i].address, 4); addr->address, 4);
if (flags & AI_CANONNAME) if (flags & AI_CANONNAME)
ai->ai_canonname = strdup(by->realname); ai->ai_canonname = strdup(by->realname);
addr = LWRES_LIST_NEXT(addr, link);
} }
} }
cleanup: cleanup:
@@ -403,12 +406,14 @@ add_ipv6(const char *hostname, int flags, struct addrinfo **aip,
struct addrinfo *ai; struct addrinfo *ai;
lwres_context_t *lwrctx = NULL; lwres_context_t *lwrctx = NULL;
lwres_gabnresponse_t *by = NULL; lwres_gabnresponse_t *by = NULL;
int i; lwres_addr_t *addr;
lwres_result_t lwres;
int result = 0; int result = 0;
i = lwres_context_create(&lwrctx, NULL, NULL, NULL); lwres = lwres_context_create(&lwrctx, NULL, NULL, NULL);
if (i != 0) if (lwres != 0)
ERR(EAI_FAIL); ERR(EAI_FAIL);
if (hostname == NULL && (flags & AI_PASSIVE) == 0) { if (hostname == NULL && (flags & AI_PASSIVE) == 0) {
if ((ai = ai_clone(*aip, AF_INET6)) == NULL) { if ((ai = ai_clone(*aip, AF_INET6)) == NULL) {
lwres_freeaddrinfo(*aip); 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); memcpy(&SIN6(ai->ai_addr)->sin6_addr, v6_loop, 16);
} else if (lwres_getaddrsbyname(lwrctx, hostname, } else if (lwres_getaddrsbyname(lwrctx, hostname,
LWRES_ADDRTYPE_V6, &by) == 0) { 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) { if ((ai = ai_clone(*aip, AF_INET6)) == NULL) {
lwres_freeaddrinfo(*aip); lwres_freeaddrinfo(*aip);
ERR(EAI_MEMORY); ERR(EAI_MEMORY);
@@ -430,9 +436,10 @@ add_ipv6(const char *hostname, int flags, struct addrinfo **aip,
ai->ai_socktype = socktype; ai->ai_socktype = socktype;
SIN6(ai->ai_addr)->sin6_port = port; SIN6(ai->ai_addr)->sin6_port = port;
memcpy(&SIN6(ai->ai_addr)->sin6_addr, memcpy(&SIN6(ai->ai_addr)->sin6_addr,
by->addrs[i].address, 16); addr->address, 16);
if (flags & AI_CANONNAME) if (flags & AI_CANONNAME)
ai->ai_canonname = strdup(by->realname); ai->ai_canonname = strdup(by->realname);
addr = LWRES_LIST_NEXT(addr, link);
} }
} }
cleanup: cleanup:

View File

@@ -680,9 +680,11 @@ hostfromaddr(lwres_gnbaresponse_t *addr, int af, const void *src) {
} }
static struct hostent * static struct hostent *
hostfromname(lwres_gabnresponse_t *name, int af) { hostfromname(lwres_gabnresponse_t *name, int af)
{
struct hostent *he; struct hostent *he;
int i; int i;
lwres_addr_t *addr;
he = malloc(sizeof *he); he = malloc(sizeof *he);
if (he == NULL) if (he == NULL)
@@ -718,11 +720,15 @@ hostfromname(lwres_gabnresponse_t *name, int af) {
/* copy addresses */ /* copy addresses */
he->h_addr_list = malloc(sizeof(char *) * (name->naddrs + 1)); 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); he->h_addr_list[i] = malloc(he->h_length);
if (he->h_addr_list[i] == NULL) if (he->h_addr_list[i] == NULL)
goto cleanup; 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; he->h_addr_list[i] = NULL;
return (he); return (he);

View File

@@ -21,7 +21,7 @@ top_srcdir = @top_srcdir@
# Only list headers that are to be installed! # Only list headers that are to be installed!
# #
HEADERS = context.h lwbuffer.h lwpacket.h lwres.h netdb.h result.h \ 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 = SUBDIRS =
TARGETS = 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/context.h>
#include <lwres/int.h> #include <lwres/int.h>
#include <lwres/lang.h> #include <lwres/lang.h>
#include <lwres/list.h>
#include <lwres/lwpacket.h> #include <lwres/lwpacket.h>
#include <lwres/result.h> #include <lwres/result.h>
@@ -102,14 +103,14 @@
typedef struct { typedef struct {
/* public */ /* public */
lwres_uint16_t datalength; lwres_uint16_t datalength;
unsigned char *data; unsigned char *data;
} lwres_nooprequest_t; } lwres_nooprequest_t;
typedef struct { typedef struct {
/* public */ /* public */
lwres_uint16_t datalength; lwres_uint16_t datalength;
unsigned char *data; unsigned char *data;
} lwres_noopresponse_t; } lwres_noopresponse_t;
/* /*
@@ -117,31 +118,35 @@ typedef struct {
*/ */
#define LWRES_OPCODE_GETADDRSBYNAME 0x00010001U #define LWRES_OPCODE_GETADDRSBYNAME 0x00010001U
typedef struct { typedef struct lwres_addr lwres_addr_t;
lwres_uint32_t family; typedef LWRES_LIST(lwres_addr_t) lwres_addrlist_t;
lwres_uint16_t length;
const unsigned char *address; struct lwres_addr {
} lwres_addr_t; lwres_uint32_t family;
lwres_uint16_t length;
const unsigned char *address;
LWRES_LINK(lwres_addr_t) link;
};
typedef struct { typedef struct {
/* public */ /* public */
lwres_uint32_t addrtypes; lwres_uint32_t addrtypes;
lwres_uint16_t namelen; lwres_uint16_t namelen;
char *name; char *name;
} lwres_gabnrequest_t; } lwres_gabnrequest_t;
typedef struct { typedef struct {
/* public */ /* public */
lwres_uint16_t naliases; lwres_uint16_t naliases;
lwres_uint16_t naddrs; lwres_uint16_t naddrs;
char *realname; char *realname;
char **aliases; char **aliases;
lwres_uint16_t realnamelen; lwres_uint16_t realnamelen;
lwres_uint16_t *aliaslen; lwres_uint16_t *aliaslen;
lwres_addr_t *addrs; lwres_addrlist_t addrs;
/* if base != NULL, it will be freed when this structure is freed. */ /* if base != NULL, it will be freed when this structure is freed. */
void *base; void *base;
size_t baselen; size_t baselen;
} lwres_gabnresponse_t; } lwres_gabnresponse_t;
/* /*
@@ -150,19 +155,19 @@ typedef struct {
#define LWRES_OPCODE_GETNAMEBYADDR 0x00010002U #define LWRES_OPCODE_GETNAMEBYADDR 0x00010002U
typedef struct { typedef struct {
/* public */ /* public */
lwres_addr_t addr; lwres_addr_t addr;
} lwres_gnbarequest_t; } lwres_gnbarequest_t;
typedef struct { typedef struct {
/* public */ /* public */
lwres_uint16_t naliases; lwres_uint16_t naliases;
char *realname; char *realname;
char **aliases; char **aliases;
lwres_uint16_t realnamelen; lwres_uint16_t realnamelen;
lwres_uint16_t *aliaslen; lwres_uint16_t *aliaslen;
/* if base != NULL, it will be freed when this structure is freed. */ /* if base != NULL, it will be freed when this structure is freed. */
void *base; void *base;
size_t baselen; size_t baselen;
} lwres_gnbaresponse_t; } lwres_gnbaresponse_t;
@@ -195,8 +200,6 @@ typedef struct {
lwres_uint8_t ndots; /* set to n in 'options ndots:n' */ lwres_uint8_t ndots; /* set to n in 'options ndots:n' */
lwres_uint8_t no_tld_query; /* non-zero if 'options no_tld_query' */ lwres_uint8_t no_tld_query; /* non-zero if 'options no_tld_query' */
} lwres_conf_t; } lwres_conf_t;
#define LWRES_ADDRTYPE_V4 0x00000001U /* ipv4 */ #define LWRES_ADDRTYPE_V4 0x00000001U /* ipv4 */
#define LWRES_ADDRTYPE_V6 0x00000002U /* ipv6 */ #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_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; * 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 void
lwres_conf_free(lwres_conf_t *confdata); lwres_conf_free(lwres_context_t *ctx);
/* /*
* Returns the data in confdata to the system. * Returns the data in confdata to the system.
* *
@@ -410,27 +413,34 @@ lwres_conf_free(lwres_conf_t *confdata);
*/ */
lwres_result_t 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. * Prints a resolv.conf-format of confdata output to fp.
*/ */
void 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 * sets all internal fields to a default state. Used to initialize a new
* lwres_conf_t structure (not reset a used on). * lwres_conf_t structure (not reset a used on).
*/ */
void 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 * frees all internally allocated memory in confdata. Uses the memory
* routines supplies by ctx (so that should probably be the same value as * routines supplies by ctx (so that should probably be the same value as
* given to lwres_conf_parse()). * 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 * 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_uint16_t addrlen, const unsigned char *addr,
lwres_gnbaresponse_t **structp); lwres_gnbaresponse_t **structp);
LWRES_LANG_ENDDECLS LWRES_LANG_ENDDECLS
#endif /* LWRES_LWRES_H */ #endif /* LWRES_LWRES_H */

View File

@@ -21,14 +21,14 @@
typedef unsigned int lwres_result_t; typedef unsigned int lwres_result_t;
#define LWRES_R_SUCCESS 0 #define LWRES_R_SUCCESS 0
#define LWRES_R_NOMEMORY -1 #define LWRES_R_NOMEMORY 1
#define LWRES_R_TIMEOUT -2 #define LWRES_R_TIMEOUT 2
#define LWRES_R_NOTFOUND -3 #define LWRES_R_NOTFOUND 3
#define LWRES_R_UNEXPECTEDEND -4 /* unexpected end of input */ #define LWRES_R_UNEXPECTEDEND 4 /* unexpected end of input */
#define LWRES_R_FAILURE -5 /* generic failure */ #define LWRES_R_FAILURE 5 /* generic failure */
#define LWRES_R_IOERROR -6 #define LWRES_R_IOERROR 6
#define LWRES_R_NOTIMPLEMENTED -7 #define LWRES_R_NOTIMPLEMENTED 7
#define LWRES_R_UNEXPECTED -8 #define LWRES_R_UNEXPECTED 8
#define LWRES_R_TRAILINGDATA -9 #define LWRES_R_TRAILINGDATA 9
#endif /* LWRES_RESULT_H */ #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); size_t size);
static lwres_result_t static lwres_result_t
lwres_conf_parsenameserver(lwres_context_t *ctx, FILE *fp, lwres_conf_parsenameserver(lwres_context_t *ctx, FILE *fp);
lwres_conf_t *confdata);
static lwres_result_t 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 static lwres_result_t
lwres_conf_parsesearch(lwres_context_t *ctx, FILE *fp, lwres_conf_parsesearch(lwres_context_t *ctx, FILE *fp);
lwres_conf_t *confdata);
static lwres_result_t static lwres_result_t
lwres_conf_parsesortlist(lwres_context_t *ctx, FILE *fp, lwres_conf_parsesortlist(lwres_context_t *ctx, FILE *fp);
lwres_conf_t *confdata);
static lwres_result_t static lwres_result_t
lwres_conf_parseoption(lwres_context_t *ctx, FILE *fp, lwres_conf_parseoption(lwres_context_t *ctx, FILE *fp);
lwres_conf_t *confdata);
static void static void
lwres_resetaddr(lwres_context_t *ctx, lwres_addr_t *addr, int freeit); 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 void
lwres_conf_init(lwres_context_t *ctx, lwres_conf_t *confdata) lwres_conf_init(lwres_context_t *ctx)
{ {
int i; int i;
lwres_conf_t *confdata;
REQUIRE(ctx != NULL); REQUIRE(ctx != NULL);
REQUIRE(confdata != NULL); confdata = &ctx->confdata;
confdata->lwctx = ctx;
confdata->nsnext = 0; confdata->nsnext = 0;
confdata->domainname = NULL; confdata->domainname = NULL;
confdata->searchnxt = 0; confdata->searchnxt = 0;
confdata->sortlistnxt = 0; confdata->sortlistnxt = 0;
confdata->resdebug = 0; confdata->resdebug = 0;
confdata->ndots = 0; confdata->ndots = 1;
confdata->no_tld_query = 0; confdata->no_tld_query = 0;
for (i = 0 ; i < LWRES_CONFMAXNAMESERVERS ; i++) for (i = 0 ; i < LWRES_CONFMAXNAMESERVERS ; i++)
@@ -191,12 +187,13 @@ lwres_conf_init(lwres_context_t *ctx, lwres_conf_t *confdata)
} }
void void
lwres_conf_clear(lwres_conf_t *confdata) lwres_conf_clear(lwres_context_t *ctx)
{ {
int i; 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++) for (i = 0 ; i < confdata->nsnext ; i++)
lwres_resetaddr(ctx, &confdata->nameservers[i], 1); lwres_resetaddr(ctx, &confdata->nameservers[i], 1);
@@ -225,16 +222,18 @@ lwres_conf_clear(lwres_conf_t *confdata)
confdata->searchnxt = 0; confdata->searchnxt = 0;
confdata->sortlistnxt = 0; confdata->sortlistnxt = 0;
confdata->resdebug = 0; confdata->resdebug = 0;
confdata->ndots = 0; confdata->ndots = 1;
confdata->no_tld_query = 0; confdata->no_tld_query = 0;
} }
static lwres_result_t static lwres_result_t
lwres_conf_parsenameserver(lwres_context_t *ctx, FILE *fp, lwres_conf_parsenameserver(lwres_context_t *ctx, FILE *fp)
lwres_conf_t *confdata)
{ {
char word[LWRES_CONFMAXLINELEN]; char word[LWRES_CONFMAXLINELEN];
int res; int res;
lwres_conf_t *confdata;
confdata = &ctx->confdata;
if (confdata->nsnext == LWRES_CONFMAXNAMESERVERS) if (confdata->nsnext == LWRES_CONFMAXNAMESERVERS)
return (LWRES_R_FAILURE); return (LWRES_R_FAILURE);
@@ -254,10 +253,13 @@ lwres_conf_parsenameserver(lwres_context_t *ctx, FILE *fp,
} }
static lwres_result_t 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]; char word[LWRES_CONFMAXLINELEN];
int res, i; int res, i;
lwres_conf_t *confdata;
confdata = &ctx->confdata;
res = getword(fp, word, sizeof(word)); res = getword(fp, word, sizeof(word));
if (strlen(word) == 0) 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 static lwres_result_t
lwres_conf_parsesearch(lwres_context_t *ctx, FILE *fp, lwres_conf_parsesearch(lwres_context_t *ctx, FILE *fp)
lwres_conf_t *confdata)
{ {
int idx, delim; int idx, delim;
char word[LWRES_CONFMAXLINELEN]; char word[LWRES_CONFMAXLINELEN];
lwres_conf_t *confdata;
confdata = &ctx->confdata;
if (confdata->domainname != NULL) { if (confdata->domainname != NULL) {
/* search and domain are mutually exclusive */ /* 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 static lwres_result_t
lwres_conf_parsesortlist(lwres_context_t *ctx, FILE *fp, lwres_conf_parsesortlist(lwres_context_t *ctx, FILE *fp)
lwres_conf_t *confdata)
{ {
int delim, res, idx; int delim, res, idx;
char word[LWRES_CONFMAXLINELEN]; char word[LWRES_CONFMAXLINELEN];
char *p; char *p;
lwres_conf_t *confdata;
confdata = &ctx->confdata;
delim = getword(fp, word, sizeof(word)); delim = getword(fp, word, sizeof(word));
if (strlen(word) == 0) if (strlen(word) == 0)
@@ -404,17 +410,16 @@ lwres_conf_parsesortlist(lwres_context_t *ctx, FILE *fp,
} }
static lwres_result_t static lwres_result_t
lwres_conf_parseoption(lwres_context_t *ctx, FILE *fp, lwres_conf_parseoption(lwres_context_t *ctx, FILE *fp)
lwres_conf_t *confdata)
{ {
int delim; int delim;
long ndots; long ndots;
char *p; char *p;
char word[LWRES_CONFMAXLINELEN]; char word[LWRES_CONFMAXLINELEN];
lwres_conf_t *confdata;
UNUSED(ctx); REQUIRE(ctx != NULL);
confdata = &ctx->confdata;
REQUIRE(confdata != NULL);
delim = getword(fp, word, sizeof(word)); delim = getword(fp, word, sizeof(word));
if (strlen(word) == 0) if (strlen(word) == 0)
@@ -442,20 +447,21 @@ lwres_conf_parseoption(lwres_context_t *ctx, FILE *fp,
} }
lwres_result_t 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; FILE *fp = NULL;
char word[256]; char word[256];
int delim; int delim;
lwres_result_t rval; lwres_result_t rval;
lwres_context_t *ctx; lwres_conf_t *confdata;
REQUIRE(ctx != NULL);
confdata = &ctx->confdata;
REQUIRE(filename != NULL); REQUIRE(filename != NULL);
REQUIRE(strlen(filename) > 0); REQUIRE(strlen(filename) > 0);
REQUIRE(confdata != NULL); REQUIRE(confdata != NULL);
ctx = confdata->lwctx;
rval = LWRES_R_FAILURE; /* Make compiler happy. */ rval = LWRES_R_FAILURE; /* Make compiler happy. */
errno = 0; errno = 0;
if ((fp = fopen(filename, "r")) == NULL) 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) if (strcmp(word, "nameserver") == 0)
rval = lwres_conf_parsenameserver(ctx, fp, confdata); rval = lwres_conf_parsenameserver(ctx, fp);
else if (strcmp(word, "domain") == 0) 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) 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) 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) else if (strcmp(word, "option") == 0)
rval = lwres_conf_parseoption(ctx, fp, confdata); rval = lwres_conf_parseoption(ctx, fp);
} while (rval == LWRES_R_SUCCESS); } while (rval == LWRES_R_SUCCESS);
fclose(fp); fclose(fp);
@@ -486,11 +492,15 @@ lwres_conf_parse(const char *filename, lwres_conf_t *confdata)
} }
lwres_result_t lwres_result_t
lwres_conf_print(FILE *fp, lwres_conf_t *confdata) lwres_conf_print(lwres_context_t *ctx, FILE *fp)
{ {
int i; int i;
char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"]; char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"];
const char *p; const char *p;
lwres_conf_t *confdata;
REQUIRE(ctx != NULL);
confdata = &ctx->confdata;
REQUIRE(confdata->nsnext <= LWRES_CONFMAXNAMESERVERS); REQUIRE(confdata->nsnext <= LWRES_CONFMAXNAMESERVERS);
@@ -553,3 +563,11 @@ lwres_conf_print(FILE *fp, lwres_conf_t *confdata)
return (LWRES_R_SUCCESS); 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; int ret;
size_t payload_length; size_t payload_length;
lwres_uint16_t datalen; lwres_uint16_t datalen;
lwres_addr_t *addr;
int x; int x;
REQUIRE(ctx != NULL); REQUIRE(ctx != NULL);
@@ -108,17 +109,22 @@ lwres_gabnresponse_render(lwres_context_t *ctx, lwres_gabnresponse_t *req,
REQUIRE(b != NULL); REQUIRE(b != NULL);
/* naliases, naddrs */ /* naliases, naddrs */
payload_length = sizeof(lwres_uint16_t) * 2; payload_length = 2 * 2;
/* real name encoding */ /* real name encoding */
payload_length += 2 + req->realnamelen + 1; payload_length += 2 + req->realnamelen + 1;
/* each alias */ /* each alias */
for (x = 0 ; x < req->naliases ; x++) for (x = 0 ; x < req->naliases ; x++)
payload_length += 2 + req->aliaslen[x] + 1; payload_length += 2 + req->aliaslen[x] + 1;
/* each address */ /* each address */
for (x = 0 ; x < req->naddrs ; x++) { x = 0;
payload_length += sizeof(lwres_uint32_t) + sizeof(lwres_uint16_t); addr = LWRES_LIST_HEAD(req->addrs);
payload_length += req->addrs[x].length; 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; buflen = LWRES_LWPACKET_LENGTH + payload_length;
buf = CTXMALLOC(buflen); buf = CTXMALLOC(buflen);
@@ -163,14 +169,14 @@ lwres_gabnresponse_render(lwres_context_t *ctx, lwres_gabnresponse_t *req,
} }
/* encode the addresses */ /* encode the addresses */
for (x = 0 ; x < req->naddrs ; x++) { addr = LWRES_LIST_HEAD(req->addrs);
datalen = req->addrs[x].length + sizeof(lwres_uint16_t) while (addr != NULL) {
+ sizeof(lwres_uint32_t); datalen = addr->length + 2 + 4;
INSIST(SPACE_OK(b, datalen)); INSIST(SPACE_OK(b, datalen));
lwres_buffer_putuint32(b, req->addrs[x].family); lwres_buffer_putuint32(b, addr->family);
lwres_buffer_putuint16(b, req->addrs[x].length); lwres_buffer_putuint16(b, addr->length);
lwres_buffer_putmem(b, req->addrs[x].address, lwres_buffer_putmem(b, addr->address, addr->length);
req->addrs[x].length); addr = LWRES_LIST_NEXT(addr, link);
} }
INSIST(LWRES_BUFFER_AVAILABLECOUNT(b) == 0); 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_gabnresponse_parse(lwres_context_t *ctx, lwres_buffer_t *b,
lwres_lwpacket_t *pkt, lwres_gabnresponse_t **structp) lwres_lwpacket_t *pkt, lwres_gabnresponse_t **structp)
{ {
int ret; lwres_result_t ret;
unsigned int x; unsigned int x;
lwres_uint16_t naliases; lwres_uint16_t naliases;
lwres_uint16_t naddrs; lwres_uint16_t naddrs;
lwres_gabnresponse_t *gabn; lwres_gabnresponse_t *gabn;
lwres_addrlist_t addrlist;
lwres_addr_t *addr;
REQUIRE(ctx != NULL); REQUIRE(ctx != NULL);
REQUIRE(pkt != NULL); REQUIRE(pkt != NULL);
@@ -257,7 +265,7 @@ lwres_gabnresponse_parse(lwres_context_t *ctx, lwres_buffer_t *b,
return (LWRES_R_NOMEMORY); return (LWRES_R_NOMEMORY);
gabn->aliases = NULL; gabn->aliases = NULL;
gabn->aliaslen = NULL; gabn->aliaslen = NULL;
gabn->addrs = NULL; LWRES_LIST_INIT(gabn->addrs);
gabn->base = NULL; gabn->base = NULL;
gabn->naliases = naliases; gabn->naliases = naliases;
@@ -277,12 +285,15 @@ lwres_gabnresponse_parse(lwres_context_t *ctx, lwres_buffer_t *b,
} }
} }
if (naddrs > 0) { LWRES_LIST_INIT(addrlist);
gabn->addrs = CTXMALLOC(sizeof(lwres_addr_t) * naddrs); for (x = 0 ; x < naddrs ; x++) {
if (gabn->addrs == NULL) { addr = CTXMALLOC(sizeof(lwres_addr_t));
if (addr == NULL) {
ret = LWRES_R_NOMEMORY; ret = LWRES_R_NOMEMORY;
goto out; 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++) { 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) if (ret != LWRES_R_SUCCESS)
goto out; goto out;
addr = LWRES_LIST_NEXT(addr, link);
} }
/*
* Do the sortlist thing here. XXXMLG
*/
gabn->addrs = addrlist;
if (LWRES_BUFFER_REMAINING(b) != 0) { if (LWRES_BUFFER_REMAINING(b) != 0) {
ret = LWRES_R_TRAILINGDATA; ret = LWRES_R_TRAILINGDATA;
goto out; goto out;
@@ -326,8 +346,12 @@ lwres_gabnresponse_parse(lwres_context_t *ctx, lwres_buffer_t *b,
if (gabn->aliaslen != NULL) if (gabn->aliaslen != NULL)
CTXFREE(gabn->aliaslen, CTXFREE(gabn->aliaslen,
sizeof(lwres_uint16_t) * naliases); sizeof(lwres_uint16_t) * naliases);
if (gabn->addrs != NULL) addr = LWRES_LIST_HEAD(addrlist);
CTXFREE(gabn->addrs, sizeof(lwres_addr_t) * naddrs); 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)); CTXFREE(gabn, sizeof(lwres_gabnresponse_t));
} }
@@ -352,6 +376,7 @@ void
lwres_gabnresponse_free(lwres_context_t *ctx, lwres_gabnresponse_t **structp) lwres_gabnresponse_free(lwres_context_t *ctx, lwres_gabnresponse_t **structp)
{ {
lwres_gabnresponse_t *gabn; lwres_gabnresponse_t *gabn;
lwres_addr_t *addr;
REQUIRE(ctx != NULL); REQUIRE(ctx != NULL);
REQUIRE(structp != NULL && *structp != 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->aliases, sizeof(char *) * gabn->naliases);
CTXFREE(gabn->aliaslen, sizeof(lwres_uint16_t) * gabn->naliases); CTXFREE(gabn->aliaslen, sizeof(lwres_uint16_t) * gabn->naliases);
} }
if (gabn->naddrs > 0) addr = LWRES_LIST_HEAD(gabn->addrs);
CTXFREE(gabn->addrs, sizeof(lwres_addr_t) * gabn->naddrs); 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) if (gabn->base != NULL)
CTXFREE(gabn->base, gabn->baselen); CTXFREE(gabn->base, gabn->baselen);
CTXFREE(gabn, sizeof(lwres_gabnresponse_t)); 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); 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_result_t
lwres_getaddrsbyname(lwres_context_t *ctx, const char *name, lwres_getaddrsbyname(lwres_context_t *ctx, const char *name,
lwres_uint32_t addrtypes, lwres_gabnresponse_t **structp) 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_lwpacket_t pkt;
lwres_uint32_t serial; lwres_uint32_t serial;
char *buffer; 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(ctx != NULL);
REQUIRE(name != NULL); REQUIRE(name != NULL);
REQUIRE(addrtypes != 0); REQUIRE(addrtypes != 0);
REQUIRE(structp != NULL && *structp == NULL); 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_in.base = NULL;
b_out.base = NULL; b_out.base = NULL;
response = NULL; response = NULL;
@@ -138,12 +175,56 @@ lwres_getaddrsbyname(lwres_context_t *ctx, const char *name,
goto out; 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. * Set up our request and render it to a buffer.
*/ */
request.addrtypes = addrtypes; request.addrtypes = addrtypes;
request.name = (char *)name; request.name = target_name;
request.namelen = strlen(name); request.namelen = target_length;
pkt.flags = 0; pkt.flags = 0;
pkt.serial = serial; pkt.serial = serial;
pkt.result = 0; pkt.result = 0;
@@ -184,6 +265,9 @@ lwres_getaddrsbyname(lwres_context_t *ctx, const char *name,
b_out.base = NULL; b_out.base = NULL;
b_out.length = 0; b_out.length = 0;
if (pkt.result == LWRES_R_NOTFOUND)
goto next_suffix;
if (pkt.result != LWRES_R_SUCCESS) { if (pkt.result != LWRES_R_SUCCESS) {
ret = pkt.result; ret = pkt.result;
goto out; goto out;

View File

@@ -742,6 +742,7 @@
./lib/lwres/include/lwres/Makefile.in MAKE 2000 ./lib/lwres/include/lwres/Makefile.in MAKE 2000
./lib/lwres/include/lwres/context.h C 2000 ./lib/lwres/include/lwres/context.h C 2000
./lib/lwres/include/lwres/ipv6.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/lwbuffer.h C 2000
./lib/lwres/include/lwres/lwpacket.h C 1999,2000 ./lib/lwres/include/lwres/lwpacket.h C 1999,2000
./lib/lwres/include/lwres/lwres.h C 2000 ./lib/lwres/include/lwres/lwres.h C 2000