mirror of
http://thekelleys.org.uk/git/dnsmasq.git
synced 2026-11-03 13:38:32 +00:00
Compare commits
14
Commits
v2.93test2
...
v2.93test4
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e4d0bb4579 | ||
|
|
84415a87be | ||
|
|
1537645e8f | ||
|
|
ceab392c60 | ||
|
|
5f0f6aa9b1 | ||
|
|
578ea08391 | ||
|
|
fbfcf87f8b | ||
|
|
19f3e06e7a | ||
|
|
40d1152059 | ||
|
|
3c830c4f1c | ||
|
|
e9f400dd37 | ||
|
|
870f14108f | ||
|
|
714d36229a | ||
|
|
60e90e2224 |
No files matched your search
@@ -24,6 +24,10 @@ version 2.93
|
||||
accepts a signed CNAME reply to a DS query as proof that no DS
|
||||
exists at the domain. This fixes the DS/zone break detection logic.
|
||||
|
||||
Fix regression in 2.92 release which broke DHCPv6 when a DHCP
|
||||
relay is in use. Many thanks to Jørgen Søvik for help
|
||||
finding this bug.
|
||||
|
||||
|
||||
version 2.92
|
||||
Redesign the interaction between DNSSEC validation and per-domain
|
||||
|
||||
+6
-8
@@ -193,22 +193,20 @@ void *blockdata_retrieve(struct blockdata *block, size_t len, void *data)
|
||||
{
|
||||
size_t blen;
|
||||
struct blockdata *b;
|
||||
uint8_t *new, *d;
|
||||
uint8_t *d;
|
||||
|
||||
static unsigned int buff_len = 0;
|
||||
static unsigned char *buff = NULL;
|
||||
|
||||
if (!data)
|
||||
{
|
||||
static unsigned int buff_len = 0;
|
||||
static unsigned char *buff = NULL;
|
||||
uint8_t *new;
|
||||
|
||||
if (len > buff_len)
|
||||
{
|
||||
blen = len + 1024;
|
||||
if (!(new = whine_malloc(blen)))
|
||||
if (!(new = whine_realloc(buff, blen)))
|
||||
return NULL;
|
||||
|
||||
if (buff)
|
||||
free(buff);
|
||||
|
||||
buff = new;
|
||||
buff_len = blen;
|
||||
}
|
||||
|
||||
+146
-102
@@ -17,13 +17,16 @@
|
||||
#include "dnsmasq.h"
|
||||
|
||||
static struct crec *cache_head = NULL, *cache_tail = NULL, **hash_table = NULL;
|
||||
#ifdef HAVE_DHCP
|
||||
static struct crec *dhcp_spare = NULL;
|
||||
#endif
|
||||
static struct crec *config_spare = NULL;
|
||||
static struct crec *new_chain = NULL;
|
||||
static int insert_error;
|
||||
static union bigname *big_free = NULL;
|
||||
static int bignames_left, hash_size;
|
||||
struct nameblock {
|
||||
struct nameblock *next;
|
||||
unsigned int last, index;
|
||||
char data[NAMEBLOCK_CHARS];
|
||||
} *hostblocks = NULL;
|
||||
|
||||
static void make_non_terminals(struct crec *source);
|
||||
static struct crec *really_insert(char *name, union all_addr *addr, unsigned short class,
|
||||
@@ -192,6 +195,61 @@ void cache_init(void)
|
||||
rehash(daemon->cachesize);
|
||||
}
|
||||
|
||||
static struct crec *get_config_crec(void)
|
||||
{
|
||||
struct crec *ret;
|
||||
|
||||
if (config_spare)
|
||||
{
|
||||
ret = config_spare;
|
||||
config_spare = config_spare->next;
|
||||
}
|
||||
else
|
||||
ret = whine_malloc(SIZEOF_POINTER_CREC);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void free_config_crec(struct crec *p)
|
||||
{
|
||||
p->next = config_spare;
|
||||
config_spare = p;
|
||||
}
|
||||
|
||||
static char *store_name(unsigned int namelen, unsigned int index)
|
||||
{
|
||||
struct nameblock *block;
|
||||
char *ret = NULL;
|
||||
|
||||
for (block = hostblocks; block; block = block->next)
|
||||
if (block->index == index && NAMEBLOCK_CHARS - block->last >= namelen)
|
||||
break;
|
||||
|
||||
if (!block && ((block = whine_malloc(sizeof(struct nameblock)))))
|
||||
{
|
||||
block->next = hostblocks;
|
||||
block->index = index;
|
||||
hostblocks = block;
|
||||
}
|
||||
|
||||
if (block && NAMEBLOCK_CHARS - block->last >= namelen)
|
||||
{
|
||||
ret = &block->data[block->last];
|
||||
block->last += namelen;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void free_names(unsigned int index)
|
||||
{
|
||||
struct nameblock *block;
|
||||
|
||||
for (block = hostblocks; block; block = block->next)
|
||||
if (index == UID_NONE || block->index == index)
|
||||
block->last = 0;
|
||||
}
|
||||
|
||||
/* In most cases, we create the hash table once here by calling this with (hash_table == NULL)
|
||||
but if the hosts file(s) are big (some people have 50000 ad-block entries), the table
|
||||
will be much too small, so the hosts reading code calls rehash every 1000 addresses, to
|
||||
@@ -441,12 +499,14 @@ unsigned int cache_remove_uid(const unsigned int uid)
|
||||
if ((crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)) && crecp->uid == uid)
|
||||
{
|
||||
*up = tmp;
|
||||
free(crecp);
|
||||
free_config_crec(crecp);
|
||||
removed++;
|
||||
}
|
||||
else
|
||||
up = &crecp->hash_next;
|
||||
}
|
||||
|
||||
free_names(uid);
|
||||
|
||||
return removed;
|
||||
}
|
||||
@@ -1261,7 +1321,7 @@ static void add_hosts_entry(struct crec *cache, union all_addr *addr, int addrle
|
||||
while ((lookup = cache_find_by_name(lookup, cache_get_name(cache), 0, cache->flags & (F_IPV4 | F_IPV6))))
|
||||
if ((lookup->flags & F_HOSTS) && memcmp(&lookup->addr, addr, addrlen) == 0)
|
||||
{
|
||||
free(cache);
|
||||
free_config_crec(cache);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1384,13 +1444,13 @@ int read_hostsfile(char *filename, unsigned int index, int cache_size, struct cr
|
||||
{
|
||||
if (inet_pton(AF_INET, token, &addr) > 0)
|
||||
{
|
||||
flags = F_HOSTS | F_IMMORTAL | F_FORWARD | F_REVERSE | F_IPV4;
|
||||
flags = F_NAMEP | F_HOSTS | F_IMMORTAL | F_FORWARD | F_REVERSE | F_IPV4;
|
||||
addrlen = INADDRSZ;
|
||||
domain_suffix = get_domain(addr.addr4);
|
||||
}
|
||||
else if (inet_pton(AF_INET6, token, &addr) > 0)
|
||||
{
|
||||
flags = F_HOSTS | F_IMMORTAL | F_FORWARD | F_REVERSE | F_IPV6;
|
||||
flags = F_NAMEP | F_HOSTS | F_IMMORTAL | F_FORWARD | F_REVERSE | F_IPV6;
|
||||
addrlen = IN6ADDRSZ;
|
||||
domain_suffix = get_domain6(&addr.addr6);
|
||||
}
|
||||
@@ -1424,27 +1484,37 @@ int read_hostsfile(char *filename, unsigned int index, int cache_size, struct cr
|
||||
if ((canon = canonicalise(token, &nomem)))
|
||||
{
|
||||
/* If set, add a version of the name with a default domain appended */
|
||||
if (option_bool(OPT_EXPAND) && domain_suffix && !fqdn &&
|
||||
(cache = whine_malloc(SIZEOF_BARE_CREC + strlen(canon) + 2 + strlen(domain_suffix))))
|
||||
if (option_bool(OPT_EXPAND) && domain_suffix && !fqdn && (cache = get_config_crec()))
|
||||
{
|
||||
strcpy(cache->name.sname, canon);
|
||||
strcat(cache->name.sname, ".");
|
||||
strcat(cache->name.sname, domain_suffix);
|
||||
cache->flags = flags;
|
||||
cache->ttd = daemon->local_ttl;
|
||||
add_hosts_entry(cache, &addr, addrlen, index, rhash, hashsz);
|
||||
name_count++;
|
||||
names_done++;
|
||||
if (!(cache->name.namep = store_name(strlen(canon) + 2 + strlen(domain_suffix), index)))
|
||||
free_config_crec(cache);
|
||||
else
|
||||
{
|
||||
strcpy(cache->name.namep, canon);
|
||||
strcat(cache->name.namep, ".");
|
||||
strcat(cache->name.namep, domain_suffix);
|
||||
cache->flags = flags;
|
||||
cache->ttd = daemon->local_ttl;
|
||||
add_hosts_entry(cache, &addr, addrlen, index, rhash, hashsz);
|
||||
name_count++;
|
||||
names_done++;
|
||||
}
|
||||
}
|
||||
if ((cache = whine_malloc(SIZEOF_BARE_CREC + strlen(canon) + 1)))
|
||||
if ((cache = get_config_crec()))
|
||||
{
|
||||
strcpy(cache->name.sname, canon);
|
||||
cache->flags = flags;
|
||||
cache->ttd = daemon->local_ttl;
|
||||
add_hosts_entry(cache, &addr, addrlen, index, rhash, hashsz);
|
||||
name_count++;
|
||||
names_done++;
|
||||
if (!(cache->name.namep = store_name(strlen(canon) + 1, index)))
|
||||
free_config_crec(cache);
|
||||
else
|
||||
{
|
||||
strcpy(cache->name.namep, canon);
|
||||
cache->flags = flags;
|
||||
cache->ttd = daemon->local_ttl;
|
||||
add_hosts_entry(cache, &addr, addrlen, index, rhash, hashsz);
|
||||
name_count++;
|
||||
names_done++;
|
||||
}
|
||||
}
|
||||
|
||||
free(canon);
|
||||
|
||||
}
|
||||
@@ -1495,7 +1565,7 @@ void cache_reload(void)
|
||||
if (cache->flags & (F_HOSTS | F_CONFIG))
|
||||
{
|
||||
*up = cache->hash_next;
|
||||
free(cache);
|
||||
free_config_crec(cache);
|
||||
}
|
||||
else if (!(cache->flags & F_DHCP))
|
||||
{
|
||||
@@ -1510,11 +1580,13 @@ void cache_reload(void)
|
||||
else
|
||||
up = &cache->hash_next;
|
||||
}
|
||||
|
||||
free_names(UID_NONE); /* free everything */
|
||||
|
||||
/* Add locally-configured CNAMEs to the cache */
|
||||
for (a = daemon->cnames; a; a = a->next)
|
||||
if (a->alias[1] != '*' &&
|
||||
((cache = whine_malloc(SIZEOF_POINTER_CREC))))
|
||||
((cache = get_config_crec())))
|
||||
{
|
||||
cache->flags = F_FORWARD | F_NAMEP | F_CNAME | F_IMMORTAL | F_CONFIG;
|
||||
cache->ttd = a->ttl;
|
||||
@@ -1528,25 +1600,30 @@ void cache_reload(void)
|
||||
|
||||
#ifdef HAVE_DNSSEC
|
||||
for (ds = daemon->ds; ds; ds = ds->next)
|
||||
if ((cache = whine_malloc(SIZEOF_POINTER_CREC)) &&
|
||||
(cache->addr.ds.keydata = blockdata_alloc(ds->digest, ds->digestlen)))
|
||||
if ((cache = get_config_crec()))
|
||||
{
|
||||
cache->flags = F_FORWARD | F_IMMORTAL | F_DS | F_CONFIG | F_NAMEP;
|
||||
cache->ttd = daemon->local_ttl;
|
||||
cache->name.namep = ds->name;
|
||||
cache->uid = ds->class;
|
||||
if (ds->digestlen != 0)
|
||||
{
|
||||
cache->addr.ds.keylen = ds->digestlen;
|
||||
cache->addr.ds.algo = ds->algo;
|
||||
cache->addr.ds.keytag = ds->keytag;
|
||||
cache->addr.ds.digest = ds->digest_type;
|
||||
}
|
||||
else
|
||||
cache->flags |= F_NEG | F_DNSSECOK | F_NO_RR;
|
||||
|
||||
cache_hash(cache);
|
||||
make_non_terminals(cache);
|
||||
if (!(cache->addr.ds.keydata = blockdata_alloc(ds->digest, ds->digestlen)))
|
||||
free_config_crec(cache);
|
||||
else
|
||||
{
|
||||
cache->flags = F_FORWARD | F_IMMORTAL | F_DS | F_CONFIG | F_NAMEP;
|
||||
cache->ttd = daemon->local_ttl;
|
||||
cache->name.namep = ds->name;
|
||||
cache->uid = ds->class;
|
||||
if (ds->digestlen != 0)
|
||||
{
|
||||
cache->addr.ds.keylen = ds->digestlen;
|
||||
cache->addr.ds.algo = ds->algo;
|
||||
cache->addr.ds.keytag = ds->keytag;
|
||||
cache->addr.ds.digest = ds->digest_type;
|
||||
}
|
||||
else
|
||||
cache->flags |= F_NEG | F_DNSSECOK | F_NO_RR;
|
||||
|
||||
cache_hash(cache);
|
||||
make_non_terminals(cache);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1561,7 +1638,7 @@ void cache_reload(void)
|
||||
for (nl = hr->names; nl; nl = nl->next)
|
||||
{
|
||||
if ((hr->flags & HR_4) &&
|
||||
(cache = whine_malloc(SIZEOF_POINTER_CREC)))
|
||||
(cache = get_config_crec()))
|
||||
{
|
||||
cache->name.namep = nl->name;
|
||||
cache->ttd = hr->ttl;
|
||||
@@ -1570,7 +1647,7 @@ void cache_reload(void)
|
||||
}
|
||||
|
||||
if ((hr->flags & HR_6) &&
|
||||
(cache = whine_malloc(SIZEOF_POINTER_CREC)))
|
||||
(cache = get_config_crec()))
|
||||
{
|
||||
cache->name.namep = nl->name;
|
||||
cache->ttd = hr->ttl;
|
||||
@@ -1662,8 +1739,7 @@ void cache_unhash_dhcp(void)
|
||||
if (cache->flags & F_DHCP)
|
||||
{
|
||||
*up = cache->hash_next;
|
||||
cache->next = dhcp_spare;
|
||||
dhcp_spare = cache;
|
||||
free_config_crec(cache);
|
||||
}
|
||||
else
|
||||
up = &cache->hash_next;
|
||||
@@ -1734,12 +1810,7 @@ void cache_add_dhcp_entry(char *host_name, int prot,
|
||||
else
|
||||
flags |= F_REVERSE;
|
||||
|
||||
if ((crec = dhcp_spare))
|
||||
dhcp_spare = dhcp_spare->next;
|
||||
else /* need new one */
|
||||
crec = whine_malloc(SIZEOF_POINTER_CREC);
|
||||
|
||||
if (crec) /* malloc may fail */
|
||||
if ((crec = get_config_crec()))
|
||||
{
|
||||
crec->flags = flags | F_NAMEP | F_DHCP | F_FORWARD;
|
||||
if (ttd == 0)
|
||||
@@ -1786,15 +1857,7 @@ static void make_non_terminals(struct crec *source)
|
||||
hostname_isequal(name, cache_get_name(crecp)))
|
||||
{
|
||||
*up = crecp->hash_next;
|
||||
#ifdef HAVE_DHCP
|
||||
if (type & F_DHCP)
|
||||
{
|
||||
crecp->next = dhcp_spare;
|
||||
dhcp_spare = crecp;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
free(crecp);
|
||||
free_config_crec(crecp);
|
||||
break;
|
||||
}
|
||||
else
|
||||
@@ -1827,17 +1890,7 @@ static void make_non_terminals(struct crec *source)
|
||||
continue;
|
||||
}
|
||||
|
||||
#ifdef HAVE_DHCP
|
||||
if ((source->flags & F_DHCP) && dhcp_spare)
|
||||
{
|
||||
crecp = dhcp_spare;
|
||||
dhcp_spare = dhcp_spare->next;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
crecp = whine_malloc(SIZEOF_POINTER_CREC);
|
||||
|
||||
if (crecp)
|
||||
if ((crecp = get_config_crec()))
|
||||
{
|
||||
crecp->flags = (source->flags | F_NAMEP) & ~(F_IPV4 | F_IPV6 | F_CNAME | F_RR | F_DNSKEY | F_DS | F_REVERSE);
|
||||
if (!(crecp->flags & F_IMMORTAL))
|
||||
@@ -2166,9 +2219,9 @@ static char *querystr(char *desc, unsigned short type)
|
||||
unsigned int i;
|
||||
int len = 10; /* strlen("type=xxxxx") */
|
||||
const char *types = NULL;
|
||||
static char *buff = NULL;
|
||||
static int bufflen = 0;
|
||||
|
||||
static struct iovec buff = { NULL, 0 };
|
||||
char *buffp;
|
||||
|
||||
for (i = 0; i < (sizeof(typestr)/sizeof(typestr[0])); i++)
|
||||
if (typestr[i].type == type)
|
||||
{
|
||||
@@ -2183,37 +2236,28 @@ static char *querystr(char *desc, unsigned short type)
|
||||
len += strlen(desc);
|
||||
}
|
||||
len++; /* terminator */
|
||||
|
||||
if (!buff || bufflen < len)
|
||||
{
|
||||
if (buff)
|
||||
free(buff);
|
||||
else if (len < 20)
|
||||
len = 20;
|
||||
|
||||
buff = whine_malloc(len);
|
||||
bufflen = len;
|
||||
}
|
||||
|
||||
if (buff)
|
||||
if (!expand_buf(&buff, len))
|
||||
return "";
|
||||
|
||||
buffp = buff.iov_base;
|
||||
|
||||
if (desc)
|
||||
{
|
||||
if (desc)
|
||||
{
|
||||
if (types)
|
||||
sprintf(buff, "%s[%s]", desc, types);
|
||||
else
|
||||
sprintf(buff, "%s[type=%d]", desc, type);
|
||||
}
|
||||
if (types)
|
||||
sprintf(buffp, "%s[%s]", desc, types);
|
||||
else
|
||||
{
|
||||
if (types)
|
||||
sprintf(buff, "<%s>", types);
|
||||
else
|
||||
sprintf(buff, "<type=%d>", type);
|
||||
}
|
||||
sprintf(buffp, "%s[type=%d]", desc, type);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (types)
|
||||
sprintf(buffp, "<%s>", types);
|
||||
else
|
||||
sprintf(buffp, "<type=%d>", type);
|
||||
}
|
||||
|
||||
return buff ? buff : "";
|
||||
return buffp;
|
||||
}
|
||||
|
||||
static char *edestr(int ede)
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#define TCP_BACKLOG 32 /* kernel backlog limit for TCP connections */
|
||||
#define EDNS_PKTSZ 1232 /* default max EDNS.0 UDP packet from from /dnsflagday.net/2020 */
|
||||
#define KEYBLOCK_LEN 40 /* choose to minimise fragmentation when storing DNSSEC keys */
|
||||
#define NAMEBLOCK_CHARS 1500 /* quantum of memory allocation for names from /etc/hosts */
|
||||
#define DNSSEC_LIMIT_WORK 40 /* Max number of queries to validate one question */
|
||||
#define DNSSEC_LIMIT_SIG_FAIL 20 /* Number of signature that can fail to validate in one answer */
|
||||
#define DNSSEC_LIMIT_CRYPTO 200 /* max no. of crypto operations to validate one query. */
|
||||
|
||||
+4
-6
@@ -126,20 +126,18 @@ int hash_init(const struct nettle_hash *hash, void **ctxp, unsigned char **diges
|
||||
|
||||
if (ctx_sz < hash->context_size)
|
||||
{
|
||||
if (!(new = whine_malloc(hash->context_size)))
|
||||
if (!(new = whine_realloc(ctx, hash->context_size)))
|
||||
return 0;
|
||||
if (ctx)
|
||||
free(ctx);
|
||||
|
||||
ctx = new;
|
||||
ctx_sz = hash->context_size;
|
||||
}
|
||||
|
||||
if (digest_sz < hash->digest_size)
|
||||
{
|
||||
if (!(new = whine_malloc(hash->digest_size)))
|
||||
if (!(new = whine_realloc(digest, hash->digest_size)))
|
||||
return 0;
|
||||
if (digest)
|
||||
free(digest);
|
||||
|
||||
digest = new;
|
||||
digest_sz = hash->digest_size;
|
||||
}
|
||||
|
||||
+1
-1
@@ -399,7 +399,7 @@ void dhcp_packet(time_t now, int pxe_fd)
|
||||
if (mess->ciaddr.s_addr != 0)
|
||||
dest.sin_addr = mess->ciaddr;
|
||||
}
|
||||
if ((is_relay_use_source || mess->giaddr.s_addr) && !is_relay_reply)
|
||||
else if ((is_relay_use_source || mess->giaddr.s_addr) && !is_relay_reply)
|
||||
{
|
||||
/* Send to BOOTP relay. */
|
||||
if (is_relay_use_source)
|
||||
|
||||
+15
-11
@@ -1450,8 +1450,6 @@ void send_event(int fd, int event, int data, char *msg)
|
||||
while (writev(fd, iov, msg ? 2 : 1) == -1 && errno == EINTR);
|
||||
}
|
||||
|
||||
/* NOTE: the memory used to return msg is leaked: use msgs in events only
|
||||
to describe fatal errors. */
|
||||
static int read_event(int fd, struct event_desc *evp, char **msg)
|
||||
{
|
||||
char *buf;
|
||||
@@ -1461,12 +1459,22 @@ static int read_event(int fd, struct event_desc *evp, char **msg)
|
||||
|
||||
*msg = NULL;
|
||||
|
||||
if (evp->msg_sz != 0 &&
|
||||
(buf = malloc(evp->msg_sz + 1)) &&
|
||||
read_write(fd, (unsigned char *)buf, evp->msg_sz, RW_READ))
|
||||
if (evp->msg_sz != 0)
|
||||
{
|
||||
buf[evp->msg_sz] = 0;
|
||||
*msg = buf;
|
||||
if (!(buf = whine_malloc(evp->msg_sz + 1)))
|
||||
{
|
||||
int i;
|
||||
unsigned char a;
|
||||
|
||||
/* Keep the stream synchronised if malloc fails. */
|
||||
for (i = 0; i < evp->msg_sz; i++)
|
||||
read_write(fd, &a, 1, RW_READ);
|
||||
}
|
||||
else if (read_write(fd, (unsigned char *)buf, evp->msg_sz, RW_READ))
|
||||
{
|
||||
buf[evp->msg_sz] = 0;
|
||||
*msg = buf;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
@@ -1529,9 +1537,6 @@ static void async_event(int pipe, time_t now)
|
||||
int wstatus, i, check = 0;
|
||||
char *msg;
|
||||
|
||||
/* NOTE: the memory used to return msg is leaked: use msgs in events only
|
||||
to describe fatal errors. */
|
||||
|
||||
if (read_event(pipe, &ev, &msg))
|
||||
switch (ev.event)
|
||||
{
|
||||
@@ -1637,7 +1642,6 @@ static void async_event(int pipe, time_t now)
|
||||
case EVENT_SCRIPT_LOG:
|
||||
my_syslog(MS_SCRIPT | LOG_DEBUG, "%s", msg ? msg : "");
|
||||
free(msg);
|
||||
msg = NULL;
|
||||
break;
|
||||
|
||||
/* necessary for fatal errors in helper */
|
||||
|
||||
+6
-4
@@ -1498,11 +1498,15 @@ void *safe_malloc(size_t size);
|
||||
void safe_strncpy(char *dest, const char *src, size_t size);
|
||||
void safe_pipe(int *fd, int read_noblock);
|
||||
#define whine_malloc(x) whine_malloc_real(__func__, __LINE__, (x))
|
||||
#define whine_realloc(x, y) whine_realloc_real(__func__, __LINE__, (x), (y))
|
||||
#define whine_realloc(x, y) whine_realloc_real(NULL, __func__, __LINE__, (x), (y))
|
||||
#define expand_buf(x, y) expand_buf_real(__func__, __LINE__, (x), (y))
|
||||
#define expand_workspace(x, y, z) expand_workspace_real(__func__, __LINE__, (x), (y), (z))
|
||||
#define free(x) free_real(__func__, __LINE__, (x))
|
||||
void free_real(const char *func, unsigned int line, void *ptr);
|
||||
void *whine_malloc_real(const char *func, unsigned int line, size_t size);
|
||||
void *whine_realloc_real(const char *func, unsigned int line, void *ptr, size_t size);
|
||||
void *whine_realloc_real(const char *wrapper, const char *func, unsigned int line, void *ptr, size_t size);
|
||||
int expand_buf_real(const char *func, unsigned int line, struct iovec *iov, size_t size);
|
||||
int expand_workspace_real(const char *func, unsigned int line, unsigned char ***wkspc, int *szp, int new);
|
||||
int sa_len(union mysockaddr *addr);
|
||||
int sockaddr_isequal(const union mysockaddr *s1, const union mysockaddr *s2);
|
||||
int sockaddr_isnull(const union mysockaddr *s);
|
||||
@@ -1524,7 +1528,6 @@ int parse_hex(char *in, unsigned char *out, int maxlen,
|
||||
unsigned int *wildcard_mask, int *mac_type);
|
||||
int memcmp_masked(unsigned char *a, unsigned char *b, int len,
|
||||
unsigned int mask);
|
||||
int expand_buf(struct iovec *iov, size_t size);
|
||||
char *print_mac(char *buff, unsigned char *mac, int len);
|
||||
int read_write(int fd, unsigned char *packet, int size, int rw);
|
||||
int read_writev(int fd, struct iovec *iov, int iovcnt, int rw);
|
||||
@@ -1916,7 +1919,6 @@ int do_poll(int timeout);
|
||||
/* rrfilter.c */
|
||||
size_t rrfilter(struct dns_header *header, size_t *plen, int mode);
|
||||
short *rrfilter_desc(int type);
|
||||
int expand_workspace(unsigned char ***wkspc, int *szp, int new);
|
||||
int to_wire(char *name);
|
||||
void from_wire(char *name);
|
||||
/* modes. */
|
||||
|
||||
+5
-2
@@ -1423,7 +1423,10 @@ static int base32_decode(char *in, unsigned char *out)
|
||||
oc |= 1;
|
||||
mask = mask >> 1;
|
||||
if (((++on) & 7) == 0)
|
||||
*p++ = oc;
|
||||
{
|
||||
*p++ = oc;
|
||||
oc = 0;
|
||||
}
|
||||
oc = oc << 1;
|
||||
}
|
||||
}
|
||||
@@ -1553,7 +1556,7 @@ static int prove_non_existence_nsec3(struct dns_header *header, size_t plen, uns
|
||||
{
|
||||
unsigned char *salt, *p, *digest;
|
||||
int digest_len, i, iterations, salt_len, base32_len, algo = 0;
|
||||
struct nettle_hash const *hash;
|
||||
struct nettle_hash const *hash = NULL;
|
||||
char *closest_encloser, *next_closest, *wildcard;
|
||||
|
||||
if (nons)
|
||||
|
||||
+1
-1
@@ -103,7 +103,7 @@ unsigned char *find_pseudoheader(struct dns_header *header, size_t plen, size_t
|
||||
size_t add_pseudoheader(struct dns_header *header, size_t plen, unsigned char *limit,
|
||||
int optno, unsigned char *opt, size_t optlen, int set_do, int replace)
|
||||
{
|
||||
unsigned char *lenp, *datap, *p, *udp_len, *buff = NULL;
|
||||
unsigned char *lenp = NULL, *datap = NULL, *p, *udp_len, *buff = NULL;
|
||||
int rdlen = 0, is_sign, is_last;
|
||||
unsigned short flags = set_do ? 0x8000 : 0, rcode = 0;
|
||||
|
||||
|
||||
+6
-3
@@ -23,6 +23,9 @@ static volatile int mem_recover = 0;
|
||||
static jmp_buf mem_jmp;
|
||||
static int one_file(char *file, int hard_opt);
|
||||
|
||||
static void *opt_malloc_real(const char *func, unsigned int line, size_t size);
|
||||
#define opt_malloc(x) opt_malloc_real(__func__, __LINE__, (x))
|
||||
|
||||
/* Solaris headers don't have facility names. */
|
||||
#ifdef HAVE_SOLARIS_NETWORK
|
||||
static const struct {
|
||||
@@ -655,13 +658,13 @@ static void unhide_metas(char *cp)
|
||||
*cp = unhide_meta(*cp);
|
||||
}
|
||||
|
||||
static void *opt_malloc(size_t size)
|
||||
static void *opt_malloc_real(const char *func, unsigned int line, size_t size)
|
||||
{
|
||||
void *ret;
|
||||
|
||||
if (mem_recover)
|
||||
{
|
||||
ret = whine_malloc(size);
|
||||
ret = whine_malloc_real(func, line, size);
|
||||
if (!ret)
|
||||
longjmp(mem_jmp, 1);
|
||||
}
|
||||
@@ -5734,7 +5737,7 @@ struct hostsfile *expand_filelist(struct hostsfile *list)
|
||||
struct dirent **namelist;
|
||||
|
||||
/* find largest used index */
|
||||
for (i = SRC_AH, ah = list; ah; ah = ah->next)
|
||||
for (last = NULL, i = SRC_AH, ah = list; ah; ah = ah->next)
|
||||
{
|
||||
last = ah;
|
||||
|
||||
|
||||
+21
-39
@@ -21,7 +21,7 @@
|
||||
|
||||
struct state {
|
||||
unsigned char *clid;
|
||||
int multicast_dest, clid_len, ia_type, interface, hostname_auth, lease_allocate;
|
||||
int clid_len, ia_type, interface, hostname_auth, lease_allocate;
|
||||
char *client_hostname, *hostname, *domain, *send_domain;
|
||||
struct dhcp_context *context;
|
||||
struct in6_addr *link_address, *fallback, *ll_addr, *ula_addr;
|
||||
@@ -34,8 +34,8 @@ struct state {
|
||||
};
|
||||
|
||||
static int dhcp6_maybe_relay(struct state *state, unsigned char *inbuff, size_t sz,
|
||||
struct in6_addr *client_addr, int is_unicast, time_t now);
|
||||
static int dhcp6_no_relay(struct state *state, int msg_type, unsigned char *inbuff, size_t sz, int is_unicast, time_t now);
|
||||
struct in6_addr *client_addr, time_t now);
|
||||
static int dhcp6_no_relay(struct state *state, int msg_type, unsigned char *inbuff, size_t sz, time_t now);
|
||||
static void log6_opts(int nest, unsigned int xid, void *start_opts, void *end_opts);
|
||||
static void log6_packet(struct state *state, char *type, struct in6_addr *addr, char *string);
|
||||
static void log6_quiet(struct state *state, char *type, struct in6_addr *addr, char *string);
|
||||
@@ -80,6 +80,10 @@ unsigned short dhcp6_reply(struct dhcp_context *context, int multicast_dest, int
|
||||
return 0;
|
||||
|
||||
msg_type = *((unsigned char *)daemon->dhcp_packet.iov_base);
|
||||
|
||||
/* request from a client must be multicast RFC-9915 section 16 */
|
||||
if (msg_type != DHCP6RELAYFORW && !multicast_dest)
|
||||
return 0;
|
||||
|
||||
/* Mark these so we only match each at most once, to avoid tangled linked lists */
|
||||
for (vendor = daemon->dhcp_vendors; vendor; vendor = vendor->next)
|
||||
@@ -87,7 +91,6 @@ unsigned short dhcp6_reply(struct dhcp_context *context, int multicast_dest, int
|
||||
|
||||
reset_counter();
|
||||
state.context = context;
|
||||
state.multicast_dest = multicast_dest;
|
||||
state.interface = interface;
|
||||
state.iface_name = iface_name;
|
||||
state.fallback = fallback;
|
||||
@@ -97,8 +100,7 @@ unsigned short dhcp6_reply(struct dhcp_context *context, int multicast_dest, int
|
||||
state.tags = NULL;
|
||||
state.link_address = NULL;
|
||||
|
||||
if (dhcp6_maybe_relay(&state, daemon->dhcp_packet.iov_base, sz, client_addr,
|
||||
IN6_IS_ADDR_MULTICAST(client_addr), now))
|
||||
if (dhcp6_maybe_relay(&state, daemon->dhcp_packet.iov_base, sz, client_addr, now))
|
||||
return msg_type == DHCP6RELAYFORW ? DHCPV6_SERVER_PORT : DHCPV6_CLIENT_PORT;
|
||||
|
||||
return 0;
|
||||
@@ -106,7 +108,7 @@ unsigned short dhcp6_reply(struct dhcp_context *context, int multicast_dest, int
|
||||
|
||||
/* This cost me blood to write, it will probably cost you blood to understand - srk. */
|
||||
static int dhcp6_maybe_relay(struct state *state, unsigned char *inbuff, size_t sz,
|
||||
struct in6_addr *client_addr, int is_unicast, time_t now)
|
||||
struct in6_addr *client_addr, time_t now)
|
||||
{
|
||||
uint8_t *end = inbuff + sz;
|
||||
uint8_t *opts = inbuff + 34;
|
||||
@@ -184,7 +186,7 @@ static int dhcp6_maybe_relay(struct state *state, unsigned char *inbuff, size_t
|
||||
return 0;
|
||||
}
|
||||
|
||||
return dhcp6_no_relay(state, msg_type, inbuff, sz, is_unicast, now);
|
||||
return dhcp6_no_relay(state, msg_type, inbuff, sz, now);
|
||||
}
|
||||
|
||||
/* must have at least msg_type+hopcount+link_address+peer_address+minimal size option
|
||||
@@ -250,9 +252,7 @@ static int dhcp6_maybe_relay(struct state *state, unsigned char *inbuff, size_t
|
||||
/* RFC6221 para 4 */
|
||||
if (!IN6_IS_ADDR_UNSPECIFIED(&align))
|
||||
state->link_address = &align;
|
||||
/* zero is_unicast since that is now known to refer to the
|
||||
relayed packet, not the original sent by the client */
|
||||
if (!dhcp6_maybe_relay(state, opt6_ptr(opt, 0), opt6_len(opt), client_addr, 0, now))
|
||||
if (!dhcp6_maybe_relay(state, opt6_ptr(opt, 0), opt6_len(opt), client_addr, now))
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
@@ -264,7 +264,7 @@ static int dhcp6_maybe_relay(struct state *state, unsigned char *inbuff, size_t
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int dhcp6_no_relay(struct state *state, int msg_type, unsigned char *inbuff, size_t sz, int is_unicast, time_t now)
|
||||
static int dhcp6_no_relay(struct state *state, int msg_type, unsigned char *inbuff, size_t sz, time_t now)
|
||||
{
|
||||
void *opt;
|
||||
int i, o, o1, start_opts, start_msg;
|
||||
@@ -340,22 +340,17 @@ static int dhcp6_no_relay(struct state *state, int msg_type, unsigned char *inbu
|
||||
|
||||
opt = opt6_find(state->packet_options, state->end, OPTION6_SERVER_ID, 1);
|
||||
|
||||
if (msg_type == DHCP6SOLICIT || msg_type == DHCP6CONFIRM || msg_type == DHCP6REBIND || msg_type == DHCP6IREQ)
|
||||
if (msg_type == DHCP6SOLICIT || msg_type == DHCP6CONFIRM || msg_type == DHCP6REBIND)
|
||||
{
|
||||
/* Above message types must be multicast 3315 Section 15. */
|
||||
if (!state->multicast_dest)
|
||||
/* SOLICIT, CONFIRM and REBIND messages MUST NOT have a server-id. 3315 para 15.x */
|
||||
if (opt)
|
||||
return 0;
|
||||
|
||||
/* server-id must match except for SOLICIT, CONFIRM and REBIND messages, which MUST NOT
|
||||
have a server-id. 3315 para 15.x */
|
||||
if (msg_type == DHCP6IREQ)
|
||||
{
|
||||
/* If server-id provided in IREQ, it must match. */
|
||||
if (opt && (opt6_len(opt) != daemon->duid_len ||
|
||||
memcmp(opt6_ptr(opt, 0), daemon->duid, daemon->duid_len) != 0))
|
||||
return 0;
|
||||
}
|
||||
else if (opt)
|
||||
}
|
||||
else if (msg_type == DHCP6IREQ)
|
||||
{
|
||||
/* If server-id provided in IREQ, it must match. */
|
||||
if (opt && (opt6_len(opt) != daemon->duid_len ||
|
||||
memcmp(opt6_ptr(opt, 0), daemon->duid, daemon->duid_len) != 0))
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
@@ -370,18 +365,6 @@ static int dhcp6_no_relay(struct state *state, int msg_type, unsigned char *inbu
|
||||
put_opt6(daemon->duid, daemon->duid_len);
|
||||
end_opt6(o);
|
||||
|
||||
if (is_unicast &&
|
||||
(msg_type == DHCP6REQUEST || msg_type == DHCP6RENEW || msg_type == DHCP6RELEASE || msg_type == DHCP6DECLINE))
|
||||
|
||||
{
|
||||
outmsgtype = DHCP6REPLY;
|
||||
o1 = new_opt6(OPTION6_STATUS_CODE);
|
||||
put_opt6_short(DHCP6USEMULTI);
|
||||
put_opt6_string("Use multicast");
|
||||
end_opt6(o1);
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* match vendor and user class options */
|
||||
for (vendor = daemon->dhcp_vendors; vendor; vendor = vendor->next)
|
||||
{
|
||||
@@ -1304,7 +1287,6 @@ static int dhcp6_no_relay(struct state *state, int msg_type, unsigned char *inbu
|
||||
|
||||
log_tags(tagif, state->xid);
|
||||
|
||||
done:
|
||||
/* Fill in the message type. Note that we store the offset,
|
||||
not a direct pointer, since the packet memory may have been
|
||||
reallocated. */
|
||||
|
||||
@@ -337,27 +337,6 @@ short *rrfilter_desc(int type)
|
||||
return p+1;
|
||||
}
|
||||
|
||||
int expand_workspace(unsigned char ***wkspc, int *szp, int new)
|
||||
{
|
||||
unsigned char **p;
|
||||
int old = *szp;
|
||||
|
||||
if (old >= new+1)
|
||||
return 1;
|
||||
|
||||
new += 5;
|
||||
|
||||
if (!(p = whine_realloc(*wkspc, new * sizeof(unsigned char *))))
|
||||
return 0;
|
||||
|
||||
memset(p+old, 0, new-old);
|
||||
|
||||
*wkspc = p;
|
||||
*szp = new;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Convert from presentation format to wire format, in place.
|
||||
Also map UC -> LC.
|
||||
Note that using extract_name to get presentation format
|
||||
|
||||
+48
-29
@@ -672,32 +672,6 @@ int memcmp_masked(unsigned char *a, unsigned char *b, int len, unsigned int mask
|
||||
return count;
|
||||
}
|
||||
|
||||
/* _note_ may copy buffer */
|
||||
int expand_buf(struct iovec *iov, size_t size)
|
||||
{
|
||||
void *new;
|
||||
|
||||
if (size <= (size_t)iov->iov_len)
|
||||
return 1;
|
||||
|
||||
if (!(new = whine_malloc(size)))
|
||||
{
|
||||
errno = ENOMEM;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (iov->iov_base)
|
||||
{
|
||||
memcpy(new, iov->iov_base, iov->iov_len);
|
||||
free(iov->iov_base);
|
||||
}
|
||||
|
||||
iov->iov_base = new;
|
||||
iov->iov_len = size;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
char *print_mac(char *buff, unsigned char *mac, int len)
|
||||
{
|
||||
char *p = buff;
|
||||
@@ -790,7 +764,7 @@ int read_writev(int fd, struct iovec *iov, int iovcnt, int rw)
|
||||
return 0;
|
||||
|
||||
done += n;
|
||||
while ((size_t)done >= iov[cur].iov_len)
|
||||
while (cur < iovcnt && (size_t)done >= iov[cur].iov_len)
|
||||
done -= iov[cur++].iov_len;
|
||||
}
|
||||
|
||||
@@ -961,7 +935,7 @@ void *whine_malloc_real(const char *func, unsigned int line, size_t size)
|
||||
return ret;
|
||||
}
|
||||
|
||||
void *whine_realloc_real(const char *func, unsigned int line, void *ptr, size_t size)
|
||||
void *whine_realloc_real(const char *wrapper, const char *func, unsigned int line, void *ptr, size_t size)
|
||||
{
|
||||
unsigned int old = hash_ptr(ptr);
|
||||
void *ret = realloc(ptr, size);
|
||||
@@ -969,11 +943,56 @@ void *whine_realloc_real(const char *func, unsigned int line, void *ptr, size_t
|
||||
if (!ret)
|
||||
my_syslog(LOG_ERR, _("failed to reallocate %d bytes"), (int) size);
|
||||
else if (daemon->log_malloc)
|
||||
my_syslog(LOG_INFO, _("realloc: %s:%u %zu bytes from %x to %x"), func, line, size, old, hash_ptr(ret));
|
||||
{
|
||||
if (!wrapper)
|
||||
wrapper = "realloc";
|
||||
my_syslog(LOG_INFO, _("%s: %s:%u %zu bytes from %x to %x"), wrapper, func, line, size, old, hash_ptr(ret));
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* _note_ may copy buffer */
|
||||
int expand_buf_real(const char *func, unsigned int line, struct iovec *iov, size_t size)
|
||||
{
|
||||
void *new;
|
||||
|
||||
if (size <= (size_t)iov->iov_len)
|
||||
return 1;
|
||||
|
||||
if (!(new = whine_realloc_real("expand_buf", func, line, iov->iov_base, size)))
|
||||
{
|
||||
errno = ENOMEM;
|
||||
return 0;
|
||||
}
|
||||
|
||||
iov->iov_base = new;
|
||||
iov->iov_len = size;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int expand_workspace_real(const char *func, unsigned int line, unsigned char ***wkspc, int *szp, int new)
|
||||
{
|
||||
unsigned char **p;
|
||||
int old = *szp;
|
||||
|
||||
if (old >= new+1)
|
||||
return 1;
|
||||
|
||||
new += 5;
|
||||
|
||||
if (!(p = whine_realloc_real("expand_workspace", func, line, *wkspc, new * sizeof(unsigned char *))))
|
||||
return 0;
|
||||
|
||||
memset(p+old, 0, new-old);
|
||||
|
||||
*wkspc = p;
|
||||
*szp = new;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
#undef free
|
||||
void free_real(const char *func, unsigned int line, void *ptr)
|
||||
{
|
||||
|
||||
Reference in new issue
Block a user