Copy addresses out, rather than keeping pointers to them from a buffer. This
simplifies code at the expense of copying more. It is, however, the easiest way to get sortlist working correctly. ipv6 addresses now sort as well.
This commit is contained in:
@@ -350,7 +350,7 @@ client_init_aliases(client_t *client)
|
||||
for (i = 0 ; i < LWRES_MAX_ADDRS ; i++) {
|
||||
client->addrs[i].family = 0;
|
||||
client->addrs[i].length = 0;
|
||||
client->addrs[i].address = NULL;
|
||||
memset(client->addrs[i].address, 0, LWRES_ADDR_MAXLEN);
|
||||
LWRES_LINK_INIT(&client->addrs[i], link);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,13 +93,13 @@ setup_addresses(client_t *client, dns_adbfind_t *find, unsigned int at)
|
||||
case AF_INET:
|
||||
sin = &ai->sockaddr->type.sin;
|
||||
addr->family = LWRES_ADDRTYPE_V4;
|
||||
addr->address = (unsigned char *)&sin->sin_addr;
|
||||
memcpy(addr->address, &sin->sin_addr, 4);
|
||||
addr->length = 4;
|
||||
break;
|
||||
case AF_INET6:
|
||||
sin6 = &ai->sockaddr->type.sin6;
|
||||
addr->family = LWRES_ADDRTYPE_V6;
|
||||
addr->address = (unsigned char *)&sin6->sin6_addr;
|
||||
memcpy(addr->address, &sin6->sin6_addr, 16);
|
||||
addr->length = 16;
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -369,7 +369,8 @@ lwres_buffer_putuint32(lwres_buffer_t *b, lwres_uint32_t val);
|
||||
*/
|
||||
|
||||
void
|
||||
lwres_buffer_putmem(lwres_buffer_t *b, const unsigned char *base, unsigned int length);
|
||||
lwres_buffer_putmem(lwres_buffer_t *b, const unsigned char *base,
|
||||
unsigned int length);
|
||||
/*
|
||||
* Copy 'length' bytes of memory at 'base' into 'b'.
|
||||
*
|
||||
@@ -380,6 +381,20 @@ lwres_buffer_putmem(lwres_buffer_t *b, const unsigned char *base, unsigned int l
|
||||
*
|
||||
*/
|
||||
|
||||
void
|
||||
lwres_buffer_getmem(lwres_buffer_t *b, unsigned char *base,
|
||||
unsigned int length);
|
||||
/*
|
||||
* Copy 'length' bytes of memory from 'b' into 'base'.
|
||||
*
|
||||
* Requires:
|
||||
* 'b' is a valid buffer.
|
||||
*
|
||||
* 'base' points to at least 'length' bytes of valid memory.
|
||||
*
|
||||
* 'b' have at least 'length' bytes remaining.
|
||||
*/
|
||||
|
||||
LWRES_LANG_ENDDECLS
|
||||
|
||||
#endif /* LWRES_BUFFER_H */
|
||||
|
||||
@@ -88,6 +88,7 @@
|
||||
|
||||
#define LWRES_UDP_PORT 921 /* XXXMLG */
|
||||
#define LWRES_RECVLENGTH 2048 /* XXXMLG */
|
||||
#define LWRES_ADDR_MAXLEN 16 /* XXXMLG changing this breaks ABI */
|
||||
|
||||
/*
|
||||
* XXXMLG
|
||||
@@ -124,7 +125,7 @@ typedef LWRES_LIST(lwres_addr_t) lwres_addrlist_t;
|
||||
struct lwres_addr {
|
||||
lwres_uint32_t family;
|
||||
lwres_uint16_t length;
|
||||
const unsigned char *address;
|
||||
unsigned char address[LWRES_ADDR_MAXLEN];
|
||||
LWRES_LINK(lwres_addr_t) link;
|
||||
};
|
||||
|
||||
@@ -174,7 +175,7 @@ typedef struct {
|
||||
/*
|
||||
* resolv.conf DATA
|
||||
*/
|
||||
|
||||
|
||||
#define LWRES_CONFMAXNAMESERVERS 3 /* max 3 "nameserver" entries */
|
||||
#define LWRES_CONFMAXSEARCH 6 /* max 6 domains in "search" entry */
|
||||
#define LWRES_CONFMAXLINELEN 256 /* max size of a line */
|
||||
|
||||
@@ -256,7 +256,8 @@ lwres_buffer_putuint32(lwres_buffer_t *b, lwres_uint32_t val)
|
||||
}
|
||||
|
||||
void
|
||||
lwres_buffer_putmem(lwres_buffer_t *b, const unsigned char *base, unsigned int length)
|
||||
lwres_buffer_putmem(lwres_buffer_t *b, const unsigned char *base,
|
||||
unsigned int length)
|
||||
{
|
||||
unsigned char *cp;
|
||||
|
||||
@@ -267,3 +268,19 @@ lwres_buffer_putmem(lwres_buffer_t *b, const unsigned char *base, unsigned int l
|
||||
memcpy(cp, base, length);
|
||||
b->used += length;
|
||||
}
|
||||
|
||||
void
|
||||
lwres_buffer_getmem(lwres_buffer_t *b, unsigned char *base,
|
||||
unsigned int length)
|
||||
{
|
||||
unsigned char *cp;
|
||||
|
||||
REQUIRE(LWRES_BUFFER_VALID(b));
|
||||
REQUIRE(b->used - b->current >= length);
|
||||
|
||||
cp = b->base;
|
||||
cp += b->current;
|
||||
b->current += length;
|
||||
|
||||
memcpy(base, cp, length);
|
||||
}
|
||||
|
||||
@@ -85,11 +85,10 @@ static lwres_result_t
|
||||
lwres_conf_parseoption(lwres_context_t *ctx, FILE *fp);
|
||||
|
||||
static void
|
||||
lwres_resetaddr(lwres_context_t *ctx, lwres_addr_t *addr, int freeit);
|
||||
lwres_resetaddr(lwres_addr_t *addr);
|
||||
|
||||
static lwres_result_t
|
||||
lwres_create_addr(lwres_context_t *ctx, const char *buff,
|
||||
lwres_addr_t *addr);
|
||||
lwres_create_addr(const char *buff, lwres_addr_t *addr);
|
||||
|
||||
/*
|
||||
* Skip over any leading whitespace and then read in the next sequence of
|
||||
@@ -130,14 +129,11 @@ getword(FILE *fp, char *buffer, size_t size)
|
||||
}
|
||||
|
||||
static void
|
||||
lwres_resetaddr(lwres_context_t *ctx, lwres_addr_t *addr, int freeit)
|
||||
lwres_resetaddr(lwres_addr_t *addr)
|
||||
{
|
||||
REQUIRE(addr != NULL);
|
||||
|
||||
if (freeit && addr->address != NULL)
|
||||
CTXFREE((void *)addr->address, addr->length);
|
||||
|
||||
addr->address = NULL;
|
||||
memset(addr->address, 0, LWRES_ADDR_MAXLEN);
|
||||
addr->family = 0;
|
||||
addr->length = 0;
|
||||
}
|
||||
@@ -175,14 +171,14 @@ lwres_conf_init(lwres_context_t *ctx)
|
||||
confdata->no_tld_query = 0;
|
||||
|
||||
for (i = 0 ; i < LWRES_CONFMAXNAMESERVERS ; i++)
|
||||
lwres_resetaddr(NULL, &confdata->nameservers[i], 0);
|
||||
lwres_resetaddr(&confdata->nameservers[i]);
|
||||
|
||||
for (i = 0 ; i < LWRES_CONFMAXSEARCH ; i++)
|
||||
confdata->search[i] = NULL;
|
||||
|
||||
for (i = 0 ; i < LWRES_CONFMAXSORTLIST ; i++) {
|
||||
lwres_resetaddr(NULL, &confdata->sortlist[i].addr, 0);
|
||||
lwres_resetaddr(NULL, &confdata->sortlist[i].mask, 0);
|
||||
lwres_resetaddr(&confdata->sortlist[i].addr);
|
||||
lwres_resetaddr(&confdata->sortlist[i].mask);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -196,7 +192,7 @@ lwres_conf_clear(lwres_context_t *ctx)
|
||||
confdata = &ctx->confdata;
|
||||
|
||||
for (i = 0 ; i < confdata->nsnext ; i++)
|
||||
lwres_resetaddr(ctx, &confdata->nameservers[i], 1);
|
||||
lwres_resetaddr(&confdata->nameservers[i]);
|
||||
|
||||
if (confdata->domainname != NULL) {
|
||||
CTXFREE(confdata->domainname,
|
||||
@@ -213,8 +209,8 @@ lwres_conf_clear(lwres_context_t *ctx)
|
||||
}
|
||||
|
||||
for (i = 0 ; i < LWRES_CONFMAXSORTLIST ; i++) {
|
||||
lwres_resetaddr(ctx, &confdata->sortlist[i].addr, 1);
|
||||
lwres_resetaddr(ctx, &confdata->sortlist[i].mask, 1);
|
||||
lwres_resetaddr(&confdata->sortlist[i].addr);
|
||||
lwres_resetaddr(&confdata->sortlist[i].mask);
|
||||
}
|
||||
|
||||
confdata->nsnext = 0;
|
||||
@@ -244,7 +240,7 @@ lwres_conf_parsenameserver(lwres_context_t *ctx, FILE *fp)
|
||||
else if (res != EOF && res != '\n')
|
||||
return (LWRES_R_FAILURE); /* extra junk on line */
|
||||
|
||||
res = lwres_create_addr(ctx, word,
|
||||
res = lwres_create_addr(word,
|
||||
&confdata->nameservers[confdata->nsnext++]);
|
||||
if (res != LWRES_R_SUCCESS)
|
||||
return (res);
|
||||
@@ -340,25 +336,26 @@ lwres_conf_parsesearch(lwres_context_t *ctx, FILE *fp)
|
||||
}
|
||||
|
||||
static lwres_result_t
|
||||
lwres_create_addr(lwres_context_t *ctx, const char *buffer, lwres_addr_t *addr)
|
||||
lwres_create_addr(const char *buffer, lwres_addr_t *addr)
|
||||
{
|
||||
unsigned char addrbuff[NS_IN6ADDRSZ];
|
||||
unsigned int len;
|
||||
|
||||
if (lwres_net_pton(AF_INET, buffer, &addrbuff) == 1) {
|
||||
addr->family = AF_INET;
|
||||
addr->family = LWRES_ADDRTYPE_V4;
|
||||
addr->length = NS_INADDRSZ;
|
||||
addr->address = CTXMALLOC(NS_INADDRSZ);
|
||||
len = 4;
|
||||
#if defined(AF_INET6)
|
||||
} else if (lwres_net_pton(AF_INET6, buffer, &addrbuff) == 1) {
|
||||
addr->family = AF_INET6;
|
||||
addr->family = LWRES_ADDRTYPE_V6;
|
||||
addr->length = NS_IN6ADDRSZ;
|
||||
addr->address = CTXMALLOC(NS_IN6ADDRSZ);
|
||||
len = 16;
|
||||
#endif
|
||||
} else {
|
||||
return (LWRES_R_FAILURE); /* unrecongnised format */
|
||||
}
|
||||
|
||||
memcpy((void *)addr->address, addrbuff, 4);
|
||||
memcpy((void *)addr->address, addrbuff, len);
|
||||
|
||||
return (LWRES_R_SUCCESS);
|
||||
}
|
||||
@@ -386,16 +383,22 @@ lwres_conf_parsesortlist(lwres_context_t *ctx, FILE *fp)
|
||||
*p++ = '\0';
|
||||
|
||||
idx = confdata->sortlistnxt;
|
||||
res = lwres_create_addr(ctx, word,
|
||||
&confdata->sortlist[idx].addr);
|
||||
res = lwres_create_addr(word, &confdata->sortlist[idx].addr);
|
||||
if (res != LWRES_R_SUCCESS)
|
||||
return (res);
|
||||
|
||||
if (p != NULL) {
|
||||
res = lwres_create_addr(ctx, p,
|
||||
res = lwres_create_addr(p,
|
||||
&confdata->sortlist[idx].mask);
|
||||
if (res != LWRES_R_SUCCESS)
|
||||
return (res);
|
||||
} else {
|
||||
/* Make up a mask. */
|
||||
confdata->sortlist[idx].mask =
|
||||
confdata->sortlist[idx].addr;
|
||||
|
||||
memset(&confdata->sortlist[idx].mask, 0xff,
|
||||
confdata->sortlist[idx].addr.length);
|
||||
}
|
||||
|
||||
confdata->sortlistnxt++;
|
||||
|
||||
@@ -29,6 +29,71 @@
|
||||
#include "context_p.h"
|
||||
#include "assert_p.h"
|
||||
|
||||
static void
|
||||
lwres_sortlist(lwres_context_t *ctx, lwres_addrlist_t *inlist,
|
||||
lwres_addrlist_t *outlist)
|
||||
{
|
||||
unsigned int i, x;
|
||||
lwres_conf_t *confdata;
|
||||
unsigned char mask[LWRES_ADDR_MAXLEN];
|
||||
unsigned char sortaddr[LWRES_ADDR_MAXLEN];
|
||||
unsigned char listaddr[LWRES_ADDR_MAXLEN];
|
||||
unsigned int length;
|
||||
lwres_addr_t *addr;
|
||||
lwres_addr_t *nextaddr;
|
||||
|
||||
confdata = &ctx->confdata;
|
||||
|
||||
/*
|
||||
* If there is no sortlist, we're done.
|
||||
*/
|
||||
if (confdata->sortlistnxt == 0) {
|
||||
*outlist = *inlist;
|
||||
return;
|
||||
}
|
||||
|
||||
LWRES_LIST_INIT(*outlist);
|
||||
|
||||
for (i = 0 ; i < confdata->sortlistnxt ; i++) {
|
||||
length = confdata->sortlist[i].addr.length;
|
||||
INSIST(length == confdata->sortlist[i].mask.length);
|
||||
memcpy(mask, confdata->sortlist[i].mask.address, length);
|
||||
memcpy(sortaddr, confdata->sortlist[i].addr.address, length);
|
||||
for (x = 0 ; x < length ; x++)
|
||||
sortaddr[x] &= mask[x];
|
||||
|
||||
addr = LWRES_LIST_HEAD(*inlist);
|
||||
while (addr != NULL) {
|
||||
nextaddr = LWRES_LIST_NEXT(addr, link);
|
||||
|
||||
if (addr->family != confdata->sortlist[i].addr.family)
|
||||
goto next;
|
||||
|
||||
memcpy(listaddr, addr->address, length);
|
||||
for (x = 0 ; x < length ; x++)
|
||||
listaddr[x] &= mask[x];
|
||||
|
||||
if (memcmp(listaddr, sortaddr, length) == 0) {
|
||||
LWRES_LIST_UNLINK(*inlist, addr, link);
|
||||
LWRES_LIST_APPEND(*outlist, addr, link);
|
||||
}
|
||||
|
||||
next:
|
||||
addr = nextaddr;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Get everything that doesn't match any sortlist lines.
|
||||
*/
|
||||
addr = LWRES_LIST_HEAD(*inlist);
|
||||
while (addr != NULL) {
|
||||
LWRES_LIST_UNLINK(*inlist, addr, link);
|
||||
LWRES_LIST_APPEND(*outlist, addr, link);
|
||||
addr = LWRES_LIST_HEAD(*inlist);
|
||||
}
|
||||
}
|
||||
|
||||
lwres_result_t
|
||||
lwres_gabnrequest_render(lwres_context_t *ctx, lwres_gabnrequest_t *req,
|
||||
lwres_lwpacket_t *pkt, lwres_buffer_t *b)
|
||||
@@ -326,16 +391,17 @@ lwres_gabnresponse_parse(lwres_context_t *ctx, lwres_buffer_t *b,
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
* Do the sortlist thing here. After this is done, "addrlist"
|
||||
* must NOT be used again, since it will be very very bogus.
|
||||
*/
|
||||
lwres_sortlist(ctx, &addrlist, &gabn->addrs);
|
||||
|
||||
*structp = gabn;
|
||||
return (LWRES_R_SUCCESS);
|
||||
|
||||
|
||||
@@ -102,8 +102,10 @@ lwres_addr_parse(lwres_buffer_t *b, lwres_addr_t *addr)
|
||||
|
||||
if (!SPACE_REMAINING(b, addr->length))
|
||||
return (LWRES_R_UNEXPECTEDEND);
|
||||
addr->address = b->base + b->current;
|
||||
lwres_buffer_forward(b, addr->length);
|
||||
if (addr->length > LWRES_ADDR_MAXLEN)
|
||||
return (LWRES_R_FAILURE);
|
||||
|
||||
lwres_buffer_getmem(b, addr->address, addr->length);
|
||||
|
||||
return (LWRES_R_SUCCESS);
|
||||
}
|
||||
@@ -335,7 +337,7 @@ lwres_getnamebyaddr(lwres_context_t *ctx, lwres_uint32_t addrtype,
|
||||
*/
|
||||
request.addr.family = addrtype;
|
||||
request.addr.length = addrlen;
|
||||
request.addr.address = addr;
|
||||
memcpy(request.addr.address, addr, addrlen);
|
||||
pkt.flags = 0;
|
||||
pkt.serial = serial;
|
||||
pkt.result = 0;
|
||||
|
||||
Reference in New Issue
Block a user