]>
Commit | Line | Data |
---|---|---|
9f89d01e | 1 | /* |
7512d88b | 2 | * Copyright (c) 2012-2017 by Internet Systems Consortium, Inc. ("ISC") |
9f89d01e | 3 | * |
7512d88b TM |
4 | * This Source Code Form is subject to the terms of the Mozilla Public |
5 | * License, v. 2.0. If a copy of the MPL was not distributed with this | |
6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. | |
9f89d01e TM |
7 | * |
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES | |
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR | |
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | |
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT | |
14 | * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
15 | * | |
16 | * Internet Systems Consortium, Inc. | |
429a56d7 TM |
17 | * PO Box 360 |
18 | * Newmarket, NH 03857 USA | |
9f89d01e TM |
19 | * <info@isc.org> |
20 | * https://www.isc.org/ | |
21 | * | |
22 | */ | |
23 | ||
24 | #include "config.h" | |
25 | #include <atf-c.h> | |
26 | #include <omapip/omapip_p.h> | |
27 | #include "dhcpd.h" | |
28 | ||
5f10a36c TM |
29 | /* |
30 | * The following structures are kept here for reference only. As hash functions | |
31 | * are somewhat convoluted, they are copied here for the reference. Original | |
32 | * location is specified. Keep in mind that it may change over time: | |
33 | * | |
34 | * copied from server/omapi.c:49 * | |
35 | * omapi_object_type_t *dhcp_type_lease; | |
36 | * omapi_object_type_t *dhcp_type_pool; | |
37 | * omapi_object_type_t *dhcp_type_class; | |
38 | * omapi_object_type_t *dhcp_type_subclass; | |
39 | * omapi_object_type_t *dhcp_type_host; | |
40 | * | |
41 | * copied from server/salloc.c:138 | |
42 | * OMAPI_OBJECT_ALLOC (lease, struct lease, dhcp_type_lease) | |
43 | * OMAPI_OBJECT_ALLOC (class, struct class, dhcp_type_class) | |
44 | * OMAPI_OBJECT_ALLOC (subclass, struct class, dhcp_type_subclass) | |
45 | * OMAPI_OBJECT_ALLOC (pool, struct pool, dhcp_type_pool) | |
46 | * OMAPI_OBJECT_ALLOC (host, struct host_decl, dhcp_type_host) | |
47 | * | |
48 | * copied from server/mdb.c:2686 | |
49 | * HASH_FUNCTIONS(lease_ip, const unsigned char *, struct lease, lease_ip_hash_t, | |
50 | * lease_reference, lease_dereference, do_ip4_hash) | |
51 | * HASH_FUNCTIONS(lease_id, const unsigned char *, struct lease, lease_id_hash_t, | |
52 | * lease_reference, lease_dereference, do_id_hash) | |
53 | * HASH_FUNCTIONS (host, const unsigned char *, struct host_decl, host_hash_t, | |
54 | * host_reference, host_dereference, do_string_hash) | |
55 | * HASH_FUNCTIONS (class, const char *, struct class, class_hash_t, | |
56 | * class_reference, class_dereference, do_string_hash) | |
57 | * | |
58 | * copied from server/mdb.c:46 | |
59 | * host_hash_t *host_hw_addr_hash; | |
60 | * host_hash_t *host_uid_hash; | |
61 | * host_hash_t *host_name_hash; | |
62 | * lease_id_hash_t *lease_uid_hash; | |
63 | * lease_ip_hash_t *lease_ip_addr_hash; | |
64 | * lease_id_hash_t *lease_hw_addr_hash; | |
65 | */ | |
9f89d01e | 66 | |
ab610112 TM |
67 | /** |
68 | * @brief sets client-id field in host declaration | |
69 | * | |
70 | * @param host pointer to host declaration | |
71 | * @param uid pointer to client-id data | |
72 | * @param uid_len length of the client-id data | |
73 | * | |
74 | * @return 1 if successful, 0 otherwise | |
75 | */ | |
76 | int lease_set_clientid(struct host_decl *host, const unsigned char *uid, int uid_len) { | |
bbcea18c | 77 | |
ab610112 | 78 | /* clean-up this mess and set client-identifier in a sane way */ |
bbcea18c TM |
79 | int real_len = uid_len; |
80 | if (uid_len == 0) { | |
81 | real_len = strlen((const char *)uid) + 1; | |
82 | } | |
83 | ||
ab610112 TM |
84 | memset(&host->client_identifier, 0, sizeof(host->client_identifier)); |
85 | host->client_identifier.len = uid_len; | |
bbcea18c | 86 | if (!buffer_allocate(&host->client_identifier.buffer, real_len, MDL)) { |
ab610112 TM |
87 | return 0; |
88 | } | |
89 | host->client_identifier.data = host->client_identifier.buffer->data; | |
bbcea18c | 90 | memcpy((char *)host->client_identifier.data, uid, real_len); |
ab610112 TM |
91 | |
92 | return 1; | |
93 | } | |
94 | ||
f94d5a14 | 95 | /// @brief executes uid hash test for specified client-ids (2 hosts) |
bbcea18c TM |
96 | /// |
97 | /// Creates two host structures, adds first host to the uid hash, | |
98 | /// then adds second host to the hash, then removes first host, | |
99 | /// then removed the second. Many checks are performed during all | |
100 | /// operations. | |
101 | /// | |
102 | /// @param clientid1 client-id of the first host | |
f94d5a14 TM |
103 | /// @param clientid1_len client-id1 length (may be 0 for strings) |
104 | /// @param clientid2 client-id of the second host | |
105 | /// @param clientid2_len client-id2 length (may be 0 for strings) | |
bbcea18c TM |
106 | void lease_hash_test_2hosts(unsigned char clientid1[], size_t clientid1_len, |
107 | unsigned char clientid2[], size_t clientid2_len) { | |
108 | ||
f94d5a14 | 109 | printf("Checking hash operation for 2 hosts: clientid1-len=%lu" |
904a771a SM |
110 | "clientid2-len=%lu\n", (unsigned long) clientid1_len, |
111 | (unsigned long) clientid2_len); | |
9f89d01e TM |
112 | |
113 | dhcp_db_objects_setup (); | |
114 | dhcp_common_objects_setup (); | |
115 | ||
116 | /* check that there is actually zero hosts in the hash */ | |
ab610112 | 117 | /* @todo: host_hash_for_each() */ |
9f89d01e TM |
118 | |
119 | struct host_decl *host1 = 0, *host2 = 0; | |
ab610112 TM |
120 | struct host_decl *check = 0; |
121 | ||
122 | /* === step 1: allocate hosts === */ | |
9f89d01e TM |
123 | ATF_CHECK_MSG(host_allocate(&host1, MDL) == ISC_R_SUCCESS, |
124 | "Failed to allocate host"); | |
125 | ATF_CHECK_MSG(host_allocate(&host2, MDL) == ISC_R_SUCCESS, | |
126 | "Failed to allocate host"); | |
127 | ||
ab610112 TM |
128 | ATF_CHECK_MSG(host_new_hash(&host_uid_hash, HOST_HASH_SIZE, MDL) != 0, |
129 | "Unable to create new hash"); | |
9f89d01e | 130 | |
ab610112 | 131 | ATF_CHECK_MSG(buffer_allocate(&host1->client_identifier.buffer, |
bbcea18c | 132 | clientid1_len, MDL) != 0, |
ab610112 | 133 | "Can't allocate uid buffer for host1"); |
9f89d01e | 134 | |
ab610112 | 135 | ATF_CHECK_MSG(buffer_allocate(&host2->client_identifier.buffer, |
bbcea18c | 136 | clientid2_len, MDL) != 0, |
ab610112 | 137 | "Can't allocate uid buffer for host2"); |
9f89d01e | 138 | |
bbcea18c TM |
139 | /* setting up host1->client_identifier is actually not needed */ |
140 | /* | |
141 | ATF_CHECK_MSG(lease_set_clientid(host1, clientid1, actual1_len) != 0, | |
ab610112 TM |
142 | "Failed to set client-id for host1"); |
143 | ||
bbcea18c | 144 | ATF_CHECK_MSG(lease_set_clientid(host2, clientid2, actual2_len) != 0, |
ab610112 | 145 | "Failed to set client-id for host2"); |
bbcea18c | 146 | */ |
ab610112 TM |
147 | |
148 | ATF_CHECK_MSG(host1->refcnt == 1, "Invalid refcnt for host1"); | |
149 | ATF_CHECK_MSG(host2->refcnt == 1, "Invalid refcnt for host2"); | |
150 | ||
151 | /* verify that our hosts are not in the hash yet */ | |
152 | ATF_CHECK_MSG(host_hash_lookup(&check, host_uid_hash, clientid1, | |
bbcea18c | 153 | clientid1_len, MDL) == 0, |
ab610112 TM |
154 | "Host1 is not supposed to be in the uid_hash."); |
155 | ||
156 | ATF_CHECK_MSG(!check, "Host1 is not supposed to be in the uid_hash."); | |
9f89d01e | 157 | |
bbcea18c TM |
158 | ATF_CHECK_MSG(host_hash_lookup(&check, host_uid_hash, clientid2, |
159 | clientid2_len, MDL) == 0, | |
ab610112 TM |
160 | "Host2 is not supposed to be in the uid_hash."); |
161 | ATF_CHECK_MSG(!check, "Host2 is not supposed to be in the uid_hash."); | |
162 | ||
163 | ||
164 | /* === step 2: add first host to the hash === */ | |
bbcea18c | 165 | host_hash_add(host_uid_hash, clientid1, clientid1_len, host1, MDL); |
9f89d01e | 166 | |
ab610112 TM |
167 | /* 2 pointers expected: ours (host1) and the one stored in hash */ |
168 | ATF_CHECK_MSG(host1->refcnt == 2, "Invalid refcnt for host1"); | |
169 | /* 1 pointer expected: just ours (host2) */ | |
170 | ATF_CHECK_MSG(host2->refcnt == 1, "Invalid refcnt for host2"); | |
171 | ||
172 | /* verify that host1 is really in the hash and the we can find it */ | |
bbcea18c TM |
173 | ATF_CHECK_MSG(host_hash_lookup(&check, host_uid_hash, clientid1, |
174 | clientid1_len, MDL), | |
ab610112 TM |
175 | "Host1 was supposed to be in the uid_hash."); |
176 | ATF_CHECK_MSG(check, "Host1 was supposed to be in the uid_hash."); | |
177 | ||
178 | /* Hey! That's not the host we were looking for! */ | |
179 | ATF_CHECK_MSG(check == host1, "Wrong host returned by host_hash_lookup"); | |
180 | ||
181 | /* 3 pointers: host1, (stored in hash), check */ | |
182 | ATF_CHECK_MSG(host1->refcnt == 3, "Invalid refcnt for host1"); | |
183 | ||
184 | /* reference count should be increased because we not have a pointer */ | |
185 | ||
186 | host_dereference(&check, MDL); /* we don't need it now */ | |
187 | ||
188 | ATF_CHECK_MSG(check == NULL, "check pointer is supposed to be NULL"); | |
189 | ||
190 | /* 2 pointers: host1, (stored in hash) */ | |
191 | ATF_CHECK_MSG(host1->refcnt == 2, "Invalid refcnt for host1"); | |
192 | ||
193 | /* verify that host2 is not in the hash */ | |
bbcea18c TM |
194 | ATF_CHECK_MSG(host_hash_lookup(&check, host_uid_hash, clientid2, |
195 | clientid2_len, MDL) == 0, | |
ab610112 TM |
196 | "Host2 was not supposed to be in the uid_hash[2]."); |
197 | ATF_CHECK_MSG(check == NULL, "Host2 was not supposed to be in the hash."); | |
198 | ||
199 | ||
200 | /* === step 3: add second hot to the hash === */ | |
bbcea18c | 201 | host_hash_add(host_uid_hash, clientid2, clientid2_len, host2, MDL); |
ab610112 TM |
202 | |
203 | /* 2 pointers expected: ours (host1) and the one stored in hash */ | |
204 | ATF_CHECK_MSG(host2->refcnt == 2, "Invalid refcnt for host2"); | |
205 | ||
bbcea18c TM |
206 | ATF_CHECK_MSG(host_hash_lookup(&check, host_uid_hash, clientid2, |
207 | clientid2_len, MDL), | |
ab610112 TM |
208 | "Host2 was supposed to be in the uid_hash."); |
209 | ATF_CHECK_MSG(check, "Host2 was supposed to be in the uid_hash."); | |
210 | ||
211 | /* Hey! That's not the host we were looking for! */ | |
212 | ATF_CHECK_MSG(check == host2, "Wrong host returned by host_hash_lookup"); | |
213 | ||
214 | /* 3 pointers: host1, (stored in hash), check */ | |
215 | ATF_CHECK_MSG(host2->refcnt == 3, "Invalid refcnt for host1"); | |
216 | ||
217 | host_dereference(&check, MDL); /* we don't need it now */ | |
218 | ||
219 | /* now we have 2 hosts in the hash */ | |
220 | ||
221 | /* verify that host1 is still in the hash and the we can find it */ | |
bbcea18c TM |
222 | ATF_CHECK_MSG(host_hash_lookup(&check, host_uid_hash, clientid1, |
223 | clientid1_len, MDL), | |
ab610112 TM |
224 | "Host1 was supposed to be in the uid_hash."); |
225 | ATF_CHECK_MSG(check, "Host1 was supposed to be in the uid_hash."); | |
226 | ||
227 | /* Hey! That's not the host we were looking for! */ | |
228 | ATF_CHECK_MSG(check == host1, "Wrong host returned by host_hash_lookup"); | |
229 | ||
230 | /* 3 pointers: host1, (stored in hash), check */ | |
231 | ATF_CHECK_MSG(host1->refcnt == 3, "Invalid refcnt for host1"); | |
232 | ||
233 | host_dereference(&check, MDL); /* we don't need it now */ | |
234 | ||
235 | ||
236 | /** | |
237 | * @todo check that there is actually two hosts in the hash. | |
238 | * Use host_hash_for_each() for that. | |
239 | */ | |
240 | ||
241 | /* === step 4: remove first host from the hash === */ | |
9f89d01e TM |
242 | |
243 | /* delete host from hash */ | |
bbcea18c | 244 | host_hash_delete(host_uid_hash, clientid1, clientid1_len, MDL); |
ab610112 TM |
245 | |
246 | ATF_CHECK_MSG(host1->refcnt == 1, "Invalid refcnt for host1"); | |
247 | ATF_CHECK_MSG(host2->refcnt == 2, "Invalid refcnt for host2"); | |
248 | ||
249 | /* verify that host1 is no longer in the hash */ | |
250 | ATF_CHECK_MSG(host_hash_lookup(&check, host_uid_hash, clientid1, | |
bbcea18c | 251 | clientid1_len, MDL) == 0, |
ab610112 TM |
252 | "Host1 is not supposed to be in the uid_hash."); |
253 | ATF_CHECK_MSG(!check, "Host1 is not supposed to be in the uid_hash."); | |
254 | ||
255 | /* host2 should be still there, though */ | |
256 | ATF_CHECK_MSG(host_hash_lookup(&check, host_uid_hash, clientid2, | |
bbcea18c | 257 | clientid2_len, MDL), |
ab610112 TM |
258 | "Host2 was supposed to still be in the uid_hash."); |
259 | host_dereference(&check, MDL); | |
260 | ||
261 | /* === step 5: remove second host from the hash === */ | |
bbcea18c | 262 | host_hash_delete(host_uid_hash, clientid2, clientid2_len, MDL); |
ab610112 TM |
263 | |
264 | ATF_CHECK_MSG(host1->refcnt == 1, "Invalid refcnt for host1"); | |
265 | ATF_CHECK_MSG(host2->refcnt == 1, "Invalid refcnt for host2"); | |
266 | ||
267 | ATF_CHECK_MSG(host_hash_lookup(&check, host_uid_hash, clientid2, | |
bbcea18c | 268 | clientid2_len, MDL) == 0, |
ab610112 TM |
269 | "Host2 was not supposed to be in the uid_hash anymore."); |
270 | ||
271 | host_dereference(&host1, MDL); | |
272 | host_dereference(&host2, MDL); | |
9f89d01e | 273 | |
ab610112 TM |
274 | /* |
275 | * No easy way to check if the host object were actually released. | |
276 | * We could run it in valgrind and check for memory leaks. | |
277 | */ | |
9f89d01e TM |
278 | |
279 | #if defined (DEBUG_MEMORY_LEAKAGE) && defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT) | |
280 | /* @todo: Should be called in cleanup */ | |
281 | free_everything (); | |
282 | #endif | |
bbcea18c TM |
283 | } |
284 | ||
f94d5a14 TM |
285 | /// @brief executes uid hash test for specified client-ids (3 hosts) |
286 | /// | |
287 | /// Creates three host structures, adds first host to the uid hash, | |
288 | /// then adds second host to the hash, then removes first host, | |
289 | /// then removed the second. Many checks are performed during all | |
290 | /// operations. | |
291 | /// | |
292 | /// @param clientid1 client-id of the first host | |
293 | /// @param clientid1_len client-id1 length (may be 0 for strings) | |
294 | /// @param clientid2 client-id of the second host | |
295 | /// @param clientid2_len client-id2 length (may be 0 for strings) | |
296 | /// @param clientid3 client-id of the second host | |
297 | /// @param clientid3_len client-id2 length (may be 0 for strings) | |
298 | void lease_hash_test_3hosts(unsigned char clientid1[], size_t clientid1_len, | |
299 | unsigned char clientid2[], size_t clientid2_len, | |
300 | unsigned char clientid3[], size_t clientid3_len) { | |
301 | ||
302 | printf("Checking hash operation for 3 hosts: clientid1-len=%lu" | |
303 | " clientid2-len=%lu clientid3-len=%lu\n", | |
904a771a SM |
304 | (unsigned long) clientid1_len, (unsigned long) clientid2_len, |
305 | (unsigned long) clientid3_len); | |
f94d5a14 TM |
306 | |
307 | dhcp_db_objects_setup (); | |
308 | dhcp_common_objects_setup (); | |
309 | ||
310 | /* check that there is actually zero hosts in the hash */ | |
311 | /* @todo: host_hash_for_each() */ | |
312 | ||
313 | struct host_decl *host1 = 0, *host2 = 0, *host3 = 0; | |
314 | struct host_decl *check = 0; | |
315 | ||
316 | /* === step 1: allocate hosts === */ | |
317 | ATF_CHECK_MSG(host_allocate(&host1, MDL) == ISC_R_SUCCESS, | |
318 | "Failed to allocate host"); | |
319 | ATF_CHECK_MSG(host_allocate(&host2, MDL) == ISC_R_SUCCESS, | |
320 | "Failed to allocate host"); | |
321 | ATF_CHECK_MSG(host_allocate(&host3, MDL) == ISC_R_SUCCESS, | |
322 | "Failed to allocate host"); | |
323 | ||
324 | ATF_CHECK_MSG(host_new_hash(&host_uid_hash, HOST_HASH_SIZE, MDL) != 0, | |
325 | "Unable to create new hash"); | |
326 | ||
327 | ATF_CHECK_MSG(buffer_allocate(&host1->client_identifier.buffer, | |
328 | clientid1_len, MDL) != 0, | |
329 | "Can't allocate uid buffer for host1"); | |
330 | ATF_CHECK_MSG(buffer_allocate(&host2->client_identifier.buffer, | |
331 | clientid2_len, MDL) != 0, | |
332 | "Can't allocate uid buffer for host2"); | |
333 | ATF_CHECK_MSG(buffer_allocate(&host3->client_identifier.buffer, | |
334 | clientid3_len, MDL) != 0, | |
335 | "Can't allocate uid buffer for host3"); | |
336 | ||
337 | /* verify that our hosts are not in the hash yet */ | |
338 | ATF_CHECK_MSG(host_hash_lookup(&check, host_uid_hash, clientid1, | |
339 | clientid1_len, MDL) == 0, | |
340 | "Host1 is not supposed to be in the uid_hash."); | |
341 | ||
342 | ATF_CHECK_MSG(!check, "Host1 is not supposed to be in the uid_hash."); | |
343 | ||
344 | ATF_CHECK_MSG(host_hash_lookup(&check, host_uid_hash, clientid2, | |
345 | clientid2_len, MDL) == 0, | |
346 | "Host2 is not supposed to be in the uid_hash."); | |
347 | ATF_CHECK_MSG(!check, "Host2 is not supposed to be in the uid_hash."); | |
348 | ||
349 | ATF_CHECK_MSG(host_hash_lookup(&check, host_uid_hash, clientid3, | |
350 | clientid3_len, MDL) == 0, | |
351 | "Host3 is not supposed to be in the uid_hash."); | |
352 | ATF_CHECK_MSG(!check, "Host3 is not supposed to be in the uid_hash."); | |
353 | ||
354 | /* === step 2: add hosts to the hash === */ | |
355 | host_hash_add(host_uid_hash, clientid1, clientid1_len, host1, MDL); | |
356 | host_hash_add(host_uid_hash, clientid2, clientid2_len, host2, MDL); | |
357 | host_hash_add(host_uid_hash, clientid3, clientid3_len, host3, MDL); | |
358 | ||
359 | ATF_CHECK_MSG(host_hash_lookup(&check, host_uid_hash, clientid1, | |
360 | clientid1_len, MDL), | |
361 | "Host1 was supposed to be in the uid_hash."); | |
362 | /* Hey! That's not the host we were looking for! */ | |
363 | ATF_CHECK_MSG(check == host1, "Wrong host returned by host_hash_lookup"); | |
364 | host_dereference(&check, MDL); /* we don't need it now */ | |
365 | ||
366 | ATF_CHECK_MSG(host_hash_lookup(&check, host_uid_hash, clientid2, | |
367 | clientid2_len, MDL), | |
368 | "Host2 was supposed to be in the uid_hash."); | |
369 | ATF_CHECK_MSG(check, "Host2 was supposed to be in the uid_hash."); | |
370 | /* Hey! That's not the host we were looking for! */ | |
371 | ATF_CHECK_MSG(check == host2, "Wrong host returned by host_hash_lookup"); | |
372 | host_dereference(&check, MDL); /* we don't need it now */ | |
373 | ||
374 | ATF_CHECK_MSG(host_hash_lookup(&check, host_uid_hash, clientid3, | |
375 | clientid3_len, MDL), | |
376 | "Host3 was supposed to be in the uid_hash."); | |
377 | ATF_CHECK_MSG(check, "Host3 was supposed to be in the uid_hash."); | |
378 | /* Hey! That's not the host we were looking for! */ | |
379 | ATF_CHECK_MSG(check == host3, "Wrong host returned by host_hash_lookup"); | |
380 | host_dereference(&check, MDL); /* we don't need it now */ | |
381 | ||
382 | /* === step 4: remove first host from the hash === */ | |
383 | ||
384 | /* delete host from hash */ | |
385 | host_hash_delete(host_uid_hash, clientid1, clientid1_len, MDL); | |
386 | ||
387 | /* verify that host1 is no longer in the hash */ | |
388 | ATF_CHECK_MSG(host_hash_lookup(&check, host_uid_hash, clientid1, | |
389 | clientid1_len, MDL) == 0, | |
390 | "Host1 is not supposed to be in the uid_hash."); | |
391 | ATF_CHECK_MSG(!check, "Host1 is not supposed to be in the uid_hash."); | |
392 | ||
393 | /* host2 and host3 should be still there, though */ | |
394 | ATF_CHECK_MSG(host_hash_lookup(&check, host_uid_hash, clientid2, | |
395 | clientid2_len, MDL), | |
396 | "Host2 was supposed to still be in the uid_hash."); | |
397 | host_dereference(&check, MDL); | |
398 | ATF_CHECK_MSG(host_hash_lookup(&check, host_uid_hash, clientid3, | |
399 | clientid3_len, MDL), | |
400 | "Host3 was supposed to still be in the uid_hash."); | |
401 | host_dereference(&check, MDL); | |
402 | ||
403 | /* === step 5: remove second host from the hash === */ | |
404 | host_hash_delete(host_uid_hash, clientid2, clientid2_len, MDL); | |
405 | ||
406 | ATF_CHECK_MSG(host_hash_lookup(&check, host_uid_hash, clientid2, | |
407 | clientid2_len, MDL) == 0, | |
408 | "Host2 was not supposed to be in the uid_hash anymore."); | |
409 | ATF_CHECK_MSG(host_hash_lookup(&check, host_uid_hash, clientid3, | |
410 | clientid3_len, MDL), | |
411 | "Host3 was supposed to still be in the uid_hash."); | |
412 | host_dereference(&check, MDL); | |
413 | ||
414 | /* === step 6: remove the last (third) host from the hash === */ | |
415 | host_hash_delete(host_uid_hash, clientid3, clientid3_len, MDL); | |
416 | ||
417 | ATF_CHECK_MSG(host_hash_lookup(&check, host_uid_hash, clientid3, | |
418 | clientid3_len, MDL) == 0, | |
419 | "Host3 was not supposed to be in the uid_hash anymore."); | |
420 | host_dereference(&check, MDL); | |
421 | ||
422 | ||
423 | host_dereference(&host1, MDL); | |
424 | host_dereference(&host2, MDL); | |
425 | host_dereference(&host3, MDL); | |
426 | ||
427 | /* | |
428 | * No easy way to check if the host object were actually released. | |
429 | * We could run it in valgrind and check for memory leaks. | |
430 | */ | |
431 | ||
432 | #if defined (DEBUG_MEMORY_LEAKAGE) && defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT) | |
433 | /* @todo: Should be called in cleanup */ | |
434 | free_everything (); | |
435 | #endif | |
436 | } | |
437 | ||
f94d5a14 TM |
438 | ATF_TC(lease_hash_basic_2hosts); |
439 | ||
440 | ATF_TC_HEAD(lease_hash_basic_2hosts, tc) { | |
bbcea18c TM |
441 | atf_tc_set_md_var(tc, "descr", "Basic lease hash tests"); |
442 | /* | |
443 | * The following functions are tested: | |
444 | * host_allocate(), host_new_hash(), buffer_allocate(), host_hash_lookup() | |
445 | * host_hash_add(), host_hash_delete() | |
446 | */ | |
447 | } | |
448 | ||
f94d5a14 | 449 | ATF_TC_BODY(lease_hash_basic_2hosts, tc) { |
bbcea18c TM |
450 | |
451 | unsigned char clientid1[] = { 0x1, 0x2, 0x3 }; | |
452 | unsigned char clientid2[] = { 0xff, 0xfe }; | |
453 | ||
454 | lease_hash_test_2hosts(clientid1, sizeof(clientid1), | |
455 | clientid2, sizeof(clientid2)); | |
456 | } | |
457 | ||
458 | ||
f94d5a14 | 459 | ATF_TC(lease_hash_string_2hosts); |
bbcea18c | 460 | |
f94d5a14 | 461 | ATF_TC_HEAD(lease_hash_string_2hosts, tc) { |
bbcea18c TM |
462 | atf_tc_set_md_var(tc, "descr", "string-based lease hash tests"); |
463 | /* | |
464 | * The following functions are tested: | |
465 | * host_allocate(), host_new_hash(), buffer_allocate(), host_hash_lookup() | |
466 | * host_hash_add(), host_hash_delete() | |
467 | */ | |
468 | } | |
469 | ||
f94d5a14 | 470 | ATF_TC_BODY(lease_hash_string_2hosts, tc) { |
bbcea18c TM |
471 | |
472 | unsigned char clientid1[] = "Alice"; | |
473 | unsigned char clientid2[] = "Bob"; | |
474 | ||
475 | lease_hash_test_2hosts(clientid1, 0, clientid2, 0); | |
476 | } | |
477 | ||
478 | ||
479 | ATF_TC(lease_hash_negative1); | |
480 | ||
481 | ATF_TC_HEAD(lease_hash_negative1, tc) { | |
482 | atf_tc_set_md_var(tc, "descr", "Negative tests for lease hash"); | |
483 | } | |
484 | ||
485 | ATF_TC_BODY(lease_hash_negative1, tc) { | |
486 | ||
487 | unsigned char clientid1[] = { 0x1 }; | |
488 | unsigned char clientid2[] = { 0x0 }; | |
9f89d01e | 489 | |
bbcea18c | 490 | lease_hash_test_2hosts(clientid1, 0, clientid2, 1); |
9f89d01e TM |
491 | } |
492 | ||
3b02a77a | 493 | |
3b02a77a | 494 | |
f94d5a14 | 495 | ATF_TC(lease_hash_string_3hosts); |
f94d5a14 TM |
496 | ATF_TC_HEAD(lease_hash_string_3hosts, tc) { |
497 | atf_tc_set_md_var(tc, "descr", "string-based lease hash tests"); | |
498 | /* | |
499 | * The following functions are tested: | |
500 | * host_allocate(), host_new_hash(), buffer_allocate(), host_hash_lookup() | |
501 | * host_hash_add(), host_hash_delete() | |
502 | */ | |
503 | } | |
f94d5a14 TM |
504 | ATF_TC_BODY(lease_hash_string_3hosts, tc) { |
505 | ||
506 | unsigned char clientid1[] = "Alice"; | |
507 | unsigned char clientid2[] = "Bob"; | |
508 | unsigned char clientid3[] = "Charlie"; | |
509 | ||
510 | lease_hash_test_3hosts(clientid1, 0, clientid2, 0, clientid3, 0); | |
511 | } | |
512 | ||
513 | ||
514 | ATF_TC(lease_hash_basic_3hosts); | |
f94d5a14 TM |
515 | ATF_TC_HEAD(lease_hash_basic_3hosts, tc) { |
516 | atf_tc_set_md_var(tc, "descr", "Basic lease hash tests"); | |
517 | /* | |
518 | * The following functions are tested: | |
519 | * host_allocate(), host_new_hash(), buffer_allocate(), host_hash_lookup() | |
520 | * host_hash_add(), host_hash_delete() | |
521 | */ | |
522 | } | |
f94d5a14 TM |
523 | ATF_TC_BODY(lease_hash_basic_3hosts, tc) { |
524 | ||
525 | unsigned char clientid1[] = { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9 }; | |
526 | unsigned char clientid2[] = { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8 }; | |
527 | unsigned char clientid3[] = { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7 }; | |
528 | ||
529 | lease_hash_test_3hosts(clientid1, sizeof(clientid1), | |
530 | clientid2, sizeof(clientid2), | |
531 | clientid3, sizeof(clientid3)); | |
532 | } | |
533 | ||
b89b8e16 SR |
534 | #if 0 |
535 | /* This test is disabled as we solved the issue by prohibiting | |
536 | the code from using an improper client id earlier and restoring | |
537 | the hash code to its previous state. As we may choose to | |
538 | redo the hash code again this test hasn't been deleted. | |
539 | */ | |
54d3aff8 TM |
540 | /* this test is a direct reproduction of 29851 issue */ |
541 | ATF_TC(uid_hash_rt29851); | |
f94d5a14 | 542 | |
54d3aff8 | 543 | ATF_TC_HEAD(uid_hash_rt29851, tc) { |
3b02a77a | 544 | atf_tc_set_md_var(tc, "descr", "Uid hash tests"); |
54d3aff8 | 545 | |
3afbcb6c TM |
546 | /* |
547 | * this test should last less than millisecond. If its execution | |
548 | * is longer than 3 second, we hit infinite loop. | |
549 | */ | |
97ddf9d1 | 550 | atf_tc_set_md_var(tc, "timeout", "3"); |
3b02a77a TM |
551 | } |
552 | ||
54d3aff8 | 553 | ATF_TC_BODY(uid_hash_rt29851, tc) { |
3b02a77a TM |
554 | |
555 | unsigned char clientid1[] = { 0x0 }; | |
556 | unsigned char clientid2[] = { 0x0 }; | |
557 | unsigned char clientid3[] = { 0x0 }; | |
558 | ||
559 | int clientid1_len = 1; | |
560 | int clientid2_len = 1; | |
561 | int clientid3_len = 0; | |
562 | ||
563 | struct lease *lease1 = 0, *lease2 = 0, *lease3 = 0; | |
564 | ||
565 | dhcp_db_objects_setup (); | |
566 | dhcp_common_objects_setup (); | |
567 | ||
568 | ATF_CHECK(lease_id_new_hash(&lease_uid_hash, LEASE_HASH_SIZE, MDL)); | |
3afbcb6c | 569 | |
3b02a77a TM |
570 | ATF_CHECK(lease_allocate (&lease1, MDL) == ISC_R_SUCCESS); |
571 | ATF_CHECK(lease_allocate (&lease2, MDL) == ISC_R_SUCCESS); | |
572 | ATF_CHECK(lease_allocate (&lease3, MDL) == ISC_R_SUCCESS); | |
573 | ||
574 | lease1->uid = clientid1; | |
575 | lease2->uid = clientid2; | |
576 | lease3->uid = clientid3; | |
577 | ||
578 | lease1->uid_len = clientid1_len; | |
579 | lease2->uid_len = clientid2_len; | |
580 | lease3->uid_len = clientid3_len; | |
581 | ||
582 | uid_hash_add(lease1); | |
3afbcb6c | 583 | /* uid_hash_delete(lease2); // not necessary for actual issue repro */ |
3b02a77a TM |
584 | uid_hash_add(lease3); |
585 | ||
3afbcb6c TM |
586 | /* lease2->uid_len = 0; // not necessary for actual issue repro */ |
587 | /* uid_hash_delete(lease2); // not necessary for actual issue repro */ | |
588 | /* uid_hash_delete(lease3); // not necessary for actual issue repro */ | |
3b02a77a TM |
589 | uid_hash_delete(lease1); |
590 | ||
3afbcb6c | 591 | /* lease2->uid_len = 1; // not necessary for actual issue repro */ |
3b02a77a TM |
592 | uid_hash_add(lease1); |
593 | uid_hash_delete(lease2); | |
594 | } | |
b89b8e16 | 595 | #endif |
f94d5a14 | 596 | |
9f89d01e | 597 | ATF_TP_ADD_TCS(tp) { |
f94d5a14 TM |
598 | ATF_TP_ADD_TC(tp, lease_hash_basic_2hosts); |
599 | ATF_TP_ADD_TC(tp, lease_hash_basic_3hosts); | |
600 | ATF_TP_ADD_TC(tp, lease_hash_string_2hosts); | |
601 | ATF_TP_ADD_TC(tp, lease_hash_string_3hosts); | |
bbcea18c | 602 | ATF_TP_ADD_TC(tp, lease_hash_negative1); |
b89b8e16 | 603 | #if 0 /* see comment in function */ |
54d3aff8 | 604 | ATF_TP_ADD_TC(tp, uid_hash_rt29851); |
b89b8e16 | 605 | #endif |
9f89d01e TM |
606 | return (atf_no_error()); |
607 | } |