1 /* $NetBSD: alloc.c,v 1.3 2022/04/03 01:10:58 christos Exp $ */
2
3 /* alloc.c
4
5 Memory allocation... */
6
7 /*
8 * Copyright (C) 2004-2022 Internet Systems Consortium, Inc. ("ISC")
9 * Copyright (c) 1996-2003 by Internet Software Consortium
10 *
11 * This Source Code Form is subject to the terms of the Mozilla Public
12 * License, v. 2.0. If a copy of the MPL was not distributed with this
13 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
16 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
17 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
18 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
21 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22 *
23 * Internet Systems Consortium, Inc.
24 * PO Box 360
25 * Newmarket, NH 03857 USA
26 * <info@isc.org>
27 * https://www.isc.org/
28 *
29 */
30
31 #include <sys/cdefs.h>
32 __RCSID("$NetBSD: alloc.c,v 1.3 2022/04/03 01:10:58 christos Exp $");
33
34 #include "dhcpd.h"
35 #include <omapip/omapip_p.h>
36
37 struct dhcp_packet *dhcp_free_list;
38 struct packet *packet_free_list;
39
option_chain_head_allocate(ptr,file,line)40 int option_chain_head_allocate (ptr, file, line)
41 struct option_chain_head **ptr;
42 const char *file;
43 int line;
44 {
45 struct option_chain_head *h;
46
47 if (!ptr) {
48 log_error ("%s(%d): null pointer", file, line);
49 #if defined (POINTER_DEBUG)
50 abort ();
51 #else
52 return 0;
53 #endif
54 }
55 if (*ptr) {
56 log_error ("%s(%d): non-null pointer", file, line);
57 #if defined (POINTER_DEBUG)
58 abort ();
59 #else
60 *ptr = (struct option_chain_head *)0;
61 #endif
62 }
63
64 h = dmalloc (sizeof *h, file, line);
65 if (h) {
66 memset (h, 0, sizeof *h);
67 return option_chain_head_reference (ptr, h, file, line);
68 }
69 return 0;
70 }
71
option_chain_head_reference(ptr,bp,file,line)72 int option_chain_head_reference (ptr, bp, file, line)
73 struct option_chain_head **ptr;
74 struct option_chain_head *bp;
75 const char *file;
76 int line;
77 {
78 if (!ptr) {
79 log_error ("%s(%d): null pointer", file, line);
80 #if defined (POINTER_DEBUG)
81 abort ();
82 #else
83 return 0;
84 #endif
85 }
86 if (*ptr) {
87 log_error ("%s(%d): non-null pointer", file, line);
88 #if defined (POINTER_DEBUG)
89 abort ();
90 #else
91 *ptr = (struct option_chain_head *)0;
92 #endif
93 }
94 *ptr = bp;
95 bp -> refcnt++;
96 rc_register (file, line, ptr, bp, bp -> refcnt, 0, RC_MISC);
97 return 1;
98 }
99
option_chain_head_dereference(ptr,file,line)100 int option_chain_head_dereference (ptr, file, line)
101 struct option_chain_head **ptr;
102 const char *file;
103 int line;
104 {
105 struct option_chain_head *option_chain_head;
106 pair car, cdr;
107
108 if (!ptr || !*ptr) {
109 log_error ("%s(%d): null pointer", file, line);
110 #if defined (POINTER_DEBUG)
111 abort ();
112 #else
113 return 0;
114 #endif
115 }
116
117 option_chain_head = *ptr;
118 *ptr = (struct option_chain_head *)0;
119 --option_chain_head -> refcnt;
120 rc_register (file, line, ptr, option_chain_head,
121 option_chain_head -> refcnt, 1, RC_MISC);
122 if (option_chain_head -> refcnt > 0)
123 return 1;
124
125 if (option_chain_head -> refcnt < 0) {
126 log_error ("%s(%d): negative refcnt!", file, line);
127 #if defined (DEBUG_RC_HISTORY)
128 dump_rc_history (option_chain_head);
129 #endif
130 #if defined (POINTER_DEBUG)
131 abort ();
132 #else
133 return 0;
134 #endif
135 }
136
137 /* If there are any options on this head, free them. */
138 for (car = option_chain_head -> first; car; car = cdr) {
139 cdr = car -> cdr;
140 if (car -> car)
141 option_cache_dereference ((struct option_cache **)
142 (void *)(&car -> car), MDL);
143 dfree (car, MDL);
144 }
145
146 dfree (option_chain_head, file, line);
147 return 1;
148 }
149
group_allocate(ptr,file,line)150 int group_allocate (ptr, file, line)
151 struct group **ptr;
152 const char *file;
153 int line;
154 {
155 struct group *g;
156
157 if (!ptr) {
158 log_error ("%s(%d): null pointer", file, line);
159 #if defined (POINTER_DEBUG)
160 abort ();
161 #else
162 return 0;
163 #endif
164 }
165 if (*ptr) {
166 log_error ("%s(%d): non-null pointer", file, line);
167 #if defined (POINTER_DEBUG)
168 abort ();
169 #else
170 *ptr = (struct group *)0;
171 #endif
172 }
173
174 g = dmalloc (sizeof *g, file, line);
175 if (g) {
176 memset (g, 0, sizeof *g);
177 return group_reference (ptr, g, file, line);
178 }
179 return 0;
180 }
181
group_reference(ptr,bp,file,line)182 int group_reference (ptr, bp, file, line)
183 struct group **ptr;
184 struct group *bp;
185 const char *file;
186 int line;
187 {
188 if (!ptr) {
189 log_error ("%s(%d): null pointer", file, line);
190 #if defined (POINTER_DEBUG)
191 abort ();
192 #else
193 return 0;
194 #endif
195 }
196 if (*ptr) {
197 log_error ("%s(%d): non-null pointer", file, line);
198 #if defined (POINTER_DEBUG)
199 abort ();
200 #else
201 *ptr = (struct group *)0;
202 #endif
203 }
204 *ptr = bp;
205 bp -> refcnt++;
206 rc_register (file, line, ptr, bp, bp -> refcnt, 0, RC_MISC);
207 return 1;
208 }
209
group_dereference(ptr,file,line)210 int group_dereference (ptr, file, line)
211 struct group **ptr;
212 const char *file;
213 int line;
214 {
215 struct group *group;
216
217 if (!ptr || !*ptr) {
218 log_error ("%s(%d): null pointer", file, line);
219 #if defined (POINTER_DEBUG)
220 abort ();
221 #else
222 return 0;
223 #endif
224 }
225
226 group = *ptr;
227 *ptr = (struct group *)0;
228 --group -> refcnt;
229 rc_register (file, line, ptr, group, group -> refcnt, 1, RC_MISC);
230 if (group -> refcnt > 0)
231 return 1;
232
233 if (group -> refcnt < 0) {
234 log_error ("%s(%d): negative refcnt!", file, line);
235 #if defined (DEBUG_RC_HISTORY)
236 dump_rc_history (group);
237 #endif
238 #if defined (POINTER_DEBUG)
239 abort ();
240 #else
241 return 0;
242 #endif
243 }
244
245 if (group -> object)
246 group_object_dereference (&group -> object, file, line);
247 if (group -> subnet)
248 subnet_dereference (&group -> subnet, file, line);
249 if (group -> shared_network)
250 shared_network_dereference (&group -> shared_network,
251 file, line);
252 if (group -> statements)
253 executable_statement_dereference (&group -> statements,
254 file, line);
255 if (group -> next)
256 group_dereference (&group -> next, file, line);
257 dfree (group, file, line);
258 return 1;
259 }
260
new_dhcp_packet(file,line)261 struct dhcp_packet *new_dhcp_packet (file, line)
262 const char *file;
263 int line;
264 {
265 struct dhcp_packet *rval;
266 rval = (struct dhcp_packet *)dmalloc (sizeof (struct dhcp_packet),
267 file, line);
268 return rval;
269 }
270
new_protocol(file,line)271 struct protocol *new_protocol (file, line)
272 const char *file;
273 int line;
274 {
275 struct protocol *rval = dmalloc (sizeof (struct protocol), file, line);
276 return rval;
277 }
278
new_domain_search_list(file,line)279 struct domain_search_list *new_domain_search_list (file, line)
280 const char *file;
281 int line;
282 {
283 struct domain_search_list *rval =
284 dmalloc (sizeof (struct domain_search_list), file, line);
285 return rval;
286 }
287
new_name_server(file,line)288 struct name_server *new_name_server (file, line)
289 const char *file;
290 int line;
291 {
292 struct name_server *rval =
293 dmalloc (sizeof (struct name_server), file, line);
294 return rval;
295 }
296
free_name_server(ptr,file,line)297 void free_name_server (ptr, file, line)
298 struct name_server *ptr;
299 const char *file;
300 int line;
301 {
302 dfree ((void *)ptr, file, line);
303 }
304
new_option(name,file,line)305 struct option *new_option (name, file, line)
306 const char *name;
307 const char *file;
308 int line;
309 {
310 struct option *rval;
311 int len;
312
313 len = strlen(name);
314
315 rval = dmalloc(sizeof(struct option) + len + 1, file, line);
316
317 if(rval) {
318 memcpy(rval + 1, name, len);
319 rval->name = (char *)(rval + 1);
320 }
321
322 return rval;
323 }
324
new_universe(file,line)325 struct universe *new_universe (file, line)
326 const char *file;
327 int line;
328 {
329 struct universe *rval =
330 dmalloc (sizeof (struct universe), file, line);
331 return rval;
332 }
333
free_universe(ptr,file,line)334 void free_universe (ptr, file, line)
335 struct universe *ptr;
336 const char *file;
337 int line;
338 {
339 dfree ((void *)ptr, file, line);
340 }
341
free_domain_search_list(ptr,file,line)342 void free_domain_search_list (ptr, file, line)
343 struct domain_search_list *ptr;
344 const char *file;
345 int line;
346 {
347 dfree ((void *)ptr, file, line);
348 }
349
free_protocol(ptr,file,line)350 void free_protocol (ptr, file, line)
351 struct protocol *ptr;
352 const char *file;
353 int line;
354 {
355 dfree ((void *)ptr, file, line);
356 }
357
free_dhcp_packet(ptr,file,line)358 void free_dhcp_packet (ptr, file, line)
359 struct dhcp_packet *ptr;
360 const char *file;
361 int line;
362 {
363 dfree ((void *)ptr, file, line);
364 }
365
new_client_lease(file,line)366 struct client_lease *new_client_lease (file, line)
367 const char *file;
368 int line;
369 {
370 return (struct client_lease *)dmalloc (sizeof (struct client_lease),
371 file, line);
372 }
373
free_client_lease(lease,file,line)374 void free_client_lease (lease, file, line)
375 struct client_lease *lease;
376 const char *file;
377 int line;
378 {
379 dfree (lease, file, line);
380 }
381
382 pair free_pairs;
383
new_pair(file,line)384 pair new_pair (file, line)
385 const char *file;
386 int line;
387 {
388 pair foo;
389
390 if (free_pairs) {
391 foo = free_pairs;
392 free_pairs = foo -> cdr;
393 memset (foo, 0, sizeof *foo);
394 dmalloc_reuse (foo, file, line, 0);
395 return foo;
396 }
397
398 foo = dmalloc (sizeof *foo, file, line);
399 if (!foo)
400 return foo;
401 memset (foo, 0, sizeof *foo);
402 return foo;
403 }
404
free_pair(foo,file,line)405 void free_pair (foo, file, line)
406 pair foo;
407 const char *file;
408 int line;
409 {
410 foo -> cdr = free_pairs;
411 free_pairs = foo;
412 dmalloc_reuse (free_pairs, __FILE__, __LINE__, 0);
413 }
414
415 #if defined (DEBUG_MEMORY_LEAKAGE) || \
416 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
relinquish_free_pairs()417 void relinquish_free_pairs ()
418 {
419 pair pf, pc;
420
421 for (pf = free_pairs; pf; pf = pc) {
422 pc = pf -> cdr;
423 dfree (pf, MDL);
424 }
425 free_pairs = (pair)0;
426 }
427 #endif
428
429 struct expression *free_expressions;
430
expression_allocate(cptr,file,line)431 int expression_allocate (cptr, file, line)
432 struct expression **cptr;
433 const char *file;
434 int line;
435 {
436 struct expression *rval;
437
438 if (free_expressions) {
439 rval = free_expressions;
440 free_expressions = rval -> data.not;
441 dmalloc_reuse (rval, file, line, 1);
442 } else {
443 rval = dmalloc (sizeof (struct expression), file, line);
444 if (!rval)
445 return 0;
446 }
447 memset (rval, 0, sizeof *rval);
448 return expression_reference (cptr, rval, file, line);
449 }
450
expression_reference(ptr,src,file,line)451 int expression_reference (ptr, src, file, line)
452 struct expression **ptr;
453 struct expression *src;
454 const char *file;
455 int line;
456 {
457 if (!ptr) {
458 log_error ("%s(%d): null pointer", file, line);
459 #if defined (POINTER_DEBUG)
460 abort ();
461 #else
462 return 0;
463 #endif
464 }
465 if (*ptr) {
466 log_error ("%s(%d): non-null pointer", file, line);
467 #if defined (POINTER_DEBUG)
468 abort ();
469 #else
470 *ptr = (struct expression *)0;
471 #endif
472 }
473 *ptr = src;
474 src -> refcnt++;
475 rc_register (file, line, ptr, src, src -> refcnt, 0, RC_MISC);
476 return 1;
477 }
478
free_expression(expr,file,line)479 void free_expression (expr, file, line)
480 struct expression *expr;
481 const char *file;
482 int line;
483 {
484 expr -> data.not = free_expressions;
485 free_expressions = expr;
486 dmalloc_reuse (free_expressions, __FILE__, __LINE__, 0);
487 }
488
489 #if defined (DEBUG_MEMORY_LEAKAGE) || \
490 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
relinquish_free_expressions()491 void relinquish_free_expressions ()
492 {
493 struct expression *e, *n;
494
495 for (e = free_expressions; e; e = n) {
496 n = e -> data.not;
497 dfree (e, MDL);
498 }
499 free_expressions = (struct expression *)0;
500 }
501 #endif
502
503 struct binding_value *free_binding_values;
504
binding_value_allocate(cptr,file,line)505 int binding_value_allocate (cptr, file, line)
506 struct binding_value **cptr;
507 const char *file;
508 int line;
509 {
510 struct binding_value *rval;
511
512 if (free_binding_values) {
513 rval = free_binding_values;
514 free_binding_values = rval -> value.bv;
515 dmalloc_reuse (rval, file, line, 1);
516 } else {
517 rval = dmalloc (sizeof (struct binding_value), file, line);
518 if (!rval)
519 return 0;
520 }
521 memset (rval, 0, sizeof *rval);
522 return binding_value_reference (cptr, rval, file, line);
523 }
524
binding_value_reference(ptr,src,file,line)525 int binding_value_reference (ptr, src, file, line)
526 struct binding_value **ptr;
527 struct binding_value *src;
528 const char *file;
529 int line;
530 {
531 if (!ptr) {
532 log_error ("%s(%d): null pointer", file, line);
533 #if defined (POINTER_DEBUG)
534 abort ();
535 #else
536 return 0;
537 #endif
538 }
539 if (*ptr) {
540 log_error ("%s(%d): non-null pointer", file, line);
541 #if defined (POINTER_DEBUG)
542 abort ();
543 #else
544 *ptr = (struct binding_value *)0;
545 #endif
546 }
547 *ptr = src;
548 src -> refcnt++;
549 rc_register (file, line, ptr, src, src -> refcnt, 0, RC_MISC);
550 return 1;
551 }
552
free_binding_value(bv,file,line)553 void free_binding_value (bv, file, line)
554 struct binding_value *bv;
555 const char *file;
556 int line;
557 {
558 bv -> value.bv = free_binding_values;
559 free_binding_values = bv;
560 dmalloc_reuse (free_binding_values, (char *)0, 0, 0);
561 }
562
563 #if defined (DEBUG_MEMORY_LEAKAGE) || \
564 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
relinquish_free_binding_values()565 void relinquish_free_binding_values ()
566 {
567 struct binding_value *b, *n;
568
569 for (b = free_binding_values; b; b = n) {
570 n = b -> value.bv;
571 dfree (b, MDL);
572 }
573 free_binding_values = (struct binding_value *)0;
574 }
575 #endif
576
fundef_allocate(cptr,file,line)577 int fundef_allocate (cptr, file, line)
578 struct fundef **cptr;
579 const char *file;
580 int line;
581 {
582 struct fundef *rval;
583
584 rval = dmalloc (sizeof (struct fundef), file, line);
585 if (!rval)
586 return 0;
587 memset (rval, 0, sizeof *rval);
588 return fundef_reference (cptr, rval, file, line);
589 }
590
fundef_reference(ptr,src,file,line)591 int fundef_reference (ptr, src, file, line)
592 struct fundef **ptr;
593 struct fundef *src;
594 const char *file;
595 int line;
596 {
597 if (!ptr) {
598 log_error ("%s(%d): null pointer", file, line);
599 #if defined (POINTER_DEBUG)
600 abort ();
601 #else
602 return 0;
603 #endif
604 }
605 if (*ptr) {
606 log_error ("%s(%d): non-null pointer", file, line);
607 #if defined (POINTER_DEBUG)
608 abort ();
609 #else
610 *ptr = (struct fundef *)0;
611 #endif
612 }
613 *ptr = src;
614 src -> refcnt++;
615 rc_register (file, line, ptr, src, src -> refcnt, 0, RC_MISC);
616 return 1;
617 }
618
619 struct option_cache *free_option_caches;
620
621 #if defined (DEBUG_MEMORY_LEAKAGE) || \
622 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
relinquish_free_option_caches()623 void relinquish_free_option_caches ()
624 {
625 struct option_cache *o, *n;
626
627 for (o = free_option_caches; o; o = n) {
628 n = (struct option_cache *)(o -> expression);
629 dfree (o, MDL);
630 }
631 free_option_caches = (struct option_cache *)0;
632 }
633 #endif
634
option_cache_allocate(cptr,file,line)635 int option_cache_allocate (cptr, file, line)
636 struct option_cache **cptr;
637 const char *file;
638 int line;
639 {
640 struct option_cache *rval;
641
642 if (free_option_caches) {
643 rval = free_option_caches;
644 free_option_caches =
645 (struct option_cache *)(rval -> expression);
646 dmalloc_reuse (rval, file, line, 0);
647 } else {
648 rval = dmalloc (sizeof (struct option_cache), file, line);
649 if (!rval)
650 return 0;
651 }
652 memset (rval, 0, sizeof *rval);
653 return option_cache_reference (cptr, rval, file, line);
654 }
655
option_cache_reference(ptr,src,file,line)656 int option_cache_reference (ptr, src, file, line)
657 struct option_cache **ptr;
658 struct option_cache *src;
659 const char *file;
660 int line;
661 {
662 if (!ptr) {
663 log_error ("%s(%d): null pointer", file, line);
664 #if defined (POINTER_DEBUG)
665 abort ();
666 #else
667 return 0;
668 #endif
669 }
670 if (*ptr) {
671 log_error ("%s(%d): non-null pointer", file, line);
672 #if defined (POINTER_DEBUG)
673 abort ();
674 #else
675 *ptr = (struct option_cache *)0;
676 #endif
677 }
678 *ptr = src;
679 src -> refcnt++;
680 rc_register (file, line, ptr, src, src -> refcnt, 0, RC_MISC);
681 return 1;
682 }
683
buffer_allocate(ptr,len,file,line)684 int buffer_allocate (ptr, len, file, line)
685 struct buffer **ptr;
686 unsigned len;
687 const char *file;
688 int line;
689 {
690 struct buffer *bp;
691
692 /* XXXSK: should check for bad ptr values, otherwise we
693 leak memory if they are wrong */
694 bp = dmalloc (len + sizeof *bp, file, line);
695 if (!bp)
696 return 0;
697 /* XXXSK: both of these initializations are unnecessary */
698 memset (bp, 0, sizeof *bp);
699 bp -> refcnt = 0;
700 return buffer_reference (ptr, bp, file, line);
701 }
702
buffer_reference(ptr,bp,file,line)703 int buffer_reference (ptr, bp, file, line)
704 struct buffer **ptr;
705 struct buffer *bp;
706 const char *file;
707 int line;
708 {
709 if (!ptr) {
710 log_error ("%s(%d): null pointer", file, line);
711 #if defined (POINTER_DEBUG)
712 abort ();
713 #else
714 return 0;
715 #endif
716 }
717 if (*ptr) {
718 log_error ("%s(%d): non-null pointer", file, line);
719 #if defined (POINTER_DEBUG)
720 abort ();
721 #else
722 *ptr = (struct buffer *)0;
723 #endif
724 }
725 *ptr = bp;
726 bp -> refcnt++;
727 rc_register (file, line, ptr, bp, bp -> refcnt, 0, RC_MISC);
728 return 1;
729 }
730
buffer_dereference(ptr,file,line)731 int buffer_dereference (ptr, file, line)
732 struct buffer **ptr;
733 const char *file;
734 int line;
735 {
736 if (!ptr) {
737 log_error ("%s(%d): null pointer", file, line);
738 #if defined (POINTER_DEBUG)
739 abort ();
740 #else
741 return 0;
742 #endif
743 }
744
745 if (!*ptr) {
746 log_error ("%s(%d): null pointer", file, line);
747 #if defined (POINTER_DEBUG)
748 abort ();
749 #else
750 return 0;
751 #endif
752 }
753
754 (*ptr) -> refcnt--;
755 rc_register (file, line, ptr, *ptr, (*ptr) -> refcnt, 1, RC_MISC);
756 if (!(*ptr) -> refcnt) {
757 dfree ((*ptr), file, line);
758 } else if ((*ptr) -> refcnt < 0) {
759 log_error ("%s(%d): negative refcnt!", file, line);
760 #if defined (DEBUG_RC_HISTORY)
761 dump_rc_history (*ptr);
762 #endif
763 #if defined (POINTER_DEBUG)
764 abort ();
765 #else
766 return 0;
767 #endif
768 }
769 *ptr = (struct buffer *)0;
770 return 1;
771 }
772
dns_host_entry_allocate(ptr,hostname,file,line)773 int dns_host_entry_allocate (ptr, hostname, file, line)
774 struct dns_host_entry **ptr;
775 const char *hostname;
776 const char *file;
777 int line;
778 {
779 struct dns_host_entry *bp;
780
781 bp = dmalloc (strlen (hostname) + sizeof *bp, file, line);
782 if (!bp)
783 return 0;
784 memset (bp, 0, sizeof *bp);
785 bp -> refcnt = 0;
786 strcpy (bp -> hostname, hostname);
787 return dns_host_entry_reference (ptr, bp, file, line);
788 }
789
dns_host_entry_reference(ptr,bp,file,line)790 int dns_host_entry_reference (ptr, bp, file, line)
791 struct dns_host_entry **ptr;
792 struct dns_host_entry *bp;
793 const char *file;
794 int line;
795 {
796 if (!ptr) {
797 log_error ("%s(%d): null pointer", file, line);
798 #if defined (POINTER_DEBUG)
799 abort ();
800 #else
801 return 0;
802 #endif
803 }
804 if (*ptr) {
805 log_error ("%s(%d): non-null pointer", file, line);
806 #if defined (POINTER_DEBUG)
807 abort ();
808 #else
809 *ptr = (struct dns_host_entry *)0;
810 #endif
811 }
812 *ptr = bp;
813 bp -> refcnt++;
814 rc_register (file, line, ptr, bp, bp -> refcnt, 0, RC_MISC);
815 return 1;
816 }
817
dns_host_entry_dereference(ptr,file,line)818 int dns_host_entry_dereference (ptr, file, line)
819 struct dns_host_entry **ptr;
820 const char *file;
821 int line;
822 {
823 if (!ptr || !*ptr) {
824 log_error ("%s(%d): null pointer", file, line);
825 #if defined (POINTER_DEBUG)
826 abort ();
827 #else
828 return 0;
829 #endif
830 }
831
832 (*ptr)->refcnt--;
833 rc_register (file, line, ptr, *ptr, (*ptr)->refcnt, 1, RC_MISC);
834 if ((*ptr)->refcnt == 0) {
835 dfree ((*ptr), file, line);
836 } else if ((*ptr)->refcnt < 0) {
837 log_error ("%s(%d): negative refcnt!", file, line);
838 #if defined (DEBUG_RC_HISTORY)
839 dump_rc_history (*ptr);
840 #endif
841 #if defined (POINTER_DEBUG)
842 abort ();
843 #else
844 return 0;
845 #endif
846 }
847 *ptr = (struct dns_host_entry *)0;
848 return 1;
849 }
850
option_state_allocate(ptr,file,line)851 int option_state_allocate (ptr, file, line)
852 struct option_state **ptr;
853 const char *file;
854 int line;
855 {
856 unsigned size;
857
858 if (!ptr) {
859 log_error ("%s(%d): null pointer", file, line);
860 #if defined (POINTER_DEBUG)
861 abort ();
862 #else
863 return 0;
864 #endif
865 }
866 if (*ptr) {
867 log_error ("%s(%d): non-null pointer", file, line);
868 #if defined (POINTER_DEBUG)
869 abort ();
870 #else
871 *ptr = (struct option_state *)0;
872 #endif
873 }
874
875 size = sizeof **ptr + (universe_count - 1) * sizeof (void *);
876 *ptr = dmalloc (size, file, line);
877 if (*ptr) {
878 memset (*ptr, 0, size);
879 (*ptr) -> universe_count = universe_count;
880 (*ptr) -> refcnt = 1;
881 rc_register (file, line,
882 ptr, *ptr, (*ptr) -> refcnt, 0, RC_MISC);
883 return 1;
884 }
885 return 0;
886 }
887
option_state_reference(ptr,bp,file,line)888 int option_state_reference (ptr, bp, file, line)
889 struct option_state **ptr;
890 struct option_state *bp;
891 const char *file;
892 int line;
893 {
894 if (!ptr) {
895 log_error ("%s(%d): null pointer", file, line);
896 #if defined (POINTER_DEBUG)
897 abort ();
898 #else
899 return 0;
900 #endif
901 }
902 if (*ptr) {
903 log_error ("%s(%d): non-null pointer", file, line);
904 #if defined (POINTER_DEBUG)
905 abort ();
906 #else
907 *ptr = (struct option_state *)0;
908 #endif
909 }
910 *ptr = bp;
911 bp -> refcnt++;
912 rc_register (file, line, ptr, bp, bp -> refcnt, 0, RC_MISC);
913 return 1;
914 }
915
option_state_dereference(ptr,file,line)916 int option_state_dereference (ptr, file, line)
917 struct option_state **ptr;
918 const char *file;
919 int line;
920 {
921 int i;
922 struct option_state *options;
923
924 if (!ptr || !*ptr) {
925 log_error ("%s(%d): null pointer", file, line);
926 #if defined (POINTER_DEBUG)
927 abort ();
928 #else
929 return 0;
930 #endif
931 }
932
933 options = *ptr;
934 *ptr = (struct option_state *)0;
935 --options -> refcnt;
936 rc_register (file, line, ptr, options, options -> refcnt, 1, RC_MISC);
937 if (options -> refcnt > 0)
938 return 1;
939
940 if (options -> refcnt < 0) {
941 log_error ("%s(%d): negative refcnt!", file, line);
942 #if defined (DEBUG_RC_HISTORY)
943 dump_rc_history (options);
944 #endif
945 #if defined (POINTER_DEBUG)
946 abort ();
947 #else
948 return 0;
949 #endif
950 }
951
952 /* Loop through the per-universe state. */
953 for (i = 0; i < options -> universe_count; i++)
954 if (options -> universes [i] &&
955 universes [i] -> option_state_dereference)
956 ((*(universes [i] -> option_state_dereference))
957 (universes [i], options, file, line));
958
959 dfree (options, file, line);
960 return 1;
961 }
962
executable_statement_allocate(ptr,file,line)963 int executable_statement_allocate (ptr, file, line)
964 struct executable_statement **ptr;
965 const char *file;
966 int line;
967 {
968 struct executable_statement *bp;
969
970 bp = dmalloc (sizeof *bp, file, line);
971 if (!bp)
972 return 0;
973 memset (bp, 0, sizeof *bp);
974 return executable_statement_reference (ptr, bp, file, line);
975 }
976
executable_statement_reference(ptr,bp,file,line)977 int executable_statement_reference (ptr, bp, file, line)
978 struct executable_statement **ptr;
979 struct executable_statement *bp;
980 const char *file;
981 int line;
982 {
983 if (!ptr) {
984 log_error ("%s(%d): null pointer", file, line);
985 #if defined (POINTER_DEBUG)
986 abort ();
987 #else
988 return 0;
989 #endif
990 }
991 if (*ptr) {
992 log_error ("%s(%d): non-null pointer", file, line);
993 #if defined (POINTER_DEBUG)
994 abort ();
995 #else
996 *ptr = (struct executable_statement *)0;
997 #endif
998 }
999 *ptr = bp;
1000 bp -> refcnt++;
1001 rc_register (file, line, ptr, bp, bp -> refcnt, 0, RC_MISC);
1002 return 1;
1003 }
1004
1005 static struct packet *free_packets;
1006
1007 #if defined (DEBUG_MEMORY_LEAKAGE) || \
1008 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
relinquish_free_packets()1009 void relinquish_free_packets ()
1010 {
1011 struct packet *p, *n;
1012 for (p = free_packets; p; p = n) {
1013 n = (struct packet *)(p -> raw);
1014 dfree (p, MDL);
1015 }
1016 free_packets = (struct packet *)0;
1017 }
1018 #endif
1019
packet_allocate(ptr,file,line)1020 int packet_allocate (ptr, file, line)
1021 struct packet **ptr;
1022 const char *file;
1023 int line;
1024 {
1025 struct packet *p;
1026
1027 if (!ptr) {
1028 log_error ("%s(%d): null pointer", file, line);
1029 #if defined (POINTER_DEBUG)
1030 abort ();
1031 #else
1032 return 0;
1033 #endif
1034 }
1035 if (*ptr) {
1036 log_error ("%s(%d): non-null pointer", file, line);
1037 #if defined (POINTER_DEBUG)
1038 abort ();
1039 #else
1040 *ptr = (struct packet *)0;
1041 #endif
1042 }
1043
1044 if (free_packets) {
1045 p = free_packets;
1046 free_packets = (struct packet *)(p -> raw);
1047 dmalloc_reuse (p, file, line, 1);
1048 } else {
1049 p = dmalloc (sizeof *p, file, line);
1050 }
1051 if (p) {
1052 memset (p, 0, sizeof *p);
1053 return packet_reference (ptr, p, file, line);
1054 }
1055 return 0;
1056 }
1057
packet_reference(ptr,bp,file,line)1058 int packet_reference (ptr, bp, file, line)
1059 struct packet **ptr;
1060 struct packet *bp;
1061 const char *file;
1062 int line;
1063 {
1064 if (!ptr) {
1065 log_error ("%s(%d): null pointer", file, line);
1066 #if defined (POINTER_DEBUG)
1067 abort ();
1068 #else
1069 return 0;
1070 #endif
1071 }
1072 if (*ptr) {
1073 log_error ("%s(%d): non-null pointer", file, line);
1074 #if defined (POINTER_DEBUG)
1075 abort ();
1076 #else
1077 *ptr = (struct packet *)0;
1078 #endif
1079 }
1080 *ptr = bp;
1081 bp -> refcnt++;
1082 rc_register (file, line, ptr, bp, bp -> refcnt, 0, RC_MISC);
1083 return 1;
1084 }
1085
packet_dereference(ptr,file,line)1086 int packet_dereference (ptr, file, line)
1087 struct packet **ptr;
1088 const char *file;
1089 int line;
1090 {
1091 int i;
1092 struct packet *packet;
1093
1094 if (!ptr || !*ptr) {
1095 log_error ("%s(%d): null pointer", file, line);
1096 #if defined (POINTER_DEBUG)
1097 abort ();
1098 #else
1099 return 0;
1100 #endif
1101 }
1102
1103 packet = *ptr;
1104 *ptr = (struct packet *)0;
1105 --packet -> refcnt;
1106 rc_register (file, line, ptr, packet, packet -> refcnt, 1, RC_MISC);
1107 if (packet -> refcnt > 0)
1108 return 1;
1109
1110 if (packet -> refcnt < 0) {
1111 log_error ("%s(%d): negative refcnt!", file, line);
1112 #if defined (DEBUG_RC_HISTORY)
1113 dump_rc_history (packet);
1114 #endif
1115 #if defined (POINTER_DEBUG)
1116 abort ();
1117 #else
1118 return 0;
1119 #endif
1120 }
1121
1122 if (packet -> options)
1123 option_state_dereference (&packet -> options, file, line);
1124 if (packet -> interface)
1125 interface_dereference (&packet -> interface, MDL);
1126 if (packet -> shared_network)
1127 shared_network_dereference (&packet -> shared_network, MDL);
1128 for (i = 0; i < packet -> class_count && i < PACKET_MAX_CLASSES; i++) {
1129 if (packet -> classes [i])
1130 omapi_object_dereference ((omapi_object_t **)
1131 &packet -> classes [i], MDL);
1132 }
1133 packet -> raw = (struct dhcp_packet *)free_packets;
1134 free_packets = packet;
1135 dmalloc_reuse (free_packets, __FILE__, __LINE__, 0);
1136 return 1;
1137 }
1138
dns_zone_allocate(ptr,file,line)1139 int dns_zone_allocate (ptr, file, line)
1140 struct dns_zone **ptr;
1141 const char *file;
1142 int line;
1143 {
1144 struct dns_zone *d;
1145
1146 if (!ptr) {
1147 log_error ("%s(%d): null pointer", file, line);
1148 #if defined (POINTER_DEBUG)
1149 abort ();
1150 #else
1151 return 0;
1152 #endif
1153 }
1154 if (*ptr) {
1155 log_error ("%s(%d): non-null pointer", file, line);
1156 #if defined (POINTER_DEBUG)
1157 abort ();
1158 #else
1159 *ptr = (struct dns_zone *)0;
1160 #endif
1161 }
1162
1163 d = dmalloc (sizeof *d, file, line);
1164 if (d) {
1165 memset (d, 0, sizeof *d);
1166 return dns_zone_reference (ptr, d, file, line);
1167 }
1168 return 0;
1169 }
1170
dns_zone_reference(ptr,bp,file,line)1171 int dns_zone_reference (ptr, bp, file, line)
1172 struct dns_zone **ptr;
1173 struct dns_zone *bp;
1174 const char *file;
1175 int line;
1176 {
1177 if (!ptr) {
1178 log_error ("%s(%d): null pointer", file, line);
1179 #if defined (POINTER_DEBUG)
1180 abort ();
1181 #else
1182 return 0;
1183 #endif
1184 }
1185 if (*ptr) {
1186 log_error ("%s(%d): non-null pointer", file, line);
1187 #if defined (POINTER_DEBUG)
1188 abort ();
1189 #else
1190 *ptr = (struct dns_zone *)0;
1191 #endif
1192 }
1193 *ptr = bp;
1194 bp -> refcnt++;
1195 rc_register (file, line, ptr, bp, bp -> refcnt, 0, RC_MISC);
1196 return 1;
1197 }
1198
binding_scope_allocate(ptr,file,line)1199 int binding_scope_allocate (ptr, file, line)
1200 struct binding_scope **ptr;
1201 const char *file;
1202 int line;
1203 {
1204 struct binding_scope *bp;
1205
1206 if (!ptr) {
1207 log_error ("%s(%d): null pointer", file, line);
1208 #if defined (POINTER_DEBUG)
1209 abort ();
1210 #else
1211 return 0;
1212 #endif
1213 }
1214
1215 if (*ptr) {
1216 log_error ("%s(%d): non-null pointer", file, line);
1217 #if defined (POINTER_DEBUG)
1218 abort ();
1219 #else
1220 return 0;
1221 #endif
1222 }
1223
1224 bp = dmalloc (sizeof *bp, file, line);
1225 if (!bp)
1226 return 0;
1227 memset (bp, 0, sizeof *bp);
1228 binding_scope_reference (ptr, bp, file, line);
1229 return 1;
1230 }
1231
binding_scope_reference(ptr,bp,file,line)1232 int binding_scope_reference (ptr, bp, file, line)
1233 struct binding_scope **ptr;
1234 struct binding_scope *bp;
1235 const char *file;
1236 int line;
1237 {
1238 if (!ptr) {
1239 log_error ("%s(%d): null pointer", file, line);
1240 #if defined (POINTER_DEBUG)
1241 abort ();
1242 #else
1243 return 0;
1244 #endif
1245 }
1246 if (*ptr) {
1247 log_error ("%s(%d): non-null pointer", file, line);
1248 #if defined (POINTER_DEBUG)
1249 abort ();
1250 #else
1251 *ptr = (struct binding_scope *)0;
1252 #endif
1253 }
1254 *ptr = bp;
1255 bp -> refcnt++;
1256 rc_register (file, line, ptr, bp, bp -> refcnt, 0, RC_MISC);
1257 return 1;
1258 }
1259
1260 /*!
1261 * \brief Constructs a null-terminated data_string from a char* and length.
1262 *
1263 * Allocates a data_string and copies into it the given length of bytes
1264 * from the given source, adding a terminating null if not present in the source
1265 * at length-1.
1266 *
1267 * \param new_string pointer to the data_string to construct. Cannot be
1268 * NULL. Note that its contents will be overwritten. Passing in the address
1269 * of an allocated data_string will result in memory leaks.
1270 * \param src data to be copied. Cannot be NULL.
1271 * \param len length of the data to copied
1272 *
1273 * \return 1 - if the data_string is constructed successfully, 0 if
1274 * target data_struct is NULL or the buffer allocation fails.
1275 */
1276 int
data_string_new(struct data_string * new_string,const char * src,unsigned int len,const char * file,int line)1277 data_string_new(struct data_string *new_string,
1278 const char *src, unsigned int len,
1279 const char *file, int line)
1280 {
1281 unsigned int copy_len = 0;
1282
1283 if (new_string == NULL) {
1284 log_error("data_string_new: new_string cannot be NULL %s(%d)",
1285 file, line);
1286 return (0);
1287 }
1288
1289 if (src == NULL) {
1290 log_error("data_string_new: src cannot be NULL %s(%d)",
1291 file, line);
1292 return (0);
1293 }
1294
1295 memset(new_string, 0, sizeof (struct data_string));
1296
1297 /* If we already have a NULL back off length by one. This lets
1298 * us always just add a NULL at the end. */
1299 copy_len = (len > 0 && src[len - 1] == 0) ? len - 1 : len;
1300
1301 /* Allocate the buffer, accounting for terminating null */
1302 if (!buffer_allocate(&(new_string->buffer), copy_len + 1, MDL)) {
1303 log_error("data_string_new: No memory %s(%d)", file, line);
1304 return (0);
1305 }
1306
1307 /* Only copy if there's something to copy */
1308 if (copy_len > 0) {
1309 memcpy(new_string->buffer->data, src, copy_len);
1310 }
1311
1312 /* Always tack on the null */
1313 new_string->buffer->data[copy_len] = 0;
1314
1315 /* Update data_string accessor values. Note len does NOT include
1316 * the NULL. */
1317 new_string->data = new_string->buffer->data;
1318 new_string->len = copy_len;
1319 new_string->terminated = 1;
1320
1321 return (1);
1322 }
1323
1324 /* Make a copy of the data in data_string, upping the buffer reference
1325 count if there's a buffer. */
1326
1327 void
data_string_copy(struct data_string * dest,const struct data_string * src,const char * file,int line)1328 data_string_copy(struct data_string *dest, const struct data_string *src,
1329 const char *file, int line)
1330 {
1331 if (src -> buffer) {
1332 buffer_reference (&dest -> buffer, src -> buffer, file, line);
1333 } else {
1334 dest->buffer = NULL;
1335 }
1336 dest -> data = src -> data;
1337 dest -> terminated = src -> terminated;
1338 dest -> len = src -> len;
1339 }
1340
1341 /* Release the reference count to a data string's buffer (if any) and
1342 zero out the other information, yielding the null data string. */
1343
data_string_forget(data,file,line)1344 void data_string_forget (data, file, line)
1345 struct data_string *data;
1346 const char *file;
1347 int line;
1348 {
1349 if (data -> buffer)
1350 buffer_dereference (&data -> buffer, file, line);
1351 memset (data, 0, sizeof *data);
1352 }
1353
1354 /* If the data_string is larger than the specified length, reduce
1355 the data_string to the specified size. */
1356
data_string_truncate(dp,len)1357 void data_string_truncate (dp, len)
1358 struct data_string *dp;
1359 int len;
1360 {
1361 /* XXX: do we need to consider the "terminated" flag in the check? */
1362 if (len < dp -> len) {
1363 dp -> terminated = 0;
1364 dp -> len = len;
1365 }
1366 }
1367
1368 /* \brief Converts a data_string to a null-terminated data string
1369 *
1370 * If the given string isn't null-terminated, replace it with a
1371 * null-terminated version and free the current string decrementing
1372 * the referecne count. If the string is null-terminated it is left
1373 * as is.
1374 *
1375 * Currently this routine doesn't check if the string is 0 length
1376 * that must be checked by the caller.
1377 *
1378 * \param [in/out] str the data_string to convert
1379 * \param file the file this routine was called from
1380 * \param line the line this routine was called from
1381 *
1382 * \return 1 if the string was converted successfully (or already terminated),
1383 * 0 if the conversion failed. Failure is only possible if memory for the new
1384 * string could not be allocated. If the conversion fails, the original
1385 * string's content is lost.
1386 */
data_string_terminate(str,file,line)1387 int data_string_terminate(str, file, line)
1388 struct data_string* str;
1389 const char *file;
1390 int line;
1391 {
1392 int ret_val = 1;
1393
1394 if (str->terminated == 0) {
1395 struct data_string temp;
1396 memset(&temp, 0, sizeof(temp));
1397
1398 data_string_copy(&temp, str, file, line);
1399 data_string_forget(str, file, line);
1400 if (data_string_new(str, (const char*)temp.data, temp.len,
1401 file, line) == 0) {
1402 /* couldn't create a copy, probably a memory issue,
1403 * an error message has already been logged. */
1404 ret_val = 0;
1405 }
1406
1407 /* get rid of temp string */
1408 data_string_forget(&temp, file, line);
1409 }
1410
1411 return (ret_val);
1412 }
1413