Merge from vendor branch HEIMDAL:
[dragonfly.git] / contrib / dhcp-3.0 / server / salloc.c
1 /* salloc.c
2
3    Memory allocation for the DHCP server... */
4
5 /*
6  * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
7  * Copyright (c) 1996-2003 by Internet Software Consortium
8  *
9  * Permission to use, copy, modify, and distribute this software for any
10  * purpose with or without fee is hereby granted, provided that the above
11  * copyright notice and this permission notice appear in all copies.
12  *
13  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
14  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15  * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
16  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
18  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
19  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20  *
21  *   Internet Systems Consortium, Inc.
22  *   950 Charter Street
23  *   Redwood City, CA 94063
24  *   <info@isc.org>
25  *   http://www.isc.org/
26  *
27  * This software has been written for Internet Systems Consortium
28  * by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc.
29  * To learn more about Internet Systems Consortium, see
30  * ``http://www.isc.org/''.  To learn more about Vixie Enterprises,
31  * see ``http://www.vix.com''.   To learn more about Nominum, Inc., see
32  * ``http://www.nominum.com''.
33  */
34
35 #ifndef lint
36 static char copyright[] =
37 "$Id: salloc.c,v 1.2.2.5 2004/06/10 17:59:57 dhankins Exp $ Copyright (c) 2004 Internet Systems Consortium.  All rights reserved.\n";
38 #endif /* not lint */
39
40 #include "dhcpd.h"
41 #include <omapip/omapip_p.h>
42
43 #if defined (COMPACT_LEASES)
44 struct lease *free_leases;
45
46 # if defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
47 struct lease *lease_hunks;
48
49 void relinquish_lease_hunks ()
50 {
51         struct lease *c, *n, **p, *f;
52         int i;
53
54         /* Account for all the leases on the free list. */
55         for (n = lease_hunks; n; n = n -> next) {
56             for (i = 1; i < n -> starts + 1; i++) {
57                 p = &free_leases;
58                 for (c = free_leases; c; c = c -> next) {
59                     if (c == &n [i]) {
60                         *p = c -> next;
61                         n -> ends++;
62                         break;
63                     }
64                     p = &c -> next;
65                 }
66                 if (!c) {
67                     log_info ("lease %s refcnt %d",
68                               piaddr (n [i].ip_addr), n [i].refcnt);
69                     dump_rc_history (&n [i]);
70                 }
71             }
72         }
73                 
74         for (c = lease_hunks; c; c = n) {
75                 n = c -> next;
76                 if (c -> ends != c -> starts) {
77                         log_info ("lease hunk %lx leases %ld free %ld",
78                                   (unsigned long)c, (unsigned long)c -> starts,
79                                   (unsigned long)c -> ends);
80                 }
81                 dfree (c, MDL);
82         }
83
84         /* Free all the rogue leases. */
85         for (c = free_leases; c; c = n) {
86                 n = c -> next;
87                 dfree (c, MDL);
88         }
89 }
90 #endif
91
92 struct lease *new_leases (n, file, line)
93         unsigned n;
94         const char *file;
95         int line;
96 {
97         struct lease *rval;
98 #if defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
99         rval = dmalloc ((n + 1) * sizeof (struct lease), file, line);
100         memset (rval, 0, sizeof (struct lease));
101         rval -> starts = n;
102         rval -> next = lease_hunks;
103         lease_hunks = rval;
104         rval++;
105 #else
106         rval = dmalloc (n * sizeof (struct lease), file, line);
107 #endif
108         return rval;
109 }
110
111 /* If we are allocating leases in aggregations, there's really no way
112    to free one, although perhaps we can maintain a free list. */
113
114 isc_result_t dhcp_lease_free (omapi_object_t *lo,
115                               const char *file, int line)
116 {
117         struct lease *lease;
118         if (lo -> type != dhcp_type_lease)
119                 return ISC_R_INVALIDARG;
120         lease = (struct lease *)lo;
121         memset (lease, 0, sizeof (struct lease));
122         lease -> next = free_leases;
123         free_leases = lease;
124         return ISC_R_SUCCESS;
125 }
126
127 isc_result_t dhcp_lease_get (omapi_object_t **lp,
128                              const char *file, int line)
129 {
130         struct lease **lease = (struct lease **)lp;
131         struct lease *lt;
132
133         if (free_leases) {
134                 lt = free_leases;
135                 free_leases = lt -> next;
136                 *lease = lt;
137                 return ISC_R_SUCCESS;
138         }
139         return ISC_R_NOMEMORY;
140 }
141 #endif /* COMPACT_LEASES */
142
143 OMAPI_OBJECT_ALLOC (lease, struct lease, dhcp_type_lease)
144 OMAPI_OBJECT_ALLOC (class, struct class, dhcp_type_class)
145 OMAPI_OBJECT_ALLOC (pool, struct pool, dhcp_type_pool)
146
147 #if !defined (NO_HOST_FREES)    /* Scary debugging mode - don't enable! */
148 OMAPI_OBJECT_ALLOC (host, struct host_decl, dhcp_type_host)
149 #else
150 isc_result_t host_allocate (struct host_decl **p, const char *file, int line)
151 {
152         return omapi_object_allocate ((omapi_object_t **)p,
153                                       dhcp_type_host, 0, file, line);
154 }
155
156 isc_result_t host_reference (struct host_decl **pptr, struct host_decl *ptr,
157                                const char *file, int line)
158 {
159         return omapi_object_reference ((omapi_object_t **)pptr,
160                                        (omapi_object_t *)ptr, file, line);
161 }
162
163 isc_result_t host_dereference (struct host_decl **ptr,
164                                const char *file, int line)
165 {
166         if ((*ptr) -> refcnt == 1) {
167                 log_error ("host dereferenced with refcnt == 1.");
168 #if defined (DEBUG_RC_HISTORY)
169                 dump_rc_history ();
170 #endif
171                 abort ();
172         }
173         return omapi_object_dereference ((omapi_object_t **)ptr, file, line);
174 }
175 #endif
176
177 struct lease_state *free_lease_states;
178
179 struct lease_state *new_lease_state (file, line)
180         const char *file;
181         int line;
182 {
183         struct lease_state *rval;
184
185         if (free_lease_states) {
186                 rval = free_lease_states;
187                 free_lease_states =
188                         (struct lease_state *)(free_lease_states -> next);
189                 dmalloc_reuse (rval, file, line, 0);
190         } else {
191                 rval = dmalloc (sizeof (struct lease_state), file, line);
192                 if (!rval)
193                         return rval;
194         }
195         memset (rval, 0, sizeof *rval);
196         if (!option_state_allocate (&rval -> options, file, line)) {
197                 free_lease_state (rval, file, line);
198                 return (struct lease_state *)0;
199         }
200         return rval;
201 }
202
203 void free_lease_state (ptr, file, line)
204         struct lease_state *ptr;
205         const char *file;
206         int line;
207 {
208         if (ptr -> options)
209                 option_state_dereference (&ptr -> options, file, line);
210         if (ptr -> packet)
211                 packet_dereference (&ptr -> packet, file, line);
212         if (ptr -> shared_network)
213                 shared_network_dereference (&ptr -> shared_network,
214                                             file, line);
215
216         data_string_forget (&ptr -> parameter_request_list, file, line);
217         data_string_forget (&ptr -> filename, file, line);
218         data_string_forget (&ptr -> server_name, file, line);
219         ptr -> next = free_lease_states;
220         free_lease_states = ptr;
221         dmalloc_reuse (free_lease_states, (char *)0, 0, 0);
222 }
223
224 #if defined (DEBUG_MEMORY_LEAKAGE) || \
225                 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
226 void relinquish_free_lease_states ()
227 {
228         struct lease_state *cs, *ns;
229
230         for (cs = free_lease_states; cs; cs = ns) {
231                 ns = cs -> next;
232                 dfree (cs, MDL);
233         }
234         free_lease_states = (struct lease_state *)0;
235 }
236 #endif
237
238 struct permit *new_permit (file, line)
239         const char *file;
240         int line;
241 {
242         struct permit *permit = ((struct permit *)
243                                  dmalloc (sizeof (struct permit), file, line));
244         if (!permit)
245                 return permit;
246         memset (permit, 0, sizeof *permit);
247         return permit;
248 }
249
250 void free_permit (permit, file, line)
251         struct permit *permit;
252         const char *file;
253         int line;
254 {
255         if (permit -> type == permit_class)
256                 class_dereference (&permit -> class, MDL);
257         dfree (permit, file, line);
258 }