]>
Commit | Line | Data |
---|---|---|
7ebd047d TL |
1 | /* salloc.c |
2 | ||
3 | Memory allocation for the DHCP server... */ | |
4 | ||
5 | /* | |
9deef2e7 | 6 | * Copyright (c) 2004-2016 by Internet Systems Consortium, Inc. ("ISC") |
98311e4b | 7 | * Copyright (c) 1996-2003 by Internet Software Consortium |
7ebd047d | 8 | * |
98311e4b DH |
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. | |
7ebd047d | 12 | * |
98311e4b DH |
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. | |
7ebd047d | 20 | * |
98311e4b DH |
21 | * Internet Systems Consortium, Inc. |
22 | * 950 Charter Street | |
23 | * Redwood City, CA 94063 | |
24 | * <info@isc.org> | |
2c85ac9b | 25 | * https://www.isc.org/ |
7ebd047d | 26 | * |
7ebd047d TL |
27 | */ |
28 | ||
7ebd047d TL |
29 | #include "dhcpd.h" |
30 | #include <omapip/omapip_p.h> | |
31 | ||
d758ad8c TL |
32 | #if defined (COMPACT_LEASES) |
33 | struct lease *free_leases; | |
34 | ||
0d93c339 | 35 | #if defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT) |
d758ad8c TL |
36 | struct lease *lease_hunks; |
37 | ||
38 | void relinquish_lease_hunks () | |
39 | { | |
0d93c339 | 40 | struct lease *c, *n, **p; |
d758ad8c TL |
41 | int i; |
42 | ||
43 | /* Account for all the leases on the free list. */ | |
0d93c339 SR |
44 | for (n = lease_hunks; n; n = n->next) { |
45 | for (i = 1; i < n->starts + 1; i++) { | |
d758ad8c | 46 | p = &free_leases; |
0d93c339 SR |
47 | for (c = free_leases; c; c = c->next) { |
48 | if (c == &n[i]) { | |
49 | *p = c->next; | |
50 | n->ends++; | |
d758ad8c TL |
51 | break; |
52 | } | |
0d93c339 | 53 | p = &c->next; |
d758ad8c TL |
54 | } |
55 | if (!c) { | |
0d93c339 SR |
56 | log_info("lease %s refcnt %d", |
57 | piaddr (n[i].ip_addr), n[i].refcnt); | |
67b2cb45 | 58 | #if defined (DEBUG_RC_HISTORY) |
0d93c339 | 59 | dump_rc_history(&n[i]); |
67b2cb45 | 60 | #endif |
d758ad8c TL |
61 | } |
62 | } | |
63 | } | |
0d93c339 | 64 | |
d758ad8c | 65 | for (c = lease_hunks; c; c = n) { |
0d93c339 SR |
66 | n = c->next; |
67 | if (c->ends != c->starts) { | |
68 | log_info("lease hunk %lx leases %ld free %ld", | |
69 | (unsigned long)c, (unsigned long)(c->starts), | |
70 | (unsigned long)(c->ends)); | |
d758ad8c | 71 | } |
0d93c339 | 72 | dfree(c, MDL); |
d758ad8c TL |
73 | } |
74 | ||
75 | /* Free all the rogue leases. */ | |
76 | for (c = free_leases; c; c = n) { | |
0d93c339 SR |
77 | n = c->next; |
78 | dfree(c, MDL); | |
d758ad8c TL |
79 | } |
80 | } | |
88c3ff5d | 81 | |
d758ad8c TL |
82 | #endif |
83 | ||
7ebd047d TL |
84 | struct lease *new_leases (n, file, line) |
85 | unsigned n; | |
86 | const char *file; | |
87 | int line; | |
88 | { | |
d758ad8c TL |
89 | struct lease *rval; |
90 | #if defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT) | |
91 | rval = dmalloc ((n + 1) * sizeof (struct lease), file, line); | |
88c3ff5d TM |
92 | if (rval != NULL) { |
93 | memset (rval, 0, sizeof (struct lease)); | |
94 | rval -> starts = n; | |
95 | rval -> next = lease_hunks; | |
96 | lease_hunks = rval; | |
97 | rval++; | |
98 | } | |
d758ad8c TL |
99 | #else |
100 | rval = dmalloc (n * sizeof (struct lease), file, line); | |
101 | #endif | |
7ebd047d TL |
102 | return rval; |
103 | } | |
104 | ||
d758ad8c TL |
105 | /* If we are allocating leases in aggregations, there's really no way |
106 | to free one, although perhaps we can maintain a free list. */ | |
107 | ||
108 | isc_result_t dhcp_lease_free (omapi_object_t *lo, | |
109 | const char *file, int line) | |
110 | { | |
111 | struct lease *lease; | |
112 | if (lo -> type != dhcp_type_lease) | |
98bf1607 | 113 | return DHCP_R_INVALIDARG; |
d758ad8c TL |
114 | lease = (struct lease *)lo; |
115 | memset (lease, 0, sizeof (struct lease)); | |
116 | lease -> next = free_leases; | |
117 | free_leases = lease; | |
118 | return ISC_R_SUCCESS; | |
119 | } | |
120 | ||
121 | isc_result_t dhcp_lease_get (omapi_object_t **lp, | |
122 | const char *file, int line) | |
123 | { | |
124 | struct lease **lease = (struct lease **)lp; | |
125 | struct lease *lt; | |
126 | ||
127 | if (free_leases) { | |
128 | lt = free_leases; | |
129 | free_leases = lt -> next; | |
130 | *lease = lt; | |
131 | return ISC_R_SUCCESS; | |
132 | } | |
133 | return ISC_R_NOMEMORY; | |
134 | } | |
135 | #endif /* COMPACT_LEASES */ | |
136 | ||
7ebd047d TL |
137 | OMAPI_OBJECT_ALLOC (lease, struct lease, dhcp_type_lease) |
138 | OMAPI_OBJECT_ALLOC (class, struct class, dhcp_type_class) | |
899d754f | 139 | OMAPI_OBJECT_ALLOC (subclass, struct class, dhcp_type_subclass) |
7ebd047d | 140 | OMAPI_OBJECT_ALLOC (pool, struct pool, dhcp_type_pool) |
ae9c72b7 TL |
141 | |
142 | #if !defined (NO_HOST_FREES) /* Scary debugging mode - don't enable! */ | |
7ebd047d | 143 | OMAPI_OBJECT_ALLOC (host, struct host_decl, dhcp_type_host) |
ae9c72b7 TL |
144 | #else |
145 | isc_result_t host_allocate (struct host_decl **p, const char *file, int line) | |
146 | { | |
147 | return omapi_object_allocate ((omapi_object_t **)p, | |
148 | dhcp_type_host, 0, file, line); | |
149 | } | |
150 | ||
151 | isc_result_t host_reference (struct host_decl **pptr, struct host_decl *ptr, | |
152 | const char *file, int line) | |
153 | { | |
154 | return omapi_object_reference ((omapi_object_t **)pptr, | |
155 | (omapi_object_t *)ptr, file, line); | |
156 | } | |
157 | ||
158 | isc_result_t host_dereference (struct host_decl **ptr, | |
159 | const char *file, int line) | |
160 | { | |
161 | if ((*ptr) -> refcnt == 1) { | |
162 | log_error ("host dereferenced with refcnt == 1."); | |
163 | #if defined (DEBUG_RC_HISTORY) | |
164 | dump_rc_history (); | |
165 | #endif | |
166 | abort (); | |
167 | } | |
168 | return omapi_object_dereference ((omapi_object_t **)ptr, file, line); | |
169 | } | |
170 | #endif | |
7ebd047d TL |
171 | |
172 | struct lease_state *free_lease_states; | |
173 | ||
174 | struct lease_state *new_lease_state (file, line) | |
175 | const char *file; | |
176 | int line; | |
177 | { | |
178 | struct lease_state *rval; | |
179 | ||
180 | if (free_lease_states) { | |
181 | rval = free_lease_states; | |
182 | free_lease_states = | |
183 | (struct lease_state *)(free_lease_states -> next); | |
184 | dmalloc_reuse (rval, file, line, 0); | |
185 | } else { | |
186 | rval = dmalloc (sizeof (struct lease_state), file, line); | |
187 | if (!rval) | |
188 | return rval; | |
189 | } | |
190 | memset (rval, 0, sizeof *rval); | |
191 | if (!option_state_allocate (&rval -> options, file, line)) { | |
192 | free_lease_state (rval, file, line); | |
193 | return (struct lease_state *)0; | |
194 | } | |
195 | return rval; | |
196 | } | |
197 | ||
198 | void free_lease_state (ptr, file, line) | |
199 | struct lease_state *ptr; | |
200 | const char *file; | |
201 | int line; | |
202 | { | |
203 | if (ptr -> options) | |
204 | option_state_dereference (&ptr -> options, file, line); | |
205 | if (ptr -> packet) | |
206 | packet_dereference (&ptr -> packet, file, line); | |
207 | if (ptr -> shared_network) | |
208 | shared_network_dereference (&ptr -> shared_network, | |
209 | file, line); | |
210 | ||
211 | data_string_forget (&ptr -> parameter_request_list, file, line); | |
212 | data_string_forget (&ptr -> filename, file, line); | |
213 | data_string_forget (&ptr -> server_name, file, line); | |
214 | ptr -> next = free_lease_states; | |
215 | free_lease_states = ptr; | |
216 | dmalloc_reuse (free_lease_states, (char *)0, 0, 0); | |
217 | } | |
218 | ||
d758ad8c TL |
219 | #if defined (DEBUG_MEMORY_LEAKAGE) || \ |
220 | defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT) | |
221 | void relinquish_free_lease_states () | |
222 | { | |
223 | struct lease_state *cs, *ns; | |
224 | ||
225 | for (cs = free_lease_states; cs; cs = ns) { | |
226 | ns = cs -> next; | |
227 | dfree (cs, MDL); | |
228 | } | |
229 | free_lease_states = (struct lease_state *)0; | |
230 | } | |
231 | #endif | |
232 | ||
7ebd047d TL |
233 | struct permit *new_permit (file, line) |
234 | const char *file; | |
235 | int line; | |
236 | { | |
237 | struct permit *permit = ((struct permit *) | |
238 | dmalloc (sizeof (struct permit), file, line)); | |
239 | if (!permit) | |
240 | return permit; | |
241 | memset (permit, 0, sizeof *permit); | |
242 | return permit; | |
243 | } | |
244 | ||
245 | void free_permit (permit, file, line) | |
246 | struct permit *permit; | |
247 | const char *file; | |
248 | int line; | |
249 | { | |
d758ad8c TL |
250 | if (permit -> type == permit_class) |
251 | class_dereference (&permit -> class, MDL); | |
7ebd047d TL |
252 | dfree (permit, file, line); |
253 | } |