ISC DHCP 4.4.3-P1
A reference DHCPv4 and DHCPv6 implementation
 
Loading...
Searching...
No Matches
alloc.c
Go to the documentation of this file.
1/* alloc.c
2
3 Functions supporting memory allocation for the object management
4 protocol... */
5
6/*
7 * Copyright (C) 2004-2022 Internet Systems Consortium, Inc. ("ISC")
8 * Copyright (c) 1999-2003 by Internet Software Consortium
9 *
10 * This Source Code Form is subject to the terms of the Mozilla Public
11 * License, v. 2.0. If a copy of the MPL was not distributed with this
12 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
15 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
16 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
17 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
18 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
19 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
20 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21 *
22 * Internet Systems Consortium, Inc.
23 * PO Box 360
24 * Newmarket, NH 03857 USA
25 * <info@isc.org>
26 * https://www.isc.org/
27 *
28 */
29
30#include "dhcpd.h"
31
32#include <omapip/omapip_p.h>
33
34#if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \
35 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
36struct dmalloc_preamble *dmalloc_list;
37unsigned long dmalloc_outstanding;
38unsigned long dmalloc_longterm;
39unsigned long dmalloc_generation;
40unsigned long dmalloc_cutoff_generation;
41#endif
42
43#if defined (DEBUG_RC_HISTORY)
44struct rc_history_entry rc_history [RC_HISTORY_MAX];
45int rc_history_index;
46int rc_history_count;
47#endif
48
49#if defined (DEBUG_RC_HISTORY)
50static void print_rc_hist_entry (int);
51#endif
52
53static int dmalloc_failures;
54static char out_of_memory[] = "Run out of memory.";
55
56void *
57dmalloc(size_t size, const char *file, int line) {
58 unsigned char *foo;
59 size_t len;
60 void **bar;
61#if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \
62 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
63 int i;
64 struct dmalloc_preamble *dp;
65#endif
66
67 len = size + DMDSIZE;
68 if (len < size)
69 return NULL;
70
71 foo = malloc(len);
72
73 if (!foo) {
74 dmalloc_failures++;
75 if (dmalloc_failures > 10) {
76 /* In case log_fatal() returns here */
78 out_of_memory,
79 strlen(out_of_memory)));
80 IGNORE_RET(write(STDERR_FILENO, "\n", 1));
81 exit(1);
82 } else if (dmalloc_failures >= 10) {
83 /* Something went wrong beyond repair. */
84 log_fatal("Fatal error: out of memory.");
85 }
86 return NULL;
87 }
88 bar = (void *)(foo + DMDOFFSET);
89 memset (bar, 0, size);
90
91#if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \
92 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
93 dp = (struct dmalloc_preamble *)foo;
94 dp -> prev = dmalloc_list;
95 if (dmalloc_list)
96 dmalloc_list -> next = dp;
97 dmalloc_list = dp;
98 dp -> next = (struct dmalloc_preamble *)0;
99 dp -> size = size;
100 dp -> file = file;
101 dp -> line = line;
102 dp -> generation = dmalloc_generation++;
103 dmalloc_outstanding += size;
104 for (i = 0; i < DMLFSIZE; i++)
105 dp -> low_fence [i] =
106 (((unsigned long)
107 (&dp -> low_fence [i])) % 143) + 113;
108 for (i = DMDOFFSET; i < DMDSIZE; i++)
109 foo [i + size] =
110 (((unsigned long)
111 (&foo [i + size])) % 143) + 113;
112#if defined (DEBUG_MALLOC_POOL_EXHAUSTIVELY)
113 /* Check _every_ entry in the pool! Very expensive. */
114 for (dp = dmalloc_list; dp; dp = dp -> prev) {
115 for (i = 0; i < DMLFSIZE; i++) {
116 if (dp -> low_fence [i] !=
117 (((unsigned long)
118 (&dp -> low_fence [i])) % 143) + 113)
119 {
120 log_error ("malloc fence modified: %s(%d)",
121 dp -> file, dp -> line);
122 abort ();
123 }
124 }
125 foo = (unsigned char *)dp;
126 for (i = DMDOFFSET; i < DMDSIZE; i++) {
127 if (foo [i + dp -> size] !=
128 (((unsigned long)
129 (&foo [i + dp -> size])) % 143) + 113) {
130 log_error ("malloc fence modified: %s(%d)",
131 dp -> file, dp -> line);
132 abort ();
133 }
134 }
135 }
136#endif
137#endif
138#ifdef DEBUG_REFCNT_DMALLOC_FREE
139 rc_register (file, line, 0, foo + DMDOFFSET, 1, 0, RC_MALLOC);
140#endif
141 return bar;
142}
143
144void
145dfree(void *ptr, const char *file, int line) {
146 if (!ptr) {
147 log_error ("dfree %s(%d): free on null pointer.", file, line);
148 return;
149 }
150#if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \
151 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
152 {
153 unsigned char *bar = ptr;
154 struct dmalloc_preamble *dp, *cur;
155 int i;
156 bar -= DMDOFFSET;
157 cur = (struct dmalloc_preamble *)bar;
158 for (dp = dmalloc_list; dp; dp = dp -> prev)
159 if (dp == cur)
160 break;
161 if (!dp) {
162 log_error ("%s(%d): freeing unknown memory: %lx",
163 file, line, (unsigned long)cur);
164 abort ();
165 }
166 if (dp -> prev)
167 dp -> prev -> next = dp -> next;
168 if (dp -> next)
169 dp -> next -> prev = dp -> prev;
170 if (dp == dmalloc_list)
171 dmalloc_list = dp -> prev;
172 if (dp -> generation >= dmalloc_cutoff_generation)
173 dmalloc_outstanding -= dp -> size;
174 else
175 dmalloc_longterm -= dp -> size;
176
177 for (i = 0; i < DMLFSIZE; i++) {
178 if (dp -> low_fence [i] !=
179 (((unsigned long)
180 (&dp -> low_fence [i])) % 143) + 113)
181 {
182 log_error ("malloc fence modified: %s(%d)",
183 dp -> file, dp -> line);
184 abort ();
185 }
186 }
187 for (i = DMDOFFSET; i < DMDSIZE; i++) {
188 if (bar [i + dp -> size] !=
189 (((unsigned long)
190 (&bar [i + dp -> size])) % 143) + 113) {
191 log_error ("malloc fence modified: %s(%d)",
192 dp -> file, dp -> line);
193 abort ();
194 }
195 }
196 ptr = bar;
197 }
198#endif
199#ifdef DEBUG_REFCNT_DMALLOC_FREE
201 0, (unsigned char *)ptr + DMDOFFSET, 0, 1, RC_MALLOC);
202#endif
203 free (ptr);
204}
205
206#if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \
207 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
208/* For allocation functions that keep their own free lists, we want to
209 account for the reuse of the memory. */
210
211void
212dmalloc_reuse(void *foo, const char *file, int line, int justref) {
213 struct dmalloc_preamble *dp;
214
215 /* Get the pointer to the dmalloc header. */
216 dp = foo;
217 dp--;
218
219 /* If we just allocated this and are now referencing it, this
220 function would almost be a no-op, except that it would
221 increment the generation count needlessly. So just return
222 in this case. */
223 if (dp -> generation == dmalloc_generation)
224 return;
225
226 /* If this is longterm data, and we just made reference to it,
227 don't put it on the short-term list or change its name -
228 we don't need to know about this. */
229 if (dp -> generation < dmalloc_cutoff_generation && justref)
230 return;
231
232 /* Take it out of the place in the allocated list where it was. */
233 if (dp -> prev)
234 dp -> prev -> next = dp -> next;
235 if (dp -> next)
236 dp -> next -> prev = dp -> prev;
237 if (dp == dmalloc_list)
238 dmalloc_list = dp -> prev;
239
240 /* Account for its removal. */
241 if (dp -> generation >= dmalloc_cutoff_generation)
242 dmalloc_outstanding -= dp -> size;
243 else
244 dmalloc_longterm -= dp -> size;
245
246 /* Now put it at the head of the list. */
247 dp -> prev = dmalloc_list;
248 if (dmalloc_list)
249 dmalloc_list -> next = dp;
250 dmalloc_list = dp;
251 dp -> next = (struct dmalloc_preamble *)0;
252
253 /* Change the reference location information. */
254 dp -> file = file;
255 dp -> line = line;
256
257 /* Increment the generation. */
258 dp -> generation = dmalloc_generation++;
259
260 /* Account for it. */
261 dmalloc_outstanding += dp -> size;
262}
263
264void dmalloc_dump_outstanding ()
265{
266 static unsigned long dmalloc_cutoff_point;
267 struct dmalloc_preamble *dp;
268#if defined(DEBUG_MALLOC_POOL)
269 unsigned char *foo;
270 int i;
271#endif
272
273 if (!dmalloc_cutoff_point)
274 dmalloc_cutoff_point = dmalloc_cutoff_generation;
275 for (dp = dmalloc_list; dp; dp = dp -> prev) {
276 if (dp -> generation <= dmalloc_cutoff_point)
277 break;
278#if defined (DEBUG_MALLOC_POOL)
279 for (i = 0; i < DMLFSIZE; i++) {
280 if (dp -> low_fence [i] !=
281 (((unsigned long)
282 (&dp -> low_fence [i])) % 143) + 113)
283 {
284 log_error ("malloc fence modified: %s(%d)",
285 dp -> file, dp -> line);
286 abort ();
287 }
288 }
289 foo = (unsigned char *)dp;
290 for (i = DMDOFFSET; i < DMDSIZE; i++) {
291 if (foo [i + dp -> size] !=
292 (((unsigned long)
293 (&foo [i + dp -> size])) % 143) + 113) {
294 log_error ("malloc fence modified: %s(%d)",
295 dp -> file, dp -> line);
296 abort ();
297 }
298 }
299#endif
300#if defined (DEBUG_MEMORY_LEAKAGE) || \
301 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
302 /* Don't count data that's actually on a free list
303 somewhere. */
304 if (dp -> file) {
305#if defined (DEBUG_RC_HISTORY)
306 int i, count, inhistory = 0, noted = 0;
307
308 /* If we have the info, see if this is actually
309 new garbage. */
310 if (rc_history_count < RC_HISTORY_MAX) {
311 count = rc_history_count;
312 } else
313 count = RC_HISTORY_MAX;
314 i = rc_history_index - 1;
315 if (i < 0)
316 i += RC_HISTORY_MAX;
317
318 do {
319 if (rc_history [i].addr == dp + 1) {
320 inhistory = 1;
321 if (!noted) {
322 log_info (" %s(%d): %ld", dp -> file,
323 dp -> line, (long) dp -> size);
324 noted = 1;
325 }
326 print_rc_hist_entry (i);
327 if (!rc_history [i].refcnt)
328 break;
329 }
330 if (--i < 0)
331 i = RC_HISTORY_MAX - 1;
332 } while (count--);
333 if (!inhistory)
334#endif
335 log_info (" %s(%d): %ld",
336 dp -> file, dp -> line,
337 (long) dp -> size);
338 }
339#endif
340 }
341 if (dmalloc_list)
342 dmalloc_cutoff_point = dmalloc_list -> generation;
343}
344#endif /* DEBUG_MEMORY_LEAKAGE || DEBUG_MALLOC_POOL */
345
346#if defined (DEBUG_RC_HISTORY)
347static void print_rc_hist_entry (int i)
348{
349 log_info (" referenced by %s(%d)[%lx]: addr = %lx refcnt = %x",
350 rc_history [i].file, rc_history [i].line,
351 (unsigned long)rc_history [i].reference,
352 (unsigned long)rc_history [i].addr,
353 rc_history [i].refcnt);
354}
355
356void dump_rc_history (void *addr)
357{
358 int i;
359
360 i = rc_history_index;
361 if (!rc_history [i].file)
362 i = 0;
363 else if (rc_history_count < RC_HISTORY_MAX) {
364 i -= rc_history_count;
365 if (i < 0)
366 i += RC_HISTORY_MAX;
367 }
368 rc_history_count = 0;
369
370 while (rc_history [i].file) {
371 if (!addr || addr == rc_history [i].addr)
372 print_rc_hist_entry (i);
373 ++i;
374 if (i == RC_HISTORY_MAX)
375 i = 0;
376 if (i == rc_history_index)
377 break;
378 }
379}
380void rc_history_next (int d)
381{
382#if defined (RC_HISTORY_COMPRESSION)
383 int i, j = 0, m, n = 0;
384 void *ap, *rp;
385
386 /* If we are decreasing the reference count, try to find the
387 entry where the reference was made and eliminate it; then
388 we can also eliminate this reference. */
389 if (d) {
390 m = rc_history_index - 1000;
391 if (m < -1)
392 m = -1;
393 ap = rc_history [rc_history_index].addr;
394 rp = rc_history [rc_history_index].reference;
395 for (i = rc_history_index - 1; i > m; i--) {
396 if (rc_history [i].addr == ap) {
397 if (rc_history [i].reference == rp) {
398 if (n > 10) {
399 for (n = i; n <= rc_history_index; n++)
400 print_rc_hist_entry (n);
401 n = 11;
402 }
403 memmove (&rc_history [i],
404 &rc_history [i + 1],
405 (unsigned)((rc_history_index - i) *
406 sizeof (struct rc_history_entry)));
407 --rc_history_count;
408 --rc_history_index;
409 for (j = i; j < rc_history_count; j++) {
410 if (rc_history [j].addr == ap)
411 --rc_history [j].refcnt;
412 }
413 if (n > 10) {
414 for (n = i; n <= rc_history_index; n++)
415 print_rc_hist_entry (n);
416 n = 11;
417 exit (0);
418 }
419 return;
420 }
421 }
422 }
423 }
424#endif
425 if (++rc_history_index == RC_HISTORY_MAX)
426 rc_history_index = 0;
427 ++rc_history_count;
428}
429#endif /* DEBUG_RC_HISTORY */
430
431#if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \
432 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
433struct caller {
434 struct dmalloc_preamble *dp;
435 int count;
436};
437
438static int dmalloc_find_entry (struct dmalloc_preamble *dp,
439 struct caller *array,
440 int min, int max)
441{
442 int middle;
443
444 middle = (min + max) / 2;
445 if (middle == min)
446 return middle;
447 if (array [middle].dp -> file == dp -> file) {
448 if (array [middle].dp -> line == dp -> line)
449 return middle;
450 else if (array [middle].dp -> line < dp -> line)
451 return dmalloc_find_entry (dp, array, middle, max);
452 else
453 return dmalloc_find_entry (dp, array, 0, middle);
454 } else if (array [middle].dp -> file < dp -> file)
455 return dmalloc_find_entry (dp, array, middle, max);
456 else
457 return dmalloc_find_entry (dp, array, 0, middle);
458}
459
461{
462 struct dmalloc_preamble *dp;
463 int ccur, cmax, i;
464 struct caller cp [1024];
465
466 cmax = 1024;
467 ccur = 0;
468
469 memset (cp, 0, sizeof cp);
470 for (dp = dmalloc_list; dp; dp = dp -> prev) {
471 i = dmalloc_find_entry (dp, cp, 0, ccur);
472 if ((i == ccur ||
473 cp [i].dp -> file != dp -> file ||
474 cp [i].dp -> line != dp -> line) &&
475 ccur == cmax) {
476 log_error ("no space for memory usage summary.");
477 return;
478 }
479 if (i == ccur) {
480 cp [ccur++].dp = dp;
481 cp [i].count = 1;
482 } else if (cp [i].dp -> file < dp -> file ||
483 (cp [i].dp -> file == dp -> file &&
484 cp [i].dp -> line < dp -> line)) {
485 if (i + 1 != ccur)
486 memmove (cp + i + 2, cp + i + 1,
487 (ccur - i) * sizeof *cp);
488 cp [i + 1].dp = dp;
489 cp [i + 1].count = 1;
490 ccur++;
491 } else if (cp [i].dp -> file != dp -> file ||
492 cp [i].dp -> line != dp -> line) {
493 memmove (cp + i + 1,
494 cp + i, (ccur - i) * sizeof *cp);
495 cp [i].dp = dp;
496 cp [i].count = 1;
497 ccur++;
498 } else
499 cp [i].count++;
500#if 0
501 printf ("%d\t%s:%d\n", i, dp -> file, dp -> line);
502 dump_rc_history (dp + 1);
503#endif
504 }
505 for (i = 0; i < ccur; i++) {
506 printf ("%d\t%s:%d\t%d\n", i,
507 cp [i].dp -> file, cp [i].dp -> line, cp [i].count);
508#if defined(DUMP_RC_HISTORY)
509 dump_rc_history (cp [i].dp + 1);
510#endif
511 }
512}
513#endif /* DEBUG_MEMORY_LEAKAGE || DEBUG_MALLOC_POOL */
514
517 size_t size,
518 const char *file, int line)
519{
520 size_t tsize;
521 omapi_object_t *foo;
522 isc_result_t status;
523
524 if (type -> allocator) {
525 foo = (omapi_object_t *)0;
526 status = (*type -> allocator) (&foo, file, line);
527 tsize = type -> size;
528 } else {
529 status = ISC_R_NOMEMORY;
530 tsize = 0;
531 }
532
533 if (status == ISC_R_NOMEMORY) {
534 if (type -> sizer)
535 tsize = (*type -> sizer) (size);
536 else
537 tsize = type -> size;
538
539 /* Sanity check. */
540 if (tsize < sizeof (omapi_object_t))
541 return DHCP_R_INVALIDARG;
542
543 foo = dmalloc (tsize, file, line);
544 if (!foo)
545 return ISC_R_NOMEMORY;
546 }
547
548 status = omapi_object_initialize (foo, type, size, tsize, file, line);
549 if (status != ISC_R_SUCCESS) {
550 if (type -> freer)
551 (*type -> freer) (foo, file, line);
552 else
553 dfree (foo, file, line);
554 return status;
555 }
556 return omapi_object_reference (o, foo, file, line);
557}
558
561 size_t usize, size_t psize,
562 const char *file, int line)
563{
564 memset (o, 0, psize);
565 o -> type = type;
566 if (type -> initialize)
567 (*type -> initialize) (o, file, line);
568 return ISC_R_SUCCESS;
569}
570
573 const char *file, int line)
574{
575 if (!h || !r)
576 return DHCP_R_INVALIDARG;
577
578 if (*r) {
579#if defined (POINTER_DEBUG)
580 log_error ("%s(%d): reference store into non-null pointer!",
581 file, line);
582 abort ();
583#else
584 return DHCP_R_INVALIDARG;
585#endif
586 }
587 *r = h;
588 h -> refcnt++;
589 rc_register (file, line, r, h, h -> refcnt, 0, h -> type -> rc_flag);
590 return ISC_R_SUCCESS;
591}
592
594 const char *file, int line)
595{
596 int outer_reference = 0;
597 int inner_reference = 0;
598 int handle_reference = 0;
599 int extra_references;
600 omapi_object_t *p, *hp;
601
602 if (!h)
603 return DHCP_R_INVALIDARG;
604
605 if (!*h) {
606#if defined (POINTER_DEBUG)
607 log_error ("%s(%d): dereference of null pointer!", file, line);
608 abort ();
609#else
610 return DHCP_R_INVALIDARG;
611#endif
612 }
613
614 if ((*h) -> refcnt <= 0) {
615#if defined (POINTER_DEBUG)
616 log_error ("%s(%d): dereference of pointer with refcnt of zero!",
617 file, line);
618#if defined (DEBUG_RC_HISTORY)
619 dump_rc_history (*h);
620#endif
621 abort ();
622#else
623 *h = 0;
624 return DHCP_R_INVALIDARG;
625#endif
626 }
627
628 /* See if this object's inner object refers to it, but don't
629 count this as a reference if we're being asked to free the
630 reference from the inner object. */
631 if ((*h) -> inner && (*h) -> inner -> outer &&
632 h != &((*h) -> inner -> outer))
633 inner_reference = 1;
634
635 /* Ditto for the outer object. */
636 if ((*h) -> outer && (*h) -> outer -> inner &&
637 h != &((*h) -> outer -> inner))
638 outer_reference = 1;
639
640 /* Ditto for the outer object. The code below assumes that
641 the only reason we'd get a dereference from the handle
642 table is if this function does it - otherwise we'd have to
643 traverse the handle table to find the address where the
644 reference is stored and compare against that, and we don't
645 want to do that if we can avoid it. */
646 if ((*h) -> handle)
647 handle_reference = 1;
648
649 /* If we are getting rid of the last reference other than
650 references to inner and outer objects, or from the handle
651 table, then we must examine all the objects in either
652 direction to see if they hold any non-inner, non-outer,
653 non-handle-table references. If not, we need to free the
654 entire chain of objects. */
655 if ((*h) -> refcnt ==
656 inner_reference + outer_reference + handle_reference + 1) {
657 if (inner_reference || outer_reference || handle_reference) {
658 /* XXX we could check for a reference from the
659 handle table here. */
660 extra_references = 0;
661 for (p = (*h) -> inner;
662 p && !extra_references; p = p -> inner) {
663 extra_references += p -> refcnt;
664 if (p -> inner && p -> inner -> outer == p)
665 --extra_references;
666 if (p -> outer)
667 --extra_references;
668 if (p -> handle)
669 --extra_references;
670 }
671 for (p = (*h) -> outer;
672 p && !extra_references; p = p -> outer) {
673 extra_references += p -> refcnt;
674 if (p -> outer && p -> outer -> inner == p)
675 --extra_references;
676 if (p -> inner)
677 --extra_references;
678 if (p -> handle)
679 --extra_references;
680 }
681 } else
682 extra_references = 0;
683
684 if (!extra_references) {
685 hp = *h;
686 *h = 0;
687 hp -> refcnt--;
688 if (inner_reference)
690 (&hp -> inner, file, line);
691 if (outer_reference)
693 (&hp -> outer, file, line);
694/* if (!hp -> type -> freer) */
695 rc_register (file, line, h, hp,
696 0, 1, hp -> type -> rc_flag);
697 if (handle_reference) {
698 if (omapi_handle_clear(hp->handle) !=
700 log_debug("Attempt to clear null "
701 "handle pointer");
702 }
703 }
704 if (hp -> type -> destroy)
705 (*(hp -> type -> destroy)) (hp, file, line);
706 if (hp -> type -> freer)
707 (hp -> type -> freer (hp, file, line));
708 else
709 dfree (hp, file, line);
710 } else {
711 (*h) -> refcnt--;
712/* if (!(*h) -> type -> freer) */
714 h, *h, (*h) -> refcnt, 1,
715 (*h) -> type -> rc_flag);
716 }
717 } else {
718 (*h) -> refcnt--;
719/* if (!(*h) -> type -> freer) */
720 rc_register (file, line, h, *h, (*h) -> refcnt, 1,
721 (*h) -> type -> rc_flag);
722 }
723 *h = 0;
724 return ISC_R_SUCCESS;
725}
726
728 const char *file, int line)
729{
731 isc_result_t status;
732
733 t = (omapi_buffer_t *)dmalloc (sizeof *t, file, line);
734 if (!t)
735 return ISC_R_NOMEMORY;
736 memset (t, 0, sizeof *t);
737 status = omapi_buffer_reference (h, t, file, line);
738 if (status != ISC_R_SUCCESS)
739 dfree (t, file, line);
740 (*h) -> head = sizeof ((*h) -> buf) - 1;
741 return status;
742}
743
746 const char *file, int line)
747{
748 if (!h || !r)
749 return DHCP_R_INVALIDARG;
750
751 if (*r) {
752#if defined (POINTER_DEBUG)
753 log_error ("%s(%d): reference store into non-null pointer!",
754 file, line);
755 abort ();
756#else
757 return DHCP_R_INVALIDARG;
758#endif
759 }
760 *r = h;
761 h -> refcnt++;
762 rc_register (file, line, r, h, h -> refcnt, 0, RC_MISC);
763 return ISC_R_SUCCESS;
764}
765
767 const char *file, int line)
768{
769 if (!h)
770 return DHCP_R_INVALIDARG;
771
772 if (!*h) {
773#if defined (POINTER_DEBUG)
774 log_error ("%s(%d): dereference of null pointer!", file, line);
775 abort ();
776#else
777 return DHCP_R_INVALIDARG;
778#endif
779 }
780
781 if ((*h) -> refcnt <= 0) {
782#if defined (POINTER_DEBUG)
783 log_error ("%s(%d): dereference of pointer with refcnt of zero!",
784 file, line);
785#if defined (DEBUG_RC_HISTORY)
786 dump_rc_history (*h);
787#endif
788 abort ();
789#else
790 *h = 0;
791 return DHCP_R_INVALIDARG;
792#endif
793 }
794
795 --(*h) -> refcnt;
796 rc_register (file, line, h, *h, (*h) -> refcnt, 1, RC_MISC);
797 if ((*h) -> refcnt == 0)
798 dfree (*h, file, line);
799 *h = 0;
800 return ISC_R_SUCCESS;
801}
802
803isc_result_t omapi_typed_data_new (const char *file, int line,
805 omapi_datatype_t type, ...)
806{
807 va_list l;
809 unsigned len;
810 unsigned val = 0;
811 int intval = 0;
812 char *s = NULL;
813 isc_result_t status;
814 omapi_object_t *obj = NULL;
815
816 va_start (l, type);
817
818 switch (type) {
821 intval = va_arg (l, int);
822 break;
824 s = va_arg (l, char *);
825 val = strlen (s);
827 if (len < val) {
828 va_end(l);
829 return DHCP_R_INVALIDARG;
830 }
831 break;
833 val = va_arg (l, unsigned);
835 if (len < val) {
836 va_end(l);
837 return DHCP_R_INVALIDARG;
838 }
839 break;
842 obj = va_arg (l, omapi_object_t *);
843 break;
844 default:
845 va_end (l);
846 return DHCP_R_INVALIDARG;
847 }
848 va_end (l);
849
850 new = dmalloc (len, file, line);
851 if (!new)
852 return ISC_R_NOMEMORY;
853 memset (new, 0, len);
854
855 switch (type) {
857 new -> u.integer = intval;
858 break;
860 memcpy (new -> u.buffer.value, s, val);
861 new -> u.buffer.len = val;
862 break;
864 new -> u.buffer.len = val;
865 break;
867 status = omapi_object_reference (&new -> u.object, obj,
868 file, line);
869 if (status != ISC_R_SUCCESS) {
870 dfree (new, file, line);
871 return status;
872 }
873 break;
874 }
875 new -> type = type;
876
877 return omapi_typed_data_reference (t, new, file, line);
878}
879
882 const char *file, int line)
883{
884 if (!h || !r)
885 return DHCP_R_INVALIDARG;
886
887 if (*r) {
888#if defined (POINTER_DEBUG)
889 log_error ("%s(%d): reference store into non-null pointer!", file, line);
890 abort ();
891#else
892 return DHCP_R_INVALIDARG;
893#endif
894 }
895 *r = h;
896 h -> refcnt++;
897 rc_register (file, line, r, h, h -> refcnt, 0, RC_MISC);
898 return ISC_R_SUCCESS;
899}
900
902 const char *file, int line)
903{
904 if (!h)
905 return DHCP_R_INVALIDARG;
906
907 if (!*h) {
908#if defined (POINTER_DEBUG)
909 log_error ("%s(%d): dereference of null pointer!", file, line);
910 abort ();
911#else
912 return DHCP_R_INVALIDARG;
913#endif
914 }
915
916 if ((*h) -> refcnt <= 0) {
917#if defined (POINTER_DEBUG)
918 log_error ("%s(%d): dereference of pointer with refcnt of zero!",
919 file, line);
920#if defined (DEBUG_RC_HISTORY)
921 dump_rc_history (*h);
922#endif
923 abort ();
924#else
925 *h = 0;
926 return DHCP_R_INVALIDARG;
927#endif
928 }
929
930 --((*h) -> refcnt);
931 rc_register (file, line, h, *h, (*h) -> refcnt, 1, RC_MISC);
932 if ((*h) -> refcnt <= 0 ) {
933 switch ((*h) -> type) {
937 default:
938 break;
940 omapi_object_dereference (&(*h) -> u.object,
941 file, line);
942 break;
943 }
944 dfree (*h, file, line);
945 }
946 *h = 0;
947 return ISC_R_SUCCESS;
948}
949
950isc_result_t omapi_data_string_new (omapi_data_string_t **d, unsigned len,
951 const char *file, int line)
952{
954 unsigned nlen;
955
956 nlen = OMAPI_DATA_STRING_EMPTY_SIZE + len;
957 if (nlen < len)
958 return DHCP_R_INVALIDARG;
959 new = dmalloc (nlen, file, line);
960 if (!new)
961 return ISC_R_NOMEMORY;
962 memset (new, 0, OMAPI_DATA_STRING_EMPTY_SIZE);
963 new -> len = len;
964 return omapi_data_string_reference (d, new, file, line);
965}
966
969 const char *file, int line)
970{
971 if (!h || !r)
972 return DHCP_R_INVALIDARG;
973
974 if (*r) {
975#if defined (POINTER_DEBUG)
976 log_error ("%s(%d): reference store into non-null pointer!", file, line);
977 abort ();
978#else
979 return DHCP_R_INVALIDARG;
980#endif
981 }
982 *r = h;
983 h -> refcnt++;
984 rc_register (file, line, r, h, h -> refcnt, 0, RC_MISC);
985 return ISC_R_SUCCESS;
986}
987
989 const char *file, int line)
990{
991 if (!h)
992 return DHCP_R_INVALIDARG;
993
994 if (!*h) {
995#if defined (POINTER_DEBUG)
996 log_error ("%s(%d): dereference of null pointer!", file, line);
997 abort ();
998#else
999 return DHCP_R_INVALIDARG;
1000#endif
1001 }
1002
1003 if ((*h) -> refcnt <= 0) {
1004#if defined (POINTER_DEBUG)
1005 log_error ("%s(%d): dereference of pointer with refcnt of zero!",
1006 file, line);
1007#if defined (DEBUG_RC_HISTORY)
1008 dump_rc_history (*h);
1009#endif
1010 abort ();
1011#else
1012 *h = 0;
1013 return DHCP_R_INVALIDARG;
1014#endif
1015 }
1016
1017 --((*h) -> refcnt);
1018 rc_register (file, line, h, *h, (*h) -> refcnt, 1, RC_MISC);
1019 if ((*h) -> refcnt <= 0 ) {
1020 dfree (*h, file, line);
1021 }
1022 *h = 0;
1023 return ISC_R_SUCCESS;
1024}
1025
1027 const char *file, int line)
1028{
1029 omapi_value_t *new;
1030
1031 new = dmalloc (sizeof *new, file, line);
1032 if (!new)
1033 return ISC_R_NOMEMORY;
1034 memset (new, 0, sizeof *new);
1035 return omapi_value_reference (d, new, file, line);
1036}
1037
1039 omapi_value_t *h,
1040 const char *file, int line)
1041{
1042 if (!h || !r)
1043 return DHCP_R_INVALIDARG;
1044
1045 if (*r) {
1046#if defined (POINTER_DEBUG)
1047 log_error ("%s(%d): reference store into non-null pointer!",
1048 file, line);
1049 abort ();
1050#else
1051 return DHCP_R_INVALIDARG;
1052#endif
1053 }
1054 *r = h;
1055 h -> refcnt++;
1056 rc_register (file, line, r, h, h -> refcnt, 0, RC_MISC);
1057 return ISC_R_SUCCESS;
1058}
1059
1061 const char *file, int line)
1062{
1063 if (!h)
1064 return DHCP_R_INVALIDARG;
1065
1066 if (!*h) {
1067#if defined (POINTER_DEBUG)
1068 log_error ("%s(%d): dereference of null pointer!", file, line);
1069 abort ();
1070#else
1071 return DHCP_R_INVALIDARG;
1072#endif
1073 }
1074
1075 if ((*h) -> refcnt <= 0) {
1076#if defined (POINTER_DEBUG)
1077 log_error ("%s(%d): dereference of pointer with refcnt of zero!",
1078 file, line);
1079#if defined (DEBUG_RC_HISTORY)
1080 dump_rc_history (*h);
1081#endif
1082 abort ();
1083#else
1084 *h = 0;
1085 return DHCP_R_INVALIDARG;
1086#endif
1087 }
1088
1089 --((*h) -> refcnt);
1090 rc_register (file, line, h, *h, (*h) -> refcnt, 1, RC_MISC);
1091 if ((*h) -> refcnt == 0) {
1092 if ((*h) -> name)
1093 omapi_data_string_dereference (&(*h) -> name,
1094 file, line);
1095 if ((*h) -> value)
1097 file, line);
1098 dfree (*h, file, line);
1099 }
1100 *h = 0;
1101 return ISC_R_SUCCESS;
1102}
1103
1104isc_result_t omapi_addr_list_new (omapi_addr_list_t **d, unsigned count,
1105 const char *file, int line)
1106{
1107 omapi_addr_list_t *new;
1108
1109 new = dmalloc ((count * sizeof (omapi_addr_t)) +
1110 sizeof (omapi_addr_list_t), file, line);
1111 if (!new)
1112 return ISC_R_NOMEMORY;
1113 memset (new, 0, ((count * sizeof (omapi_addr_t)) +
1114 sizeof (omapi_addr_list_t)));
1115 new -> count = count;
1116 new -> addresses = (omapi_addr_t *)(new + 1);
1117 return omapi_addr_list_reference (d, new, file, line);
1118}
1119
1122 const char *file, int line)
1123{
1124 if (!h || !r)
1125 return DHCP_R_INVALIDARG;
1126
1127 if (*r) {
1128#if defined (POINTER_DEBUG)
1129 log_error ("%s(%d): reference store into non-null pointer!",
1130 file, line);
1131 abort ();
1132#else
1133 return DHCP_R_INVALIDARG;
1134#endif
1135 }
1136 *r = h;
1137 h -> refcnt++;
1138 rc_register (file, line, r, h, h -> refcnt, 0, RC_MISC);
1139 return ISC_R_SUCCESS;
1140}
1141
1143 const char *file, int line)
1144{
1145 if (!h)
1146 return DHCP_R_INVALIDARG;
1147
1148 if (!*h) {
1149#if defined (POINTER_DEBUG)
1150 log_error ("%s(%d): dereference of null pointer!", file, line);
1151 abort ();
1152#else
1153 return DHCP_R_INVALIDARG;
1154#endif
1155 }
1156
1157 if ((*h) -> refcnt <= 0) {
1158#if defined (POINTER_DEBUG)
1159 log_error ("%s(%d): dereference of pointer with zero refcnt!",
1160 file, line);
1161#if defined (DEBUG_RC_HISTORY)
1162 dump_rc_history (*h);
1163#endif
1164 abort ();
1165#else
1166 *h = 0;
1167 return DHCP_R_INVALIDARG;
1168#endif
1169 }
1170
1171 --((*h) -> refcnt);
1172 rc_register (file, line, h, *h, (*h) -> refcnt, 1, RC_MISC);
1173 if ((*h) -> refcnt <= 0 ) {
1174 dfree (*h, file, line);
1175 }
1176 *h = 0;
1177 return ISC_R_SUCCESS;
1178}
#define DMDSIZE
Definition alloc.h:51
#define RC_MISC
Definition alloc.h:56
#define rc_register(file, line, reference, addr, refcnt, d, f)
Definition alloc.h:88
#define DMDOFFSET
Definition alloc.h:50
struct _omapi_buffer omapi_buffer_t
#define IGNORE_RET(x)
Definition cdefs.h:54
const char int line
Definition dhcpd.h:3802
const char * file
Definition dhcpd.h:3802
#define ISC_R_SUCCESS
isc_result_t omapi_typed_data_new(const char *file, int line, omapi_typed_data_t **t, omapi_datatype_t type,...)
Definition alloc.c:803
isc_result_t omapi_object_reference(omapi_object_t **r, omapi_object_t *h, const char *file, int line)
Definition alloc.c:571
isc_result_t omapi_value_new(omapi_value_t **d, const char *file, int line)
Definition alloc.c:1026
isc_result_t omapi_value_dereference(omapi_value_t **h, const char *file, int line)
Definition alloc.c:1060
isc_result_t omapi_data_string_reference(omapi_data_string_t **r, omapi_data_string_t *h, const char *file, int line)
Definition alloc.c:967
isc_result_t omapi_addr_list_new(omapi_addr_list_t **d, unsigned count, const char *file, int line)
Definition alloc.c:1104
isc_result_t omapi_typed_data_dereference(omapi_typed_data_t **h, const char *file, int line)
Definition alloc.c:901
isc_result_t omapi_data_string_new(omapi_data_string_t **d, unsigned len, const char *file, int line)
Definition alloc.c:950
isc_result_t omapi_data_string_dereference(omapi_data_string_t **h, const char *file, int line)
Definition alloc.c:988
isc_result_t omapi_typed_data_reference(omapi_typed_data_t **r, omapi_typed_data_t *h, const char *file, int line)
Definition alloc.c:880
isc_result_t omapi_value_reference(omapi_value_t **r, omapi_value_t *h, const char *file, int line)
Definition alloc.c:1038
isc_result_t omapi_buffer_dereference(omapi_buffer_t **h, const char *file, int line)
Definition alloc.c:766
isc_result_t omapi_object_allocate(omapi_object_t **o, omapi_object_type_t *type, size_t size, const char *file, int line)
Definition alloc.c:515
isc_result_t omapi_buffer_new(omapi_buffer_t **h, const char *file, int line)
Definition alloc.c:727
isc_result_t omapi_addr_list_reference(omapi_addr_list_t **r, omapi_addr_list_t *h, const char *file, int line)
Definition alloc.c:1120
isc_result_t omapi_object_initialize(omapi_object_t *o, omapi_object_type_t *type, size_t usize, size_t psize, const char *file, int line)
Definition alloc.c:559
isc_result_t omapi_buffer_reference(omapi_buffer_t **r, omapi_buffer_t *h, const char *file, int line)
Definition alloc.c:744
isc_result_t omapi_addr_list_dereference(omapi_addr_list_t **h, const char *file, int line)
Definition alloc.c:1142
void omapi_print_dmalloc_usage_by_caller(void)
struct __omapi_object_type_t omapi_object_type_t
isc_result_t omapi_object_dereference(omapi_object_t **, const char *, int)
Definition alloc.c:593
#define OMAPI_TYPED_DATA_INT_LEN
Definition omapip.h:73
#define dmalloc_reuse(x, y, l, z)
Definition omapip.h:565
struct __omapi_object omapi_object_t
Definition omapip.h:39
omapi_datatype_t
Definition omapip.h:41
@ omapi_datatype_string
Definition omapip.h:43
@ omapi_datatype_object
Definition omapip.h:45
@ omapi_datatype_int
Definition omapip.h:42
@ omapi_datatype_data
Definition omapip.h:44
void * dmalloc(size_t, const char *, int)
Definition alloc.c:57
void dfree(void *, const char *, int)
Definition alloc.c:145
#define OMAPI_TYPED_DATA_OBJECT_LEN
Definition omapip.h:59
#define OMAPI_DATA_STRING_EMPTY_SIZE
Definition omapip.h:83
#define OMAPI_TYPED_DATA_NOBUFFER_LEN
Definition omapip.h:54
int log_error(const char *,...) __attribute__((__format__(__printf__
int int int log_debug(const char *,...) __attribute__((__format__(__printf__
void log_fatal(const char *,...) __attribute__((__format__(__printf__
isc_result_t omapi_handle_clear(omapi_handle_t)
Definition handle.c:298
int int log_info(const char *,...) __attribute__((__format__(__printf__
#define STDERR_FILENO
Definition osdep.h:287
#define DHCP_R_INVALIDARG
Definition result.h:49
Definition data.h:289
Definition data.h:205