Annotation of embedaddon/dnsmasq/src/blockdata.c, revision 1.1.1.2
1.1.1.2 ! misho 1: /* dnsmasq is Copyright (c) 2000-2016 Simon Kelley
1.1 misho 2:
3: This program is free software; you can redistribute it and/or modify
4: it under the terms of the GNU General Public License as published by
5: the Free Software Foundation; version 2 dated June, 1991, or
6: (at your option) version 3 dated 29 June, 2007.
7:
8: This program is distributed in the hope that it will be useful,
9: but WITHOUT ANY WARRANTY; without even the implied warranty of
10: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11: GNU General Public License for more details.
12:
13: You should have received a copy of the GNU General Public License
14: along with this program. If not, see <http://www.gnu.org/licenses/>.
15: */
16:
17: #include "dnsmasq.h"
18:
19: #ifdef HAVE_DNSSEC
20:
21: static struct blockdata *keyblock_free;
22: static unsigned int blockdata_count, blockdata_hwm, blockdata_alloced;
23:
24: static void blockdata_expand(int n)
25: {
26: struct blockdata *new = whine_malloc(n * sizeof(struct blockdata));
27:
28: if (n > 0 && new)
29: {
30: int i;
31:
32: new[n-1].next = keyblock_free;
33: keyblock_free = new;
34:
35: for (i = 0; i < n - 1; i++)
36: new[i].next = &new[i+1];
37:
38: blockdata_alloced += n;
39: }
40: }
41:
42: /* Preallocate some blocks, proportional to cachesize, to reduce heap fragmentation. */
43: void blockdata_init(void)
44: {
45: keyblock_free = NULL;
46: blockdata_alloced = 0;
47: blockdata_count = 0;
48: blockdata_hwm = 0;
49:
50: /* Note that daemon->cachesize is enforced to have non-zero size if OPT_DNSSEC_VALID is set */
51: if (option_bool(OPT_DNSSEC_VALID))
52: blockdata_expand((daemon->cachesize * 100) / sizeof(struct blockdata));
53: }
54:
55: void blockdata_report(void)
56: {
57: if (option_bool(OPT_DNSSEC_VALID))
58: my_syslog(LOG_INFO, _("DNSSEC memory in use %u, max %u, allocated %u"),
59: blockdata_count * sizeof(struct blockdata),
60: blockdata_hwm * sizeof(struct blockdata),
61: blockdata_alloced * sizeof(struct blockdata));
62: }
63:
64: struct blockdata *blockdata_alloc(char *data, size_t len)
65: {
66: struct blockdata *block, *ret = NULL;
67: struct blockdata **prev = &ret;
68: size_t blen;
69:
70: while (len > 0)
71: {
72: if (!keyblock_free)
73: blockdata_expand(50);
74:
75: if (keyblock_free)
76: {
77: block = keyblock_free;
78: keyblock_free = block->next;
79: blockdata_count++;
80: }
81: else
82: {
83: /* failed to alloc, free partial chain */
84: blockdata_free(ret);
85: return NULL;
86: }
87:
88: if (blockdata_hwm < blockdata_count)
89: blockdata_hwm = blockdata_count;
90:
91: blen = len > KEYBLOCK_LEN ? KEYBLOCK_LEN : len;
92: memcpy(block->key, data, blen);
93: data += blen;
94: len -= blen;
95: *prev = block;
96: prev = &block->next;
97: block->next = NULL;
98: }
99:
100: return ret;
101: }
102:
103: void blockdata_free(struct blockdata *blocks)
104: {
105: struct blockdata *tmp;
106:
107: if (blocks)
108: {
109: for (tmp = blocks; tmp->next; tmp = tmp->next)
110: blockdata_count--;
111: tmp->next = keyblock_free;
112: keyblock_free = blocks;
113: blockdata_count--;
114: }
115: }
116:
117: /* if data == NULL, return pointer to static block of sufficient size */
118: void *blockdata_retrieve(struct blockdata *block, size_t len, void *data)
119: {
120: size_t blen;
121: struct blockdata *b;
122: void *new, *d;
123:
124: static unsigned int buff_len = 0;
125: static unsigned char *buff = NULL;
126:
127: if (!data)
128: {
129: if (len > buff_len)
130: {
131: if (!(new = whine_malloc(len)))
132: return NULL;
133: if (buff)
134: free(buff);
135: buff = new;
136: }
137: data = buff;
138: }
139:
140: for (d = data, b = block; len > 0 && b; b = b->next)
141: {
142: blen = len > KEYBLOCK_LEN ? KEYBLOCK_LEN : len;
143: memcpy(d, b->key, blen);
144: d += blen;
145: len -= blen;
146: }
147:
148: return data;
149: }
150:
151: #endif
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>