1 /* dnsmasq is Copyright (c) 2000-2015 Simon Kelley
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.
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.
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/>.
21 static struct blockdata
*keyblock_free
;
22 static unsigned int blockdata_count
, blockdata_hwm
, blockdata_alloced
;
24 static void blockdata_expand(int n
)
26 struct blockdata
*new = whine_malloc(n
* sizeof(struct blockdata
));
32 new[n
-1].next
= keyblock_free
;
35 for (i
= 0; i
< n
- 1; i
++)
36 new[i
].next
= &new[i
+1];
38 blockdata_alloced
+= n
;
42 /* Preallocate some blocks, proportional to cachesize, to reduce heap fragmentation. */
43 void blockdata_init(void)
46 blockdata_alloced
= 0;
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
));
55 void blockdata_report(void)
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
));
64 struct blockdata
*blockdata_alloc(char *data
, size_t len
)
66 struct blockdata
*block
, *ret
= NULL
;
67 struct blockdata
**prev
= &ret
;
77 block
= keyblock_free
;
78 keyblock_free
= block
->next
;
83 /* failed to alloc, free partial chain */
88 if (blockdata_hwm
< blockdata_count
)
89 blockdata_hwm
= blockdata_count
;
91 blen
= len
> KEYBLOCK_LEN
? KEYBLOCK_LEN
: len
;
92 memcpy(block
->key
, data
, blen
);
103 void blockdata_free(struct blockdata
*blocks
)
105 struct blockdata
*tmp
;
109 for (tmp
= blocks
; tmp
->next
; tmp
= tmp
->next
)
111 tmp
->next
= keyblock_free
;
112 keyblock_free
= blocks
;
117 /* if data == NULL, return pointer to static block of sufficient size */
118 void *blockdata_retrieve(struct blockdata
*block
, size_t len
, void *data
)
124 static unsigned int buff_len
= 0;
125 static unsigned char *buff
= NULL
;
131 if (!(new = whine_malloc(len
)))
140 for (d
= data
, b
= block
; len
> 0 && b
; b
= b
->next
)
142 blen
= len
> KEYBLOCK_LEN
? KEYBLOCK_LEN
: len
;
143 memcpy(d
, b
->key
, blen
);