ISC DHCP  4.4.1
A reference DHCPv4 and DHCPv6 implementation
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
mdb.c
Go to the documentation of this file.
1 /* mdb.c
2 
3  Server-specific in-memory database support. */
4 
5 /*
6  * Copyright (c) 2004-2017 by Internet Systems Consortium, Inc. ("ISC")
7  * Copyright (c) 1996-2003 by Internet Software Consortium
8  *
9  * This Source Code Form is subject to the terms of the Mozilla Public
10  * License, v. 2.0. If a copy of the MPL was not distributed with this
11  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
12  *
13  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
14  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
16  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
18  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
19  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20  *
21  * Internet Systems Consortium, Inc.
22  * 950 Charter Street
23  * Redwood City, CA 94063
24  * <info@isc.org>
25  * https://www.isc.org/
26  *
27  */
28 
29 #include "dhcpd.h"
30 #include "omapip/hash.h"
31 
32 struct subnet *subnets;
40 
41 /*
42  * We allow users to specify any option as a host identifier.
43  *
44  * Any host is uniquely identified by the combination of
45  * option type & option data.
46  *
47  * We expect people will only use a few types of options as host
48  * identifier. Because of this, we store a list with an entry for
49  * each option type. Each of these has a hash table, which contains
50  * hash of the option data.
51  *
52  * For v6 we also include a relay count - this specifies which
53  * relay to check for the requested option. As each different
54  * value of relays creates a new instance admins should use the
55  * same value across each option for all host-identifers.
56  * A value of 0 indicates that we aren't doing relay options
57  * and should simply look in the current option list.
58  */
59 typedef struct host_id_info {
60  struct option *option;
62  int relays;
63  struct host_id_info *next;
65 
66 static host_id_info_t *host_id_info = NULL;
67 
69 
71 
72 isc_result_t enter_class(cd, dynamicp, commit)
73  struct class *cd;
74  int dynamicp;
75  int commit;
76 {
77  if (!collections -> classes) {
78  /* A subclass with no parent is invalid. */
79  if (cd->name == NULL)
80  return DHCP_R_INVALIDARG;
81 
82  class_reference (&collections -> classes, cd, MDL);
83  } else if (cd->name != NULL) { /* regular class */
84  struct class *c = 0;
85 
86  if (find_class(&c, cd->name, MDL) != ISC_R_NOTFOUND) {
87  class_dereference(&c, MDL);
88  return ISC_R_EXISTS;
89  }
90 
91  /* Find the tail. */
92  for (c = collections -> classes;
93  c -> nic; c = c -> nic)
94  /* nothing */ ;
95  class_reference (&c -> nic, cd, MDL);
96  }
97 
98  if (dynamicp && commit) {
99  const char *name = cd->name;
100 
101  if (name == NULL) {
102  name = cd->superclass->name;
103  }
104 
105  write_named_billing_class ((const unsigned char *)name, 0, cd);
106  if (!commit_leases ())
107  return ISC_R_IOERROR;
108  }
109 
110  return ISC_R_SUCCESS;
111 }
112 
113 
114 /* Variable to check if we're starting the server. The server will init as
115  * starting - but just to be safe start out as false to avoid triggering new
116  * special-case code
117  * XXX: There is actually a server_startup state...which is never entered...
118  */
119 #define SS_NOSYNC 1
120 #define SS_QFOLLOW 2
121 static int server_starting = 0;
122 
123 static int find_uid_statement (struct executable_statement *esp,
124  void *vp, int condp)
125 {
126  struct executable_statement **evp = vp;
127 
128  if (esp -> op == supersede_option_statement &&
129  esp -> data.option &&
130  (esp -> data.option -> option -> universe ==
131  &dhcp_universe) &&
132  (esp -> data.option -> option -> code ==
134  if (condp) {
135  log_error ("dhcp client identifier may not be %s",
136  "specified conditionally.");
137  } else if (!(*evp)) {
139  return 1;
140  } else {
141  log_error ("only one dhcp client identifier may be %s",
142  "specified");
143  }
144  }
145  return 0;
146 }
147 
148 
149 static host_id_info_t *
150 find_host_id_info(unsigned int option_code, int relays) {
151  host_id_info_t *p;
152 
153  for (p = host_id_info; p != NULL; p = p->next) {
154  if ((p->option->code == option_code) &&
155  (p->relays == relays)) {
156  break;
157  }
158  }
159  return p;
160 }
161 
162 /* Debugging code */
163 #if 0
164 isc_result_t
165 print_host(const void *name, unsigned len, void *value) {
166  struct host_decl *h;
167  printf("--------------\n");
168  printf("name:'%s'\n", print_hex_1(len, name, 60));
169  printf("len:%d\n", len);
170  h = (struct host_decl *)value;
171  printf("host @%p is '%s'\n", h, h->name);
172  return ISC_R_SUCCESS;
173 }
174 
175 void
176 hash_print_hosts(struct hash_table *h) {
177  hash_foreach(h, print_host);
178  printf("--------------\n");
179 }
180 #endif /* 0 */
181 
182 void
183 change_host_uid(struct host_decl *host, const char *uid, int len) {
184  /* XXX: should consolidate this type of code throughout */
185  if (host_uid_hash == NULL) {
186  if (!host_new_hash(&host_uid_hash, HOST_HASH_SIZE, MDL)) {
187  log_fatal("Can't allocate host/uid hash");
188  }
189  }
190 
191  /*
192  * Remove the old entry, if one exists.
193  */
194  if (host->client_identifier.data != NULL) {
195  host_hash_delete(host_uid_hash,
196  host->client_identifier.data,
197  host->client_identifier.len,
198  MDL);
200  }
201 
202  /*
203  * Set our new value.
204  */
205  memset(&host->client_identifier, 0, sizeof(host->client_identifier));
206  host->client_identifier.len = len;
207  if (!buffer_allocate(&host->client_identifier.buffer, len, MDL)) {
208  log_fatal("Can't allocate uid buffer");
209  }
211  memcpy((char *)host->client_identifier.data, uid, len);
212 
213  /*
214  * And add to hash.
215  */
216  host_hash_add(host_uid_hash, host->client_identifier.data,
217  host->client_identifier.len, host, MDL);
218 }
219 
220 isc_result_t enter_host (hd, dynamicp, commit)
221  struct host_decl *hd;
222  int dynamicp;
223  int commit;
224 {
225  struct host_decl *hp = (struct host_decl *)0;
226  struct host_decl *np = (struct host_decl *)0;
227  struct executable_statement *esp;
228  host_id_info_t *h_id_info;
229 
230  if (!host_name_hash) {
231  if (!host_new_hash(&host_name_hash, HOST_HASH_SIZE, MDL))
232  log_fatal ("Can't allocate host name hash");
233  host_hash_add (host_name_hash,
234  (unsigned char *)hd -> name,
235  strlen (hd -> name), hd, MDL);
236  } else {
237  host_hash_lookup (&hp, host_name_hash,
238  (unsigned char *)hd -> name,
239  strlen (hd -> name), MDL);
240 
241  /* If it's deleted, we can supersede it. */
242  if (hp && (hp -> flags & HOST_DECL_DELETED)) {
243  host_hash_delete (host_name_hash,
244  (unsigned char *)hd -> name,
245  strlen (hd -> name), MDL);
246  /* If the old entry wasn't dynamic, then we
247  always have to keep the deletion. */
248  if (hp -> flags & HOST_DECL_STATIC) {
249  hd -> flags |= HOST_DECL_STATIC;
250  }
251  host_dereference (&hp, MDL);
252  }
253 
254  /* If we are updating an existing host declaration, we
255  can just delete it and add it again. */
256  if (hp && hp == hd) {
257  host_dereference (&hp, MDL);
258  delete_host (hd, 0);
259  if (!write_host (hd))
260  return ISC_R_IOERROR;
261  hd -> flags &= ~HOST_DECL_DELETED;
262  }
263 
264  /* If there isn't already a host decl matching this
265  address, add it to the hash table. */
266  if (!hp) {
267  host_hash_add (host_name_hash,
268  (unsigned char *)hd -> name,
269  strlen (hd -> name), hd, MDL);
270  } else {
271  /* XXX actually, we have to delete the old one
272  XXX carefully and replace it. Not done yet. */
273  host_dereference (&hp, MDL);
274  return ISC_R_EXISTS;
275  }
276  }
277 
278  if (hd -> n_ipaddr)
279  host_dereference (&hd -> n_ipaddr, MDL);
280 
281  if (!hd -> type)
282  hd -> type = dhcp_type_host;
283 
284  if (hd -> interface.hlen) {
285  if (!host_hw_addr_hash) {
286  if (!host_new_hash(&host_hw_addr_hash,
288  log_fatal ("Can't allocate host/hw hash");
289  } else {
290  /* If there isn't already a host decl matching this
291  address, add it to the hash table. */
292  host_hash_lookup (&hp, host_hw_addr_hash,
293  hd -> interface.hbuf,
294  hd -> interface.hlen, MDL);
295  }
296  if (!hp)
297  host_hash_add (host_hw_addr_hash, hd -> interface.hbuf,
298  hd -> interface.hlen, hd, MDL);
299  else {
300  /* If there was already a host declaration for
301  this hardware address, add this one to the
302  end of the list. */
303  for (np = hp; np -> n_ipaddr; np = np -> n_ipaddr)
304  ;
305  host_reference (&np -> n_ipaddr, hd, MDL);
306  host_dereference (&hp, MDL);
307  }
308  }
309 
310  /* See if there's a statement that sets the client identifier.
311  This is a kludge - the client identifier really shouldn't be
312  set with an executable statement. */
313  esp = NULL;
314  if (executable_statement_foreach (hd->group->statements,
315  find_uid_statement, &esp, 0)) {
316  (void) evaluate_option_cache (&hd->client_identifier,
317  NULL, NULL, NULL, NULL, NULL,
318  &global_scope,
319  esp->data.option, MDL);
320  }
321 
322  /* If we got a client identifier, hash this entry by
323  client identifier. */
324  if (hd -> client_identifier.len) {
325  /* If there's no uid hash, make one; otherwise, see if
326  there's already an entry in the hash for this host. */
327  if (!host_uid_hash) {
328  if (!host_new_hash(&host_uid_hash,
330  log_fatal ("Can't allocate host/uid hash");
331 
332  host_hash_add (host_uid_hash,
333  hd -> client_identifier.data,
334  hd -> client_identifier.len,
335  hd, MDL);
336  } else {
337  /* If there's already a host declaration for this
338  client identifier, add this one to the end of the
339  list. Otherwise, add it to the hash table. */
340  if (host_hash_lookup (&hp, host_uid_hash,
341  hd -> client_identifier.data,
342  hd -> client_identifier.len,
343  MDL)) {
344  /* Don't link it in twice... */
345  if (!np) {
346  for (np = hp; np -> n_ipaddr;
347  np = np -> n_ipaddr) {
348  if (hd == np)
349  break;
350  }
351  if (hd != np)
352  host_reference (&np -> n_ipaddr,
353  hd, MDL);
354  }
355  host_dereference (&hp, MDL);
356  } else {
357  host_hash_add (host_uid_hash,
358  hd -> client_identifier.data,
359  hd -> client_identifier.len,
360  hd, MDL);
361  }
362  }
363  }
364 
365 
366  /*
367  * If we use an option as our host identifier, record it here.
368  */
369  if (hd->host_id_option != NULL) {
370  /*
371  * Look for the host identifier information for this option,
372  * and create a new entry if there is none.
373  */
374  h_id_info = find_host_id_info(hd->host_id_option->code,
375  hd->relays);
376  if (h_id_info == NULL) {
377  h_id_info = dmalloc(sizeof(*h_id_info), MDL);
378  if (h_id_info == NULL) {
379  log_fatal("No memory for host-identifier "
380  "option information.");
381  }
382  option_reference(&h_id_info->option,
383  hd->host_id_option, MDL);
384  if (!host_new_hash(&h_id_info->values_hash,
385  HOST_HASH_SIZE, MDL)) {
386  log_fatal("No memory for host-identifier "
387  "option hash.");
388  }
389  h_id_info->relays = hd->relays;
390  h_id_info->next = host_id_info;
391  host_id_info = h_id_info;
392  }
393 
394  if (host_hash_lookup(&hp, h_id_info->values_hash,
395  hd->host_id.data, hd->host_id.len, MDL)) {
396  /*
397  * If this option is already present, then add
398  * this host to the list in n_ipaddr, unless
399  * we have already done so previously.
400  *
401  * XXXSK: This seems scary to me, but I don't
402  * fully understand how these are used.
403  * Shouldn't there be multiple lists, or
404  * maybe we should just forbid duplicates?
405  */
406  if (np == NULL) {
407  np = hp;
408  while (np->n_ipaddr != NULL) {
409  np = np->n_ipaddr;
410  }
411  if (hd != np) {
412  host_reference(&np->n_ipaddr, hd, MDL);
413  }
414  }
415  host_dereference(&hp, MDL);
416  } else {
417  host_hash_add(h_id_info->values_hash,
418  hd->host_id.data,
419  hd->host_id.len,
420  hd, MDL);
421  }
422  }
423 
424  if (dynamicp && commit) {
425  if (!write_host (hd))
426  return ISC_R_IOERROR;
427  if (!commit_leases ())
428  return ISC_R_IOERROR;
429  }
430 
431  return ISC_R_SUCCESS;
432 }
433 
434 
435 isc_result_t delete_class (cp, commit)
436  struct class *cp;
437  int commit;
438 {
439  cp->flags |= CLASS_DECL_DELETED;
440 
441  /* do the write first as we won't be leaving it in any data
442  structures, unlike the host objects */
443 
444  if (commit) {
445  write_named_billing_class ((unsigned char *)cp->name, 0, cp);
446  if (!commit_leases ())
447  return ISC_R_IOERROR;
448  }
449 
450  /*
451  * If this is a subclass remove it from the class's hash table
452  */
453  if (cp->superclass) {
454  class_hash_delete(cp->superclass->hash,
455  (const char *)cp->hash_string.data,
456  cp->hash_string.len,
457  MDL);
458  }
459 
460  /* remove from collections */
461  unlink_class(&cp);
462 
463  return ISC_R_SUCCESS;
464 }
465 
466 
467 isc_result_t delete_host (hd, commit)
468  struct host_decl *hd;
469  int commit;
470 {
471  struct host_decl *hp = (struct host_decl *)0;
472  struct host_decl *np = (struct host_decl *)0;
473  struct host_decl *foo;
474  int hw_head = 0, uid_head = 1;
475 
476  /* Don't need to do it twice. */
477  if (hd -> flags & HOST_DECL_DELETED)
478  return ISC_R_SUCCESS;
479 
480  /* But we do need to do it once! :') */
481  hd -> flags |= HOST_DECL_DELETED;
482 
483  if (hd -> interface.hlen) {
484  if (host_hw_addr_hash) {
485  if (host_hash_lookup (&hp, host_hw_addr_hash,
486  hd -> interface.hbuf,
487  hd -> interface.hlen, MDL)) {
488  if (hp == hd) {
489  host_hash_delete (host_hw_addr_hash,
490  hd -> interface.hbuf,
491  hd -> interface.hlen, MDL);
492  hw_head = 1;
493  } else {
494  np = (struct host_decl *)0;
495  foo = (struct host_decl *)0;
496  host_reference (&foo, hp, MDL);
497  while (foo) {
498  if (foo == hd)
499  break;
500  if (np)
501  host_dereference (&np, MDL);
502  host_reference (&np, foo, MDL);
503  host_dereference (&foo, MDL);
504  if (np -> n_ipaddr)
505  host_reference (&foo, np -> n_ipaddr, MDL);
506  }
507 
508  if (foo) {
509  host_dereference (&np -> n_ipaddr, MDL);
510  if (hd -> n_ipaddr)
511  host_reference (&np -> n_ipaddr,
512  hd -> n_ipaddr, MDL);
513  host_dereference (&foo, MDL);
514  }
515  if (np)
516  host_dereference (&np, MDL);
517  }
518  host_dereference (&hp, MDL);
519  }
520  }
521  }
522 
523  /* If we got a client identifier, hash this entry by
524  client identifier. */
525  if (hd -> client_identifier.len) {
526  if (host_uid_hash) {
527  if (host_hash_lookup (&hp, host_uid_hash,
528  hd -> client_identifier.data,
529  hd -> client_identifier.len, MDL)) {
530  if (hp == hd) {
531  host_hash_delete (host_uid_hash,
532  hd -> client_identifier.data,
533  hd -> client_identifier.len, MDL);
534  uid_head = 1;
535  } else {
536  np = (struct host_decl *)0;
537  foo = (struct host_decl *)0;
538  host_reference (&foo, hp, MDL);
539  while (foo) {
540  if (foo == hd)
541  break;
542  if (np)
543  host_dereference (&np, MDL);
544  host_reference (&np, foo, MDL);
545  host_dereference (&foo, MDL);
546  if (np -> n_ipaddr)
547  host_reference (&foo, np -> n_ipaddr, MDL);
548  }
549 
550  if (foo) {
551  host_dereference (&np -> n_ipaddr, MDL);
552  if (hd -> n_ipaddr)
553  host_reference (&np -> n_ipaddr,
554  hd -> n_ipaddr, MDL);
555  host_dereference (&foo, MDL);
556  }
557  if (np)
558  host_dereference (&np, MDL);
559  }
560  host_dereference (&hp, MDL);
561  }
562  }
563  }
564 
565  if (hd->host_id_option != NULL) {
566  option_dereference(&hd->host_id_option, MDL);
567  data_string_forget(&hd->host_id, MDL);
568  }
569 
570  if (hd -> n_ipaddr) {
571  if (uid_head && hd -> n_ipaddr -> client_identifier.len) {
572  host_hash_add
573  (host_uid_hash,
575  hd -> n_ipaddr -> client_identifier.len,
576  hd -> n_ipaddr, MDL);
577  }
578  if (hw_head && hd -> n_ipaddr -> interface.hlen) {
579  host_hash_add (host_hw_addr_hash,
580  hd -> n_ipaddr -> interface.hbuf,
581  hd -> n_ipaddr -> interface.hlen,
582  hd -> n_ipaddr, MDL);
583  }
584  host_dereference (&hd -> n_ipaddr, MDL);
585  }
586 
587  if (host_name_hash) {
588  if (host_hash_lookup (&hp, host_name_hash,
589  (unsigned char *)hd -> name,
590  strlen (hd -> name), MDL)) {
591  if (hp == hd && !(hp -> flags & HOST_DECL_STATIC)) {
592  host_hash_delete (host_name_hash,
593  (unsigned char *)hd -> name,
594  strlen (hd -> name), MDL);
595  }
596  host_dereference (&hp, MDL);
597  }
598  }
599 
600  if (commit) {
601  if (!write_host (hd))
602  return ISC_R_IOERROR;
603  if (!commit_leases ())
604  return ISC_R_IOERROR;
605  }
606  return ISC_R_SUCCESS;
607 }
608 
609 int find_hosts_by_haddr (struct host_decl **hp, int htype,
610  const unsigned char *haddr, unsigned hlen,
611  const char *file, int line)
612 {
613  struct hardware h;
614 #if defined(LDAP_CONFIGURATION)
615  int ret;
616 
617  if ((ret = find_haddr_in_ldap (hp, htype, hlen, haddr, file, line)))
618  return ret;
619 #endif
620 
621  h.hlen = hlen + 1;
622  h.hbuf [0] = htype;
623  memcpy (&h.hbuf [1], haddr, hlen);
624 
625  return host_hash_lookup (hp, host_hw_addr_hash,
626  h.hbuf, h.hlen, file, line);
627 }
628 
629 int find_hosts_by_uid (struct host_decl **hp,
630  const unsigned char *data, unsigned len,
631  const char *file, int line)
632 {
633  return host_hash_lookup (hp, host_uid_hash, data, len, file, line);
634 }
635 
636 int
638  struct packet *packet,
639  struct option_state *opt_state,
640  const char *file, int line) {
641  host_id_info_t *p;
642  struct option_cache *oc;
643  struct data_string data;
644  int found;
645  struct packet *relay_packet;
646  struct option_state *relay_state;
647 
648 #if defined(LDAP_CONFIGURATION)
649  if ((found = find_client_in_ldap (hp, packet, opt_state, file, line)))
650  return found;
651 #endif
652 
653  for (p = host_id_info; p != NULL; p = p->next) {
654  relay_packet = packet;
655  relay_state = opt_state;
656 
657  /* If this option block is for a relay (relays != 0)
658  * and we are processing the main options and not
659  * options from the IA (packet->options == opt_state)
660  * try to find the proper relay
661  */
662  if ((p->relays != 0) && (packet->options == opt_state)) {
663  int i = p->relays;
664  while ((i != 0) &&
665  (relay_packet->dhcpv6_container_packet != NULL)) {
666  relay_packet =
667  relay_packet->dhcpv6_container_packet;
668  i--;
669  }
670  /* We wanted a specific relay but were
671  * unable to find it */
672  if ((p->relays <= MAX_V6RELAY_HOPS) && (i != 0))
673  continue;
674 
675  relay_state = relay_packet->options;
676  }
677 
678  oc = lookup_option(p->option->universe,
679  relay_state, p->option->code);
680  if (oc != NULL) {
681  memset(&data, 0, sizeof(data));
682 
683  if (!evaluate_option_cache(&data, relay_packet, NULL,
684  NULL, relay_state, NULL,
685  &global_scope, oc,
686  MDL)) {
687  log_error("Error evaluating option cache");
688  return 0;
689  }
690 
691  found = host_hash_lookup(hp, p->values_hash,
692  data.data, data.len,
693  file, line);
694 
695  data_string_forget(&data, MDL);
696 
697  if (found) {
698  return 1;
699  }
700  }
701  }
702  return 0;
703 }
704 
705 /* More than one host_decl can be returned by find_hosts_by_haddr or
706  find_hosts_by_uid, and each host_decl can have multiple addresses.
707  Loop through the list of hosts, and then for each host, through the
708  list of addresses, looking for an address that's in the same shared
709  network as the one specified. Store the matching address through
710  the addr pointer, update the host pointer to point at the host_decl
711  that matched, and return the subnet that matched. */
712 
713 int find_host_for_network (struct subnet **sp, struct host_decl **host,
714  struct iaddr *addr, struct shared_network *share)
715 {
716  int i;
717  struct iaddr ip_address;
718  struct host_decl *hp;
719  struct data_string fixed_addr;
720 
721  memset (&fixed_addr, 0, sizeof fixed_addr);
722 
723  for (hp = *host; hp; hp = hp -> n_ipaddr) {
724  if (!hp -> fixed_addr)
725  continue;
726  if (!evaluate_option_cache (&fixed_addr, (struct packet *)0,
727  (struct lease *)0,
728  (struct client_state *)0,
729  (struct option_state *)0,
730  (struct option_state *)0,
731  &global_scope,
732  hp -> fixed_addr, MDL))
733  continue;
734  for (i = 0; i < fixed_addr.len; i += 4) {
735  ip_address.len = 4;
736  memcpy (ip_address.iabuf,
737  fixed_addr.data + i, 4);
738  if (find_grouped_subnet (sp, share, ip_address, MDL)) {
739  struct host_decl *tmp = (struct host_decl *)0;
740  *addr = ip_address;
741  /* This is probably not necessary, but
742  just in case *host is the only reference
743  to that host declaration, make a temporary
744  reference so that dereferencing it doesn't
745  dereference hp out from under us. */
746  host_reference (&tmp, *host, MDL);
747  host_dereference (host, MDL);
748  host_reference (host, hp, MDL);
749  host_dereference (&tmp, MDL);
750  data_string_forget (&fixed_addr, MDL);
751  return 1;
752  }
753  }
754  data_string_forget (&fixed_addr, MDL);
755  }
756  return 0;
757 }
758 
759 void new_address_range (cfile, low, high, subnet, pool, lpchain)
760  struct parse *cfile;
761  struct iaddr low, high;
762  struct subnet *subnet;
763  struct pool *pool;
764  struct lease **lpchain;
765 {
766 #if defined(COMPACT_LEASES)
767  struct lease *address_range;
768  unsigned s;
769 #endif
770  unsigned min, max, i, num_addrs;
771  char lowbuf [16], highbuf [16], netbuf [16];
772  struct shared_network *share = subnet -> shared_network;
773  struct lease *lt = (struct lease *)0;
774 #if !defined(COMPACT_LEASES)
775  isc_result_t status;
776 #endif
777 
778  /* All subnets should have attached shared network structures. */
779  if (!share) {
780  strcpy (netbuf, piaddr (subnet -> net));
781  log_fatal ("No shared network for network %s (%s)",
782  netbuf, piaddr (subnet -> netmask));
783  }
784 
785  /* Initialize the hash table if it hasn't been done yet. */
786  if (!lease_uid_hash) {
787  if (!lease_id_new_hash(&lease_uid_hash, LEASE_HASH_SIZE, MDL))
788  log_fatal ("Can't allocate lease/uid hash");
789  }
790  if (!lease_ip_addr_hash) {
791  if (!lease_ip_new_hash(&lease_ip_addr_hash, LEASE_HASH_SIZE,
792  MDL))
793  log_fatal ("Can't allocate lease/ip hash");
794  }
795  if (!lease_hw_addr_hash) {
796  if (!lease_id_new_hash(&lease_hw_addr_hash, LEASE_HASH_SIZE,
797  MDL))
798  log_fatal ("Can't allocate lease/hw hash");
799  }
800 
801  /* Make sure that high and low addresses are in this subnet. */
802  if (!addr_eq(subnet->net, subnet_number(low, subnet->netmask))) {
803  strcpy(lowbuf, piaddr(low));
804  strcpy(netbuf, piaddr(subnet->net));
805  log_fatal("bad range, address %s not in subnet %s netmask %s",
806  lowbuf, netbuf, piaddr(subnet->netmask));
807  }
808 
809  if (!addr_eq(subnet->net, subnet_number(high, subnet->netmask))) {
810  strcpy(highbuf, piaddr(high));
811  strcpy(netbuf, piaddr(subnet->net));
812  log_fatal("bad range, address %s not in subnet %s netmask %s",
813  highbuf, netbuf, piaddr(subnet->netmask));
814  }
815 
816  /* Get the high and low host addresses... */
817  max = host_addr (high, subnet -> netmask);
818  min = host_addr (low, subnet -> netmask);
819 
820  /* Allow range to be specified high-to-low as well as low-to-high. */
821  if (min > max) {
822  max = min;
823  min = host_addr (high, subnet -> netmask);
824  }
825 
826  /* get the number of addresses we want, and add it to the pool info
827  * this value is only for use when setting up lease chains and will
828  * be overwritten when expire_all_pools is run
829  */
830  num_addrs = max - min + 1;
831 #if defined (BINARY_LEASES)
832  pool->lease_count += num_addrs;
833 #endif
834 
835  /* Get a lease structure for each address in the range. */
836 #if defined (COMPACT_LEASES)
837  s = (num_addrs + 1) * sizeof (struct lease);
838  /* Check unsigned overflow in new_leases().
839  With 304 byte lease structure (x64_86), this happens at
840  range 10.0.0.0 10.215.148.52; */
841  if (((s % sizeof (struct lease)) != 0) ||
842  ((s / sizeof (struct lease)) != (num_addrs + 1))) {
843  strcpy (lowbuf, piaddr (low));
844  strcpy (highbuf, piaddr (high));
845  parse_warn (cfile, "%s-%s is an overly large address range.",
846  lowbuf, highbuf);
847  log_fatal ("Memory overflow.");
848  }
849  address_range = new_leases (num_addrs, MDL);
850  if (!address_range) {
851  strcpy (lowbuf, piaddr (low));
852  strcpy (highbuf, piaddr (high));
853  log_fatal ("No memory for address range %s-%s.",
854  lowbuf, highbuf);
855  }
856 #endif
857 
858  /* Fill out the lease structures with some minimal information. */
859  for (i = 0; i < num_addrs; i++) {
860  struct lease *lp = (struct lease *)0;
861 #if defined (COMPACT_LEASES)
862  omapi_object_initialize ((omapi_object_t *)&address_range [i],
864  0, sizeof (struct lease), MDL);
865  lease_reference (&lp, &address_range [i], MDL);
866 #else
867  status = lease_allocate (&lp, MDL);
868  if (status != ISC_R_SUCCESS)
869  log_fatal ("No memory for lease %s: %s",
870  piaddr (ip_addr (subnet -> net,
871  subnet -> netmask,
872  i + min)),
873  isc_result_totext (status));
874 #endif
875  lp->ip_addr = ip_addr(subnet->net, subnet->netmask, i + min);
876  lp->starts = MIN_TIME;
877  lp->ends = MIN_TIME;
878  subnet_reference(&lp->subnet, subnet, MDL);
879  pool_reference(&lp->pool, pool, MDL);
880  lp->binding_state = FTS_FREE;
883  lp->flags = 0;
884 
885  /* Remember the lease in the IP address hash. */
886  if (find_lease_by_ip_addr (&lt, lp -> ip_addr, MDL)) {
887  if (lt -> pool) {
888  parse_warn (cfile,
889  "lease %s is declared twice!",
890  piaddr (lp -> ip_addr));
891  } else
892  pool_reference (&lt -> pool, pool, MDL);
893  lease_dereference (&lt, MDL);
894  } else
895  lease_ip_hash_add(lease_ip_addr_hash,
896  lp->ip_addr.iabuf, lp->ip_addr.len,
897  lp, MDL);
898  /* Put the lease on the chain for the caller. */
899  if (lpchain) {
900  if (*lpchain) {
901  lease_reference (&lp -> next, *lpchain, MDL);
902  lease_dereference (lpchain, MDL);
903  }
904  lease_reference (lpchain, lp, MDL);
905  }
906  lease_dereference (&lp, MDL);
907  }
908 }
909 
910 int find_subnet (struct subnet **sp,
911  struct iaddr addr, const char *file, int line)
912 {
913  struct subnet *rv;
914 
915  for (rv = subnets; rv; rv = rv -> next_subnet) {
916 #if defined(DHCP4o6)
917  if (addr.len != rv->netmask.len)
918  continue;
919 #endif
920  if (addr_eq (subnet_number (addr, rv -> netmask), rv -> net)) {
921  if (subnet_reference (sp, rv,
922  file, line) != ISC_R_SUCCESS)
923  return 0;
924  return 1;
925  }
926  }
927  return 0;
928 }
929 
930 int find_grouped_subnet (struct subnet **sp,
931  struct shared_network *share, struct iaddr addr,
932  const char *file, int line)
933 {
934  struct subnet *rv;
935 
936  for (rv = share -> subnets; rv; rv = rv -> next_sibling) {
937 #if defined(DHCP4o6)
938  if (addr.len != rv->netmask.len)
939  continue;
940 #endif
941  if (addr_eq (subnet_number (addr, rv -> netmask), rv -> net)) {
942  if (subnet_reference (sp, rv,
943  file, line) != ISC_R_SUCCESS)
944  return 0;
945  return 1;
946  }
947  }
948  return 0;
949 }
950 
951 /* XXX: could speed up if everyone had a prefix length */
952 int
954  const struct subnet *scan,
955  int warnp) {
956 #if defined(DHCP4o6)
957  if (subnet->net.len != scan->net.len)
958  return 0;
959 #endif
960  if (addr_eq(subnet_number(subnet->net, scan->netmask), scan->net) ||
961  addr_eq(subnet_number(scan->net, subnet->netmask), subnet->net)) {
962  char n1buf[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255")];
963  int i, j;
964  for (i = 0; i < 128; i++)
965  if (subnet->netmask.iabuf[3 - (i >> 3)]
966  & (1 << (i & 7)))
967  break;
968  for (j = 0; j < 128; j++)
969  if (scan->netmask.iabuf[3 - (j >> 3)] &
970  (1 << (j & 7)))
971  break;
972  if (warnp) {
973  strcpy(n1buf, piaddr(subnet->net));
974  log_error("Warning: subnet %s/%d overlaps subnet %s/%d",
975  n1buf, 32 - i,
976  piaddr(scan->net), 32 - j);
977  }
978  if (i < j)
979  return 1;
980  }
981  return 0;
982 }
983 
984 /* Enter a new subnet into the subnet list. */
986  struct subnet *subnet;
987 {
988  struct subnet *scan = (struct subnet *)0;
989  struct subnet *next = (struct subnet *)0;
990  struct subnet *prev = (struct subnet *)0;
991 
992  /* Check for duplicates... */
993  if (subnets)
994  subnet_reference (&next, subnets, MDL);
995  while (next) {
996  subnet_reference (&scan, next, MDL);
997  subnet_dereference (&next, MDL);
998 
999  /* When we find a conflict, make sure that the
1000  subnet with the narrowest subnet mask comes
1001  first. */
1002  if (subnet_inner_than (subnet, scan, 1)) {
1003  if (prev) {
1004  if (prev -> next_subnet)
1005  subnet_dereference (&prev -> next_subnet, MDL);
1006  subnet_reference (&prev -> next_subnet, subnet, MDL);
1007  subnet_dereference (&prev, MDL);
1008  } else {
1009  subnet_dereference (&subnets, MDL);
1010  subnet_reference (&subnets, subnet, MDL);
1011  }
1012  subnet_reference (&subnet -> next_subnet, scan, MDL);
1013  subnet_dereference (&scan, MDL);
1014  return;
1015  }
1016  subnet_reference (&prev, scan, MDL);
1017  subnet_dereference (&scan, MDL);
1018  }
1019  if (prev)
1020  subnet_dereference (&prev, MDL);
1021 
1022  /* XXX use the BSD radix tree code instead of a linked list. */
1023  if (subnets) {
1024  subnet_reference (&subnet -> next_subnet, subnets, MDL);
1025  subnet_dereference (&subnets, MDL);
1026  }
1027  subnet_reference (&subnets, subnet, MDL);
1028 }
1029 
1030 /* Enter a new shared network into the shared network list. */
1031 
1033  struct shared_network *share;
1034 {
1035  if (shared_networks) {
1036  shared_network_reference (&share -> next,
1037  shared_networks, MDL);
1038  shared_network_dereference (&shared_networks, MDL);
1039  }
1040  shared_network_reference (&shared_networks, share, MDL);
1041 }
1042 
1044  struct parse *cfile;
1045  struct shared_network *share;
1046  const char *name;
1047 {
1048  struct interface_info *ip;
1049  isc_result_t status;
1050 
1051  if (share -> interface) {
1052  parse_warn (cfile,
1053  "A subnet or shared network can't be connected %s",
1054  "to two interfaces.");
1055  return;
1056  }
1057 
1058  for (ip = interfaces; ip; ip = ip -> next)
1059  if (!strcmp (ip -> name, name))
1060  break;
1061  if (!ip) {
1062  status = interface_allocate (&ip, MDL);
1063  if (status != ISC_R_SUCCESS)
1064  log_fatal ("new_shared_network_interface %s: %s",
1065  name, isc_result_totext (status));
1066  if (strlen (name) > sizeof ip -> name) {
1067  memcpy (ip -> name, name, (sizeof ip -> name) - 1);
1068  ip -> name [(sizeof ip -> name) - 1] = 0;
1069  } else
1070  strcpy (ip -> name, name);
1071  if (interfaces) {
1072  interface_reference (&ip -> next, interfaces, MDL);
1073  interface_dereference (&interfaces, MDL);
1074  }
1075  interface_reference (&interfaces, ip, MDL);
1076  ip -> flags = INTERFACE_REQUESTED;
1077  /* XXX this is a reference loop. */
1078  shared_network_reference (&ip -> shared_network, share, MDL);
1079  interface_reference (&share -> interface, ip, MDL);
1080  }
1081 }
1082 
1083 /* Enter a lease into the system. This is called by the parser each
1084  time it reads in a new lease. If the subnet for that lease has
1085  already been read in (usually the case), just update that lease;
1086  otherwise, allocate temporary storage for the lease and keep it around
1087  until we're done reading in the config file. */
1088 
1090  struct lease *lease;
1091 {
1092  struct lease *comp = (struct lease *)0;
1093 
1094  if (find_lease_by_ip_addr (&comp, lease -> ip_addr, MDL)) {
1095  if (!comp -> pool) {
1096  log_error ("undeclared lease found in database: %s",
1097  piaddr (lease -> ip_addr));
1098  } else
1099  pool_reference (&lease -> pool, comp -> pool, MDL);
1100 
1101  if (comp -> subnet)
1102  subnet_reference (&lease -> subnet,
1103  comp -> subnet, MDL);
1104  lease_ip_hash_delete(lease_ip_addr_hash,
1105  lease->ip_addr.iabuf, lease->ip_addr.len,
1106  MDL);
1107  lease_dereference (&comp, MDL);
1108  }
1109 
1110  /* The only way a lease can get here without a subnet is if it's in
1111  the lease file, but not in the dhcpd.conf file. In this case, we
1112  *should* keep it around until it's expired, but never reallocate it
1113  or renew it. Currently, to maintain consistency, we are not doing
1114  this.
1115  XXX fix this so that the lease is kept around until it expires.
1116  XXX this will be important in IPv6 with addresses that become
1117  XXX non-renewable as a result of a renumbering event. */
1118 
1119  if (!lease -> subnet) {
1120  log_error ("lease %s: no subnet.", piaddr (lease -> ip_addr));
1121  return;
1122  }
1123  lease_ip_hash_add(lease_ip_addr_hash, lease->ip_addr.iabuf,
1124  lease->ip_addr.len, lease, MDL);
1125 }
1126 
1127 /* Replace the data in an existing lease with the data in a new lease;
1128  adjust hash tables to suit, and insertion sort the lease into the
1129  list of leases by expiry time so that we can always find the oldest
1130  lease. */
1131 
1132 int supersede_lease (comp, lease, commit, propogate, pimmediate, from_pool)
1133  struct lease *comp, *lease;
1134  int commit;
1135  int propogate;
1136  int pimmediate;
1137  int from_pool;
1138 {
1139  LEASE_STRUCT_PTR lq;
1140  struct timeval tv;
1141 #if defined (FAILOVER_PROTOCOL)
1142  int do_pool_check = 0;
1143 
1144  /* We must commit leases before sending updates regarding them
1145  to failover peers. It is, therefore, an error to set pimmediate
1146  and not commit. */
1147  if (pimmediate && !commit)
1148  return 0;
1149 #endif
1150  /* If there is no sample lease, just do the move. */
1151  if (!lease)
1152  goto just_move_it;
1153 
1154  /* Static leases are not currently kept in the database... */
1155  if (lease -> flags & STATIC_LEASE)
1156  return 1;
1157 
1158  /* If the existing lease hasn't expired and has a different
1159  unique identifier or, if it doesn't have a unique
1160  identifier, a different hardware address, then the two
1161  leases are in conflict. If the existing lease has a uid
1162  and the new one doesn't, but they both have the same
1163  hardware address, and dynamic bootp is allowed on this
1164  lease, then we allow that, in case a dynamic BOOTP lease is
1165  requested *after* a DHCP lease has been assigned. */
1166 
1167  if (lease -> binding_state != FTS_ABANDONED &&
1168  lease -> next_binding_state != FTS_ABANDONED &&
1169  comp -> binding_state == FTS_ACTIVE &&
1170  (((comp -> uid && lease -> uid) &&
1171  (comp -> uid_len != lease -> uid_len ||
1172  memcmp (comp -> uid, lease -> uid, comp -> uid_len))) ||
1173  (!comp -> uid &&
1174  ((comp -> hardware_addr.hlen !=
1175  lease -> hardware_addr.hlen) ||
1176  memcmp (comp -> hardware_addr.hbuf,
1177  lease -> hardware_addr.hbuf,
1178  comp -> hardware_addr.hlen))))) {
1179  log_error ("Lease conflict at %s",
1180  piaddr (comp -> ip_addr));
1181  }
1182 
1183  /* If there's a Unique ID, dissociate it from the hash
1184  table and free it if necessary. */
1185  if (comp->uid) {
1186  uid_hash_delete(comp);
1187  if (comp->uid != comp->uid_buf) {
1188  dfree(comp->uid, MDL);
1189  comp->uid_max = 0;
1190  comp->uid_len = 0;
1191  }
1192  comp -> uid = (unsigned char *)0;
1193  }
1194 
1195  /* If there's a hardware address, remove the lease from its
1196  * old position in the hash bucket's ordered list.
1197  */
1198  if (comp->hardware_addr.hlen)
1199  hw_hash_delete(comp);
1200 
1201  /* If the lease has been billed to a class, remove the billing. */
1202  if (comp -> billing_class != lease -> billing_class) {
1203  if (comp->billing_class)
1204  unbill_class(comp);
1205  if (lease -> billing_class)
1206  bill_class (comp, lease -> billing_class);
1207  }
1208 
1209  /* Copy the data files, but not the linkages. */
1210  comp -> starts = lease -> starts;
1211  if (lease -> uid) {
1212  if (lease -> uid_len <= sizeof (lease -> uid_buf)) {
1213  memcpy (comp -> uid_buf,
1214  lease -> uid, lease -> uid_len);
1215  comp -> uid = &comp -> uid_buf [0];
1216  comp -> uid_max = sizeof comp -> uid_buf;
1217  comp -> uid_len = lease -> uid_len;
1218  } else if (lease -> uid != &lease -> uid_buf [0]) {
1219  comp -> uid = lease -> uid;
1220  comp -> uid_max = lease -> uid_max;
1221  lease -> uid = (unsigned char *)0;
1222  lease -> uid_max = 0;
1223  comp -> uid_len = lease -> uid_len;
1224  lease -> uid_len = 0;
1225  } else {
1226  log_fatal ("corrupt lease uid."); /* XXX */
1227  }
1228  } else {
1229  comp -> uid = (unsigned char *)0;
1230  comp -> uid_len = comp -> uid_max = 0;
1231  }
1232  if (comp -> host)
1233  host_dereference (&comp -> host, MDL);
1234  host_reference (&comp -> host, lease -> host, MDL);
1235  comp -> hardware_addr = lease -> hardware_addr;
1236  if (comp -> scope)
1237  binding_scope_dereference (&comp -> scope, MDL);
1238  if (lease -> scope) {
1239  binding_scope_reference (&comp -> scope, lease -> scope, MDL);
1240  binding_scope_dereference (&lease -> scope, MDL);
1241  }
1242 
1243  if (comp -> agent_options)
1245  if (lease -> agent_options) {
1246  /* Only retain the agent options if the lease is still
1247  affirmatively associated with a client. */
1248  if (lease -> next_binding_state == FTS_ACTIVE ||
1249  lease -> next_binding_state == FTS_EXPIRED)
1251  lease -> agent_options,
1252  MDL);
1254  }
1255 
1256  /* Record the hostname information in the lease. */
1257  if (comp -> client_hostname)
1258  dfree (comp -> client_hostname, MDL);
1259  comp -> client_hostname = lease -> client_hostname;
1260  lease -> client_hostname = (char *)0;
1261 
1262  if (lease->on_star.on_expiry) {
1263  if (comp->on_star.on_expiry)
1265  (&comp->on_star.on_expiry, MDL);
1266  executable_statement_reference (&comp->on_star.on_expiry,
1267  lease->on_star.on_expiry,
1268  MDL);
1269  }
1270  if (lease->on_star.on_commit) {
1271  if (comp->on_star.on_commit)
1273  (&comp->on_star.on_commit, MDL);
1274  executable_statement_reference (&comp->on_star.on_commit,
1275  lease->on_star.on_commit,
1276  MDL);
1277  }
1278  if (lease->on_star.on_release) {
1279  if (comp->on_star.on_release)
1281  (&comp->on_star.on_release, MDL);
1282  executable_statement_reference (&comp->on_star.on_release,
1283  lease->on_star.on_release,
1284  MDL);
1285  }
1286 
1287  /* Record the lease in the uid hash if necessary. */
1288  if (comp->uid)
1289  uid_hash_add(comp);
1290 
1291  /* Record it in the hardware address hash if necessary. */
1292  if (comp->hardware_addr.hlen)
1293  hw_hash_add(comp);
1294 
1295  comp->cltt = lease->cltt;
1296 #if defined (FAILOVER_PROTOCOL)
1297  comp->tstp = lease->tstp;
1298  comp->tsfp = lease->tsfp;
1299  comp->atsfp = lease->atsfp;
1300 #endif /* FAILOVER_PROTOCOL */
1301  comp->ends = lease->ends;
1302  comp->next_binding_state = lease->next_binding_state;
1303 
1304  /*
1305  * If we have a control block pointer copy it in.
1306  * We don't zero out an older ponter as it is still
1307  * in use. We shouldn't need to overwrite an
1308  * old pointer with a new one as the old transaction
1309  * should have been cancelled before getting here.
1310  */
1311  if (lease->ddns_cb != NULL)
1312  comp->ddns_cb = lease->ddns_cb;
1313 
1314  just_move_it:
1315 #if defined (FAILOVER_PROTOCOL)
1316  /*
1317  * Atsfp should be cleared upon any state change that implies
1318  * propagation whether supersede_lease was given a copy lease
1319  * structure or not (often from the pool_timer()).
1320  */
1321  if (propogate)
1322  comp->atsfp = 0;
1323 #endif /* FAILOVER_PROTOCOL */
1324 
1325  if (!comp -> pool) {
1326  log_error ("Supersede_lease: lease %s with no pool.",
1327  piaddr (comp -> ip_addr));
1328  return 0;
1329  }
1330 
1331  /* Figure out which queue it's on. */
1332  switch (comp -> binding_state) {
1333  case FTS_FREE:
1334  if (comp->flags & RESERVED_LEASE)
1335  lq = &comp->pool->reserved;
1336  else {
1337  lq = &comp->pool->free;
1338  comp->pool->free_leases--;
1339  }
1340 
1341 #if defined(FAILOVER_PROTOCOL)
1342  do_pool_check = 1;
1343 #endif
1344  break;
1345 
1346  case FTS_ACTIVE:
1347  lq = &comp -> pool -> active;
1348  break;
1349 
1350  case FTS_EXPIRED:
1351  case FTS_RELEASED:
1352  case FTS_RESET:
1353  lq = &comp -> pool -> expired;
1354  break;
1355 
1356  case FTS_ABANDONED:
1357  lq = &comp -> pool -> abandoned;
1358  break;
1359 
1360  case FTS_BACKUP:
1361  if (comp->flags & RESERVED_LEASE)
1362  lq = &comp->pool->reserved;
1363  else {
1364  lq = &comp->pool->backup;
1365  comp->pool->backup_leases--;
1366  }
1367 
1368 #if defined(FAILOVER_PROTOCOL)
1369  do_pool_check = 1;
1370 #endif
1371  break;
1372 
1373  default:
1374  log_error ("Lease with bogus binding state: %d",
1375  comp -> binding_state);
1376 #if defined (BINDING_STATE_DEBUG)
1377  abort ();
1378 #endif
1379  return 0;
1380  }
1381 
1382  /* Remove the lease from its current place in its current
1383  timer sequence. */
1384  LEASE_REMOVEP(lq, comp);
1385 
1386  /* Now that we've done the flag-affected queue removal
1387  * we can update the new lease's flags, if there's an
1388  * existing lease */
1389  if (lease) {
1390  comp->flags = ((lease->flags & ~PERSISTENT_FLAGS) |
1391  (comp->flags & ~EPHEMERAL_FLAGS));
1392  }
1393 
1394  /* Make the state transition. */
1395  if (commit || !pimmediate)
1397 
1398  /* Put the lease back on the appropriate queue. If the lease
1399  is corrupt (as detected by lease_enqueue), don't go any farther. */
1400  if (!lease_enqueue (comp))
1401  return 0;
1402 
1403  /* If this is the next lease that will timeout on the pool,
1404  zap the old timeout and set the timeout on this pool to the
1405  time that the lease's next event will happen.
1406 
1407  We do not actually set the timeout unless commit is true -
1408  we don't want to thrash the timer queue when reading the
1409  lease database. Instead, the database code calls the
1410  expiry event on each pool after reading in the lease file,
1411  and the expiry code sets the timer if there's anything left
1412  to expire after it's run any outstanding expiry events on
1413  the pool. */
1414  if ((commit || !pimmediate) &&
1415  comp -> sort_time != MIN_TIME &&
1416  comp -> sort_time > cur_time &&
1417  (comp -> sort_time < comp -> pool -> next_event_time ||
1418  comp -> pool -> next_event_time == MIN_TIME)) {
1419  comp -> pool -> next_event_time = comp -> sort_time;
1420  tv . tv_sec = comp -> pool -> next_event_time;
1421  tv . tv_usec = 0;
1422  add_timeout (&tv,
1423  pool_timer, comp -> pool,
1424  (tvref_t)pool_reference,
1425  (tvunref_t)pool_dereference);
1426  }
1427 
1428  if (commit) {
1429 #if defined(FAILOVER_PROTOCOL)
1430  /*
1431  * If commit and propogate are set, then we can save a
1432  * possible fsync later in BNDUPD socket transmission by
1433  * stepping the rewind state forward to the new state, in
1434  * case it has changed. This is only worth doing if the
1435  * failover connection is currently connected, as in this
1436  * case it is likely we will be transmitting to the peer very
1437  * shortly.
1438  */
1439  if (propogate && (comp->pool->failover_peer != NULL) &&
1440  ((comp->pool->failover_peer->service_state ==
1441  cooperating) ||
1442  (comp->pool->failover_peer->service_state ==
1443  not_responding)))
1444  comp->rewind_binding_state = comp->binding_state;
1445 #endif
1446 
1447  if (!write_lease (comp))
1448  return 0;
1449  if ((server_starting & SS_NOSYNC) == 0) {
1450  if (!commit_leases ())
1451  return 0;
1452  }
1453  }
1454 
1455 #if defined (FAILOVER_PROTOCOL)
1456  if (propogate) {
1457  comp -> desired_binding_state = comp -> binding_state;
1458  if (!dhcp_failover_queue_update (comp, pimmediate))
1459  return 0;
1460  }
1461  if (do_pool_check && comp->pool->failover_peer)
1462  dhcp_failover_pool_check(comp->pool);
1463 #endif
1464 
1465  /* If the current binding state has already expired and we haven't
1466  * been called from pool_timer, do an expiry event right now.
1467  */
1468  /* XXX At some point we should optimize this so that we don't
1469  XXX write the lease twice, but this is a safe way to fix the
1470  XXX problem for 3.0 (I hope!). */
1471  if ((from_pool == 0) &&
1472  (commit || !pimmediate) &&
1473  (comp->sort_time < cur_time) &&
1474  (comp->next_binding_state != comp->binding_state))
1475  pool_timer(comp->pool);
1476 
1477  return 1;
1478 }
1479 
1481 {
1482 
1483 #if defined (FAILOVER_PROTOCOL)
1484  dhcp_failover_state_t *peer;
1485 
1486  if (lease -> pool && lease -> pool -> failover_peer)
1487  peer = lease -> pool -> failover_peer;
1488  else
1489  peer = (dhcp_failover_state_t *)0;
1490 #endif
1491 
1492  /* If the lease was active and is now no longer active, but isn't
1493  released, then it just expired, so do the expiry event. */
1494  if (lease -> next_binding_state != lease -> binding_state &&
1495  ((
1496 #if defined (FAILOVER_PROTOCOL)
1497  peer &&
1498  (lease->binding_state == FTS_EXPIRED ||
1499  lease->binding_state == FTS_ACTIVE) &&
1500  (lease->next_binding_state == FTS_FREE ||
1501  lease->next_binding_state == FTS_BACKUP)) ||
1502  (!peer &&
1503 #endif
1504  lease -> binding_state == FTS_ACTIVE &&
1505  lease -> next_binding_state != FTS_RELEASED))) {
1506 #if defined (NSUPDATE)
1507  (void) ddns_removals(lease, NULL, NULL, ISC_TRUE);
1508 #endif
1509  if (lease->on_star.on_expiry) {
1510  execute_statements(NULL, NULL, lease,
1511  NULL, NULL, NULL,
1512  &lease->scope,
1513  lease->on_star.on_expiry,
1514  NULL);
1515  if (lease->on_star.on_expiry)
1517  (&lease->on_star.on_expiry, MDL);
1518  }
1519 
1520  /* No sense releasing a lease after it's expired. */
1521  if (lease->on_star.on_release)
1523  (&lease->on_star.on_release, MDL);
1524  /* Get rid of client-specific bindings that are only
1525  correct when the lease is active. */
1526  if (lease->billing_class)
1527  unbill_class(lease);
1528  if (lease -> agent_options)
1530  MDL);
1531  if (lease -> client_hostname) {
1532  dfree (lease -> client_hostname, MDL);
1533  lease -> client_hostname = (char *)0;
1534  }
1535  if (lease -> host)
1536  host_dereference (&lease -> host, MDL);
1537 
1538  /* Send the expiry time to the peer. */
1539  lease -> tstp = lease -> ends;
1540  }
1541 
1542  /* If the lease was active and is now released, do the release
1543  event. */
1544  if (lease -> next_binding_state != lease -> binding_state &&
1545  ((
1546 #if defined (FAILOVER_PROTOCOL)
1547  peer &&
1548  lease -> binding_state == FTS_RELEASED &&
1549  (lease -> next_binding_state == FTS_FREE ||
1550  lease -> next_binding_state == FTS_BACKUP)) ||
1551  (!peer &&
1552 #endif
1553  lease -> binding_state == FTS_ACTIVE &&
1554  lease -> next_binding_state == FTS_RELEASED))) {
1555 #if defined (NSUPDATE)
1556  /*
1557  * Note: ddns_removals() is also iterated when the lease
1558  * enters state 'released' in 'release_lease()'. The below
1559  * is caught when a peer receives a BNDUPD from a failover
1560  * peer; it may not have received the client's release (it
1561  * may have been offline).
1562  *
1563  * We could remove the call from release_lease() because
1564  * it will also catch here on the originating server after the
1565  * peer acknowledges the state change. However, there could
1566  * be many hours inbetween, and in this case we /know/ the
1567  * client is no longer using the lease when we receive the
1568  * release message. This is not true of expiry, where the
1569  * peer may have extended the lease.
1570  */
1571  (void) ddns_removals(lease, NULL, NULL, ISC_TRUE);
1572 #endif
1573  if (lease->on_star.on_release) {
1574  execute_statements(NULL, NULL, lease,
1575  NULL, NULL, NULL,
1576  &lease->scope,
1577  lease->on_star.on_release,
1578  NULL);
1580  (&lease->on_star.on_release, MDL);
1581  }
1582 
1583  /* A released lease can't expire. */
1584  if (lease->on_star.on_expiry)
1586  (&lease->on_star.on_expiry, MDL);
1587 
1588  /* Get rid of client-specific bindings that are only
1589  correct when the lease is active. */
1590  if (lease->billing_class)
1591  unbill_class(lease);
1592  if (lease -> agent_options)
1594  MDL);
1595  if (lease -> client_hostname) {
1596  dfree (lease -> client_hostname, MDL);
1597  lease -> client_hostname = (char *)0;
1598  }
1599  if (lease -> host)
1600  host_dereference (&lease -> host, MDL);
1601 
1602  /* Send the release time (should be == cur_time) to the
1603  peer. */
1604  lease -> tstp = lease -> ends;
1605  }
1606 
1607 #if defined (DEBUG_LEASE_STATE_TRANSITIONS)
1608  log_debug ("lease %s moves from %s to %s",
1609  piaddr (lease -> ip_addr),
1610  binding_state_print (lease -> binding_state),
1611  binding_state_print (lease -> next_binding_state));
1612 #endif
1613 
1614  lease -> binding_state = lease -> next_binding_state;
1615  switch (lease -> binding_state) {
1616  case FTS_ACTIVE:
1617 #if defined (FAILOVER_PROTOCOL)
1618  if (lease -> pool && lease -> pool -> failover_peer)
1619  lease -> next_binding_state = FTS_EXPIRED;
1620  else
1621 #endif
1622  lease -> next_binding_state = FTS_FREE;
1623  break;
1624 
1625  case FTS_EXPIRED:
1626  case FTS_RELEASED:
1627  case FTS_ABANDONED:
1628  case FTS_RESET:
1629  lease->next_binding_state = FTS_FREE;
1630 #if defined(FAILOVER_PROTOCOL)
1631  /* If we are not in partner_down, leases don't go from
1632  EXPIRED to FREE on a timeout - only on an update.
1633  If we're in partner_down, they expire at mclt past
1634  the time we entered partner_down. */
1635  if ((lease->pool != NULL) &&
1636  (lease->pool->failover_peer != NULL) &&
1637  (lease->pool->failover_peer->me.state == partner_down))
1638  lease->tsfp =
1639  (lease->pool->failover_peer->me.stos +
1640  lease->pool->failover_peer->mclt);
1641 #endif /* FAILOVER_PROTOCOL */
1642  break;
1643 
1644  case FTS_FREE:
1645  case FTS_BACKUP:
1646  lease -> next_binding_state = lease -> binding_state;
1647  break;
1648  }
1649 #if defined (DEBUG_LEASE_STATE_TRANSITIONS)
1650  log_debug ("lease %s: next binding state %s",
1651  piaddr (lease -> ip_addr),
1652  binding_state_print (lease -> next_binding_state));
1653 #endif
1654 }
1655 
1656 /* Copy the contents of one lease into another, correctly maintaining
1657  reference counts. */
1658 int lease_copy (struct lease **lp,
1659  struct lease *lease, const char *file, int line)
1660 {
1661  struct lease *lt = (struct lease *)0;
1662  isc_result_t status;
1663 
1664  status = lease_allocate (&lt, MDL);
1665  if (status != ISC_R_SUCCESS)
1666  return 0;
1667 
1668  lt -> ip_addr = lease -> ip_addr;
1669  lt -> starts = lease -> starts;
1670  lt -> ends = lease -> ends;
1671  lt -> uid_len = lease -> uid_len;
1672  lt -> uid_max = lease -> uid_max;
1673  if (lease -> uid == lease -> uid_buf) {
1674  lt -> uid = lt -> uid_buf;
1675  memcpy (lt -> uid_buf, lease -> uid_buf, sizeof lt -> uid_buf);
1676  } else if (!lease -> uid_max) {
1677  lt -> uid = (unsigned char *)0;
1678  } else {
1679  lt -> uid = dmalloc (lt -> uid_max, MDL);
1680  if (!lt -> uid) {
1681  lease_dereference (&lt, MDL);
1682  return 0;
1683  }
1684  memcpy (lt -> uid, lease -> uid, lease -> uid_max);
1685  }
1686  if (lease -> client_hostname) {
1687  lt -> client_hostname =
1688  dmalloc (strlen (lease -> client_hostname) + 1, MDL);
1689  if (!lt -> client_hostname) {
1690  lease_dereference (&lt, MDL);
1691  return 0;
1692  }
1693  strcpy (lt -> client_hostname, lease -> client_hostname);
1694  }
1695  if (lease -> scope)
1696  binding_scope_reference (&lt -> scope, lease -> scope, MDL);
1697  if (lease -> agent_options)
1699  lease -> agent_options, MDL);
1700  host_reference (&lt -> host, lease -> host, file, line);
1701  subnet_reference (&lt -> subnet, lease -> subnet, file, line);
1702  pool_reference (&lt -> pool, lease -> pool, file, line);
1703  class_reference (&lt -> billing_class,
1704  lease -> billing_class, file, line);
1705  lt -> hardware_addr = lease -> hardware_addr;
1706  if (lease->on_star.on_expiry)
1708  lease->on_star.on_expiry,
1709  file, line);
1710  if (lease->on_star.on_commit)
1712  lease->on_star.on_commit,
1713  file, line);
1714  if (lease->on_star.on_release)
1716  lease->on_star.on_release,
1717  file, line);
1718  lt->flags = lease->flags;
1719  lt->tstp = lease->tstp;
1720  lt->tsfp = lease->tsfp;
1721  lt->atsfp = lease->atsfp;
1722  lt->cltt = lease -> cltt;
1723  lt->binding_state = lease->binding_state;
1726  status = lease_reference(lp, lt, file, line);
1727  lease_dereference(&lt, MDL);
1728  return status == ISC_R_SUCCESS;
1729 }
1730 
1731 /* Release the specified lease and re-hash it as appropriate. */
1733  struct lease *lease;
1734  struct packet *packet;
1735 {
1736  /* If there are statements to execute when the lease is
1737  released, execute them. */
1738 #if defined (NSUPDATE)
1739  (void) ddns_removals(lease, NULL, NULL, ISC_FALSE);
1740 #endif
1741  if (lease->on_star.on_release) {
1742  execute_statements (NULL, packet, lease,
1743  NULL, packet->options,
1744  NULL, &lease->scope,
1745  lease->on_star.on_release, NULL);
1746  if (lease->on_star.on_release)
1748  (&lease->on_star.on_release, MDL);
1749  }
1750 
1751  /* We do either the on_release or the on_expiry events, but
1752  not both (it's possible that they could be the same,
1753  in any case). */
1754  if (lease->on_star.on_expiry)
1756  (&lease->on_star.on_expiry, MDL);
1757 
1758  if (lease -> binding_state != FTS_FREE &&
1759  lease -> binding_state != FTS_BACKUP &&
1760  lease -> binding_state != FTS_RELEASED &&
1761  lease -> binding_state != FTS_EXPIRED &&
1762  lease -> binding_state != FTS_RESET) {
1763  if (lease->on_star.on_commit)
1765  (&lease->on_star.on_commit, MDL);
1766 
1767  /* Blow away any bindings. */
1768  if (lease -> scope)
1769  binding_scope_dereference (&lease -> scope, MDL);
1770 
1771  /* Set sort times to the present. */
1772  lease -> ends = cur_time;
1773  /* Lower layers of muckery set tstp to ->ends. But we send
1774  * protocol messages before this. So it is best to set
1775  * tstp now anyway.
1776  */
1777  lease->tstp = cur_time;
1778 #if defined (FAILOVER_PROTOCOL)
1779  if (lease -> pool && lease -> pool -> failover_peer) {
1780  dhcp_failover_state_t *peer = NULL;
1781 
1782  if (lease->pool != NULL)
1783  peer = lease->pool->failover_peer;
1784 
1785  if ((peer->service_state == not_cooperating) &&
1786  (((peer->i_am == primary) &&
1787  (lease->rewind_binding_state == FTS_FREE)) ||
1788  ((peer->i_am == secondary) &&
1789  (lease->rewind_binding_state == FTS_BACKUP)))) {
1790  lease->next_binding_state =
1791  lease->rewind_binding_state;
1792  } else
1793  lease -> next_binding_state = FTS_RELEASED;
1794  } else {
1795  lease -> next_binding_state = FTS_FREE;
1796  }
1797 #else
1798  lease -> next_binding_state = FTS_FREE;
1799 #endif
1800  supersede_lease(lease, NULL, 1, 1, 1, 0);
1801  }
1802 }
1803 
1804 /* Abandon the specified lease (set its timeout to infinity and its
1805  particulars to zero, and re-hash it as appropriate. */
1806 
1807 void abandon_lease (lease, message)
1808  struct lease *lease;
1809  const char *message;
1810 {
1811  struct lease *lt = NULL;
1812 #if defined (NSUPDATE)
1813  (void) ddns_removals(lease, NULL, NULL, ISC_FALSE);
1814 #endif
1815 
1816  if (!lease_copy(&lt, lease, MDL)) {
1817  return;
1818  }
1819 
1820  if (lt->scope) {
1822  }
1823 
1824  /* Calculate the abandone expiry time. If it wraps,
1825  * use the maximum expiry time. */
1827  if (lt->ends < cur_time || lt->ends > MAX_TIME) {
1828  lt->ends = MAX_TIME;
1829  }
1830 
1832 
1833  log_error ("Abandoning IP address %s: %s", piaddr(lease->ip_addr),
1834  message);
1835  lt->hardware_addr.hlen = 0;
1836  if (lt->uid && lt->uid != lt->uid_buf) {
1837  dfree(lt->uid, MDL);
1838  }
1839 
1840  lt->uid = NULL;
1841  lt->uid_len = 0;
1842  lt->uid_max = 0;
1843  supersede_lease(lease, lt, 1, 1, 1, 0);
1844  lease_dereference(&lt, MDL);
1845 }
1846 
1847 #if 0
1848 /*
1849  * This doesn't appear to be in use for anything anymore.
1850  * I'm ifdeffing it now and if there are no complaints in
1851  * the future it will be removed.
1852  * SAR
1853  */
1854 
1855 /* Abandon the specified lease (set its timeout to infinity and its
1856  particulars to zero, and re-hash it as appropriate. */
1857 
1858 void dissociate_lease (lease)
1859  struct lease *lease;
1860 {
1861  struct lease *lt = (struct lease *)0;
1862 #if defined (NSUPDATE)
1863  (void) ddns_removals(lease, NULL, NULL, ISC_FALSE);
1864 #endif
1865 
1866  if (!lease_copy (&lt, lease, MDL))
1867  return;
1868 
1869 #if defined (FAILOVER_PROTOCOL)
1870  if (lease -> pool && lease -> pool -> failover_peer) {
1871  lt -> next_binding_state = FTS_RESET;
1872  } else {
1873  lt -> next_binding_state = FTS_FREE;
1874  }
1875 #else
1876  lt -> next_binding_state = FTS_FREE;
1877 #endif
1878  lt -> ends = cur_time; /* XXX */
1879  lt -> hardware_addr.hlen = 0;
1880  if (lt -> uid && lt -> uid != lt -> uid_buf)
1881  dfree (lt -> uid, MDL);
1882  lt -> uid = (unsigned char *)0;
1883  lt -> uid_len = 0;
1884  lt -> uid_max = 0;
1885  supersede_lease (lease, lt, 1, 1, 1, 0);
1886  lease_dereference (&lt, MDL);
1887 }
1888 #endif
1889 
1890 /* Timer called when a lease in a particular pool expires. */
1891 void pool_timer (vpool)
1892  void *vpool;
1893 {
1894  struct pool *pool;
1895  struct lease *next = NULL;
1896  struct lease *lease = NULL;
1897  struct lease *ltemp = NULL;
1898 #define FREE_LEASES 0
1899 #define ACTIVE_LEASES 1
1900 #define EXPIRED_LEASES 2
1901 #define ABANDONED_LEASES 3
1902 #define BACKUP_LEASES 4
1903 #define RESERVED_LEASES 5
1905  TIME next_expiry = MAX_TIME;
1906  int i;
1907  struct timeval tv;
1908 
1909  pool = (struct pool *)vpool;
1910 
1911  lptr[FREE_LEASES] = &pool->free;
1912  lptr[ACTIVE_LEASES] = &pool->active;
1913  lptr[EXPIRED_LEASES] = &pool->expired;
1914  lptr[ABANDONED_LEASES] = &pool->abandoned;
1915  lptr[BACKUP_LEASES] = &pool->backup;
1916  lptr[RESERVED_LEASES] = &pool->reserved;
1917 
1918  for (i = FREE_LEASES; i <= RESERVED_LEASES; i++) {
1919  /* If there's nothing on the queue, skip it. */
1920  if (!(LEASE_NOT_EMPTYP(lptr[i])))
1921  continue;
1922 
1923 #if defined (FAILOVER_PROTOCOL)
1924  if (pool->failover_peer &&
1925  pool->failover_peer->me.state != partner_down) {
1926  /*
1927  * Normally the secondary doesn't initiate expiration
1928  * events (unless in partner-down), but rather relies
1929  * on the primary to expire the lease. However, when
1930  * disconnected from its peer, the server is allowed to
1931  * rewind a lease to the previous state that the peer
1932  * would have recorded it. This means there may be
1933  * opportunities for active->free or active->backup
1934  * expirations while out of contact.
1935  *
1936  * Q: Should we limit this expiration to
1937  * comms-interrupt rather than not-normal?
1938  */
1939  if ((i == ACTIVE_LEASES) &&
1940  (pool->failover_peer->i_am == secondary) &&
1941  (pool->failover_peer->me.state == normal))
1942  continue;
1943 
1944  /* Leases in an expired state don't move to
1945  free because of a timeout unless we're in
1946  partner_down. */
1947  if (i == EXPIRED_LEASES)
1948  continue;
1949  }
1950 #endif
1951  lease_reference(&lease, LEASE_GET_FIRSTP(lptr[i]), MDL);
1952 
1953  while (lease) {
1954  /* Remember the next lease in the list. */
1955  if (next)
1956  lease_dereference(&next, MDL);
1957  ltemp = LEASE_GET_NEXTP(lptr[i], lease);
1958  if (ltemp)
1959  lease_reference(&next, ltemp, MDL);
1960 
1961  /* If we've run out of things to expire on this list,
1962  stop. */
1963  if (lease->sort_time > cur_time) {
1964  if (lease->sort_time < next_expiry)
1965  next_expiry = lease->sort_time;
1966  break;
1967  }
1968 
1969  /* If there is a pending state change, and
1970  this lease has gotten to the time when the
1971  state change should happen, just call
1972  supersede_lease on it to make the change
1973  happen. */
1974  if (lease->next_binding_state != lease->binding_state)
1975  {
1976 #if defined(FAILOVER_PROTOCOL)
1977  dhcp_failover_state_t *peer = NULL;
1978 
1979  if (lease->pool != NULL)
1980  peer = lease->pool->failover_peer;
1981 
1982  /* Can we rewind the lease to a free state? */
1983  if (peer != NULL &&
1984  peer->service_state == not_cooperating &&
1985  lease->next_binding_state == FTS_EXPIRED &&
1986  ((peer->i_am == primary &&
1987  lease->rewind_binding_state == FTS_FREE)
1988  ||
1989  (peer->i_am == secondary &&
1990  lease->rewind_binding_state ==
1991  FTS_BACKUP)))
1992  lease->next_binding_state =
1993  lease->rewind_binding_state;
1994 #endif
1995  supersede_lease(lease, NULL, 1, 1, 1, 1);
1996  }
1997 
1998  lease_dereference(&lease, MDL);
1999  if (next)
2000  lease_reference(&lease, next, MDL);
2001  }
2002  if (next)
2003  lease_dereference(&next, MDL);
2004  if (lease)
2005  lease_dereference(&lease, MDL);
2006  }
2007 
2008  /* If we found something to expire and its expiration time
2009  * is either less than the current expiration time or the
2010  * current expiration time is already expired update the
2011  * timer.
2012  */
2013  if ((next_expiry != MAX_TIME) &&
2014  ((pool->next_event_time > next_expiry) ||
2015  (pool->next_event_time <= cur_time))) {
2016  pool->next_event_time = next_expiry;
2017  tv.tv_sec = pool->next_event_time;
2018  tv.tv_usec = 0;
2019  add_timeout (&tv, pool_timer, pool,
2020  (tvref_t)pool_reference,
2021  (tvunref_t)pool_dereference);
2022  } else
2023  pool->next_event_time = MIN_TIME;
2024 
2025 }
2026 
2027 /* Locate the lease associated with a given IP address... */
2028 
2029 int find_lease_by_ip_addr (struct lease **lp, struct iaddr addr,
2030  const char *file, int line)
2031 {
2032  return lease_ip_hash_lookup(lp, lease_ip_addr_hash, addr.iabuf,
2033  addr.len, file, line);
2034 }
2035 
2036 int find_lease_by_uid (struct lease **lp, const unsigned char *uid,
2037  unsigned len, const char *file, int line)
2038 {
2039  if (len == 0)
2040  return 0;
2041  return lease_id_hash_lookup (lp, lease_uid_hash, uid, len, file, line);
2042 }
2043 
2044 int find_lease_by_hw_addr (struct lease **lp,
2045  const unsigned char *hwaddr, unsigned hwlen,
2046  const char *file, int line)
2047 {
2048  if (hwlen == 0)
2049  return (0);
2050 
2051  /*
2052  * If it's an infiniband address don't bother
2053  * as we don't have a useful address to hash.
2054  */
2055  if ((hwlen == 1) && (hwaddr[0] == HTYPE_INFINIBAND))
2056  return (0);
2057 
2058  return (lease_id_hash_lookup(lp, lease_hw_addr_hash, hwaddr, hwlen,
2059  file, line));
2060 }
2061 
2062 /* If the lease is preferred over the candidate, return truth. The
2063  * 'cand' and 'lease' names are retained to read more clearly against
2064  * the 'uid_hash_add' and 'hw_hash_add' functions (this is common logic
2065  * to those two functions).
2066  *
2067  * 1) ACTIVE leases are preferred. The active lease with
2068  * the longest lifetime is preferred over shortest.
2069  * 2) "transitional states" are next, this time with the
2070  * most recent CLTT.
2071  * 3) free/backup/etc states are next, again with CLTT. In truth we
2072  * should never see reset leases for this.
2073  * 4) Abandoned leases are always dead last.
2074  */
2075 static isc_boolean_t
2076 client_lease_preferred(struct lease *cand, struct lease *lease)
2077 {
2078  if (cand->binding_state == FTS_ACTIVE) {
2079  if (lease->binding_state == FTS_ACTIVE &&
2080  lease->ends >= cand->ends)
2081  return ISC_TRUE;
2082  } else if (cand->binding_state == FTS_EXPIRED ||
2083  cand->binding_state == FTS_RELEASED) {
2084  if (lease->binding_state == FTS_ACTIVE)
2085  return ISC_TRUE;
2086 
2087  if ((lease->binding_state == FTS_EXPIRED ||
2088  lease->binding_state == FTS_RELEASED) &&
2089  lease->cltt >= cand->cltt)
2090  return ISC_TRUE;
2091  } else if (cand->binding_state != FTS_ABANDONED) {
2092  if (lease->binding_state == FTS_ACTIVE ||
2093  lease->binding_state == FTS_EXPIRED ||
2094  lease->binding_state == FTS_RELEASED)
2095  return ISC_TRUE;
2096 
2097  if (lease->binding_state != FTS_ABANDONED &&
2098  lease->cltt >= cand->cltt)
2099  return ISC_TRUE;
2100  } else /* (cand->binding_state == FTS_ABANDONED) */ {
2101  if (lease->binding_state != FTS_ABANDONED ||
2102  lease->cltt >= cand->cltt)
2103  return ISC_TRUE;
2104  }
2105 
2106  return ISC_FALSE;
2107 }
2108 
2109 /* Add the specified lease to the uid hash. */
2110 void
2111 uid_hash_add(struct lease *lease)
2112 {
2113  struct lease *head = NULL;
2114  struct lease *cand = NULL;
2115  struct lease *prev = NULL;
2116  struct lease *next = NULL;
2117 
2118  /* If it's not in the hash, just add it. */
2119  if (!find_lease_by_uid (&head, lease -> uid, lease -> uid_len, MDL))
2120  lease_id_hash_add(lease_uid_hash, lease->uid, lease->uid_len,
2121  lease, MDL);
2122  else {
2123  /* Otherwise, insert it into the list in order of its
2124  * preference for "resuming allocation to the client."
2125  *
2126  * Because we don't have control of the hash bucket index
2127  * directly, we have to remove and re-insert the client
2128  * id into the hash if we're inserting onto the head.
2129  */
2130  lease_reference(&cand, head, MDL);
2131  while (cand != NULL) {
2132  if (client_lease_preferred(cand, lease))
2133  break;
2134 
2135  if (prev != NULL)
2136  lease_dereference(&prev, MDL);
2137  lease_reference(&prev, cand, MDL);
2138 
2139  if (cand->n_uid != NULL)
2140  lease_reference(&next, cand->n_uid, MDL);
2141 
2142  lease_dereference(&cand, MDL);
2143 
2144  if (next != NULL) {
2145  lease_reference(&cand, next, MDL);
2146  lease_dereference(&next, MDL);
2147  }
2148  }
2149 
2150  /* If we want to insert 'before cand', and prev is NULL,
2151  * then it was the head of the list. Assume that position.
2152  */
2153  if (prev == NULL) {
2154  lease_reference(&lease->n_uid, head, MDL);
2155  lease_id_hash_delete(lease_uid_hash, lease->uid,
2156  lease->uid_len, MDL);
2157  lease_id_hash_add(lease_uid_hash, lease->uid,
2158  lease->uid_len, lease, MDL);
2159  } else /* (prev != NULL) */ {
2160  if(prev->n_uid != NULL) {
2161  lease_reference(&lease->n_uid, prev->n_uid,
2162  MDL);
2163  lease_dereference(&prev->n_uid, MDL);
2164  }
2165  lease_reference(&prev->n_uid, lease, MDL);
2166 
2167  lease_dereference(&prev, MDL);
2168  }
2169 
2170  if (cand != NULL)
2171  lease_dereference(&cand, MDL);
2172  lease_dereference(&head, MDL);
2173  }
2174 }
2175 
2176 /* Delete the specified lease from the uid hash. */
2177 
2178 void uid_hash_delete (lease)
2179  struct lease *lease;
2180 {
2181  struct lease *head = (struct lease *)0;
2182  struct lease *scan;
2183 
2184  /* If it's not in the hash, we have no work to do. */
2185  if (!find_lease_by_uid (&head, lease -> uid, lease -> uid_len, MDL)) {
2186  if (lease -> n_uid)
2187  lease_dereference (&lease -> n_uid, MDL);
2188  return;
2189  }
2190 
2191  /* If the lease we're freeing is at the head of the list,
2192  remove the hash table entry and add a new one with the
2193  next lease on the list (if there is one). */
2194  if (head == lease) {
2195  lease_id_hash_delete(lease_uid_hash, lease->uid,
2196  lease->uid_len, MDL);
2197  if (lease -> n_uid) {
2198  lease_id_hash_add(lease_uid_hash, lease->n_uid->uid,
2199  lease->n_uid->uid_len, lease->n_uid,
2200  MDL);
2201  lease_dereference (&lease -> n_uid, MDL);
2202  }
2203  } else {
2204  /* Otherwise, look for the lease in the list of leases
2205  attached to the hash table entry, and remove it if
2206  we find it. */
2207  for (scan = head; scan -> n_uid; scan = scan -> n_uid) {
2208  if (scan -> n_uid == lease) {
2209  lease_dereference (&scan -> n_uid, MDL);
2210  if (lease -> n_uid) {
2211  lease_reference (&scan -> n_uid,
2212  lease -> n_uid, MDL);
2213  lease_dereference (&lease -> n_uid,
2214  MDL);
2215  }
2216  break;
2217  }
2218  }
2219  }
2220  lease_dereference (&head, MDL);
2221 }
2222 
2223 /* Add the specified lease to the hardware address hash. */
2224 /* We don't add leases with infiniband addresses to the
2225  * hash as there isn't any address to hash on. */
2226 
2227 void
2228 hw_hash_add(struct lease *lease)
2229 {
2230  struct lease *head = NULL;
2231  struct lease *cand = NULL;
2232  struct lease *prev = NULL;
2233  struct lease *next = NULL;
2234 
2235  /*
2236  * If it's an infiniband address don't bother
2237  * as we don't have a useful address to hash.
2238  */
2239  if ((lease->hardware_addr.hlen == 1) &&
2240  (lease->hardware_addr.hbuf[0] == HTYPE_INFINIBAND))
2241  return;
2242 
2243  /* If it's not in the hash, just add it. */
2244  if (!find_lease_by_hw_addr (&head, lease -> hardware_addr.hbuf,
2245  lease -> hardware_addr.hlen, MDL))
2246  lease_id_hash_add(lease_hw_addr_hash,
2247  lease->hardware_addr.hbuf,
2248  lease->hardware_addr.hlen, lease, MDL);
2249  else {
2250  /* Otherwise, insert it into the list in order of its
2251  * preference for "resuming allocation to the client."
2252  *
2253  * Because we don't have control of the hash bucket index
2254  * directly, we have to remove and re-insert the client
2255  * id into the hash if we're inserting onto the head.
2256  */
2257  lease_reference(&cand, head, MDL);
2258  while (cand != NULL) {
2259  if (client_lease_preferred(cand, lease))
2260  break;
2261 
2262  if (prev != NULL)
2263  lease_dereference(&prev, MDL);
2264  lease_reference(&prev, cand, MDL);
2265 
2266  if (cand->n_hw != NULL)
2267  lease_reference(&next, cand->n_hw, MDL);
2268 
2269  lease_dereference(&cand, MDL);
2270 
2271  if (next != NULL) {
2272  lease_reference(&cand, next, MDL);
2273  lease_dereference(&next, MDL);
2274  }
2275  }
2276 
2277  /* If we want to insert 'before cand', and prev is NULL,
2278  * then it was the head of the list. Assume that position.
2279  */
2280  if (prev == NULL) {
2281  lease_reference(&lease->n_hw, head, MDL);
2282  lease_id_hash_delete(lease_hw_addr_hash,
2283  lease->hardware_addr.hbuf,
2284  lease->hardware_addr.hlen, MDL);
2285  lease_id_hash_add(lease_hw_addr_hash,
2286  lease->hardware_addr.hbuf,
2287  lease->hardware_addr.hlen,
2288  lease, MDL);
2289  } else /* (prev != NULL) */ {
2290  if(prev->n_hw != NULL) {
2291  lease_reference(&lease->n_hw, prev->n_hw,
2292  MDL);
2293  lease_dereference(&prev->n_hw, MDL);
2294  }
2295  lease_reference(&prev->n_hw, lease, MDL);
2296 
2297  lease_dereference(&prev, MDL);
2298  }
2299 
2300  if (cand != NULL)
2301  lease_dereference(&cand, MDL);
2302  lease_dereference(&head, MDL);
2303  }
2304 }
2305 
2306 /* Delete the specified lease from the hardware address hash. */
2307 
2308 void hw_hash_delete (lease)
2309  struct lease *lease;
2310 {
2311  struct lease *head = (struct lease *)0;
2312  struct lease *next = (struct lease *)0;
2313 
2314  /*
2315  * If it's an infiniband address don't bother
2316  * as we don't have a useful address to hash.
2317  */
2318  if ((lease->hardware_addr.hlen == 1) &&
2319  (lease->hardware_addr.hbuf[0] == HTYPE_INFINIBAND))
2320  return;
2321 
2322  /* If it's not in the hash, we have no work to do. */
2323  if (!find_lease_by_hw_addr (&head, lease -> hardware_addr.hbuf,
2324  lease -> hardware_addr.hlen, MDL)) {
2325  if (lease -> n_hw)
2326  lease_dereference (&lease -> n_hw, MDL);
2327  return;
2328  }
2329 
2330  /* If the lease we're freeing is at the head of the list,
2331  remove the hash table entry and add a new one with the
2332  next lease on the list (if there is one). */
2333  if (head == lease) {
2334  lease_id_hash_delete(lease_hw_addr_hash,
2335  lease->hardware_addr.hbuf,
2336  lease->hardware_addr.hlen, MDL);
2337  if (lease->n_hw) {
2338  lease_id_hash_add(lease_hw_addr_hash,
2339  lease->n_hw->hardware_addr.hbuf,
2340  lease->n_hw->hardware_addr.hlen,
2341  lease->n_hw, MDL);
2342  lease_dereference(&lease->n_hw, MDL);
2343  }
2344  } else {
2345  /* Otherwise, look for the lease in the list of leases
2346  attached to the hash table entry, and remove it if
2347  we find it. */
2348  while (head -> n_hw) {
2349  if (head -> n_hw == lease) {
2350  lease_dereference (&head -> n_hw, MDL);
2351  if (lease -> n_hw) {
2352  lease_reference (&head -> n_hw,
2353  lease -> n_hw, MDL);
2354  lease_dereference (&lease -> n_hw,
2355  MDL);
2356  }
2357  break;
2358  }
2359  lease_reference (&next, head -> n_hw, MDL);
2360  lease_dereference (&head, MDL);
2361  lease_reference (&head, next, MDL);
2362  lease_dereference (&next, MDL);
2363  }
2364  }
2365  if (head)
2366  lease_dereference (&head, MDL);
2367 }
2368 
2369 /* Write v4 leases to permanent storage. */
2370 int write_leases4(void) {
2371  struct lease *l;
2372  struct shared_network *s;
2373  struct pool *p;
2375  int num_written = 0, i;
2376 
2377  /* Write all the leases. */
2378  for (s = shared_networks; s; s = s->next) {
2379  for (p = s->pools; p; p = p->next) {
2380  lptr[FREE_LEASES] = &p->free;
2381  lptr[ACTIVE_LEASES] = &p->active;
2382  lptr[EXPIRED_LEASES] = &p->expired;
2383  lptr[ABANDONED_LEASES] = &p->abandoned;
2384  lptr[BACKUP_LEASES] = &p->backup;
2385  lptr[RESERVED_LEASES] = &p->reserved;
2386 
2387  for (i = FREE_LEASES; i <= RESERVED_LEASES; i++) {
2388  for (l = LEASE_GET_FIRSTP(lptr[i]);
2389  l != NULL;
2390  l = LEASE_GET_NEXTP(lptr[i], l)) {
2391 #if !defined (DEBUG_DUMP_ALL_LEASES)
2392  if (l->hardware_addr.hlen != 0 || l->uid_len != 0 ||
2393  l->tsfp != 0 || l->binding_state != FTS_FREE)
2394 #endif
2395  {
2396  if (write_lease(l) == 0)
2397  return (0);
2398  num_written++;
2399  }
2400  }
2401  }
2402  }
2403  }
2404 
2405  log_info ("Wrote %d leases to leases file.", num_written);
2406  return (1);
2407 }
2408 
2409 /* Write all interesting leases to permanent storage. */
2410 
2412 {
2413  struct host_decl *hp;
2414  struct group_object *gp;
2415  struct hash_bucket *hb;
2416  struct class *cp;
2417  struct collection *colp;
2418  int i;
2419  int num_written;
2420 
2421  /* write all the dynamically-created class declarations. */
2422  if (collections->classes) {
2423  numclasseswritten = 0;
2424  for (colp = collections ; colp ; colp = colp->next) {
2425  for (cp = colp->classes ; cp ; cp = cp->nic) {
2427  (unsigned char *)cp->name,
2428  0, cp);
2429  }
2430  }
2431 
2432  /* XXXJAB this number doesn't include subclasses... */
2433  log_info ("Wrote %d class decls to leases file.",
2435  }
2436 
2437 
2438  /* Write all the dynamically-created group declarations. */
2439  if (group_name_hash) {
2440  num_written = 0;
2441  for (i = 0; i < group_name_hash -> hash_count; i++) {
2442  for (hb = group_name_hash -> buckets [i];
2443  hb; hb = hb -> next) {
2444  gp = (struct group_object *)hb -> value;
2445  if ((gp -> flags & GROUP_OBJECT_DYNAMIC) ||
2446  ((gp -> flags & GROUP_OBJECT_STATIC) &&
2447  (gp -> flags & GROUP_OBJECT_DELETED))) {
2448  if (!write_group (gp))
2449  return 0;
2450  ++num_written;
2451  }
2452  }
2453  }
2454  log_info ("Wrote %d group decls to leases file.", num_written);
2455  }
2456 
2457  /* Write all the deleted host declarations. */
2458  if (host_name_hash) {
2459  num_written = 0;
2460  for (i = 0; i < host_name_hash -> hash_count; i++) {
2461  for (hb = host_name_hash -> buckets [i];
2462  hb; hb = hb -> next) {
2463  hp = (struct host_decl *)hb -> value;
2464  if (((hp -> flags & HOST_DECL_STATIC) &&
2465  (hp -> flags & HOST_DECL_DELETED))) {
2466  if (!write_host (hp))
2467  return 0;
2468  ++num_written;
2469  }
2470  }
2471  }
2472  log_info ("Wrote %d deleted host decls to leases file.",
2473  num_written);
2474  }
2475 
2476  /* Write all the new, dynamic host declarations. */
2477  if (host_name_hash) {
2478  num_written = 0;
2479  for (i = 0; i < host_name_hash -> hash_count; i++) {
2480  for (hb = host_name_hash -> buckets [i];
2481  hb; hb = hb -> next) {
2482  hp = (struct host_decl *)hb -> value;
2483  if ((hp -> flags & HOST_DECL_DYNAMIC)) {
2484  if (!write_host (hp))
2485  ++num_written;
2486  }
2487  }
2488  }
2489  log_info ("Wrote %d new dynamic host decls to leases file.",
2490  num_written);
2491  }
2492 
2493 #if defined (FAILOVER_PROTOCOL)
2494  /* Write all the failover states. */
2496  return 0;
2497 #endif
2498 
2499  switch (local_family) {
2500  case AF_INET:
2501  if (write_leases4() == 0)
2502  return (0);
2503  break;
2504 #ifdef DHCPv6
2505  case AF_INET6:
2506  if (write_leases6() == 0)
2507  return (0);
2508  break;
2509 #endif /* DHCPv6 */
2510  }
2511 
2512  if (commit_leases() == 0)
2513  return (0);
2514  return (1);
2515 }
2516 
2517 #if !defined (BINARY_LEASES)
2518 /* Unlink all the leases in the queue. */
2519 void lease_remove_all(struct lease **lq) {
2520  struct lease *lp, *ln = NULL;
2521 
2522  /* nothing to do */
2523  if (*lq == NULL)
2524  return;
2525 
2526  /* We simply derefernce the first item in the list. When
2527  * it's reference counter goes to zero it will be cleaned
2528  * and the reference counter
2529  *
2530  * Get a pointer to the first item in the list and then
2531  * drop the reference from the queue pointer
2532  */
2533  lease_reference(&lp, *lq, MDL);
2534  lease_dereference(lq, MDL);
2535 
2536  do {
2537  /* if we have a next save a pointer to it and unlink it */
2538  if (lp->next) {
2539  lease_reference(&ln, lp->next, MDL);
2540  lease_dereference(&lp->next, MDL);
2541  }
2542 
2543  /* get rid of what we currently have */
2544  lease_dereference(&lp, MDL);
2545 
2546  /* move the next to the current and loop */
2547  lp = ln;
2548  ln = NULL;
2549  } while (lp != NULL);
2550 }
2551 
2552 /*
2553  * This routine walks through a given lease queue (lq) looking
2554  * for comp. If it doesn't find the lease it is a fatal error
2555  * as it should be on the given queue. Once we find the lease
2556  * we can remove it from this list.
2557  */
2558 void lease_remove(struct lease **lq, struct lease *comp)
2559 {
2560  struct lease *prev, *lp;
2561 
2562  prev = NULL;
2563  for (lp = *lq; lp != NULL; lp = lp->next) {
2564  if (lp == comp)
2565  break;
2566  prev = lp;
2567  }
2568 
2569  if (!lp) {
2570  log_fatal("Lease with binding state %s not on its queue.",
2571  (comp->binding_state < 1 ||
2572  comp->binding_state > FTS_LAST)
2573  ? "unknown"
2574  : binding_state_names[comp->binding_state - 1]);
2575  }
2576 
2577  if (prev) {
2578  lease_dereference(&prev->next, MDL);
2579  if (comp->next) {
2580  lease_reference(&prev->next, comp->next, MDL);
2581  lease_dereference (&comp->next, MDL);
2582  }
2583  } else {
2584  lease_dereference(lq, MDL);
2585  if (comp->next) {
2586  lease_reference(lq, comp->next, MDL);
2587  lease_dereference(&comp->next, MDL);
2588  }
2589  }
2590 }
2591 
2592 /* This routine inserts comp into lq in a sorted fashion.
2593  * The sort key is comp->sort_time, smaller values are
2594  * placed earlier in the list.
2595  */
2596 void lease_insert(struct lease **lq, struct lease *comp)
2597 {
2598  struct lease *prev, *lp;
2599  static struct lease **last_lq = NULL;
2600  static struct lease *last_insert_point = NULL;
2601 
2602  /* This only works during server startup: during runtime, the last
2603  * lease may be dequeued in between calls. If the queue is the same
2604  * as was used previously, and the lease structure isn't (this is not
2605  * a re-queue), use that as a starting point for the insertion-sort.
2606  */
2607  if ((server_starting & SS_QFOLLOW) && (lq == last_lq) &&
2608  (comp != last_insert_point) &&
2609  (last_insert_point->sort_time <= comp->sort_time)) {
2610  prev = last_insert_point;
2611  lp = prev->next;
2612  } else {
2613  prev = NULL;
2614  lp = *lq;
2615  }
2616 
2617  /* Insertion sort the lease onto the appropriate queue. */
2618  for (; lp != NULL ; lp = lp->next) {
2619  if (lp->sort_time >= comp->sort_time)
2620  break;
2621  prev = lp;
2622  }
2623 
2624  if (prev) {
2625  if (prev->next) {
2626  lease_reference(&comp->next, prev->next, MDL);
2627  lease_dereference(&prev->next, MDL);
2628  }
2629  lease_reference(&prev->next, comp, MDL);
2630  } else {
2631  if (*lq) {
2632  lease_reference (&comp->next, *lq, MDL);
2633  lease_dereference(lq, MDL);
2634  }
2635  lease_reference(lq, comp, MDL);
2636  }
2637  last_insert_point = comp;
2638  last_lq = lq;
2639 
2640  return;
2641 }
2642 #endif
2643 
2644 /* In addition to placing this lease upon a lease queue depending on its
2645  * state, it also keeps track of the number of FREE and BACKUP leases in
2646  * existence, and sets the sort_time on the lease.
2647  *
2648  * Sort_time is used in pool_timer() to determine when the lease will
2649  * bubble to the top of the list and be supersede_lease()'d into its next
2650  * state (possibly, if all goes well). Example, ACTIVE leases move to
2651  * EXPIRED state when the 'ends' value is reached, so that is its sort
2652  * time. Most queues are sorted by 'ends', since it is generally best
2653  * practice to re-use the oldest lease, to reduce address collision
2654  * chances.
2655  */
2656 int lease_enqueue (struct lease *comp)
2657 {
2658  LEASE_STRUCT_PTR lq;
2659 
2660  /* No queue to put it on? */
2661  if (!comp -> pool)
2662  return 0;
2663 
2664  /* Figure out which queue it's going to. */
2665  switch (comp -> binding_state) {
2666  case FTS_FREE:
2667  if (comp->flags & RESERVED_LEASE) {
2668  lq = &comp->pool->reserved;
2669  } else {
2670  lq = &comp->pool->free;
2671  comp->pool->free_leases++;
2672  }
2673  comp -> sort_time = comp -> ends;
2674  break;
2675 
2676  case FTS_ACTIVE:
2677  lq = &comp -> pool -> active;
2678  comp -> sort_time = comp -> ends;
2679  break;
2680 
2681  case FTS_EXPIRED:
2682  case FTS_RELEASED:
2683  case FTS_RESET:
2684  lq = &comp -> pool -> expired;
2685 #if defined(FAILOVER_PROTOCOL)
2686  /* In partner_down, tsfp is the time at which the lease
2687  * may be reallocated (stos+mclt). We can do that with
2688  * lease_mine_to_reallocate() anywhere between tsfp and
2689  * ends. But we prefer to wait until ends before doing it
2690  * automatically (choose the greater of the two). Note
2691  * that 'ends' is usually a historic timestamp in the
2692  * case of expired leases, is really only in the future
2693  * on released leases, and if we know a lease to be released
2694  * the peer might still know it to be active...in which case
2695  * it's possible the peer has renewed this lease, so avoid
2696  * doing that.
2697  */
2698  if (comp->pool->failover_peer &&
2699  comp->pool->failover_peer->me.state == partner_down)
2700  comp->sort_time = (comp->tsfp > comp->ends) ?
2701  comp->tsfp : comp->ends;
2702  else
2703 #endif
2704  comp->sort_time = comp->ends;
2705 
2706  break;
2707 
2708  case FTS_ABANDONED:
2709  lq = &comp -> pool -> abandoned;
2710  comp -> sort_time = comp -> ends;
2711  break;
2712 
2713  case FTS_BACKUP:
2714  if (comp->flags & RESERVED_LEASE) {
2715  lq = &comp->pool->reserved;
2716  } else {
2717  lq = &comp->pool->backup;
2718  comp->pool->backup_leases++;
2719  }
2720  comp -> sort_time = comp -> ends;
2721  break;
2722 
2723  default:
2724  log_error ("Lease with bogus binding state: %d",
2725  comp -> binding_state);
2726 #if defined (BINDING_STATE_DEBUG)
2727  abort ();
2728 #endif
2729  return 0;
2730  }
2731 
2732  LEASE_INSERTP(lq, comp);
2733 
2734  return 1;
2735 }
2736 
2737 /* For a given lease, sort it onto the right list in its pool and put it
2738  in each appropriate hash, understanding that it's already by definition
2739  in lease_ip_addr_hash. */
2740 
2741 isc_result_t
2742 lease_instantiate(const void *key, unsigned len, void *object)
2743 {
2744  struct lease *lease = object;
2745  struct class *class;
2746  /* XXX If the lease doesn't have a pool at this point, it's an
2747  XXX orphan, which we *should* keep around until it expires,
2748  XXX but which right now we just forget. */
2749  if (!lease -> pool) {
2750  lease_ip_hash_delete(lease_ip_addr_hash, lease->ip_addr.iabuf,
2751  lease->ip_addr.len, MDL);
2752  return ISC_R_SUCCESS;
2753  }
2754 
2755 #if defined (FAILOVER_PROTOCOL)
2756  /* If the lease is in FTS_BACKUP but there is no peer, then the
2757  * pool must have been formerly configured for failover and
2758  * is now configured as standalone. This means we need to
2759  * move the lease to FTS_FREE to make it available. */
2760  if ((lease->binding_state == FTS_BACKUP) &&
2761  (lease->pool->failover_peer == NULL)) {
2762 #else
2763  /* We aren't compiled for failover, so just move to FTS_FREE */
2764  if (lease->binding_state == FTS_BACKUP) {
2765 #endif
2766  lease->binding_state = FTS_FREE;
2767  lease->next_binding_state = FTS_FREE;
2768  lease->rewind_binding_state = FTS_FREE;
2769  }
2770 
2771  /* Put the lease on the right queue. Failure to queue is probably
2772  * due to a bogus binding state. In such a case, we claim success,
2773  * so that later leases in a hash_foreach are processed, but we
2774  * return early as we really don't want hw address hash entries or
2775  * other cruft to surround such a bogus entry.
2776  */
2777  if (!lease_enqueue(lease))
2778  return ISC_R_SUCCESS;
2779 
2780  /* Record the lease in the uid hash if possible. */
2781  if (lease -> uid) {
2782  uid_hash_add (lease);
2783  }
2784 
2785  /* Record it in the hardware address hash if possible. */
2786  if (lease -> hardware_addr.hlen) {
2787  hw_hash_add (lease);
2788  }
2789 
2790  /* If the lease has a billing class, set up the billing. */
2791  if (lease -> billing_class) {
2792  class = (struct class *)0;
2793  class_reference (&class, lease -> billing_class, MDL);
2794  class_dereference (&lease -> billing_class, MDL);
2795  /* If the lease is available for allocation, the billing
2796  is invalid, so we don't keep it. */
2797  if (lease -> binding_state == FTS_ACTIVE ||
2798  lease -> binding_state == FTS_EXPIRED ||
2799  lease -> binding_state == FTS_RELEASED ||
2800  lease -> binding_state == FTS_RESET)
2801  bill_class (lease, class);
2802  class_dereference (&class, MDL);
2803  }
2804  return ISC_R_SUCCESS;
2805 }
2806 
2807 /* Run expiry events on every pool. This is called on startup so that
2808  any expiry events that occurred after the server stopped and before it
2809  was restarted can be run. At the same time, if failover support is
2810  compiled in, we compute the balance of leases for the pool. */
2811 
2813 {
2814  struct shared_network *s;
2815  struct pool *p;
2816  int i;
2817  struct lease *l;
2819 
2820  /* Indicate that we are in the startup phase */
2821  server_starting = SS_NOSYNC | SS_QFOLLOW;
2822 
2823 #if defined (BINARY_LEASES)
2824  /* set up the growth factors for the binary leases.
2825  * We use 100% for free, 50% for active and backup
2826  * 20% for expired, abandoned and reserved
2827  * but no less than 100, 50, and 20.
2828  */
2829  for (s = shared_networks; s; s = s -> next) {
2830  for (p = s -> pools; p != NULL; p = p -> next) {
2831  size_t num_f = 100, num_a = 50, num_e = 20;
2832  if (p->lease_count > 100) {
2833  num_f = p->lease_count;
2834  num_a = num_f / 2;
2835  num_e = num_f / 5;
2836  }
2837  lc_init_growth(&p->free, num_f);
2838  lc_init_growth(&p->active, num_a);
2839  lc_init_growth(&p->expired, num_a);
2840  lc_init_growth(&p->abandoned, num_e);
2841  lc_init_growth(&p->backup, num_e);
2842  lc_init_growth(&p->reserved, num_e);
2843  }
2844  }
2845 #endif
2846 
2847  /* First, go over the hash list and actually put all the leases
2848  on the appropriate lists. */
2849  lease_ip_hash_foreach(lease_ip_addr_hash, lease_instantiate);
2850 
2851  /* Loop through each pool in each shared network and call the
2852  * expiry routine on the pool. It is no longer safe to follow
2853  * the queue insertion point, as expiration of a lease can move
2854  * it between queues (and this may be the lease that function
2855  * points at).
2856  */
2857  server_starting &= ~SS_QFOLLOW;
2858  for (s = shared_networks; s; s = s -> next) {
2859  for (p = s -> pools; p; p = p -> next) {
2860  pool_timer (p);
2861 
2862  p -> lease_count = 0;
2863  p -> free_leases = 0;
2864  p -> backup_leases = 0;
2865 
2866  lptr [FREE_LEASES] = &p -> free;
2867  lptr [ACTIVE_LEASES] = &p -> active;
2868  lptr [EXPIRED_LEASES] = &p -> expired;
2869  lptr [ABANDONED_LEASES] = &p -> abandoned;
2870  lptr [BACKUP_LEASES] = &p -> backup;
2871  lptr [RESERVED_LEASES] = &p->reserved;
2872 
2873  for (i = FREE_LEASES; i <= RESERVED_LEASES; i++) {
2874  for (l = LEASE_GET_FIRSTP(lptr[i]);
2875  l != NULL;
2876  l = LEASE_GET_NEXTP(lptr[i], l)) {
2877  p -> lease_count++;
2878  if (l -> ends <= cur_time) {
2879  if (l->binding_state == FTS_FREE) {
2880  if (i == FREE_LEASES)
2881  p->free_leases++;
2882  else if (i != RESERVED_LEASES)
2883  log_fatal("Impossible case "
2884  "at %s:%d.", MDL);
2885  } else if (l->binding_state == FTS_BACKUP) {
2886  if (i == BACKUP_LEASES)
2887  p->backup_leases++;
2888  else if (i != RESERVED_LEASES)
2889  log_fatal("Impossible case "
2890  "at %s:%d.", MDL);
2891  }
2892  }
2893 #if defined (FAILOVER_PROTOCOL)
2894  if (p -> failover_peer &&
2895  l -> tstp > l -> atsfp &&
2896  !(l -> flags & ON_UPDATE_QUEUE)) {
2899  }
2900 #endif
2901  }
2902  }
2903  }
2904  }
2905 
2906  /* turn off startup phase */
2907  server_starting = 0;
2908 }
2909 
2911 {
2912  struct lease *l;
2913  struct shared_network *s;
2914  struct subnet *n;
2915  struct pool *p;
2917  int i;
2918 
2919  log_info ("Subnets:");
2920  for (n = subnets; n; n = n -> next_subnet) {
2921  log_debug (" Subnet %s", piaddr (n -> net));
2922  log_debug (" netmask %s",
2923  piaddr (n -> netmask));
2924  }
2925  log_info ("Shared networks:");
2926  for (s = shared_networks; s; s = s -> next) {
2927  log_info (" %s", s -> name);
2928  for (p = s -> pools; p; p = p -> next) {
2929  lptr [FREE_LEASES] = &p -> free;
2930  lptr [ACTIVE_LEASES] = &p -> active;
2931  lptr [EXPIRED_LEASES] = &p -> expired;
2932  lptr [ABANDONED_LEASES] = &p -> abandoned;
2933  lptr [BACKUP_LEASES] = &p -> backup;
2934  lptr [RESERVED_LEASES] = &p->reserved;
2935 
2936  for (i = FREE_LEASES; i <= RESERVED_LEASES; i++) {
2937  for (l = LEASE_GET_FIRSTP(lptr[i]);
2938  l != NULL;
2939  l = LEASE_GET_NEXTP(lptr[i], l)) {
2940  print_lease (l);
2941  }
2942  }
2943  }
2944  }
2945 }
2946 
2947 HASH_FUNCTIONS(lease_ip, const unsigned char *, struct lease, lease_ip_hash_t,
2948  lease_reference, lease_dereference, do_ip4_hash)
2949 HASH_FUNCTIONS(lease_id, const unsigned char *, struct lease, lease_id_hash_t,
2950  lease_reference, lease_dereference, do_id_hash)
2951 HASH_FUNCTIONS (host, const unsigned char *, struct host_decl, host_hash_t,
2952  host_reference, host_dereference, do_string_hash)
2953 HASH_FUNCTIONS (class, const char *, struct class, class_hash_t,
2954  class_reference, class_dereference, do_string_hash)
2955 
2956 #if defined (DEBUG_MEMORY_LEAKAGE) && \
2957  defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
2958 extern struct hash_table *dns_zone_hash;
2959 extern struct interface_info **interface_vector;
2960 extern int interface_count;
2962 extern struct hash_table *auth_key_hash;
2963 struct hash_table *universe_hash;
2964 struct universe **universes;
2966 #if 0
2967 extern int end;
2968 #endif
2969 
2970 #if defined (COMPACT_LEASES)
2971 extern struct lease *lease_hunks;
2972 #endif
2973 
2974 void free_everything(void)
2975 {
2976  struct subnet *sc = (struct subnet *)0, *sn = (struct subnet *)0;
2977  struct shared_network *nc = (struct shared_network *)0,
2978  *nn = (struct shared_network *)0;
2979  struct pool *pc = (struct pool *)0, *pn = (struct pool *)0;
2980  struct lease *lc = NULL, *ln = NULL, *ltemp = NULL;
2981  struct interface_info *ic = (struct interface_info *)0,
2982  *in = (struct interface_info *)0;
2983  struct class *cc = (struct class *)0, *cn = (struct class *)0;
2984  struct collection *lp;
2985  int i;
2986 
2987  /* Get rid of all the hash tables. */
2988  if (host_hw_addr_hash)
2989  host_free_hash_table (&host_hw_addr_hash, MDL);
2990  host_hw_addr_hash = 0;
2991  if (host_uid_hash)
2992  host_free_hash_table (&host_uid_hash, MDL);
2993  host_uid_hash = 0;
2994  if (lease_uid_hash)
2995  lease_id_free_hash_table (&lease_uid_hash, MDL);
2996  lease_uid_hash = 0;
2997  if (lease_ip_addr_hash)
2998  lease_ip_free_hash_table (&lease_ip_addr_hash, MDL);
2999  lease_ip_addr_hash = 0;
3000  if (lease_hw_addr_hash)
3001  lease_id_free_hash_table (&lease_hw_addr_hash, MDL);
3002  lease_hw_addr_hash = 0;
3003  if (host_name_hash)
3004  host_free_hash_table (&host_name_hash, MDL);
3005  host_name_hash = 0;
3006  if (dns_zone_hash)
3007  dns_zone_free_hash_table (&dns_zone_hash, MDL);
3008  dns_zone_hash = 0;
3009 
3010  while (host_id_info != NULL) {
3011  host_id_info_t *tmp;
3012  option_dereference(&host_id_info->option, MDL);
3013  host_free_hash_table(&host_id_info->values_hash, MDL);
3014  tmp = host_id_info->next;
3015  dfree(host_id_info, MDL);
3016  host_id_info = tmp;
3017  }
3018 #if 0
3019  if (auth_key_hash)
3020  auth_key_free_hash_table (&auth_key_hash, MDL);
3021 #endif
3022  auth_key_hash = 0;
3023 
3024  omapi_object_dereference ((omapi_object_t **)&dhcp_control_object,
3025  MDL);
3026 
3027  for (lp = collections; lp; lp = lp -> next) {
3028  if (lp -> classes) {
3029  class_reference (&cn, lp -> classes, MDL);
3030  do {
3031  if (cn) {
3032  class_reference (&cc, cn, MDL);
3033  class_dereference (&cn, MDL);
3034  }
3035  if (cc -> nic) {
3036  class_reference (&cn, cc -> nic, MDL);
3037  class_dereference (&cc -> nic, MDL);
3038  }
3039  group_dereference (&cc -> group, MDL);
3040  if (cc -> hash) {
3041  class_free_hash_table (&cc -> hash, MDL);
3042  cc -> hash = (struct hash_table *)0;
3043  }
3044  class_dereference (&cc, MDL);
3045  } while (cn);
3046  class_dereference (&lp -> classes, MDL);
3047  }
3048  }
3049 
3050  if (interface_vector) {
3051  for (i = 0; i < interface_count; i++) {
3052  if (interface_vector [i])
3053  interface_dereference (&interface_vector [i], MDL);
3054  }
3055  dfree (interface_vector, MDL);
3056  interface_vector = 0;
3057  }
3058 
3059  if (interfaces) {
3060  interface_reference (&in, interfaces, MDL);
3061  do {
3062  if (in) {
3063  interface_reference (&ic, in, MDL);
3064  interface_dereference (&in, MDL);
3065  }
3066  if (ic -> next) {
3067  interface_reference (&in, ic -> next, MDL);
3068  interface_dereference (&ic -> next, MDL);
3069  }
3071  if (ic -> shared_network) {
3072  if (ic -> shared_network -> interface)
3073  interface_dereference
3074  (&ic -> shared_network -> interface, MDL);
3075  shared_network_dereference (&ic -> shared_network, MDL);
3076  }
3077  interface_dereference (&ic, MDL);
3078  } while (in);
3079  interface_dereference (&interfaces, MDL);
3080  }
3081 
3082  /* Subnets are complicated because of the extra links. */
3083  if (subnets) {
3084  subnet_reference (&sn, subnets, MDL);
3085  do {
3086  if (sn) {
3087  subnet_reference (&sc, sn, MDL);
3088  subnet_dereference (&sn, MDL);
3089  }
3090  if (sc -> next_subnet) {
3091  subnet_reference (&sn, sc -> next_subnet, MDL);
3092  subnet_dereference (&sc -> next_subnet, MDL);
3093  }
3094  if (sc -> next_sibling)
3095  subnet_dereference (&sc -> next_sibling, MDL);
3096  if (sc -> shared_network)
3097  shared_network_dereference (&sc -> shared_network, MDL);
3098  group_dereference (&sc -> group, MDL);
3099  if (sc -> interface)
3100  interface_dereference (&sc -> interface, MDL);
3101  subnet_dereference (&sc, MDL);
3102  } while (sn);
3103  subnet_dereference (&subnets, MDL);
3104  }
3105 
3106  /* So are shared networks. */
3107  /* XXX: this doesn't work presently, but i'm ok just filtering
3108  * it out of the noise (you get a bigger spike on the real leaks).
3109  * It would be good to fix this, but it is not a "real bug," so not
3110  * today. This hack is incomplete, it doesn't trim out sub-values.
3111  */
3112  if (shared_networks) {
3113  shared_network_dereference (&shared_networks, MDL);
3114  /* This is the old method (tries to free memory twice, broken) */
3115  } else if (0) {
3116  shared_network_reference (&nn, shared_networks, MDL);
3117  do {
3118  if (nn) {
3119  shared_network_reference (&nc, nn, MDL);
3120  shared_network_dereference (&nn, MDL);
3121  }
3122  if (nc -> next) {
3123  shared_network_reference (&nn, nc -> next, MDL);
3124  shared_network_dereference (&nc -> next, MDL);
3125  }
3126 
3127  /* As are pools. */
3128  if (nc -> pools) {
3129  pool_reference (&pn, nc -> pools, MDL);
3130  do {
3132 
3133  if (pn) {
3134  pool_reference (&pc, pn, MDL);
3135  pool_dereference (&pn, MDL);
3136  }
3137  if (pc -> next) {
3138  pool_reference (&pn, pc -> next, MDL);
3139  pool_dereference (&pc -> next, MDL);
3140  }
3141 
3142  lptr [FREE_LEASES] = &pc -> free;
3143  lptr [ACTIVE_LEASES] = &pc -> active;
3144  lptr [EXPIRED_LEASES] = &pc -> expired;
3145  lptr [ABANDONED_LEASES] = &pc -> abandoned;
3146  lptr [BACKUP_LEASES] = &pc -> backup;
3147  lptr [RESERVED_LEASES] = &pc->reserved;
3148 
3149  /* As (sigh) are leases. */
3150  for (i = FREE_LEASES ; i <= RESERVED_LEASES ; i++) {
3151  if (LEASE_NOT_EMPTYP(lptr[i])) {
3152  lease_reference(&ln, LEASE_GET_FIRSTP(lptr[i]), MDL);
3153  do {
3154  /* save a pointer to the current lease */
3155  lease_reference (&lc, ln, MDL);
3156  lease_dereference (&ln, MDL);
3157 
3158  /* get the next lease if there is one */
3159  ltemp = LEASE_GET_NEXTP(lptr[i], lc);
3160  if (ltemp != NULL) {
3161  lease_reference(&ln, ltemp, MDL);
3162  }
3163 
3164  /* remove the current lease from the queue */
3165  LEASE_REMOVEP(lptr[i], lc);
3166 
3167  if (lc -> billing_class)
3168  class_dereference (&lc -> billing_class,
3169  MDL);
3170  if (lc -> state)
3171  free_lease_state (lc -> state, MDL);
3172  lc -> state = (struct lease_state *)0;
3173  if (lc -> n_hw)
3174  lease_dereference (&lc -> n_hw, MDL);
3175  if (lc -> n_uid)
3176  lease_dereference (&lc -> n_uid, MDL);
3177  lease_dereference (&lc, MDL);
3178  } while (ln);
3179  }
3180  }
3181  if (pc -> group)
3182  group_dereference (&pc -> group, MDL);
3183  if (pc -> shared_network)
3184  shared_network_dereference (&pc -> shared_network,
3185  MDL);
3186  pool_dereference (&pc, MDL);
3187  } while (pn);
3188  pool_dereference (&nc -> pools, MDL);
3189  }
3190  /* Because of a circular reference, we need to nuke this
3191  manually. */
3192  group_dereference (&nc -> group, MDL);
3193  shared_network_dereference (&nc, MDL);
3194  } while (nn);
3195  shared_network_dereference (&shared_networks, MDL);
3196  }
3197 
3200 #if defined(DELAYED_ACK)
3201  relinquish_ackqueue();
3202 #endif
3203  trace_free_all ();
3206 
3213 
3215 
3216  universe_free_hash_table (&universe_hash, MDL);
3217  for (i = 0; i < universe_count; i++) {
3218 #if 0
3219  union {
3220  const char *c;
3221  char *s;
3222  } foo;
3223 #endif
3224  if (universes [i]) {
3225  if (universes[i]->name_hash)
3226  option_name_free_hash_table(
3227  &universes[i]->name_hash,
3228  MDL);
3229  if (universes[i]->code_hash)
3230  option_code_free_hash_table(
3231  &universes[i]->code_hash,
3232  MDL);
3233 #if 0
3234  if (universes [i] -> name > (char *)&end) {
3235  foo.c = universes [i] -> name;
3236  dfree (foo.s, MDL);
3237  }
3238  if (universes [i] > (struct universe *)&end)
3239  dfree (universes [i], MDL);
3240 #endif
3241  }
3242  }
3243  dfree (universes, MDL);
3244 
3245  relinquish_free_lease_states ();
3246  relinquish_free_pairs ();
3247  relinquish_free_expressions ();
3248  relinquish_free_binding_values ();
3249  relinquish_free_option_caches ();
3250  relinquish_free_packets ();
3251 #if defined(COMPACT_LEASES)
3253 #endif
3256 }
3257 #endif /* DEBUG_MEMORY_LEAKAGE_ON_EXIT */
#define FTS_ABANDONED
Definition: dhcpd.h:541
int supersede_lease(struct lease *, struct lease *, int, int, int, int)
Definition: mdb.c:1132
#define FTS_LAST
Definition: dhcpd.h:547
#define GROUP_OBJECT_DYNAMIC
Definition: dhcpd.h:943
LEASE_STRUCT reserved
Definition: dhcpd.h:1027
return DHCP_R_INVALIDARG
Definition: parse.c:1222
struct leasechain * lc
Definition: dhcpd.h:565
int executable_statement_reference(struct executable_statement **ptr, struct executable_statement *bp, const char *file, int line)
Definition: alloc.c:972
int find_grouped_subnet(struct subnet **, struct shared_network *, struct iaddr, const char *, int)
Definition: mdb.c:930
struct class * nic
Definition: dhcpd.h:1090
void unbill_class(struct lease *lease)
Definition: dhclient.c:1532
struct lease * new_leases(unsigned, const char *, int)
#define SS_QFOLLOW
Definition: mdb.c:120
const char int line
Definition: dhcpd.h:3782
lease_id_hash_t * lease_uid_hash
Definition: mdb.c:37
LEASE_STRUCT expired
Definition: dhcpd.h:1023
struct binding_scope * global_scope
Definition: tree.c:38
struct on_star on_star
Definition: dhcpd.h:583
struct universe * universe
Definition: tree.h:348
struct host_id_info host_id_info_t
Definition: dhcpd.h:560
unsigned len
Definition: tree.h:79
int executable_statement_dereference(struct executable_statement **ptr, const char *file, int line)
Definition: execute.c:623
int find_host_for_network(struct subnet **, struct host_decl **, struct iaddr *, struct shared_network *)
Definition: mdb.c:713
const char * piaddr(const struct iaddr addr)
Definition: inet.c:579
u_int8_t hlen
Definition: dhcpd.h:492
#define FTS_FREE
Definition: dhcpd.h:537
struct shared_network * shared_networks
Definition: mdb.c:33
unsigned do_id_hash(const void *, unsigned, unsigned)
Definition: hash.c:290
unsigned char * uid
Definition: dhcpd.h:585
#define LEASE_REMOVEP(LQ, LEASE)
Definition: dhcpd.h:263
void expire_all_pools(void)
Definition: mdb.c:2812
char name[IFNAMSIZ]
Definition: dhcpd.h:1393
struct executable_statement * default_classification_rules
Definition: class.c:31
int executable_statement_foreach(struct executable_statement *stmt, int(*callback)(structexecutable_statement *, void *, int), void *vp, int condp)
Definition: execute.c:1113
Definition: dhcpd.h:1061
int execute_statements(struct binding_value **result, struct packet *packet, struct lease *lease, struct client_state *client_state, struct option_state *in_options, struct option_state *out_options, struct binding_scope **scope, struct executable_statement *statements, struct on_star *on_star)
Definition: execute.c:35
void dhcp_failover_pool_check(struct pool *)
struct iaddr ip_addr(struct iaddr subnet, struct iaddr mask, u_int32_t host_address)
Definition: inet.c:63
isc_result_t unlink_class(struct class **class)
Definition: class.c:209
#define MDL
Definition: omapip.h:567
#define HOST_DECL_DYNAMIC
Definition: dhcpd.h:979
int find_hosts_by_option(struct host_decl **, struct packet *, struct option_state *, const char *, int)
Definition: mdb.c:637
unsigned char iabuf[16]
Definition: inet.h:33
void lease_remove(struct lease **lq, struct lease *comp)
Definition: mdb.c:2558
#define print_hex_1(len, data, limit)
Definition: dhcpd.h:2622
#define HASH_FUNCTIONS(name, bufarg, type, hashtype, ref, deref, hasher)
Definition: hash.h:89
#define FTS_RELEASED
Definition: dhcpd.h:540
#define CLASS_DECL_DELETED
Definition: dhcpd.h:1120
host_hash_t * host_uid_hash
Definition: mdb.c:35
int int int log_debug(const char *,...) __attribute__((__format__(__printf__
omapi_object_type_t * dhcp_type_lease
Definition: omapi.c:46
enum executable_statement::statement_op op
void omapi_type_relinquish(void)
struct option * option
Definition: mdb.c:60
struct executable_statement * on_release
Definition: dhcpd.h:556
unsigned end
Definition: tree.h:335
void uid_hash_add(struct lease *)
Definition: mdb.c:2111
int option_reference(struct option **dest, struct option *src, const char *file, int line)
Definition: tables.c:984
struct universe dhcp_universe
return ISC_R_SUCCESS
Definition: parse.c:1341
void data_string_forget(struct data_string *data, const char *file, int line)
Definition: alloc.c:1339
void hw_hash_delete(struct lease *)
Definition: mdb.c:2308
struct class * billing_class
Definition: dhcpd.h:579
struct group * root_group
Definition: memory.c:31
p
Definition: options.c:1628
int log_error(const char *,...) __attribute__((__format__(__printf__
#define HOST_DECL_DELETED
Definition: dhcpd.h:978
lease_id_hash_t * lease_hw_addr_hash
Definition: mdb.c:39
#define FTS_EXPIRED
Definition: dhcpd.h:539
void cancel_all_timeouts(void)
int binding_scope_dereference(struct binding_scope **ptr, const char *file, int line)
Definition: tree.c:3786
#define ON_UPDATE_QUEUE
Definition: dhcpd.h:596
void add_timeout(struct timeval *when, void(*)(void *) where, void *what, tvref_t ref, tvunref_t unref)
Definition: dispatch.c:206
unsigned short uid_max
Definition: dhcpd.h:587
struct subnet * subnets
Definition: mdb.c:32
void relinquish_lease_hunks(void)
unsigned len
Definition: inet.h:32
dhcp_failover_state_t * failover_peer
Definition: dhcpd.h:1037
void release_lease(struct lease *, struct packet *)
Definition: mdb.c:1732
int find_hosts_by_haddr(struct host_decl **, int, const unsigned char *, unsigned, const char *, int)
Definition: mdb.c:609
parse_warn(cfile,"expecting ip-address or ip-address/prefixlen")
strcpy(uname, val)
log_fatal("no memory for uname information.")
struct data_string client_identifier
Definition: dhcpd.h:966
const char * binding_state_print(enum failover_state state)
Definition: failover.c:6502
struct option_state * options
Definition: dhcpd.h:449
isc_result_t enter_class(struct class *, int, int)
Definition: mdb.c:72
Definition: dhcpd.h:288
Definition: tree.h:301
char * name
Definition: dhcpd.h:1092
LEASE_STRUCT free
Definition: dhcpd.h:1024
int write_leases6(void)
isc_result_t omapi_object_initialize(omapi_object_t *, omapi_object_type_t *, size_t, size_t, const char *, int)
Definition: alloc.c:559
isc_result_t omapi_io_state_foreach(isc_result_t(*func)(omapi_object_t *, void *), void *p)
calls a given function on every object
Definition: dispatch.c:904
#define LEASE_HASH_SIZE
Definition: dhcpd.h:196
int write_leases4(void)
Definition: mdb.c:2370
void dump_subnets(void)
Definition: mdb.c:2910
void pool_timer(void *)
Definition: mdb.c:1891
void free_lease_state(struct lease_state *, const char *, int)
Definition: salloc.c:198
universe_hash_t * universe_hash
Definition: tables.c:966
struct hardware hardware_addr
Definition: dhcpd.h:589
struct iaddr subnet_number(struct iaddr addr, struct iaddr mask)
Definition: inet.c:34
int interface_count
Definition: discover.c:87
int find_subnet(struct subnet **sp, struct iaddr addr, const char *file, int line)
Definition: dhclient.c:1537
#define LEASE_INSERTP(LQ, LEASE)
Definition: dhcpd.h:262
void relinquish_timeouts(void)
void change_host_uid(struct host_decl *host, const char *data, int len)
Definition: mdb.c:183
int subnet_inner_than(const struct subnet *, const struct subnet *, int)
Definition: mdb.c:953
#define FAILOVER_PROTOCOL
Definition: config.h:33
int evaluate_option_cache(struct data_string *result, struct packet *packet, struct lease *lease, struct client_state *client_state, struct option_state *in_options, struct option_state *cfg_options, struct binding_scope **scope, struct option_cache *oc, const char *file, int line)
Definition: tree.c:2699
struct host_id_info * next
Definition: mdb.c:63
Definition: tree.h:345
#define HOST_DECL_STATIC
Definition: dhcpd.h:980
int write_host(struct host_decl *host)
Definition: dhclient.c:2091
int option_chain_head_dereference(struct option_chain_head **ptr, const char *file, int line)
Definition: alloc.c:95
host_hash_t * host_name_hash
Definition: mdb.c:36
TIME sort_time
Definition: dhcpd.h:570
#define MAX_V6RELAY_HOPS
Definition: dhcp6.h:246
#define MIN_TIME
Definition: dhcpd.h:1616
void lease_remove_all(struct lease **lq)
Definition: mdb.c:2519
isc_result_t delete_host(struct host_decl *, int)
Definition: mdb.c:467
#define LEASE_NOT_EMPTYP(LQ)
Definition: dhcpd.h:265
void enter_shared_network(struct shared_network *)
Definition: mdb.c:1032
Definition: dhcpd.h:1015
unsigned do_string_hash(const void *, unsigned, unsigned)
Definition: hash.c:266
void abandon_lease(struct lease *, const char *)
Definition: mdb.c:1807
binding_state_t binding_state
Definition: dhcpd.h:623
#define HTYPE_INFINIBAND
Definition: dhcp.h:78
struct iaddr net
Definition: dhcpd.h:1068
int buffer_allocate(struct buffer **ptr, unsigned len, const char *file, int line)
Definition: alloc.c:679
struct option_cache * option
Definition: statement.h:65
unsigned code
Definition: tree.h:349
int write_lease(struct lease *lease)
Definition: dhclient.c:2085
int group_dereference(struct group **ptr, const char *file, int line)
Definition: alloc.c:205
#define EXPIRED_LEASES
if(parse_ip_addr(cfile,&match->addr))
Definition: parse.c:532
void enter_lease(struct lease *)
Definition: mdb.c:1089
#define FTS_BACKUP
Definition: dhcpd.h:543
Definition: dhcpd.h:405
isc_result_t omapi_object_dereference(omapi_object_t **, const char *, int)
Definition: alloc.c:593
struct pool * pool
Definition: dhcpd.h:578
char * name
Definition: dhcpd.h:964
int find_lease_by_hw_addr(struct lease **, const unsigned char *, unsigned, const char *, int)
Definition: mdb.c:2044
host_hash_t * host_hw_addr_hash
Definition: mdb.c:34
TIME atsfp
Definition: dhcpd.h:639
#define cur_time
Definition: dhcpd.h:2110
struct lease * n_hw
Definition: dhcpd.h:567
int free_leases
Definition: dhcpd.h:1030
Definition: ip.h:47
void(* tvref_t)(void *, void *, const char *, int)
Definition: dhcpd.h:1437
struct lease * n_uid
Definition: dhcpd.h:567
#define BACKUP_LEASES
TIME starts
Definition: dhcpd.h:570
omapi_object_type_t * dhcp_type_host
Definition: mdb.c:70
u_int8_t flags
Definition: dhcpd.h:591
int lease_count
Definition: dhcpd.h:1029
struct host_decl * n_ipaddr
Definition: dhcpd.h:962
int option_chain_head_reference(struct option_chain_head **ptr, struct option_chain_head *bp, const char *file, int line)
Definition: alloc.c:67
void uid_hash_delete(struct lease *)
Definition: mdb.c:2178
struct option_cache * lookup_option(struct universe *universe, struct option_state *options, unsigned code)
Definition: options.c:2465
#define FTS_RESET
Definition: dhcpd.h:542
#define ABANDONED_LEASES
int struct parse * cfile
Definition: parse.c:523
int int log_info(const char *,...) __attribute__((__format__(__printf__
isc_result_t write_named_billing_class(const void *, unsigned, void *)
Definition: db.c:879
struct subnet * subnet
Definition: dhcpd.h:577
#define GROUP_OBJECT_DELETED
Definition: dhcpd.h:942
struct class * classes
Definition: dhcpd.h:1078
void * dmalloc(size_t, const char *, int)
Definition: alloc.c:57
void new_address_range(struct parse *, struct iaddr, struct iaddr, struct subnet *, struct pool *, struct lease **)
Definition: mdb.c:759
struct interface_info * interfaces
Definition: discover.c:42
u_int32_t flags
Definition: dhcpd.h:1407
int write_leases(void)
Definition: mdb.c:2411
#define PERSISTENT_FLAGS
Definition: dhcpd.h:603
int find_hosts_by_uid(struct host_decl **, const unsigned char *, unsigned, const char *, int)
Definition: mdb.c:629
int addr_eq(struct iaddr addr1, struct iaddr addr2)
Definition: inet.c:166
unsigned do_ip4_hash(const void *, unsigned, unsigned)
Definition: hash.c:332
int write_group(struct group_object *)
Definition: db.c:449
isc_result_t delete_class(struct class *, int)
Definition: mdb.c:435
struct subnet * next_subnet
Definition: dhcpd.h:1063
void(* tvunref_t)(void *, const char *, int)
Definition: dhcpd.h:1438
union executable_statement::@7 data
int struct iaddr * addr
Definition: inet.c:185
dhcp_control_object_t * dhcp_control_object
TIME cltt
Definition: dhcpd.h:640
struct universe ** universes
Definition: tables.c:967
dfree(uname, MDL)
struct lease * prev
Definition: dhcpd.h:564
Definition: inet.h:31
int local_family
Definition: discover.c:56
unsigned short uid_len
Definition: dhcpd.h:586
struct iaddr ip_addr
Definition: dhcpd.h:569
u_int32_t host_addr(struct iaddr addr, struct iaddr mask)
Definition: inet.c:138
#define EPHEMERAL_FLAGS
Definition: dhcpd.h:605
Definition: dhcpd.h:948
isc_result_t ddns_removals(struct lease *, struct iasubopt *, struct dhcp_ddns_cb *, isc_boolean_t)
enum dhcp_shutdown_state shutdown_state
Definition: dhcpd.c:1638
#define RESERVED_LEASE
Definition: dhcpd.h:594
#define LEASE_STRUCT_PTR
Definition: dhcpd.h:257
int binding_scope_reference(struct binding_scope **ptr, struct binding_scope *bp, const char *file, int line)
Definition: alloc.c:1227
int hash_foreach(struct hash_table *, hash_foreach_func)
Definition: hash.c:511
int lease_enqueue(struct lease *)
Definition: mdb.c:2656
binding_state_t rewind_binding_state
Definition: dhcpd.h:626
TIME tstp
Definition: dhcpd.h:637
struct interface_info * next
Definition: dhcpd.h:1368
isc_result_t dhcp_io_shutdown(omapi_object_t *, void *)
Definition: dhcpd.c:1640
host_hash_t * values_hash
Definition: mdb.c:61
struct host_decl * host
Definition: dhcpd.h:576
void make_binding_state_transition(struct lease *)
Definition: mdb.c:1480
#define SS_NOSYNC
Definition: mdb.c:119
struct iaddr netmask
Definition: dhcpd.h:1069
int dhcp_failover_queue_update(struct lease *, int)
isc_result_t find_class(struct class **c, const char *s, const char *file, int line)
Definition: dhclient.c:1512
time_t TIME
Definition: dhcpd.h:85
isc_result_t omapi_unregister_io_object(omapi_object_t *)
Definition: dispatch.c:355
binding_state_t desired_binding_state
Definition: dhcpd.h:625
void relinquish_hash_bucket_hunks(void)
struct subnet * next_sibling
Definition: dhcpd.h:1064
dns_zone_hash_t * dns_zone_hash
Definition: dns.c:136
int dhcp_failover_write_all_states(void)
int commit_leases()
Definition: dhclient.c:2080
unsigned char data[1]
Definition: tree.h:62
unsigned code
Definition: parse.c:1219
int find_lease_by_uid(struct lease **, const unsigned char *, unsigned, const char *, int)
Definition: mdb.c:2036
void enter_subnet(struct subnet *)
Definition: mdb.c:985
struct option_cache * oc
Definition: options.c:1687
TIME tsfp
Definition: dhcpd.h:638
isc_result_t enter_host(struct host_decl *, int, int)
Definition: mdb.c:220
#define RESERVED_LEASES
return ISC_R_NOTFOUND
Definition: parse.c:1336
int flags
Definition: dhcpd.h:941
group_hash_t * group_name_hash
Definition: memory.c:32
int flags
Definition: dhcpd.h:1125
#define STATIC_LEASE
Definition: dhcpd.h:592
u_int8_t hbuf[HARDWARE_ADDR_LEN+1]
Definition: dhcpd.h:493
struct lease * next
Definition: dhcpd.h:562
#define MAX_TIME
Definition: dhcpd.h:1615
#define HOST_HASH_SIZE
Definition: dhcpd.h:186
#define FREE_LEASES
int min
Definition: parse.c:980
struct ipv6_pool ** pools
struct collection * collections
Definition: parse.c:34
void lc_init_growth(struct leasechain *lc, size_t growth)
int flags
Definition: dhcpd.h:977
int numclasseswritten
Definition: mdb.c:68
int relays
Definition: mdb.c:62
unsigned char uid_buf[7]
Definition: dhcpd.h:588
#define LEASE_GET_FIRSTP(LQ)
Definition: dhcpd.h:259
const char * binding_state_names[]
Definition: stables.c:161
struct executable_statement * on_expiry
Definition: dhcpd.h:554
struct shared_network * next
Definition: dhcpd.h:1045
const char * file
Definition: dhcpd.h:3782
#define DHO_DHCP_CLIENT_IDENTIFIER
Definition: dhcp.h:152
int universe_max
Definition: tables.c:968
void new_shared_network_interface(struct parse *, struct shared_network *, const char *)
Definition: mdb.c:1043
LEASE_STRUCT active
Definition: dhcpd.h:1022
#define ACTIVE_LEASES
struct collection * next
Definition: dhcpd.h:1075
int bill_class(struct lease *, struct class *)
Definition: class.c:295
struct interface_info ** interface_vector
Definition: discover.c:86
struct executable_statement * on_commit
Definition: dhcpd.h:555
#define LEASE_GET_NEXTP(LQ, LEASE)
Definition: dhcpd.h:261
Definition: dhcpd.h:1088
const unsigned char * data
Definition: tree.h:78
TIME ends
Definition: dhcpd.h:570
struct binding_scope * scope
Definition: dhcpd.h:575
struct hardware interface
Definition: dhcpd.h:965
isc_result_t lease_instantiate(const void *, unsigned, void *)
Definition: mdb.c:2742
LEASE_STRUCT backup
Definition: dhcpd.h:1025
int find_lease_by_ip_addr(struct lease **, struct iaddr, const char *, int)
Definition: mdb.c:2029
u_int32_t abandon_lease_time
Definition: dhcpd.c:99
binding_state_t next_binding_state
Definition: dhcpd.h:624
LEASE_STRUCT abandoned
Definition: dhcpd.h:1026
void hw_hash_add(struct lease *)
Definition: mdb.c:2228
struct pool * pools
Definition: dhcpd.h:1053
lease_ip_hash_t * lease_ip_addr_hash
Definition: mdb.c:38
#define GROUP_OBJECT_STATIC
Definition: dhcpd.h:944
#define INTERFACE_REQUESTED
Definition: dhcpd.h:1408
int universe_count
Definition: tables.c:968
struct buffer * buffer
Definition: tree.h:77
struct pool * next
Definition: dhcpd.h:1017
int option_dereference(struct option **dest, const char *file, int line)
Definition: tables.c:1006
void lease_insert(struct lease **lq, struct lease *comp)
Definition: mdb.c:2596
char * client_hostname
Definition: dhcpd.h:574
void trace_free_all(void)
int lease_copy(struct lease **, struct lease *, const char *, int)
Definition: mdb.c:1658
int backup_leases
Definition: dhcpd.h:1031
struct packet * dhcpv6_container_packet
Definition: dhcpd.h:422
#define FTS_ACTIVE
Definition: dhcpd.h:538