mirror of
https://github.com/pi-hole/dnsmasq.git
synced 2025-12-19 10:18:25 +00:00
120 lines
2.9 KiB
C
120 lines
2.9 KiB
C
/* dnsmasq is Copyright (c) 2000-2014 Simon Kelley
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; version 2 dated June, 1991, or
|
|
(at your option) version 3 dated 29 June, 2007.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include "dnsmasq.h"
|
|
|
|
#ifdef HAVE_DNSSEC
|
|
|
|
static struct blockdata *keyblock_free = NULL;
|
|
static unsigned int blockdata_count = 0, blockdata_hwm = 0;
|
|
|
|
void blockdata_report(void)
|
|
{
|
|
my_syslog(LOG_INFO, _("DNSSEC memory in use %u, max %u"),
|
|
blockdata_count * sizeof(struct blockdata), blockdata_hwm * sizeof(struct blockdata));
|
|
}
|
|
|
|
struct blockdata *blockdata_alloc(char *data, size_t len)
|
|
{
|
|
struct blockdata *block, *ret = NULL;
|
|
struct blockdata **prev = &ret;
|
|
size_t blen;
|
|
|
|
while (len > 0)
|
|
{
|
|
if (keyblock_free)
|
|
{
|
|
block = keyblock_free;
|
|
keyblock_free = block->next;
|
|
blockdata_count++;
|
|
}
|
|
else if ((block = whine_malloc(sizeof(struct blockdata))))
|
|
{
|
|
blockdata_count++;
|
|
if (blockdata_hwm < blockdata_count)
|
|
blockdata_hwm = blockdata_count;
|
|
}
|
|
|
|
if (!block)
|
|
{
|
|
/* failed to alloc, free partial chain */
|
|
blockdata_free(ret);
|
|
return NULL;
|
|
}
|
|
|
|
blen = len > KEYBLOCK_LEN ? KEYBLOCK_LEN : len;
|
|
memcpy(block->key, data, blen);
|
|
data += blen;
|
|
len -= blen;
|
|
*prev = block;
|
|
prev = &block->next;
|
|
block->next = NULL;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
size_t blockdata_walk(struct blockdata **key, unsigned char **p, size_t cnt)
|
|
{
|
|
if (*p == NULL)
|
|
*p = (*key)->key;
|
|
else if (*p == (*key)->key + KEYBLOCK_LEN)
|
|
{
|
|
*key = (*key)->next;
|
|
if (*key == NULL)
|
|
return 0;
|
|
*p = (*key)->key;
|
|
}
|
|
|
|
return MIN(cnt, (size_t)((*key)->key + KEYBLOCK_LEN - (*p)));
|
|
}
|
|
|
|
void blockdata_free(struct blockdata *blocks)
|
|
{
|
|
struct blockdata *tmp;
|
|
|
|
if (blocks)
|
|
{
|
|
for (tmp = blocks; tmp->next; tmp = tmp->next)
|
|
blockdata_count--;
|
|
tmp->next = keyblock_free;
|
|
keyblock_free = blocks;
|
|
blockdata_count--;
|
|
}
|
|
}
|
|
|
|
/* copy blocks into data[], return 1 if data[] unchanged by so doing */
|
|
int blockdata_retrieve(struct blockdata *block, size_t len, void *data)
|
|
{
|
|
size_t blen;
|
|
struct blockdata *b;
|
|
int match = 1;
|
|
|
|
for (b = block; len > 0 && b; b = b->next)
|
|
{
|
|
blen = len > KEYBLOCK_LEN ? KEYBLOCK_LEN : len;
|
|
if (memcmp(data, b->key, blen) != 0)
|
|
match = 0;
|
|
memcpy(data, b->key, blen);
|
|
data += blen;
|
|
len -= blen;
|
|
}
|
|
|
|
return match;
|
|
}
|
|
|
|
#endif
|