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:
Michael Graff
2000-03-12 01:58:41 +00:00
parent d736db6dc5
commit 915723e400
8 changed files with 143 additions and 39 deletions

View File

@@ -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);
}
}

View File

@@ -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:

View File

@@ -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 */

View File

@@ -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 */

View File

@@ -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);
}

View File

@@ -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++;

View File

@@ -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);

View File

@@ -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;