mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-30 05:57:52 +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:
parent
2311073ce0
commit
d736db6dc5
@ -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;
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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:
|
||||
|
@ -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);
|
||||
|
@ -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 =
|
||||
|
116
lib/lwres/include/lwres/list.h
Normal file
116
lib/lwres/include/lwres/list.h
Normal 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 */
|
@ -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>
|
||||
|
||||
@ -102,14 +103,14 @@
|
||||
|
||||
typedef struct {
|
||||
/* public */
|
||||
lwres_uint16_t datalength;
|
||||
unsigned char *data;
|
||||
lwres_uint16_t datalength;
|
||||
unsigned char *data;
|
||||
} lwres_nooprequest_t;
|
||||
|
||||
typedef struct {
|
||||
/* public */
|
||||
lwres_uint16_t datalength;
|
||||
unsigned char *data;
|
||||
lwres_uint16_t datalength;
|
||||
unsigned char *data;
|
||||
} lwres_noopresponse_t;
|
||||
|
||||
/*
|
||||
@ -117,31 +118,35 @@ typedef struct {
|
||||
*/
|
||||
#define LWRES_OPCODE_GETADDRSBYNAME 0x00010001U
|
||||
|
||||
typedef struct {
|
||||
lwres_uint32_t family;
|
||||
lwres_uint16_t length;
|
||||
const unsigned char *address;
|
||||
} lwres_addr_t;
|
||||
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_LINK(lwres_addr_t) link;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
/* public */
|
||||
lwres_uint32_t addrtypes;
|
||||
lwres_uint16_t namelen;
|
||||
char *name;
|
||||
lwres_uint32_t addrtypes;
|
||||
lwres_uint16_t namelen;
|
||||
char *name;
|
||||
} lwres_gabnrequest_t;
|
||||
|
||||
typedef struct {
|
||||
/* public */
|
||||
lwres_uint16_t naliases;
|
||||
lwres_uint16_t naddrs;
|
||||
char *realname;
|
||||
char **aliases;
|
||||
lwres_uint16_t realnamelen;
|
||||
lwres_uint16_t *aliaslen;
|
||||
lwres_addr_t *addrs;
|
||||
lwres_uint16_t naliases;
|
||||
lwres_uint16_t naddrs;
|
||||
char *realname;
|
||||
char **aliases;
|
||||
lwres_uint16_t realnamelen;
|
||||
lwres_uint16_t *aliaslen;
|
||||
lwres_addrlist_t addrs;
|
||||
/* if base != NULL, it will be freed when this structure is freed. */
|
||||
void *base;
|
||||
size_t baselen;
|
||||
void *base;
|
||||
size_t baselen;
|
||||
} lwres_gabnresponse_t;
|
||||
|
||||
/*
|
||||
@ -150,19 +155,19 @@ typedef struct {
|
||||
#define LWRES_OPCODE_GETNAMEBYADDR 0x00010002U
|
||||
typedef struct {
|
||||
/* public */
|
||||
lwres_addr_t addr;
|
||||
lwres_addr_t addr;
|
||||
} lwres_gnbarequest_t;
|
||||
|
||||
typedef struct {
|
||||
/* public */
|
||||
lwres_uint16_t naliases;
|
||||
char *realname;
|
||||
char **aliases;
|
||||
lwres_uint16_t realnamelen;
|
||||
lwres_uint16_t *aliaslen;
|
||||
lwres_uint16_t naliases;
|
||||
char *realname;
|
||||
char **aliases;
|
||||
lwres_uint16_t realnamelen;
|
||||
lwres_uint16_t *aliaslen;
|
||||
/* if base != NULL, it will be freed when this structure is freed. */
|
||||
void *base;
|
||||
size_t baselen;
|
||||
void *base;
|
||||
size_t baselen;
|
||||
} lwres_gnbaresponse_t;
|
||||
|
||||
|
||||
@ -195,8 +200,6 @@ typedef struct {
|
||||
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_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 */
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
unsigned int x;
|
||||
lwres_uint16_t naliases;
|
||||
lwres_uint16_t naddrs;
|
||||
lwres_gabnresponse_t *gabn;
|
||||
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));
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user