3 Server-specific in-memory database support. */
6 * Copyright (c) 1996-2000 Internet Software Consortium.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. Neither the name of The Internet Software Consortium nor the names
19 * of its contributors may be used to endorse or promote products derived
20 * from this software without specific prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
23 * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
24 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
25 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26 * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
27 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
29 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
30 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
31 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
32 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
33 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 * This software has been written for the Internet Software Consortium
37 * by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc.
38 * To learn more about the Internet Software Consortium, see
39 * ``http://www.isc.org/''. To learn more about Vixie Enterprises,
40 * see ``http://www.vix.com''. To learn more about Nominum, Inc., see
41 * ``http://www.nominum.com''.
45 static char copyright
[] =
46 "$Id: mdb.c,v 1.69 2001/06/22 16:47:17 brister Exp $ Copyright (c) 1996-2000 The Internet Software Consortium. All rights reserved.\n";
51 struct subnet
*subnets
;
52 struct shared_network
*shared_networks
;
53 struct hash_table
*host_hw_addr_hash
;
54 struct hash_table
*host_uid_hash
;
55 struct hash_table
*lease_uid_hash
;
56 struct hash_table
*lease_ip_addr_hash
;
57 struct hash_table
*lease_hw_addr_hash
;
58 struct hash_table
*host_name_hash
;
60 omapi_object_type_t
*dhcp_type_host
;
62 isc_result_t
enter_class(cd
, dynamicp
, commit
)
67 if (!collections
-> classes
) {
68 class_reference (&collections
-> classes
, cd
, MDL
);
69 } else if (cd
->name
!= NULL
) { /* regular class */
72 if (find_class(&c
, cd
->name
, MDL
) != ISC_R_NOTFOUND
) {
73 class_dereference(&c
, MDL
);
77 for (c
= collections
-> classes
;
78 c
-> nic
; c
= c
-> nic
)
80 class_reference (&c
-> nic
, cd
, MDL
);
83 if (dynamicp
&& commit
) {
84 const char *name
= cd
->name
;
87 name
= cd
->superclass
->name
;
90 write_named_billing_class (name
, 0, cd
);
91 if (!commit_leases ())
99 isc_result_t
enter_host (hd
, dynamicp
, commit
)
100 struct host_decl
*hd
;
104 struct host_decl
*hp
= (struct host_decl
*)0;
105 struct host_decl
*np
= (struct host_decl
*)0;
106 struct executable_statement
*esp
;
108 if (!host_name_hash
) {
110 new_hash ((hash_reference
)host_reference
,
111 (hash_dereference
)host_dereference
, 0);
113 log_fatal ("Can't allocate host name hash");
114 host_hash_add (host_name_hash
,
115 (unsigned char *)hd
-> name
,
116 strlen (hd
-> name
), hd
, MDL
);
118 host_hash_lookup (&hp
, host_name_hash
,
119 (unsigned char *)hd
-> name
,
120 strlen (hd
-> name
), MDL
);
122 /* If it's deleted, we can supersede it. */
123 if (hp
&& (hp
-> flags
& HOST_DECL_DELETED
)) {
124 host_hash_delete (host_name_hash
,
125 (unsigned char *)hd
-> name
,
126 strlen (hd
-> name
), MDL
);
127 /* If the old entry wasn't dynamic, then we
128 always have to keep the deletion. */
129 if (!hp
-> flags
& HOST_DECL_DYNAMIC
)
130 hd
-> flags
|= HOST_DECL_STATIC
;
133 /* If there isn't already a host decl matching this
134 address, add it to the hash table. */
136 host_hash_add (host_name_hash
,
137 (unsigned char *)hd
-> name
,
138 strlen (hd
-> name
), hd
, MDL
);
140 /* XXX actually, we have to delete the old one
141 XXX carefully and replace it. Not done yet. */
142 host_dereference (&hp
, MDL
);
148 host_dereference (&hd
-> n_ipaddr
, MDL
);
151 hd
-> type
= dhcp_type_host
;
153 if (hd
-> interface
.hlen
) {
154 if (!host_hw_addr_hash
) {
156 new_hash ((hash_reference
)host_reference
,
157 (hash_dereference
)host_dereference
,
159 if (!host_hw_addr_hash
)
160 log_fatal ("Can't allocate host/hw hash");
162 /* If there isn't already a host decl matching this
163 address, add it to the hash table. */
164 host_hash_lookup (&hp
, host_hw_addr_hash
,
165 hd
-> interface
.hbuf
,
166 hd
-> interface
.hlen
, MDL
);
169 host_hash_add (host_hw_addr_hash
, hd
-> interface
.hbuf
,
170 hd
-> interface
.hlen
, hd
, MDL
);
172 /* If there was already a host declaration for
173 this hardware address, add this one to the
175 for (np
= hp
; np
-> n_ipaddr
; np
= np
-> n_ipaddr
)
177 host_reference (&np
-> n_ipaddr
, hd
, MDL
);
178 host_dereference (&hp
, MDL
);
182 /* See if there's a statement that sets the client identifier.
183 This is a kludge - the client identifier really shouldn't be
184 set with an executable statement. */
185 for (esp
= hd
-> group
-> statements
; esp
; esp
= esp
-> next
) {
186 if (esp
-> op
== supersede_option_statement
&&
187 esp
-> data
.option
&&
188 (esp
-> data
.option
-> option
-> universe
==
190 (esp
-> data
.option
-> option
-> code
==
191 DHO_DHCP_CLIENT_IDENTIFIER
)) {
192 evaluate_option_cache
193 (&hd
-> client_identifier
, (struct packet
*)0,
194 (struct lease
*)0, (struct client_state
*)0,
195 (struct option_state
*)0,
196 (struct option_state
*)0, &global_scope
,
197 esp
-> data
.option
, MDL
);
202 /* If we got a client identifier, hash this entry by
203 client identifier. */
204 if (hd
-> client_identifier
.len
) {
205 /* If there's no uid hash, make one; otherwise, see if
206 there's already an entry in the hash for this host. */
207 if (!host_uid_hash
) {
209 new_hash ((hash_reference
)host_reference
,
210 (hash_dereference
)host_dereference
,
213 log_fatal ("Can't allocate host/uid hash");
215 host_hash_add (host_uid_hash
,
216 hd
-> client_identifier
.data
,
217 hd
-> client_identifier
.len
,
220 /* If there's already a host declaration for this
221 client identifier, add this one to the end of the
222 list. Otherwise, add it to the hash table. */
223 if (host_hash_lookup (&hp
, host_uid_hash
,
224 hd
-> client_identifier
.data
,
225 hd
-> client_identifier
.len
,
227 /* Don't link it in twice... */
229 for (np
= hp
; np
-> n_ipaddr
;
230 np
= np
-> n_ipaddr
) {
235 host_reference (&np
-> n_ipaddr
,
238 host_dereference (&hp
, MDL
);
240 host_hash_add (host_uid_hash
,
241 hd
-> client_identifier
.data
,
242 hd
-> client_identifier
.len
,
248 if (dynamicp
&& commit
) {
249 if (!write_host (hd
))
250 return ISC_R_IOERROR
;
251 if (!commit_leases ())
252 return ISC_R_IOERROR
;
255 return ISC_R_SUCCESS
;
259 isc_result_t
delete_class (cp
, commit
)
263 cp
->flags
|= CLASS_DECL_DELETED
;
265 /* do the write first as we won't be leaving it in any data
266 structures, unlike the host objects */
269 write_named_billing_class (cp
->name
, 0, cp
);
270 if (!commit_leases ())
271 return ISC_R_IOERROR
;
274 unlink_class(&cp
); /* remove from collections */
276 class_dereference(&cp
, MDL
);
278 return ISC_R_SUCCESS
;
282 isc_result_t
delete_host (hd
, commit
)
283 struct host_decl
*hd
;
286 struct host_decl
*hp
= (struct host_decl
*)0;
287 struct host_decl
*np
= (struct host_decl
*)0;
288 struct host_decl
*foo
;
289 struct executable_statement
*esp
;
290 int hw_head
= 0, uid_head
= 1;
292 /* Don't need to do it twice. */
293 if (hd
-> flags
& HOST_DECL_DELETED
)
294 return ISC_R_SUCCESS
;
296 /* But we do need to do it once! :') */
297 hd
-> flags
|= HOST_DECL_DELETED
;
299 if (hd
-> interface
.hlen
) {
300 if (host_hw_addr_hash
) {
301 if (host_hash_lookup (&hp
, host_hw_addr_hash
,
302 hd
-> interface
.hbuf
,
303 hd
-> interface
.hlen
, MDL
)) {
305 host_hash_delete (host_hw_addr_hash
,
306 hd
-> interface
.hbuf
,
307 hd
-> interface
.hlen
, MDL
);
310 np
= (struct host_decl
*)0;
311 foo
= (struct host_decl
*)0;
312 host_reference (&foo
, hp
, MDL
);
316 host_reference (&np
, foo
, MDL
);
317 host_dereference (&foo
, MDL
);
319 host_reference (&foo
, np
-> n_ipaddr
, MDL
);
323 host_dereference (&np
-> n_ipaddr
, MDL
);
325 host_reference (&np
-> n_ipaddr
,
326 hd
-> n_ipaddr
, MDL
);
327 host_dereference (&foo
, MDL
);
330 host_dereference (&np
, MDL
);
332 host_dereference (&hp
, MDL
);
337 /* If we got a client identifier, hash this entry by
338 client identifier. */
339 if (hd
-> client_identifier
.len
) {
341 if (host_hash_lookup (&hp
, host_uid_hash
,
342 hd
-> client_identifier
.data
,
343 hd
-> client_identifier
.len
, MDL
)) {
345 host_hash_delete (host_uid_hash
,
346 hd
-> client_identifier
.data
,
347 hd
-> client_identifier
.len
, MDL
);
350 np
= (struct host_decl
*)0;
351 foo
= (struct host_decl
*)0;
352 host_reference (&foo
, hp
, MDL
);
356 host_reference (&np
, foo
, MDL
);
357 host_dereference (&foo
, MDL
);
359 host_reference (&foo
, np
-> n_ipaddr
, MDL
);
363 host_dereference (&np
-> n_ipaddr
, MDL
);
365 host_reference (&np
-> n_ipaddr
,
366 hd
-> n_ipaddr
, MDL
);
367 host_dereference (&foo
, MDL
);
370 host_dereference (&np
, MDL
);
372 host_dereference (&hp
, MDL
);
377 if (hd
-> n_ipaddr
) {
378 if (uid_head
&& hd
-> n_ipaddr
-> client_identifier
.len
) {
381 hd
-> n_ipaddr
-> client_identifier
.data
,
382 hd
-> n_ipaddr
-> client_identifier
.len
,
383 hd
-> n_ipaddr
, MDL
);
385 if (hw_head
&& hd
-> n_ipaddr
-> interface
.hlen
) {
386 host_hash_add (host_hw_addr_hash
,
387 hd
-> n_ipaddr
-> interface
.hbuf
,
388 hd
-> n_ipaddr
-> interface
.hlen
,
389 hd
-> n_ipaddr
, MDL
);
391 host_dereference (&hd
-> n_ipaddr
, MDL
);
394 if (host_name_hash
) {
395 if (host_hash_lookup (&hp
, host_name_hash
,
396 (unsigned char *)hd
-> name
,
397 strlen (hd
-> name
), MDL
)) {
398 if (hp
== hd
&& !(hp
-> flags
& HOST_DECL_STATIC
)) {
399 host_hash_delete (host_name_hash
,
400 (unsigned char *)hd
-> name
,
401 strlen (hd
-> name
), MDL
);
403 host_dereference (&hp
, MDL
);
408 if (!write_host (hd
))
409 return ISC_R_IOERROR
;
410 if (!commit_leases ())
411 return ISC_R_IOERROR
;
413 return ISC_R_SUCCESS
;
416 int find_hosts_by_haddr (struct host_decl
**hp
, int htype
,
417 const unsigned char *haddr
, unsigned hlen
,
418 const char *file
, int line
)
420 struct host_decl
*foo
;
425 memcpy (&h
.hbuf
[1], haddr
, hlen
);
427 return host_hash_lookup (hp
, host_hw_addr_hash
,
428 h
.hbuf
, h
.hlen
, file
, line
);
431 int find_hosts_by_uid (struct host_decl
**hp
,
432 const unsigned char *data
, unsigned len
,
433 const char *file
, int line
)
435 return host_hash_lookup (hp
, host_uid_hash
, data
, len
, file
, line
);
438 /* More than one host_decl can be returned by find_hosts_by_haddr or
439 find_hosts_by_uid, and each host_decl can have multiple addresses.
440 Loop through the list of hosts, and then for each host, through the
441 list of addresses, looking for an address that's in the same shared
442 network as the one specified. Store the matching address through
443 the addr pointer, update the host pointer to point at the host_decl
444 that matched, and return the subnet that matched. */
446 int find_host_for_network (struct subnet
**sp
, struct host_decl
**host
,
447 struct iaddr
*addr
, struct shared_network
*share
)
450 struct subnet
*subnet
;
451 struct iaddr ip_address
;
452 struct host_decl
*hp
;
453 struct data_string fixed_addr
;
455 memset (&fixed_addr
, 0, sizeof fixed_addr
);
457 for (hp
= *host
; hp
; hp
= hp
-> n_ipaddr
) {
458 if (!hp
-> fixed_addr
)
460 if (!evaluate_option_cache (&fixed_addr
, (struct packet
*)0,
462 (struct client_state
*)0,
463 (struct option_state
*)0,
464 (struct option_state
*)0,
466 hp
-> fixed_addr
, MDL
))
468 for (i
= 0; i
< fixed_addr
.len
; i
+= 4) {
470 memcpy (ip_address
.iabuf
,
471 fixed_addr
.data
+ i
, 4);
472 if (find_grouped_subnet (sp
, share
, ip_address
, MDL
)) {
473 struct host_decl
*tmp
= (struct host_decl
*)0;
475 /* This is probably not necessary, but
476 just in case *host is the only reference
477 to that host declaration, make a temporary
478 reference so that dereferencing it doesn't
479 dereference hp out from under us. */
480 host_reference (&tmp
, *host
, MDL
);
481 host_dereference (host
, MDL
);
482 host_reference (host
, hp
, MDL
);
483 host_dereference (&tmp
, MDL
);
484 data_string_forget (&fixed_addr
, MDL
);
488 data_string_forget (&fixed_addr
, MDL
);
493 void new_address_range (low
, high
, subnet
, pool
)
494 struct iaddr low
, high
;
495 struct subnet
*subnet
;
498 struct lease
*address_range
, *lp
, *plp
;
500 unsigned min
, max
, i
;
501 char lowbuf
[16], highbuf
[16], netbuf
[16];
502 struct shared_network
*share
= subnet
-> shared_network
;
504 struct lease
*lt
= (struct lease
*)0;
506 /* All subnets should have attached shared network structures. */
508 strcpy (netbuf
, piaddr (subnet
-> net
));
509 log_fatal ("No shared network for network %s (%s)",
510 netbuf
, piaddr (subnet
-> netmask
));
513 /* Initialize the hash table if it hasn't been done yet. */
514 if (!lease_uid_hash
) {
516 new_hash ((hash_reference
)lease_reference
,
517 (hash_dereference
)lease_dereference
, 0);
519 log_fatal ("Can't allocate lease/uid hash");
521 if (!lease_ip_addr_hash
) {
523 new_hash ((hash_reference
)lease_reference
,
524 (hash_dereference
)lease_dereference
, 0);
526 log_fatal ("Can't allocate lease/ip hash");
528 if (!lease_hw_addr_hash
) {
530 new_hash ((hash_reference
)lease_reference
,
531 (hash_dereference
)lease_dereference
, 0);
533 log_fatal ("Can't allocate lease/hw hash");
536 /* Make sure that high and low addresses are in same subnet. */
537 net
= subnet_number (low
, subnet
-> netmask
);
538 if (!addr_eq (net
, subnet_number (high
, subnet
-> netmask
))) {
539 strcpy (lowbuf
, piaddr (low
));
540 strcpy (highbuf
, piaddr (high
));
541 strcpy (netbuf
, piaddr (subnet
-> netmask
));
542 log_fatal ("Address range %s to %s, netmask %s spans %s!",
543 lowbuf
, highbuf
, netbuf
, "multiple subnets");
546 /* Make sure that the addresses are on the correct subnet. */
547 if (!addr_eq (net
, subnet
-> net
)) {
548 strcpy (lowbuf
, piaddr (low
));
549 strcpy (highbuf
, piaddr (high
));
550 strcpy (netbuf
, piaddr (subnet
-> netmask
));
551 log_fatal ("Address range %s to %s not on net %s/%s!",
552 lowbuf
, highbuf
, piaddr (subnet
-> net
), netbuf
);
555 /* Get the high and low host addresses... */
556 max
= host_addr (high
, subnet
-> netmask
);
557 min
= host_addr (low
, subnet
-> netmask
);
559 /* Allow range to be specified high-to-low as well as low-to-high. */
562 min
= host_addr (high
, subnet
-> netmask
);
565 /* Get a lease structure for each address in the range. */
566 #if defined (COMPACT_LEASES)
567 address_range
= new_leases (max
- min
+ 1, MDL
);
568 if (!address_range
) {
569 strcpy (lowbuf
, piaddr (low
));
570 strcpy (highbuf
, piaddr (high
));
571 log_fatal ("No memory for address range %s-%s.",
576 /* Fill out the lease structures with some minimal information. */
577 for (i
= 0; i
< max
- min
+ 1; i
++) {
578 struct lease
*lp
= (struct lease
*)0;
579 #if defined (COMPACT_LEASES)
580 omapi_object_initialize ((omapi_object_t
*)&address_range
[i
],
582 0, sizeof (struct lease
), MDL
);
583 lease_reference (&lp
, &address_range
[i
], MDL
);
585 status
= lease_allocate (&lp
, MDL
);
586 if (status
!= ISC_R_SUCCESS
)
587 log_fatal ("No memory for lease %s: %s",
588 piaddr (ip_addr (subnet
-> net
,
591 isc_result_totext (status
));
593 lp
-> ip_addr
= ip_addr (subnet
-> net
,
594 subnet
-> netmask
, i
+ min
);
595 lp
-> starts
= lp
-> timestamp
= MIN_TIME
;
596 lp
-> ends
= MIN_TIME
;
597 subnet_reference (&lp
-> subnet
, subnet
, MDL
);
598 pool_reference (&lp
-> pool
, pool
, MDL
);
599 lp
-> binding_state
= FTS_FREE
;
600 lp
-> next_binding_state
= FTS_FREE
;
603 /* Remember the lease in the IP address hash. */
604 if (find_lease_by_ip_addr (<
, lp
-> ip_addr
, MDL
)) {
606 log_error ("duplicate entries for lease %s",
607 piaddr (lp
-> ip_addr
));
609 pool_reference (<
-> pool
, pool
, MDL
);
610 lease_dereference (<
, MDL
);
612 lease_hash_add (lease_ip_addr_hash
,
614 lp
-> ip_addr
.len
, lp
, MDL
);
615 lease_dereference (&lp
, MDL
);
620 #if defined (COMPACT_LEASES)
621 struct lease
*free_leases
;
623 /* If we are allocating leases in aggregations, there's really no way
624 to free one, although perhaps we can maintain a free list. */
626 isc_result_t
dhcp_lease_free (omapi_object_t
*lo
,
627 const char *file
, int line
)
630 if (lo
-> type
!= dhcp_type_lease
)
631 return ISC_R_INVALIDARG
;
632 lease
= (struct lease
*)lo
;
633 lease
-> next
= free_leases
;
635 return ISC_R_SUCCESS
;
638 isc_result_t
dhcp_lease_get (omapi_object_t
**lp
,
639 const char *file
, int line
)
641 struct lease
**lease
= (struct lease
**)lp
;
646 free_leases
= lt
-> next
;
648 return ISC_R_SUCCESS
;
650 return ISC_R_NOMEMORY
;
654 int find_subnet (struct subnet
**sp
,
655 struct iaddr addr
, const char *file
, int line
)
659 for (rv
= subnets
; rv
; rv
= rv
-> next_subnet
) {
660 if (addr_eq (subnet_number (addr
, rv
-> netmask
), rv
-> net
)) {
661 if (subnet_reference (sp
, rv
,
662 file
, line
) != ISC_R_SUCCESS
)
670 int find_grouped_subnet (struct subnet
**sp
,
671 struct shared_network
*share
, struct iaddr addr
,
672 const char *file
, int line
)
676 for (rv
= share
-> subnets
; rv
; rv
= rv
-> next_sibling
) {
677 if (addr_eq (subnet_number (addr
, rv
-> netmask
), rv
-> net
)) {
678 if (subnet_reference (sp
, rv
,
679 file
, line
) != ISC_R_SUCCESS
)
687 int subnet_inner_than (subnet
, scan
, warnp
)
688 struct subnet
*subnet
, *scan
;
691 if (addr_eq (subnet_number (subnet
-> net
, scan
-> netmask
),
693 addr_eq (subnet_number (scan
-> net
, subnet
-> netmask
),
697 for (i
= 0; i
< 32; i
++)
698 if (subnet
-> netmask
.iabuf
[3 - (i
>> 3)]
701 for (j
= 0; j
< 32; j
++)
702 if (scan
-> netmask
.iabuf
[3 - (j
>> 3)] &
705 strcpy (n1buf
, piaddr (subnet
-> net
));
707 log_error ("%ssubnet %s/%d overlaps subnet %s/%d",
708 "Warning: ", n1buf
, 32 - i
,
709 piaddr (scan
-> net
), 32 - j
);
716 /* Enter a new subnet into the subnet list. */
717 void enter_subnet (subnet
)
718 struct subnet
*subnet
;
720 struct subnet
*scan
, *prev
= (struct subnet
*)0;
722 /* Check for duplicates... */
723 for (scan
= subnets
; scan
; scan
= scan
-> next_subnet
) {
724 /* When we find a conflict, make sure that the
725 subnet with the narrowest subnet mask comes
727 if (subnet_inner_than (subnet
, scan
, 1)) {
729 subnet_reference (&prev
-> next_subnet
,
732 subnet_reference (&subnets
, subnet
, MDL
);
733 subnet_reference (&subnet
-> next_subnet
, scan
, MDL
);
739 /* XXX use the BSD radix tree code instead of a linked list. */
740 subnet
-> next_subnet
= subnets
;
744 /* Enter a new shared network into the shared network list. */
746 void enter_shared_network (share
)
747 struct shared_network
*share
;
749 if (shared_networks
) {
750 shared_network_reference (&share
-> next
,
751 shared_networks
, MDL
);
752 shared_network_dereference (&shared_networks
, MDL
);
754 shared_network_reference (&shared_networks
, share
, MDL
);
757 void new_shared_network_interface (cfile
, share
, name
)
759 struct shared_network
*share
;
762 struct interface_info
*ip
;
765 if (share
-> interface
) {
767 "A subnet or shared network can't be connected %s",
768 "to two interfaces.");
772 for (ip
= interfaces
; ip
; ip
= ip
-> next
)
773 if (!strcmp (ip
-> name
, name
))
776 status
= interface_allocate (&ip
, MDL
);
777 if (status
!= ISC_R_SUCCESS
)
778 log_fatal ("new_shared_network_interface %s: %s",
779 name
, isc_result_totext (status
));
780 if (strlen (name
) > sizeof ip
-> name
) {
781 memcpy (ip
-> name
, name
, (sizeof ip
-> name
) - 1);
782 ip
-> name
[(sizeof ip
-> name
) - 1] = 0;
784 strcpy (ip
-> name
, name
);
786 interface_reference (&ip
-> next
, interfaces
, MDL
);
787 interface_dereference (&interfaces
, MDL
);
789 interface_reference (&interfaces
, ip
, MDL
);
790 ip
-> flags
= INTERFACE_REQUESTED
;
791 /* XXX this is a reference loop. */
792 shared_network_reference (&ip
-> shared_network
, share
, MDL
);
793 interface_reference (&share
-> interface
, ip
, MDL
);
797 /* Enter a lease into the system. This is called by the parser each
798 time it reads in a new lease. If the subnet for that lease has
799 already been read in (usually the case), just update that lease;
800 otherwise, allocate temporary storage for the lease and keep it around
801 until we're done reading in the config file. */
803 void enter_lease (lease
)
806 struct lease
*comp
= (struct lease
*)0;
809 if (find_lease_by_ip_addr (&comp
, lease
-> ip_addr
, MDL
)) {
811 log_error ("undeclared lease found in database: %s",
812 piaddr (lease
-> ip_addr
));
814 pool_reference (&lease
-> pool
, comp
-> pool
, MDL
);
817 subnet_reference (&lease
-> subnet
,
818 comp
-> subnet
, MDL
);
819 lease_hash_delete (lease_ip_addr_hash
,
820 lease
-> ip_addr
.iabuf
,
821 lease
-> ip_addr
.len
, MDL
);
822 lease_dereference (&comp
, MDL
);
825 /* The only way a lease can get here without a subnet is if it's in
826 the lease file, but not in the dhcpd.conf file. In this case, we
827 *should* keep it around until it's expired, but never reallocate it
828 or renew it. Currently, to maintain consistency, we are not doing
830 XXX fix this so that the lease is kept around until it expires.
831 XXX this will be important in IPv6 with addresses that become
832 XXX non-renewable as a result of a renumbering event. */
834 if (!lease
-> subnet
) {
835 log_error ("lease %s: no subnet.", piaddr (lease
-> ip_addr
));
838 lease_hash_add (lease_ip_addr_hash
,
839 lease
-> ip_addr
.iabuf
,
840 lease
-> ip_addr
.len
, lease
, MDL
);
843 /* Replace the data in an existing lease with the data in a new lease;
844 adjust hash tables to suit, and insertion sort the lease into the
845 list of leases by expiry time so that we can always find the oldest
848 int supersede_lease (comp
, lease
, commit
, propogate
, pimmediate
)
849 struct lease
*comp
, *lease
;
855 int enter_hwaddr
= 0;
856 struct lease
*lp
, **lq
, *prev
;
859 #if defined (FAILOVER_PROTOCOL)
860 /* We must commit leases before sending updates regarding them
861 to failover peers. It is, therefore, an error to set pimmediate
863 if (pimmediate
&& !commit
)
867 /* If there is no sample lease, just do the move. */
871 /* Static leases are not currently kept in the database... */
872 if (lease
-> flags
& STATIC_LEASE
)
875 /* If the existing lease hasn't expired and has a different
876 unique identifier or, if it doesn't have a unique
877 identifier, a different hardware address, then the two
878 leases are in conflict. If the existing lease has a uid
879 and the new one doesn't, but they both have the same
880 hardware address, and dynamic bootp is allowed on this
881 lease, then we allow that, in case a dynamic BOOTP lease is
882 requested *after* a DHCP lease has been assigned. */
884 if (lease
-> binding_state
!= FTS_ABANDONED
&&
885 lease
-> next_binding_state
!= FTS_ABANDONED
&&
886 (comp
-> binding_state
== FTS_ACTIVE
||
887 comp
-> binding_state
== FTS_RESERVED
||
888 comp
-> binding_state
== FTS_BOOTP
) &&
889 (((comp
-> uid
&& lease
-> uid
) &&
890 (comp
-> uid_len
!= lease
-> uid_len
||
891 memcmp (comp
-> uid
, lease
-> uid
, comp
-> uid_len
))) ||
893 ((comp
-> hardware_addr
.hlen
!=
894 lease
-> hardware_addr
.hlen
) ||
895 memcmp (comp
-> hardware_addr
.hbuf
,
896 lease
-> hardware_addr
.hbuf
,
897 comp
-> hardware_addr
.hlen
))))) {
898 log_error ("Lease conflict at %s",
899 piaddr (comp
-> ip_addr
));
903 /* If there's a Unique ID, dissociate it from the hash
904 table and free it if necessary. */
906 uid_hash_delete (comp
);
908 if (comp
-> uid
!= &comp
-> uid_buf
[0]) {
909 dfree (comp
-> uid
, MDL
);
913 comp
-> uid
= (unsigned char *)0;
917 if (comp
-> hardware_addr
.hlen
&&
918 ((comp
-> hardware_addr
.hlen
!=
919 lease
-> hardware_addr
.hlen
) ||
920 memcmp (comp
-> hardware_addr
.hbuf
,
921 lease
-> hardware_addr
.hbuf
,
922 comp
-> hardware_addr
.hlen
))) {
923 hw_hash_delete (comp
);
925 } else if (!comp
-> hardware_addr
.hlen
)
928 /* If the lease has been billed to a class, remove the billing. */
929 if (comp
-> billing_class
!= lease
-> billing_class
) {
930 if (comp
-> billing_class
)
931 unbill_class (comp
, comp
-> billing_class
);
932 if (lease
-> billing_class
)
933 bill_class (comp
, lease
-> billing_class
);
936 /* Copy the data files, but not the linkages. */
937 comp
-> starts
= lease
-> starts
;
939 if (lease
-> uid_len
<= sizeof (lease
-> uid_buf
)) {
940 memcpy (comp
-> uid_buf
,
941 lease
-> uid
, lease
-> uid_len
);
942 comp
-> uid
= &comp
-> uid_buf
[0];
943 comp
-> uid_max
= sizeof comp
-> uid_buf
;
944 comp
-> uid_len
= lease
-> uid_len
;
945 } else if (lease
-> uid
!= &lease
-> uid_buf
[0]) {
946 comp
-> uid
= lease
-> uid
;
947 comp
-> uid_max
= lease
-> uid_max
;
948 lease
-> uid
= (unsigned char *)0;
949 lease
-> uid_max
= 0;
950 comp
-> uid_len
= lease
-> uid_len
;
951 lease
-> uid_len
= 0;
953 log_fatal ("corrupt lease uid."); /* XXX */
956 comp
-> uid
= (unsigned char *)0;
957 comp
-> uid_len
= comp
-> uid_max
= 0;
960 host_dereference (&comp
-> host
, MDL
);
961 host_reference (&comp
-> host
, lease
-> host
, MDL
);
962 comp
-> hardware_addr
= lease
-> hardware_addr
;
963 comp
-> flags
= ((lease
-> flags
& ~PERSISTENT_FLAGS
) |
964 (comp
-> flags
& ~EPHEMERAL_FLAGS
));
966 binding_scope_dereference (&comp
-> scope
, MDL
);
967 if (lease
-> scope
) {
968 binding_scope_reference (&comp
-> scope
, lease
-> scope
, MDL
);
969 binding_scope_dereference (&lease
-> scope
, MDL
);
972 if (comp
-> agent_options
)
973 option_chain_head_dereference (&comp
-> agent_options
, MDL
);
974 if (lease
-> agent_options
) {
975 /* Only retain the agent options if the lease is still
976 affirmatively associated with a client. */
977 if (lease
-> next_binding_state
== FTS_ACTIVE
||
978 lease
-> next_binding_state
== FTS_EXPIRED
||
979 lease
-> next_binding_state
== FTS_RESERVED
||
980 lease
-> next_binding_state
== FTS_BOOTP
)
981 option_chain_head_reference (&comp
-> agent_options
,
982 lease
-> agent_options
,
984 option_chain_head_dereference (&lease
-> agent_options
, MDL
);
987 /* Record the hostname information in the lease. */
988 if (comp
-> client_hostname
)
989 dfree (comp
-> client_hostname
, MDL
);
990 comp
-> client_hostname
= lease
-> client_hostname
;
991 lease
-> client_hostname
= (char *)0;
993 if (lease
-> on_expiry
) {
994 if (comp
-> on_expiry
)
995 executable_statement_dereference (&comp
-> on_expiry
,
997 executable_statement_reference (&comp
-> on_expiry
,
1001 if (lease
-> on_commit
) {
1002 if (comp
-> on_commit
)
1003 executable_statement_dereference (&comp
-> on_commit
,
1005 executable_statement_reference (&comp
-> on_commit
,
1009 if (lease
-> on_release
) {
1010 if (comp
-> on_release
)
1011 executable_statement_dereference (&comp
-> on_release
,
1013 executable_statement_reference (&comp
-> on_release
,
1014 lease
-> on_release
, MDL
);
1017 /* Record the lease in the uid hash if necessary. */
1018 if (enter_uid
&& comp
-> uid
) {
1019 uid_hash_add (comp
);
1022 /* Record it in the hardware address hash if necessary. */
1023 if (enter_hwaddr
&& lease
-> hardware_addr
.hlen
) {
1027 #if defined (FAILOVER_PROTOCOL)
1028 comp
-> cltt
= lease
-> cltt
;
1029 comp
-> tstp
= lease
-> tstp
;
1030 comp
-> tsfp
= lease
-> tsfp
;
1031 #endif /* FAILOVER_PROTOCOL */
1032 comp
-> ends
= lease
-> ends
;
1033 comp
-> next_binding_state
= lease
-> next_binding_state
;
1036 if (!comp
-> pool
) {
1037 log_error ("Supersede_lease: lease %s with no pool.",
1038 piaddr (comp
-> ip_addr
));
1042 /* Figure out which queue it's on. */
1043 switch (comp
-> binding_state
) {
1045 lq
= &comp
-> pool
-> free
;
1046 comp
-> pool
-> free_leases
--;
1052 lq
= &comp
-> pool
-> active
;
1058 lq
= &comp
-> pool
-> expired
;
1062 lq
= &comp
-> pool
-> abandoned
;
1066 lq
= &comp
-> pool
-> backup
;
1067 comp
-> pool
-> backup_leases
--;
1071 log_error ("Lease with bogus binding state: %d",
1072 comp
-> binding_state
);
1073 #if defined (BINDING_STATE_DEBUG)
1079 /* Remove the lease from its current place in its current
1081 prev
= (struct lease
*)0;
1082 for (lp
= *lq
; lp
; lp
= lp
-> next
) {
1089 log_error ("Lease with binding state %s not on its queue.",
1090 (comp
-> binding_state
< 1 &&
1091 comp
-> binding_state
< FTS_BOOTP
)
1093 : binding_state_names
[comp
-> binding_state
- 1]);
1098 lease_dereference (&prev
-> next
, MDL
);
1100 lease_reference (&prev
-> next
, comp
-> next
, MDL
);
1101 lease_dereference (&comp
-> next
, MDL
);
1104 lease_dereference (lq
, MDL
);
1106 lease_reference (lq
, comp
-> next
, MDL
);
1107 lease_dereference (&comp
-> next
, MDL
);
1111 /* Make the state transition. */
1112 if (commit
|| !pimmediate
)
1113 make_binding_state_transition (comp
);
1115 /* Put the lease back on the appropriate queue. If the lease
1116 is corrupt (as detected by lease_enqueue), don't go any farther. */
1117 if (!lease_enqueue (comp
))
1120 /* If this is the next lease that will timeout on the pool,
1121 zap the old timeout and set the timeout on this pool to the
1122 time that the lease's next event will happen.
1124 We do not actually set the timeout unless commit is true -
1125 we don't want to thrash the timer queue when reading the
1126 lease database. Instead, the database code calls the
1127 expiry event on each pool after reading in the lease file,
1128 and the expiry code sets the timer if there's anything left
1129 to expire after it's run any outstanding expiry events on
1131 if ((commit
|| !pimmediate
) &&
1132 comp
-> sort_time
!= MIN_TIME
&&
1133 comp
-> sort_time
> cur_time
&&
1134 (comp
-> sort_time
< comp
-> pool
-> next_event_time
||
1135 comp
-> pool
-> next_event_time
== MIN_TIME
)) {
1136 comp
-> pool
-> next_event_time
= comp
-> sort_time
;
1137 add_timeout (comp
-> pool
-> next_event_time
,
1138 pool_timer
, comp
-> pool
,
1139 (tvref_t
)pool_reference
,
1140 (tvunref_t
)pool_dereference
);
1144 if (!write_lease (comp
))
1146 if (!commit_leases ())
1150 #if defined (FAILOVER_PROTOCOL)
1152 if (!dhcp_failover_queue_update (comp
, pimmediate
))
1160 void make_binding_state_transition (struct lease
*lease
)
1162 #if defined (FAILOVER_PROTOCOL)
1163 dhcp_failover_state_t
*peer
;
1165 if (lease
&& lease
-> pool
&& lease
-> pool
-> failover_peer
)
1166 peer
= lease
-> pool
-> failover_peer
;
1168 peer
= (dhcp_failover_state_t
*)0;
1171 /* If the lease was active and is now no longer active, but isn't
1172 released, then it just expired, so do the expiry event. */
1173 if (lease
-> next_binding_state
!= lease
-> binding_state
&&
1175 #if defined (FAILOVER_PROTOCOL)
1177 lease
-> binding_state
== FTS_EXPIRED
&&
1178 (lease
-> next_binding_state
== FTS_FREE
||
1179 lease
-> next_binding_state
== FTS_BACKUP
)) ||
1182 (lease
-> binding_state
== FTS_ACTIVE
||
1183 lease
-> binding_state
== FTS_BOOTP
||
1184 lease
-> binding_state
== FTS_RESERVED
) &&
1185 lease
-> next_binding_state
!= FTS_RELEASED
))) {
1186 #if defined (NSUPDATE)
1187 ddns_removals (lease
);
1189 if (lease
-> on_expiry
) {
1190 execute_statements ((struct binding_value
**)0,
1191 (struct packet
*)0, lease
,
1192 (struct client_state
*)0,
1193 (struct option_state
*)0,
1194 (struct option_state
*)0, /* XXX */
1196 lease
-> on_expiry
);
1197 if (lease
-> on_expiry
)
1198 executable_statement_dereference
1199 (&lease
-> on_expiry
, MDL
);
1202 /* No sense releasing a lease after it's expired. */
1203 if (lease
-> on_release
)
1204 executable_statement_dereference (&lease
-> on_release
,
1206 if (lease
-> billing_class
)
1207 unbill_class (lease
, lease
-> billing_class
);
1209 /* Send the expiry time to the peer. */
1210 lease
-> tstp
= lease
-> ends
;
1213 /* If the lease was active and is now released, do the release
1215 if (lease
-> next_binding_state
!= lease
-> binding_state
&&
1217 #if defined (FAILOVER_PROTOCOL)
1219 lease
-> binding_state
== FTS_RELEASED
&&
1220 (lease
-> next_binding_state
== FTS_FREE
||
1221 lease
-> next_binding_state
== FTS_BACKUP
)) ||
1224 (lease
-> binding_state
== FTS_ACTIVE
||
1225 lease
-> binding_state
== FTS_BOOTP
||
1226 lease
-> binding_state
== FTS_RESERVED
) &&
1227 lease
-> next_binding_state
== FTS_RELEASED
))) {
1228 #if defined (NSUPDATE)
1229 ddns_removals (lease
);
1231 if (lease
-> on_release
) {
1232 execute_statements ((struct binding_value
**)0,
1233 (struct packet
*)0, lease
,
1234 (struct client_state
*)0,
1235 (struct option_state
*)0,
1236 (struct option_state
*)0, /* XXX */
1238 lease
-> on_release
);
1239 executable_statement_dereference (&lease
-> on_release
,
1243 /* A released lease can't expire. */
1244 if (lease
-> on_expiry
)
1245 executable_statement_dereference (&lease
-> on_expiry
,
1248 if (lease
-> billing_class
)
1249 unbill_class (lease
, lease
-> billing_class
);
1251 /* Send the release time (should be == cur_time) to the
1253 lease
-> tstp
= lease
-> ends
;
1256 #if defined (DEBUG_LEASE_STATE_TRANSITIONS)
1257 log_debug ("lease %s moves from %s to %s",
1258 piaddr (lease
-> ip_addr
),
1259 binding_state_print (lease
-> binding_state
),
1260 binding_state_print (lease
-> next_binding_state
));
1263 lease
-> binding_state
= lease
-> next_binding_state
;
1264 switch (lease
-> binding_state
) {
1267 #if defined (FAILOVER_PROTOCOL)
1268 if (lease
-> pool
&& lease
-> pool
-> failover_peer
)
1269 lease
-> next_binding_state
= FTS_EXPIRED
;
1272 lease
-> next_binding_state
= FTS_FREE
;
1279 lease
-> next_binding_state
= FTS_FREE
;
1280 /* If we are not in partner_down, leases don't go from
1281 EXPIRED to FREE on a timeout - only on an update.
1282 If we're in partner_down, they expire at mclt past
1283 the time we entered partner_down. */
1284 if (lease
-> pool
-> failover_peer
&&
1285 lease
-> pool
-> failover_peer
-> me
.state
== partner_down
)
1287 (lease
-> pool
-> failover_peer
-> me
.stos
+
1288 lease
-> pool
-> failover_peer
-> mclt
);
1294 lease
-> next_binding_state
= lease
-> binding_state
;
1297 #if defined (DEBUG_LEASE_STATE_TRANSITIONS)
1298 log_debug ("lease %s: next binding state %s",
1299 piaddr (lease
-> ip_addr
),
1300 binding_state_print (lease
-> next_binding_state
));
1305 /* Copy the contents of one lease into another, correctly maintaining
1306 reference counts. */
1307 int lease_copy (struct lease
**lp
,
1308 struct lease
*lease
, const char *file
, int line
)
1310 struct lease
*lt
= (struct lease
*)0;
1311 isc_result_t status
;
1313 status
= lease_allocate (<
, MDL
);
1314 if (status
!= ISC_R_SUCCESS
)
1317 lt
-> ip_addr
= lease
-> ip_addr
;
1318 lt
-> starts
= lease
-> starts
;
1319 lt
-> ends
= lease
-> ends
;
1320 lt
-> timestamp
= lease
-> timestamp
;
1321 lt
-> uid_len
= lease
-> uid_len
;
1322 lt
-> uid_max
= lease
-> uid_max
;
1323 if (lease
-> uid
== lease
-> uid_buf
) {
1324 lt
-> uid
= lt
-> uid_buf
;
1325 memcpy (lt
-> uid_buf
, lease
-> uid_buf
, sizeof lt
-> uid_buf
);
1326 } else if (!lease
-> uid_max
) {
1327 lt
-> uid
= (unsigned char *)0;
1329 lt
-> uid
= dmalloc (lt
-> uid_max
, MDL
);
1331 lease_dereference (<
, MDL
);
1334 memcpy (lt
-> uid
, lease
-> uid
, lease
-> uid_max
);
1336 if (lease
-> client_hostname
) {
1337 lt
-> client_hostname
=
1338 dmalloc (strlen (lease
-> client_hostname
) + 1, MDL
);
1339 if (!lt
-> client_hostname
) {
1340 lease_dereference (<
, MDL
);
1343 strcpy (lt
-> client_hostname
, lease
-> client_hostname
);
1346 binding_scope_reference (<
-> scope
, lease
-> scope
, MDL
);
1347 if (lease
-> agent_options
)
1348 option_chain_head_reference (<
-> agent_options
,
1349 lease
-> agent_options
, MDL
);
1350 host_reference (<
-> host
, lease
-> host
, file
, line
);
1351 subnet_reference (<
-> subnet
, lease
-> subnet
, file
, line
);
1352 pool_reference (<
-> pool
, lease
-> pool
, file
, line
);
1353 class_reference (<
-> billing_class
,
1354 lease
-> billing_class
, file
, line
);
1355 lt
-> hardware_addr
= lease
-> hardware_addr
;
1356 if (lease
-> on_expiry
)
1357 executable_statement_reference (<
-> on_expiry
,
1360 if (lease
-> on_commit
)
1361 executable_statement_reference (<
-> on_commit
,
1364 if (lease
-> on_release
)
1365 executable_statement_reference (<
-> on_release
,
1366 lease
-> on_release
,
1368 lt
-> flags
= lease
-> flags
;
1369 lt
-> tstp
= lease
-> tstp
;
1370 lt
-> tsfp
= lease
-> tsfp
;
1371 lt
-> cltt
= lease
-> cltt
;
1372 lt
-> binding_state
= lease
-> binding_state
;
1373 lt
-> next_binding_state
= lease
-> next_binding_state
;
1374 status
= lease_reference (lp
, lt
, file
, line
);
1375 lease_dereference (<
, MDL
);
1376 return status
== ISC_R_SUCCESS
;
1379 /* Release the specified lease and re-hash it as appropriate. */
1380 void release_lease (lease
, packet
)
1381 struct lease
*lease
;
1382 struct packet
*packet
;
1384 /* If there are statements to execute when the lease is
1385 released, execute them. */
1386 #if defined (NSUPDATE)
1387 ddns_removals (lease
);
1389 if (lease
-> on_release
) {
1390 execute_statements ((struct binding_value
**)0,
1391 packet
, lease
, (struct client_state
*)0,
1393 (struct option_state
*)0, /* XXX */
1394 &lease
-> scope
, lease
-> on_release
);
1395 if (lease
-> on_release
)
1396 executable_statement_dereference (&lease
-> on_release
,
1400 /* We do either the on_release or the on_expiry events, but
1401 not both (it's possible that they could be the same,
1403 if (lease
-> on_expiry
)
1404 executable_statement_dereference (&lease
-> on_expiry
, MDL
);
1406 if (lease
-> binding_state
!= FTS_FREE
&&
1407 lease
-> binding_state
!= FTS_BACKUP
&&
1408 lease
-> binding_state
!= FTS_RELEASED
&&
1409 lease
-> binding_state
!= FTS_EXPIRED
&&
1410 lease
-> binding_state
!= FTS_RESET
) {
1411 if (lease
-> on_commit
)
1412 executable_statement_dereference (&lease
-> on_commit
,
1415 /* Blow away any bindings. */
1417 binding_scope_dereference (&lease
-> scope
, MDL
);
1418 lease
-> ends
= cur_time
;
1419 #if defined (FAILOVER_PROTOCOL)
1420 if (lease
-> pool
&& lease
-> pool
-> failover_peer
) {
1421 lease
-> next_binding_state
= FTS_RELEASED
;
1423 lease
-> next_binding_state
= FTS_FREE
;
1426 lease
-> next_binding_state
= FTS_FREE
;
1428 supersede_lease (lease
, (struct lease
*)0, 1, 1, 1);
1432 /* Abandon the specified lease (set its timeout to infinity and its
1433 particulars to zero, and re-hash it as appropriate. */
1435 void abandon_lease (lease
, message
)
1436 struct lease
*lease
;
1437 const char *message
;
1439 struct lease
*lt
= (struct lease
*)0;
1441 if (!lease_copy (<
, lease
, MDL
))
1444 lt
-> ends
= cur_time
; /* XXX */
1445 lt
-> next_binding_state
= FTS_ABANDONED
;
1447 log_error ("Abandoning IP address %s: %s",
1448 piaddr (lease
-> ip_addr
), message
);
1449 lt
-> hardware_addr
.hlen
= 0;
1450 if (lt
-> uid
&& lt
-> uid
!= lt
-> uid_buf
)
1451 dfree (lt
-> uid
, MDL
);
1452 lt
-> uid
= (unsigned char *)0;
1455 supersede_lease (lease
, lt
, 1, 1, 1);
1456 lease_dereference (<
, MDL
);
1459 /* Abandon the specified lease (set its timeout to infinity and its
1460 particulars to zero, and re-hash it as appropriate. */
1462 void dissociate_lease (lease
)
1463 struct lease
*lease
;
1465 struct lease
*lt
= (struct lease
*)0;
1467 if (!lease_copy (<
, lease
, MDL
))
1470 #if defined (FAILOVER_PROTOCOL)
1471 if (lease
-> pool
&& lease
-> pool
-> failover_peer
) {
1472 lt
-> next_binding_state
= FTS_RESET
;
1474 lt
-> next_binding_state
= FTS_FREE
;
1477 lt
-> next_binding_state
= FTS_FREE
;
1479 lt
-> ends
= cur_time
; /* XXX */
1480 lt
-> hardware_addr
.hlen
= 0;
1481 if (lt
-> uid
&& lt
-> uid
!= lt
-> uid_buf
)
1482 dfree (lt
-> uid
, MDL
);
1483 lt
-> uid
= (unsigned char *)0;
1486 supersede_lease (lease
, lt
, 1, 1, 1);
1487 lease_dereference (<
, MDL
);
1490 /* Timer called when a lease in a particular pool expires. */
1491 void pool_timer (vpool
)
1495 struct lease
*lt
= (struct lease
*)0;
1496 struct lease
*next
= (struct lease
*)0;
1497 struct lease
*lease
= (struct lease
*)0;
1498 struct lease
**lptr
[5];
1499 TIME next_expiry
= MAX_TIME
;
1502 pool
= (struct pool
*)vpool
;
1504 #define FREE_LEASES 0
1505 lptr
[FREE_LEASES
] = &pool
-> free
;
1506 #define ACTIVE_LEASES 1
1507 lptr
[ACTIVE_LEASES
] = &pool
-> active
;
1508 #define EXPIRED_LEASES 2
1509 lptr
[EXPIRED_LEASES
] = &pool
-> expired
;
1510 #define ABANDONED_LEASES 3
1511 lptr
[ABANDONED_LEASES
] = &pool
-> abandoned
;
1512 #define BACKUP_LEASES 4
1513 lptr
[BACKUP_LEASES
] = &pool
-> backup
;
1515 for (i
= FREE_LEASES
; i
<= BACKUP_LEASES
; i
++) {
1516 /* If there's nothing on the queue, skip it. */
1520 #if defined (FAILOVER_PROTOCOL)
1521 if (pool
-> failover_peer
&&
1522 pool
-> failover_peer
-> me
.state
!= partner_down
) {
1523 /* The secondary can't remove a lease from the
1524 active state except in partner_down. */
1525 if (i
== ACTIVE_LEASES
&&
1526 pool
-> failover_peer
-> i_am
== secondary
)
1528 /* Leases in an expired state don't move to
1529 free because of a timeout unless we're in
1531 if (i
== EXPIRED_LEASES
)
1535 lease_reference (&lease
, *(lptr
[i
]), MDL
);
1538 /* Remember the next lease in the list. */
1540 lease_dereference (&next
, MDL
);
1542 lease_reference (&next
, lease
-> next
, MDL
);
1544 /* If we've run out of things to expire on this list,
1546 if (lease
-> sort_time
> cur_time
) {
1547 if (lease
-> sort_time
< next_expiry
)
1548 next_expiry
= lease
-> sort_time
;
1552 /* If there is a pending state change, and
1553 this lease has gotten to the time when the
1554 state change should happen, just call
1555 supersede_lease on it to make the change
1557 if (lease
-> next_binding_state
!=
1558 lease
-> binding_state
)
1559 supersede_lease (lease
,
1560 (struct lease
*)0, 1, 1, 1);
1562 lease_dereference (&lease
, MDL
);
1564 lease_reference (&lease
, next
, MDL
);
1567 lease_dereference (&next
, MDL
);
1569 lease_dereference (&lease
, MDL
);
1571 if (next_expiry
!= MAX_TIME
) {
1572 pool
-> next_event_time
= next_expiry
;
1573 add_timeout (pool
-> next_event_time
, pool_timer
, pool
,
1574 (tvref_t
)pool_reference
,
1575 (tvunref_t
)pool_dereference
);
1577 pool
-> next_event_time
= MIN_TIME
;
1581 /* Locate the lease associated with a given IP address... */
1583 int find_lease_by_ip_addr (struct lease
**lp
, struct iaddr addr
,
1584 const char *file
, int line
)
1586 return lease_hash_lookup (lp
, lease_ip_addr_hash
,
1587 addr
.iabuf
, addr
.len
, file
, line
);
1590 int find_lease_by_uid (struct lease
**lp
, const unsigned char *uid
,
1591 unsigned len
, const char *file
, int line
)
1595 return lease_hash_lookup (lp
, lease_uid_hash
, uid
, len
, file
, line
);
1598 int find_lease_by_hw_addr (struct lease
**lp
,
1599 const unsigned char *hwaddr
, unsigned hwlen
,
1600 const char *file
, int line
)
1604 return lease_hash_lookup (lp
, lease_hw_addr_hash
,
1605 hwaddr
, hwlen
, file
, line
);
1608 /* Add the specified lease to the uid hash. */
1610 void uid_hash_add (lease
)
1611 struct lease
*lease
;
1613 struct lease
*head
= (struct lease
*)0;
1614 struct lease
*next
= (struct lease
*)0;
1617 /* If it's not in the hash, just add it. */
1618 if (!find_lease_by_uid (&head
, lease
-> uid
, lease
-> uid_len
, MDL
))
1619 lease_hash_add (lease_uid_hash
, lease
-> uid
,
1620 lease
-> uid_len
, lease
, MDL
);
1622 /* Otherwise, attach it to the end of the list. */
1623 while (head
-> n_uid
) {
1624 lease_reference (&next
, head
-> n_uid
, MDL
);
1625 lease_dereference (&head
, MDL
);
1626 lease_reference (&head
, next
, MDL
);
1627 lease_dereference (&next
, MDL
);
1629 lease_reference (&head
-> n_uid
, lease
, MDL
);
1630 lease_dereference (&head
, MDL
);
1634 /* Delete the specified lease from the uid hash. */
1636 void uid_hash_delete (lease
)
1637 struct lease
*lease
;
1639 struct lease
*head
= (struct lease
*)0;
1642 /* If it's not in the hash, we have no work to do. */
1643 if (!find_lease_by_uid (&head
, lease
-> uid
, lease
-> uid_len
, MDL
)) {
1645 lease_dereference (&lease
-> n_uid
, MDL
);
1649 /* If the lease we're freeing is at the head of the list,
1650 remove the hash table entry and add a new one with the
1651 next lease on the list (if there is one). */
1652 if (head
== lease
) {
1653 lease_hash_delete (lease_uid_hash
,
1654 lease
-> uid
, lease
-> uid_len
, MDL
);
1655 if (lease
-> n_uid
) {
1656 lease_hash_add (lease_uid_hash
,
1657 lease
-> n_uid
-> uid
,
1658 lease
-> n_uid
-> uid_len
,
1659 lease
-> n_uid
, MDL
);
1660 lease_dereference (&lease
-> n_uid
, MDL
);
1663 /* Otherwise, look for the lease in the list of leases
1664 attached to the hash table entry, and remove it if
1666 for (scan
= head
; scan
-> n_uid
; scan
= scan
-> n_uid
) {
1667 if (scan
-> n_uid
== lease
) {
1668 lease_dereference (&scan
-> n_uid
, MDL
);
1669 if (lease
-> n_uid
) {
1670 lease_reference (&scan
-> n_uid
,
1671 lease
-> n_uid
, MDL
);
1672 lease_dereference (&lease
-> n_uid
,
1679 lease_dereference (&head
, MDL
);
1682 /* Add the specified lease to the hardware address hash. */
1684 void hw_hash_add (lease
)
1685 struct lease
*lease
;
1687 struct lease
*head
= (struct lease
*)0;
1688 struct lease
*next
= (struct lease
*)0;
1690 /* If it's not in the hash, just add it. */
1691 if (!find_lease_by_hw_addr (&head
, lease
-> hardware_addr
.hbuf
,
1692 lease
-> hardware_addr
.hlen
, MDL
))
1693 lease_hash_add (lease_hw_addr_hash
,
1694 lease
-> hardware_addr
.hbuf
,
1695 lease
-> hardware_addr
.hlen
,
1698 /* Otherwise, attach it to the end of the list. */
1699 while (head
-> n_hw
) {
1700 lease_reference (&next
, head
-> n_hw
, MDL
);
1701 lease_dereference (&head
, MDL
);
1702 lease_reference (&head
, next
, MDL
);
1703 lease_dereference (&next
, MDL
);
1706 lease_reference (&head
-> n_hw
, lease
, MDL
);
1707 lease_dereference (&head
, MDL
);
1711 /* Delete the specified lease from the hardware address hash. */
1713 void hw_hash_delete (lease
)
1714 struct lease
*lease
;
1716 struct lease
*head
= (struct lease
*)0;
1717 struct lease
*next
= (struct lease
*)0;
1719 /* If it's not in the hash, we have no work to do. */
1720 if (!find_lease_by_hw_addr (&head
, lease
-> hardware_addr
.hbuf
,
1721 lease
-> hardware_addr
.hlen
, MDL
)) {
1723 lease_dereference (&lease
-> n_hw
, MDL
);
1727 /* If the lease we're freeing is at the head of the list,
1728 remove the hash table entry and add a new one with the
1729 next lease on the list (if there is one). */
1730 if (head
== lease
) {
1731 lease_hash_delete (lease_hw_addr_hash
,
1732 lease
-> hardware_addr
.hbuf
,
1733 lease
-> hardware_addr
.hlen
, MDL
);
1734 if (lease
-> n_hw
) {
1735 lease_hash_add (lease_hw_addr_hash
,
1736 lease
-> n_hw
-> hardware_addr
.hbuf
,
1737 lease
-> n_hw
-> hardware_addr
.hlen
,
1738 lease
-> n_hw
, MDL
);
1739 lease_dereference (&lease
-> n_hw
, MDL
);
1742 /* Otherwise, look for the lease in the list of leases
1743 attached to the hash table entry, and remove it if
1745 while (head
-> n_hw
) {
1746 if (head
-> n_hw
== lease
) {
1747 lease_dereference (&head
-> n_hw
, MDL
);
1748 if (lease
-> n_hw
) {
1749 lease_reference (&head
-> n_hw
,
1750 lease
-> n_hw
, MDL
);
1751 lease_dereference (&lease
-> n_hw
,
1756 lease_reference (&next
, head
-> n_hw
, MDL
);
1757 lease_dereference (&head
, MDL
);
1758 lease_reference (&head
, next
, MDL
);
1759 lease_dereference (&next
, MDL
);
1763 lease_dereference (&head
, MDL
);
1766 /* Write all interesting leases to permanent storage. */
1768 void write_leases ()
1771 struct shared_network
*s
;
1773 struct host_decl
*hp
;
1774 struct group_object
*gp
;
1775 struct hash_bucket
*hb
;
1777 struct collection
*colp
;
1780 struct lease
**lptr
[5];
1782 /* write all the dynamically-created class declarations. */
1783 if (collections
->classes
) {
1785 for (colp
= collections
; colp
; colp
= colp
->next
) {
1786 for (cp
= colp
->classes
; cp
; cp
= cp
->nic
) {
1787 write_named_billing_class(cp
->name
,
1793 /* XXXJAB this number doesn't include subclasses... */
1794 log_info ("Wrote %d class decls to leases file.", num_written
);
1798 /* Write all the dynamically-created group declarations. */
1799 if (group_name_hash
) {
1801 for (i
= 0; i
< group_name_hash
-> hash_count
; i
++) {
1802 for (hb
= group_name_hash
-> buckets
[i
];
1803 hb
; hb
= hb
-> next
) {
1804 gp
= (struct group_object
*)hb
-> value
;
1805 if ((gp
-> flags
& GROUP_OBJECT_DYNAMIC
) ||
1806 ((gp
-> flags
& GROUP_OBJECT_STATIC
) &&
1807 (gp
-> flags
& GROUP_OBJECT_DELETED
))) {
1813 log_info ("Wrote %d group decls to leases file.", num_written
);
1816 /* Write all the deleted host declarations. */
1817 if (host_name_hash
) {
1819 for (i
= 0; i
< host_name_hash
-> hash_count
; i
++) {
1820 for (hb
= host_name_hash
-> buckets
[i
];
1821 hb
; hb
= hb
-> next
) {
1822 hp
= (struct host_decl
*)hb
-> value
;
1823 if (((hp
-> flags
& HOST_DECL_STATIC
) &&
1824 (hp
-> flags
& HOST_DECL_DELETED
))) {
1830 log_info ("Wrote %d deleted host decls to leases file.",
1834 /* Write all the new, dynamic host declarations. */
1835 if (host_name_hash
) {
1837 for (i
= 0; i
< host_name_hash
-> hash_count
; i
++) {
1838 for (hb
= host_name_hash
-> buckets
[i
];
1839 hb
; hb
= hb
-> next
) {
1840 hp
= (struct host_decl
*)hb
-> value
;
1841 if ((hp
-> flags
& HOST_DECL_DYNAMIC
)) {
1847 log_info ("Wrote %d new dynamic host decls to leases file.",
1851 #if defined (FAILOVER_PROTOCOL)
1852 /* Write all the failover states. */
1853 dhcp_failover_write_all_states ();
1856 /* Write all the leases. */
1858 for (s
= shared_networks
; s
; s
= s
-> next
) {
1859 for (p
= s
-> pools
; p
; p
= p
-> next
) {
1860 lptr
[FREE_LEASES
] = &p
-> free
;
1861 lptr
[ACTIVE_LEASES
] = &p
-> active
;
1862 lptr
[EXPIRED_LEASES
] = &p
-> expired
;
1863 lptr
[ABANDONED_LEASES
] = &p
-> abandoned
;
1864 lptr
[BACKUP_LEASES
] = &p
-> backup
;
1866 for (i
= FREE_LEASES
; i
<= BACKUP_LEASES
; i
++) {
1867 for (l
= *(lptr
[i
]); l
; l
= l
-> next
) {
1868 if (l
-> hardware_addr
.hlen
||
1870 (l
-> binding_state
!= FTS_FREE
)) {
1871 if (!write_lease (l
))
1872 log_fatal ("Can't rewrite lease database");
1879 log_info ("Wrote %d leases to leases file.", num_written
);
1880 if (!commit_leases ())
1881 log_fatal ("Can't commit leases to new database: %m");
1884 int lease_enqueue (struct lease
*comp
)
1886 struct lease
**lq
, *prev
, *lp
;
1888 /* No queue to put it on? */
1892 /* Figure out which queue it's going to. */
1893 switch (comp
-> binding_state
) {
1895 lq
= &comp
-> pool
-> free
;
1896 comp
-> pool
-> free_leases
++;
1897 comp
-> sort_time
= comp
-> ends
;
1903 lq
= &comp
-> pool
-> active
;
1904 comp
-> sort_time
= comp
-> ends
;
1910 lq
= &comp
-> pool
-> expired
;
1911 comp
-> sort_time
= comp
-> ends
;
1916 lq
= &comp
-> pool
-> abandoned
;
1917 comp
-> sort_time
= comp
-> ends
;
1921 lq
= &comp
-> pool
-> backup
;
1922 comp
-> pool
-> backup_leases
++;
1923 comp
-> sort_time
= comp
-> ends
;
1927 log_error ("Lease with bogus binding state: %d",
1928 comp
-> binding_state
);
1929 #if defined (BINDING_STATE_DEBUG)
1935 /* Insertion sort the lease onto the appropriate queue. */
1936 prev
= (struct lease
*)0;
1937 for (lp
= *lq
; lp
; lp
= lp
-> next
) {
1938 if (lp
-> sort_time
>= comp
-> sort_time
)
1944 lease_reference (&comp
-> next
, prev
-> next
, MDL
);
1945 lease_dereference (&prev
-> next
, MDL
);
1947 lease_reference (&prev
-> next
, comp
, MDL
);
1950 lease_reference (&comp
-> next
, *lq
, MDL
);
1951 lease_dereference (lq
, MDL
);
1953 lease_reference (lq
, comp
, MDL
);
1958 /* For a given lease, sort it onto the right list in its pool and put it
1959 in each appropriate hash, understanding that it's already by definition
1960 in lease_ip_addr_hash. */
1962 void lease_instantiate (const unsigned char *val
, unsigned len
,
1963 struct lease
*lease
)
1965 struct class *class;
1966 /* XXX If the lease doesn't have a pool at this point, it's an
1967 XXX orphan, which we *should* keep around until it expires,
1968 XXX but which right now we just forget. */
1969 if (!lease
-> pool
) {
1970 lease_hash_delete (lease_ip_addr_hash
,
1971 lease
-> ip_addr
.iabuf
,
1972 lease
-> ip_addr
.len
, MDL
);
1976 /* Put the lease on the right queue. */
1977 lease_enqueue (lease
);
1979 /* Record the lease in the uid hash if possible. */
1981 uid_hash_add (lease
);
1984 /* Record it in the hardware address hash if possible. */
1985 if (lease
-> hardware_addr
.hlen
) {
1986 hw_hash_add (lease
);
1989 /* If the lease has a billing class, set up the billing. */
1990 if (lease
-> billing_class
) {
1991 class = (struct class *)0;
1992 class_reference (&class, lease
-> billing_class
, MDL
);
1993 class_dereference (&lease
-> billing_class
, MDL
);
1994 /* If the lease is available for allocation, the billing
1995 is invalid, so we don't keep it. */
1996 if (lease
-> binding_state
== FTS_ACTIVE
||
1997 lease
-> binding_state
== FTS_EXPIRED
||
1998 lease
-> binding_state
== FTS_RELEASED
||
1999 lease
-> binding_state
== FTS_RESET
||
2000 lease
-> binding_state
== FTS_RESERVED
||
2001 lease
-> binding_state
== FTS_BOOTP
)
2002 bill_class (lease
, class);
2003 class_dereference (&class, MDL
);
2008 /* Run expiry events on every pool. This is called on startup so that
2009 any expiry events that occurred after the server stopped and before it
2010 was restarted can be run. At the same time, if failover support is
2011 compiled in, we compute the balance of leases for the pool. */
2013 void expire_all_pools ()
2015 struct shared_network
*s
;
2017 struct hash_bucket
*hb
;
2020 struct lease
**lptr
[5];
2022 /* First, go over the hash list and actually put all the leases
2023 on the appropriate lists. */
2024 lease_hash_foreach (lease_ip_addr_hash
, lease_instantiate
);
2026 /* Loop through each pool in each shared network and call the
2027 expiry routine on the pool. */
2028 for (s
= shared_networks
; s
; s
= s
-> next
) {
2029 for (p
= s
-> pools
; p
; p
= p
-> next
) {
2032 p
-> lease_count
= 0;
2033 p
-> free_leases
= 0;
2034 p
-> backup_leases
= 0;
2036 lptr
[FREE_LEASES
] = &p
-> free
;
2037 lptr
[ACTIVE_LEASES
] = &p
-> active
;
2038 lptr
[EXPIRED_LEASES
] = &p
-> expired
;
2039 lptr
[ABANDONED_LEASES
] = &p
-> abandoned
;
2040 lptr
[BACKUP_LEASES
] = &p
-> backup
;
2042 for (i
= FREE_LEASES
; i
<= BACKUP_LEASES
; i
++) {
2043 for (l
= *(lptr
[i
]); l
; l
= l
-> next
) {
2045 if (l
-> ends
<= cur_time
) {
2046 if (l
-> binding_state
== FTS_FREE
)
2048 else if (l
-> binding_state
== FTS_BACKUP
)
2049 p
-> backup_leases
++;
2051 #if defined (FAILOVER_PROTOCOL)
2052 if (p
-> failover_peer
&&
2053 l
-> tstp
> l
-> tsfp
&&
2054 !(l
-> flags
& ON_UPDATE_QUEUE
))
2055 dhcp_failover_queue_update (l
, 1);
2063 void dump_subnets ()
2066 struct shared_network
*s
;
2069 struct lease
**lptr
[5];
2072 log_info ("Subnets:");
2073 for (n
= subnets
; n
; n
= n
-> next_subnet
) {
2074 log_debug (" Subnet %s", piaddr (n
-> net
));
2075 log_debug (" netmask %s",
2076 piaddr (n
-> netmask
));
2078 log_info ("Shared networks:");
2079 for (s
= shared_networks
; s
; s
= s
-> next
) {
2080 log_info (" %s", s
-> name
);
2081 for (p
= s
-> pools
; p
; p
= p
-> next
) {
2082 lptr
[FREE_LEASES
] = &p
-> free
;
2083 lptr
[ACTIVE_LEASES
] = &p
-> active
;
2084 lptr
[EXPIRED_LEASES
] = &p
-> expired
;
2085 lptr
[ABANDONED_LEASES
] = &p
-> abandoned
;
2086 lptr
[BACKUP_LEASES
] = &p
-> backup
;
2088 for (i
= FREE_LEASES
; i
<= BACKUP_LEASES
; i
++) {
2089 for (l
= *(lptr
[i
]); l
; l
= l
-> next
) {
2097 HASH_FUNCTIONS (lease
, const unsigned char *, struct lease
)
2098 HASH_FUNCTIONS (host
, const unsigned char *, struct host_decl
)
2099 HASH_FUNCTIONS (class, const char *, struct class)