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