ISC DHCP  4.3.6
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;
316  find_uid_statement, &esp, 0)) {
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) {
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);
752  return 1;
753  }
754  }
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) ||
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 
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);
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,
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);
1269  MDL);
1270  }
1271  if (lease->on_star.on_commit) {
1272  if (comp->on_star.on_commit)
1274  (&comp->on_star.on_commit, MDL);
1277  MDL);
1278  }
1279  if (lease->on_star.on_release) {
1280  if (comp->on_star.on_release)
1282  (&comp->on_star.on_release, MDL);
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;
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)
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 &&
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,
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)
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,
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)
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:
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)
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)
1710  file, line);
1711  if (lease->on_star.on_commit)
1714  file, line);
1715  if (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;
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) {
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) &&
1789  ((peer->i_am == secondary) &&
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 = NULL;
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 
1821  if (lt->scope) {
1823  }
1824 
1825  /* Calculate the abandone expiry time. If it wraps,
1826  * use the maximum expiry time. */
1828  if (lt->ends < cur_time || lt->ends > MAX_TIME) {
1829  lt->ends = MAX_TIME;
1830  }
1831 
1833 
1834  log_error ("Abandoning IP address %s: %s", piaddr(lease->ip_addr),
1835  message);
1836  lt->hardware_addr.hlen = 0;
1837  if (lt->uid && lt->uid != lt->uid_buf) {
1838  dfree(lt->uid, MDL);
1839  }
1840 
1841  lt->uid = NULL;
1842  lt->uid_len = 0;
1843  lt->uid_max = 0;
1844  supersede_lease(lease, lt, 1, 1, 1, 0);
1845  lease_dereference(&lt, MDL);
1846 }
1847 
1848 #if 0
1849 /*
1850  * This doesn't appear to be in use for anything anymore.
1851  * I'm ifdeffing it now and if there are no complaints in
1852  * the future it will be removed.
1853  * SAR
1854  */
1855 
1856 /* Abandon the specified lease (set its timeout to infinity and its
1857  particulars to zero, and re-hash it as appropriate. */
1858 
1859 void dissociate_lease (lease)
1860  struct lease *lease;
1861 {
1862  struct lease *lt = (struct lease *)0;
1863 #if defined (NSUPDATE)
1864  (void) ddns_removals(lease, NULL, NULL, ISC_FALSE);
1865 #endif
1866 
1867  if (!lease_copy (&lt, lease, MDL))
1868  return;
1869 
1870 #if defined (FAILOVER_PROTOCOL)
1871  if (lease -> pool && lease -> pool -> failover_peer) {
1872  lt -> next_binding_state = FTS_RESET;
1873  } else {
1874  lt -> next_binding_state = FTS_FREE;
1875  }
1876 #else
1877  lt -> next_binding_state = FTS_FREE;
1878 #endif
1879  lt -> ends = cur_time; /* XXX */
1880  lt -> hardware_addr.hlen = 0;
1881  if (lt -> uid && lt -> uid != lt -> uid_buf)
1882  dfree (lt -> uid, MDL);
1883  lt -> uid = (unsigned char *)0;
1884  lt -> uid_len = 0;
1885  lt -> uid_max = 0;
1886  supersede_lease (lease, lt, 1, 1, 1, 0);
1887  lease_dereference (&lt, MDL);
1888 }
1889 #endif
1890 
1891 /* Timer called when a lease in a particular pool expires. */
1892 void pool_timer (vpool)
1893  void *vpool;
1894 {
1895  struct pool *pool;
1896  struct lease *next = NULL;
1897  struct lease *lease = NULL;
1898  struct lease *ltemp = NULL;
1899 #define FREE_LEASES 0
1900 #define ACTIVE_LEASES 1
1901 #define EXPIRED_LEASES 2
1902 #define ABANDONED_LEASES 3
1903 #define BACKUP_LEASES 4
1904 #define RESERVED_LEASES 5
1906  TIME next_expiry = MAX_TIME;
1907  int i;
1908  struct timeval tv;
1909 
1910  pool = (struct pool *)vpool;
1911 
1912  lptr[FREE_LEASES] = &pool->free;
1913  lptr[ACTIVE_LEASES] = &pool->active;
1914  lptr[EXPIRED_LEASES] = &pool->expired;
1915  lptr[ABANDONED_LEASES] = &pool->abandoned;
1916  lptr[BACKUP_LEASES] = &pool->backup;
1917  lptr[RESERVED_LEASES] = &pool->reserved;
1918 
1919  for (i = FREE_LEASES; i <= RESERVED_LEASES; i++) {
1920  /* If there's nothing on the queue, skip it. */
1921  if (!(LEASE_NOT_EMPTYP(lptr[i])))
1922  continue;
1923 
1924 #if defined (FAILOVER_PROTOCOL)
1925  if (pool->failover_peer &&
1926  pool->failover_peer->me.state != partner_down) {
1927  /*
1928  * Normally the secondary doesn't initiate expiration
1929  * events (unless in partner-down), but rather relies
1930  * on the primary to expire the lease. However, when
1931  * disconnected from its peer, the server is allowed to
1932  * rewind a lease to the previous state that the peer
1933  * would have recorded it. This means there may be
1934  * opportunities for active->free or active->backup
1935  * expirations while out of contact.
1936  *
1937  * Q: Should we limit this expiration to
1938  * comms-interrupt rather than not-normal?
1939  */
1940  if ((i == ACTIVE_LEASES) &&
1941  (pool->failover_peer->i_am == secondary) &&
1942  (pool->failover_peer->me.state == normal))
1943  continue;
1944 
1945  /* Leases in an expired state don't move to
1946  free because of a timeout unless we're in
1947  partner_down. */
1948  if (i == EXPIRED_LEASES)
1949  continue;
1950  }
1951 #endif
1952  lease_reference(&lease, LEASE_GET_FIRSTP(lptr[i]), MDL);
1953 
1954  while (lease) {
1955  /* Remember the next lease in the list. */
1956  if (next)
1957  lease_dereference(&next, MDL);
1958  ltemp = LEASE_GET_NEXTP(lptr[i], lease);
1959  if (ltemp)
1960  lease_reference(&next, ltemp, MDL);
1961 
1962  /* If we've run out of things to expire on this list,
1963  stop. */
1964  if (lease->sort_time > cur_time) {
1965  if (lease->sort_time < next_expiry)
1966  next_expiry = lease->sort_time;
1967  break;
1968  }
1969 
1970  /* If there is a pending state change, and
1971  this lease has gotten to the time when the
1972  state change should happen, just call
1973  supersede_lease on it to make the change
1974  happen. */
1976  {
1977 #if defined(FAILOVER_PROTOCOL)
1978  dhcp_failover_state_t *peer = NULL;
1979 
1980  if (lease->pool != NULL)
1981  peer = lease->pool->failover_peer;
1982 
1983  /* Can we rewind the lease to a free state? */
1984  if (peer != NULL &&
1985  peer->service_state == not_cooperating &&
1987  ((peer->i_am == primary &&
1989  ||
1990  (peer->i_am == secondary &&
1992  FTS_BACKUP)))
1995 #endif
1996  supersede_lease(lease, NULL, 1, 1, 1, 1);
1997  }
1998 
1999  lease_dereference(&lease, MDL);
2000  if (next)
2001  lease_reference(&lease, next, MDL);
2002  }
2003  if (next)
2004  lease_dereference(&next, MDL);
2005  if (lease)
2006  lease_dereference(&lease, MDL);
2007  }
2008 
2009  /* If we found something to expire and its expiration time
2010  * is either less than the current expiration time or the
2011  * current expiration time is already expired update the
2012  * timer.
2013  */
2014  if ((next_expiry != MAX_TIME) &&
2015  ((pool->next_event_time > next_expiry) ||
2016  (pool->next_event_time <= cur_time))) {
2017  pool->next_event_time = next_expiry;
2018  tv.tv_sec = pool->next_event_time;
2019  tv.tv_usec = 0;
2020  add_timeout (&tv, pool_timer, pool,
2021  (tvref_t)pool_reference,
2022  (tvunref_t)pool_dereference);
2023  } else
2025 
2026 }
2027 
2028 /* Locate the lease associated with a given IP address... */
2029 
2030 int find_lease_by_ip_addr (struct lease **lp, struct iaddr addr,
2031  const char *file, int line)
2032 {
2033  return lease_ip_hash_lookup(lp, lease_ip_addr_hash, addr.iabuf,
2034  addr.len, file, line);
2035 }
2036 
2037 int find_lease_by_uid (struct lease **lp, const unsigned char *uid,
2038  unsigned len, const char *file, int line)
2039 {
2040  if (len == 0)
2041  return 0;
2042  return lease_id_hash_lookup (lp, lease_uid_hash, uid, len, file, line);
2043 }
2044 
2045 int find_lease_by_hw_addr (struct lease **lp,
2046  const unsigned char *hwaddr, unsigned hwlen,
2047  const char *file, int line)
2048 {
2049  if (hwlen == 0)
2050  return (0);
2051 
2052  /*
2053  * If it's an infiniband address don't bother
2054  * as we don't have a useful address to hash.
2055  */
2056  if ((hwlen == 1) && (hwaddr[0] == HTYPE_INFINIBAND))
2057  return (0);
2058 
2059  return (lease_id_hash_lookup(lp, lease_hw_addr_hash, hwaddr, hwlen,
2060  file, line));
2061 }
2062 
2063 /* If the lease is preferred over the candidate, return truth. The
2064  * 'cand' and 'lease' names are retained to read more clearly against
2065  * the 'uid_hash_add' and 'hw_hash_add' functions (this is common logic
2066  * to those two functions).
2067  *
2068  * 1) ACTIVE leases are preferred. The active lease with
2069  * the longest lifetime is preferred over shortest.
2070  * 2) "transitional states" are next, this time with the
2071  * most recent CLTT.
2072  * 3) free/backup/etc states are next, again with CLTT. In truth we
2073  * should never see reset leases for this.
2074  * 4) Abandoned leases are always dead last.
2075  */
2076 static isc_boolean_t
2077 client_lease_preferred(struct lease *cand, struct lease *lease)
2078 {
2079  if (cand->binding_state == FTS_ACTIVE) {
2080  if (lease->binding_state == FTS_ACTIVE &&
2081  lease->ends >= cand->ends)
2082  return ISC_TRUE;
2083  } else if (cand->binding_state == FTS_EXPIRED ||
2084  cand->binding_state == FTS_RELEASED) {
2085  if (lease->binding_state == FTS_ACTIVE)
2086  return ISC_TRUE;
2087 
2088  if ((lease->binding_state == FTS_EXPIRED ||
2090  lease->cltt >= cand->cltt)
2091  return ISC_TRUE;
2092  } else if (cand->binding_state != FTS_ABANDONED) {
2093  if (lease->binding_state == FTS_ACTIVE ||
2096  return ISC_TRUE;
2097 
2098  if (lease->binding_state != FTS_ABANDONED &&
2099  lease->cltt >= cand->cltt)
2100  return ISC_TRUE;
2101  } else /* (cand->binding_state == FTS_ABANDONED) */ {
2102  if (lease->binding_state != FTS_ABANDONED ||
2103  lease->cltt >= cand->cltt)
2104  return ISC_TRUE;
2105  }
2106 
2107  return ISC_FALSE;
2108 }
2109 
2110 /* Add the specified lease to the uid hash. */
2111 void
2113 {
2114  struct lease *head = NULL;
2115  struct lease *cand = NULL;
2116  struct lease *prev = NULL;
2117  struct lease *next = NULL;
2118 
2119  /* If it's not in the hash, just add it. */
2120  if (!find_lease_by_uid (&head, lease -> uid, lease -> uid_len, MDL))
2121  lease_id_hash_add(lease_uid_hash, lease->uid, lease->uid_len,
2122  lease, MDL);
2123  else {
2124  /* Otherwise, insert it into the list in order of its
2125  * preference for "resuming allocation to the client."
2126  *
2127  * Because we don't have control of the hash bucket index
2128  * directly, we have to remove and re-insert the client
2129  * id into the hash if we're inserting onto the head.
2130  */
2131  lease_reference(&cand, head, MDL);
2132  while (cand != NULL) {
2133  if (client_lease_preferred(cand, lease))
2134  break;
2135 
2136  if (prev != NULL)
2137  lease_dereference(&prev, MDL);
2138  lease_reference(&prev, cand, MDL);
2139 
2140  if (cand->n_uid != NULL)
2141  lease_reference(&next, cand->n_uid, MDL);
2142 
2143  lease_dereference(&cand, MDL);
2144 
2145  if (next != NULL) {
2146  lease_reference(&cand, next, MDL);
2147  lease_dereference(&next, MDL);
2148  }
2149  }
2150 
2151  /* If we want to insert 'before cand', and prev is NULL,
2152  * then it was the head of the list. Assume that position.
2153  */
2154  if (prev == NULL) {
2155  lease_reference(&lease->n_uid, head, MDL);
2156  lease_id_hash_delete(lease_uid_hash, lease->uid,
2157  lease->uid_len, MDL);
2158  lease_id_hash_add(lease_uid_hash, lease->uid,
2159  lease->uid_len, lease, MDL);
2160  } else /* (prev != NULL) */ {
2161  if(prev->n_uid != NULL) {
2162  lease_reference(&lease->n_uid, prev->n_uid,
2163  MDL);
2164  lease_dereference(&prev->n_uid, MDL);
2165  }
2166  lease_reference(&prev->n_uid, lease, MDL);
2167 
2168  lease_dereference(&prev, MDL);
2169  }
2170 
2171  if (cand != NULL)
2172  lease_dereference(&cand, MDL);
2173  lease_dereference(&head, MDL);
2174  }
2175 }
2176 
2177 /* Delete the specified lease from the uid hash. */
2178 
2180  struct lease *lease;
2181 {
2182  struct lease *head = (struct lease *)0;
2183  struct lease *scan;
2184 
2185  /* If it's not in the hash, we have no work to do. */
2186  if (!find_lease_by_uid (&head, lease -> uid, lease -> uid_len, MDL)) {
2187  if (lease -> n_uid)
2188  lease_dereference (&lease -> n_uid, MDL);
2189  return;
2190  }
2191 
2192  /* If the lease we're freeing is at the head of the list,
2193  remove the hash table entry and add a new one with the
2194  next lease on the list (if there is one). */
2195  if (head == lease) {
2196  lease_id_hash_delete(lease_uid_hash, lease->uid,
2197  lease->uid_len, MDL);
2198  if (lease -> n_uid) {
2199  lease_id_hash_add(lease_uid_hash, lease->n_uid->uid,
2201  MDL);
2202  lease_dereference (&lease -> n_uid, MDL);
2203  }
2204  } else {
2205  /* Otherwise, look for the lease in the list of leases
2206  attached to the hash table entry, and remove it if
2207  we find it. */
2208  for (scan = head; scan -> n_uid; scan = scan -> n_uid) {
2209  if (scan -> n_uid == lease) {
2210  lease_dereference (&scan -> n_uid, MDL);
2211  if (lease -> n_uid) {
2212  lease_reference (&scan -> n_uid,
2213  lease -> n_uid, MDL);
2214  lease_dereference (&lease -> n_uid,
2215  MDL);
2216  }
2217  break;
2218  }
2219  }
2220  }
2221  lease_dereference (&head, MDL);
2222 }
2223 
2224 /* Add the specified lease to the hardware address hash. */
2225 /* We don't add leases with infiniband addresses to the
2226  * hash as there isn't any address to hash on. */
2227 
2228 void
2230 {
2231  struct lease *head = NULL;
2232  struct lease *cand = NULL;
2233  struct lease *prev = NULL;
2234  struct lease *next = NULL;
2235 
2236  /*
2237  * If it's an infiniband address don't bother
2238  * as we don't have a useful address to hash.
2239  */
2240  if ((lease->hardware_addr.hlen == 1) &&
2242  return;
2243 
2244  /* If it's not in the hash, just add it. */
2246  lease -> hardware_addr.hlen, MDL))
2247  lease_id_hash_add(lease_hw_addr_hash,
2250  else {
2251  /* Otherwise, insert it into the list in order of its
2252  * preference for "resuming allocation to the client."
2253  *
2254  * Because we don't have control of the hash bucket index
2255  * directly, we have to remove and re-insert the client
2256  * id into the hash if we're inserting onto the head.
2257  */
2258  lease_reference(&cand, head, MDL);
2259  while (cand != NULL) {
2260  if (client_lease_preferred(cand, lease))
2261  break;
2262 
2263  if (prev != NULL)
2264  lease_dereference(&prev, MDL);
2265  lease_reference(&prev, cand, MDL);
2266 
2267  if (cand->n_hw != NULL)
2268  lease_reference(&next, cand->n_hw, MDL);
2269 
2270  lease_dereference(&cand, MDL);
2271 
2272  if (next != NULL) {
2273  lease_reference(&cand, next, MDL);
2274  lease_dereference(&next, MDL);
2275  }
2276  }
2277 
2278  /* If we want to insert 'before cand', and prev is NULL,
2279  * then it was the head of the list. Assume that position.
2280  */
2281  if (prev == NULL) {
2282  lease_reference(&lease->n_hw, head, MDL);
2283  lease_id_hash_delete(lease_hw_addr_hash,
2286  lease_id_hash_add(lease_hw_addr_hash,
2289  lease, MDL);
2290  } else /* (prev != NULL) */ {
2291  if(prev->n_hw != NULL) {
2292  lease_reference(&lease->n_hw, prev->n_hw,
2293  MDL);
2294  lease_dereference(&prev->n_hw, MDL);
2295  }
2296  lease_reference(&prev->n_hw, lease, MDL);
2297 
2298  lease_dereference(&prev, MDL);
2299  }
2300 
2301  if (cand != NULL)
2302  lease_dereference(&cand, MDL);
2303  lease_dereference(&head, MDL);
2304  }
2305 }
2306 
2307 /* Delete the specified lease from the hardware address hash. */
2308 
2310  struct lease *lease;
2311 {
2312  struct lease *head = (struct lease *)0;
2313  struct lease *next = (struct lease *)0;
2314 
2315  /*
2316  * If it's an infiniband address don't bother
2317  * as we don't have a useful address to hash.
2318  */
2319  if ((lease->hardware_addr.hlen == 1) &&
2321  return;
2322 
2323  /* If it's not in the hash, we have no work to do. */
2325  lease -> hardware_addr.hlen, MDL)) {
2326  if (lease -> n_hw)
2327  lease_dereference (&lease -> n_hw, MDL);
2328  return;
2329  }
2330 
2331  /* If the lease we're freeing is at the head of the list,
2332  remove the hash table entry and add a new one with the
2333  next lease on the list (if there is one). */
2334  if (head == lease) {
2335  lease_id_hash_delete(lease_hw_addr_hash,
2338  if (lease->n_hw) {
2339  lease_id_hash_add(lease_hw_addr_hash,
2342  lease->n_hw, MDL);
2343  lease_dereference(&lease->n_hw, MDL);
2344  }
2345  } else {
2346  /* Otherwise, look for the lease in the list of leases
2347  attached to the hash table entry, and remove it if
2348  we find it. */
2349  while (head -> n_hw) {
2350  if (head -> n_hw == lease) {
2351  lease_dereference (&head -> n_hw, MDL);
2352  if (lease -> n_hw) {
2353  lease_reference (&head -> n_hw,
2354  lease -> n_hw, MDL);
2355  lease_dereference (&lease -> n_hw,
2356  MDL);
2357  }
2358  break;
2359  }
2360  lease_reference (&next, head -> n_hw, MDL);
2361  lease_dereference (&head, MDL);
2362  lease_reference (&head, next, MDL);
2363  lease_dereference (&next, MDL);
2364  }
2365  }
2366  if (head)
2367  lease_dereference (&head, MDL);
2368 }
2369 
2370 /* Write v4 leases to permanent storage. */
2371 int write_leases4(void) {
2372  struct lease *l;
2373  struct shared_network *s;
2374  struct pool *p;
2376  int num_written = 0, i;
2377 
2378  /* Write all the leases. */
2379  for (s = shared_networks; s; s = s->next) {
2380  for (p = s->pools; p; p = p->next) {
2381  lptr[FREE_LEASES] = &p->free;
2382  lptr[ACTIVE_LEASES] = &p->active;
2383  lptr[EXPIRED_LEASES] = &p->expired;
2384  lptr[ABANDONED_LEASES] = &p->abandoned;
2385  lptr[BACKUP_LEASES] = &p->backup;
2386  lptr[RESERVED_LEASES] = &p->reserved;
2387 
2388  for (i = FREE_LEASES; i <= RESERVED_LEASES; i++) {
2389  for (l = LEASE_GET_FIRSTP(lptr[i]);
2390  l != NULL;
2391  l = LEASE_GET_NEXTP(lptr[i], l)) {
2392 #if !defined (DEBUG_DUMP_ALL_LEASES)
2393  if (l->hardware_addr.hlen != 0 || l->uid_len != 0 ||
2394  l->tsfp != 0 || l->binding_state != FTS_FREE)
2395 #endif
2396  {
2397  if (write_lease(l) == 0)
2398  return (0);
2399  num_written++;
2400  }
2401  }
2402  }
2403  }
2404  }
2405 
2406  log_info ("Wrote %d leases to leases file.", num_written);
2407  return (1);
2408 }
2409 
2410 /* Write all interesting leases to permanent storage. */
2411 
2413 {
2414  struct host_decl *hp;
2415  struct group_object *gp;
2416  struct hash_bucket *hb;
2417  struct class *cp;
2418  struct collection *colp;
2419  int i;
2420  int num_written;
2421 
2422  /* write all the dynamically-created class declarations. */
2423  if (collections->classes) {
2424  numclasseswritten = 0;
2425  for (colp = collections ; colp ; colp = colp->next) {
2426  for (cp = colp->classes ; cp ; cp = cp->nic) {
2428  (unsigned char *)cp->name,
2429  0, cp);
2430  }
2431  }
2432 
2433  /* XXXJAB this number doesn't include subclasses... */
2434  log_info ("Wrote %d class decls to leases file.",
2436  }
2437 
2438 
2439  /* Write all the dynamically-created group declarations. */
2440  if (group_name_hash) {
2441  num_written = 0;
2442  for (i = 0; i < group_name_hash -> hash_count; i++) {
2443  for (hb = group_name_hash -> buckets [i];
2444  hb; hb = hb -> next) {
2445  gp = (struct group_object *)hb -> value;
2446  if ((gp -> flags & GROUP_OBJECT_DYNAMIC) ||
2447  ((gp -> flags & GROUP_OBJECT_STATIC) &&
2448  (gp -> flags & GROUP_OBJECT_DELETED))) {
2449  if (!write_group (gp))
2450  return 0;
2451  ++num_written;
2452  }
2453  }
2454  }
2455  log_info ("Wrote %d group decls to leases file.", num_written);
2456  }
2457 
2458  /* Write all the deleted host declarations. */
2459  if (host_name_hash) {
2460  num_written = 0;
2461  for (i = 0; i < host_name_hash -> hash_count; i++) {
2462  for (hb = host_name_hash -> buckets [i];
2463  hb; hb = hb -> next) {
2464  hp = (struct host_decl *)hb -> value;
2465  if (((hp -> flags & HOST_DECL_STATIC) &&
2466  (hp -> flags & HOST_DECL_DELETED))) {
2467  if (!write_host (hp))
2468  return 0;
2469  ++num_written;
2470  }
2471  }
2472  }
2473  log_info ("Wrote %d deleted host decls to leases file.",
2474  num_written);
2475  }
2476 
2477  /* Write all the new, dynamic host declarations. */
2478  if (host_name_hash) {
2479  num_written = 0;
2480  for (i = 0; i < host_name_hash -> hash_count; i++) {
2481  for (hb = host_name_hash -> buckets [i];
2482  hb; hb = hb -> next) {
2483  hp = (struct host_decl *)hb -> value;
2484  if ((hp -> flags & HOST_DECL_DYNAMIC)) {
2485  if (!write_host (hp))
2486  ++num_written;
2487  }
2488  }
2489  }
2490  log_info ("Wrote %d new dynamic host decls to leases file.",
2491  num_written);
2492  }
2493 
2494 #if defined (FAILOVER_PROTOCOL)
2495  /* Write all the failover states. */
2497  return 0;
2498 #endif
2499 
2500  switch (local_family) {
2501  case AF_INET:
2502  if (write_leases4() == 0)
2503  return (0);
2504  break;
2505 #ifdef DHCPv6
2506  case AF_INET6:
2507  if (write_leases6() == 0)
2508  return (0);
2509  break;
2510 #endif /* DHCPv6 */
2511  }
2512 
2513  if (commit_leases() == 0)
2514  return (0);
2515  return (1);
2516 }
2517 
2518 #if !defined (BINARY_LEASES)
2519 /* Unlink all the leases in the queue. */
2520 void lease_remove_all(struct lease **lq) {
2521  struct lease *lp, *ln = NULL;
2522 
2523  /* nothing to do */
2524  if (*lq == NULL)
2525  return;
2526 
2527  /* We simply derefernce the first item in the list. When
2528  * it's reference counter goes to zero it will be cleaned
2529  * and the reference counter
2530  *
2531  * Get a pointer to the first item in the list and then
2532  * drop the reference from the queue pointer
2533  */
2534  lease_reference(&lp, *lq, MDL);
2535  lease_dereference(lq, MDL);
2536 
2537  do {
2538  /* if we have a next save a pointer to it and unlink it */
2539  if (lp->next) {
2540  lease_reference(&ln, lp->next, MDL);
2541  lease_dereference(&lp->next, MDL);
2542  }
2543 
2544  /* get rid of what we currently have */
2545  lease_dereference(&lp, MDL);
2546 
2547  /* move the next to the current and loop */
2548  lp = ln;
2549  ln = NULL;
2550  } while (lp != NULL);
2551 }
2552 
2553 /*
2554  * This routine walks through a given lease queue (lq) looking
2555  * for comp. If it doesn't find the lease it is a fatal error
2556  * as it should be on the given queue. Once we find the lease
2557  * we can remove it from this list.
2558  */
2559 void lease_remove(struct lease **lq, struct lease *comp)
2560 {
2561  struct lease *prev, *lp;
2562 
2563  prev = NULL;
2564  for (lp = *lq; lp != NULL; lp = lp->next) {
2565  if (lp == comp)
2566  break;
2567  prev = lp;
2568  }
2569 
2570  if (!lp) {
2571  log_fatal("Lease with binding state %s not on its queue.",
2572  (comp->binding_state < 1 ||
2573  comp->binding_state > FTS_LAST)
2574  ? "unknown"
2575  : binding_state_names[comp->binding_state - 1]);
2576  }
2577 
2578  if (prev) {
2579  lease_dereference(&prev->next, MDL);
2580  if (comp->next) {
2581  lease_reference(&prev->next, comp->next, MDL);
2582  lease_dereference (&comp->next, MDL);
2583  }
2584  } else {
2585  lease_dereference(lq, MDL);
2586  if (comp->next) {
2587  lease_reference(lq, comp->next, MDL);
2588  lease_dereference(&comp->next, MDL);
2589  }
2590  }
2591 }
2592 
2593 /* This routine inserts comp into lq in a sorted fashion.
2594  * The sort key is comp->sort_time, smaller values are
2595  * placed earlier in the list.
2596  */
2597 void lease_insert(struct lease **lq, struct lease *comp)
2598 {
2599  struct lease *prev, *lp;
2600  static struct lease **last_lq = NULL;
2601  static struct lease *last_insert_point = NULL;
2602 
2603  /* This only works during server startup: during runtime, the last
2604  * lease may be dequeued in between calls. If the queue is the same
2605  * as was used previously, and the lease structure isn't (this is not
2606  * a re-queue), use that as a starting point for the insertion-sort.
2607  */
2608  if ((server_starting & SS_QFOLLOW) && (lq == last_lq) &&
2609  (comp != last_insert_point) &&
2610  (last_insert_point->sort_time <= comp->sort_time)) {
2611  prev = last_insert_point;
2612  lp = prev->next;
2613  } else {
2614  prev = NULL;
2615  lp = *lq;
2616  }
2617 
2618  /* Insertion sort the lease onto the appropriate queue. */
2619  for (; lp != NULL ; lp = lp->next) {
2620  if (lp->sort_time >= comp->sort_time)
2621  break;
2622  prev = lp;
2623  }
2624 
2625  if (prev) {
2626  if (prev->next) {
2627  lease_reference(&comp->next, prev->next, MDL);
2628  lease_dereference(&prev->next, MDL);
2629  }
2630  lease_reference(&prev->next, comp, MDL);
2631  } else {
2632  if (*lq) {
2633  lease_reference (&comp->next, *lq, MDL);
2634  lease_dereference(lq, MDL);
2635  }
2636  lease_reference(lq, comp, MDL);
2637  }
2638  last_insert_point = comp;
2639  last_lq = lq;
2640 
2641  return;
2642 }
2643 #endif
2644 
2645 /* In addition to placing this lease upon a lease queue depending on its
2646  * state, it also keeps track of the number of FREE and BACKUP leases in
2647  * existence, and sets the sort_time on the lease.
2648  *
2649  * Sort_time is used in pool_timer() to determine when the lease will
2650  * bubble to the top of the list and be supersede_lease()'d into its next
2651  * state (possibly, if all goes well). Example, ACTIVE leases move to
2652  * EXPIRED state when the 'ends' value is reached, so that is its sort
2653  * time. Most queues are sorted by 'ends', since it is generally best
2654  * practice to re-use the oldest lease, to reduce address collision
2655  * chances.
2656  */
2657 int lease_enqueue (struct lease *comp)
2658 {
2659  LEASE_STRUCT_PTR lq;
2660 
2661  /* No queue to put it on? */
2662  if (!comp -> pool)
2663  return 0;
2664 
2665  /* Figure out which queue it's going to. */
2666  switch (comp -> binding_state) {
2667  case FTS_FREE:
2668  if (comp->flags & RESERVED_LEASE) {
2669  lq = &comp->pool->reserved;
2670  } else {
2671  lq = &comp->pool->free;
2672  comp->pool->free_leases++;
2673  }
2674  comp -> sort_time = comp -> ends;
2675  break;
2676 
2677  case FTS_ACTIVE:
2678  lq = &comp -> pool -> active;
2679  comp -> sort_time = comp -> ends;
2680  break;
2681 
2682  case FTS_EXPIRED:
2683  case FTS_RELEASED:
2684  case FTS_RESET:
2685  lq = &comp -> pool -> expired;
2686 #if defined(FAILOVER_PROTOCOL)
2687  /* In partner_down, tsfp is the time at which the lease
2688  * may be reallocated (stos+mclt). We can do that with
2689  * lease_mine_to_reallocate() anywhere between tsfp and
2690  * ends. But we prefer to wait until ends before doing it
2691  * automatically (choose the greater of the two). Note
2692  * that 'ends' is usually a historic timestamp in the
2693  * case of expired leases, is really only in the future
2694  * on released leases, and if we know a lease to be released
2695  * the peer might still know it to be active...in which case
2696  * it's possible the peer has renewed this lease, so avoid
2697  * doing that.
2698  */
2699  if (comp->pool->failover_peer &&
2700  comp->pool->failover_peer->me.state == partner_down)
2701  comp->sort_time = (comp->tsfp > comp->ends) ?
2702  comp->tsfp : comp->ends;
2703  else
2704 #endif
2705  comp->sort_time = comp->ends;
2706 
2707  break;
2708 
2709  case FTS_ABANDONED:
2710  lq = &comp -> pool -> abandoned;
2711  comp -> sort_time = comp -> ends;
2712  break;
2713 
2714  case FTS_BACKUP:
2715  if (comp->flags & RESERVED_LEASE) {
2716  lq = &comp->pool->reserved;
2717  } else {
2718  lq = &comp->pool->backup;
2719  comp->pool->backup_leases++;
2720  }
2721  comp -> sort_time = comp -> ends;
2722  break;
2723 
2724  default:
2725  log_error ("Lease with bogus binding state: %d",
2726  comp -> binding_state);
2727 #if defined (BINDING_STATE_DEBUG)
2728  abort ();
2729 #endif
2730  return 0;
2731  }
2732 
2733  LEASE_INSERTP(lq, comp);
2734 
2735  return 1;
2736 }
2737 
2738 /* For a given lease, sort it onto the right list in its pool and put it
2739  in each appropriate hash, understanding that it's already by definition
2740  in lease_ip_addr_hash. */
2741 
2742 isc_result_t
2743 lease_instantiate(const void *key, unsigned len, void *object)
2744 {
2745  struct lease *lease = object;
2746  struct class *class;
2747  /* XXX If the lease doesn't have a pool at this point, it's an
2748  XXX orphan, which we *should* keep around until it expires,
2749  XXX but which right now we just forget. */
2750  if (!lease -> pool) {
2751  lease_ip_hash_delete(lease_ip_addr_hash, lease->ip_addr.iabuf,
2752  lease->ip_addr.len, MDL);
2753  return ISC_R_SUCCESS;
2754  }
2755 
2756 #if defined (FAILOVER_PROTOCOL)
2757  /* If the lease is in FTS_BACKUP but there is no peer, then the
2758  * pool must have been formerly configured for failover and
2759  * is now configured as standalone. This means we need to
2760  * move the lease to FTS_FREE to make it available. */
2761  if ((lease->binding_state == FTS_BACKUP) &&
2762  (lease->pool->failover_peer == NULL)) {
2763 #else
2764  /* We aren't compiled for failover, so just move to FTS_FREE */
2765  if (lease->binding_state == FTS_BACKUP) {
2766 #endif
2770  }
2771 
2772  /* Put the lease on the right queue. Failure to queue is probably
2773  * due to a bogus binding state. In such a case, we claim success,
2774  * so that later leases in a hash_foreach are processed, but we
2775  * return early as we really don't want hw address hash entries or
2776  * other cruft to surround such a bogus entry.
2777  */
2778  if (!lease_enqueue(lease))
2779  return ISC_R_SUCCESS;
2780 
2781  /* Record the lease in the uid hash if possible. */
2782  if (lease -> uid) {
2783  uid_hash_add (lease);
2784  }
2785 
2786  /* Record it in the hardware address hash if possible. */
2787  if (lease -> hardware_addr.hlen) {
2788  hw_hash_add (lease);
2789  }
2790 
2791  /* If the lease has a billing class, set up the billing. */
2792  if (lease -> billing_class) {
2793  class = (struct class *)0;
2794  class_reference (&class, lease -> billing_class, MDL);
2795  class_dereference (&lease -> billing_class, MDL);
2796  /* If the lease is available for allocation, the billing
2797  is invalid, so we don't keep it. */
2798  if (lease -> binding_state == FTS_ACTIVE ||
2799  lease -> binding_state == FTS_EXPIRED ||
2800  lease -> binding_state == FTS_RELEASED ||
2801  lease -> binding_state == FTS_RESET)
2802  bill_class (lease, class);
2803  class_dereference (&class, MDL);
2804  }
2805  return ISC_R_SUCCESS;
2806 }
2807 
2808 /* Run expiry events on every pool. This is called on startup so that
2809  any expiry events that occurred after the server stopped and before it
2810  was restarted can be run. At the same time, if failover support is
2811  compiled in, we compute the balance of leases for the pool. */
2812 
2814 {
2815  struct shared_network *s;
2816  struct pool *p;
2817  int i;
2818  struct lease *l;
2820 
2821  /* Indicate that we are in the startup phase */
2822  server_starting = SS_NOSYNC | SS_QFOLLOW;
2823 
2824 #if defined (BINARY_LEASES)
2825  /* set up the growth factors for the binary leases.
2826  * We use 100% for free, 50% for active and backup
2827  * 20% for expired, abandoned and reserved
2828  * but no less than 100, 50, and 20.
2829  */
2830  for (s = shared_networks; s; s = s -> next) {
2831  for (p = s -> pools; p != NULL; p = p -> next) {
2832  size_t num_f = 100, num_a = 50, num_e = 20;
2833  if (p->lease_count > 100) {
2834  num_f = p->lease_count;
2835  num_a = num_f / 2;
2836  num_e = num_f / 5;
2837  }
2838  lc_init_growth(&p->free, num_f);
2839  lc_init_growth(&p->active, num_a);
2840  lc_init_growth(&p->expired, num_a);
2841  lc_init_growth(&p->abandoned, num_e);
2842  lc_init_growth(&p->backup, num_e);
2843  lc_init_growth(&p->reserved, num_e);
2844  }
2845  }
2846 #endif
2847 
2848  /* First, go over the hash list and actually put all the leases
2849  on the appropriate lists. */
2850  lease_ip_hash_foreach(lease_ip_addr_hash, lease_instantiate);
2851 
2852  /* Loop through each pool in each shared network and call the
2853  * expiry routine on the pool. It is no longer safe to follow
2854  * the queue insertion point, as expiration of a lease can move
2855  * it between queues (and this may be the lease that function
2856  * points at).
2857  */
2858  server_starting &= ~SS_QFOLLOW;
2859  for (s = shared_networks; s; s = s -> next) {
2860  for (p = s -> pools; p; p = p -> next) {
2861  pool_timer (p);
2862 
2863  p -> lease_count = 0;
2864  p -> free_leases = 0;
2865  p -> backup_leases = 0;
2866 
2867  lptr [FREE_LEASES] = &p -> free;
2868  lptr [ACTIVE_LEASES] = &p -> active;
2869  lptr [EXPIRED_LEASES] = &p -> expired;
2870  lptr [ABANDONED_LEASES] = &p -> abandoned;
2871  lptr [BACKUP_LEASES] = &p -> backup;
2872  lptr [RESERVED_LEASES] = &p->reserved;
2873 
2874  for (i = FREE_LEASES; i <= RESERVED_LEASES; i++) {
2875  for (l = LEASE_GET_FIRSTP(lptr[i]);
2876  l != NULL;
2877  l = LEASE_GET_NEXTP(lptr[i], l)) {
2878  p -> lease_count++;
2879  if (l -> ends <= cur_time) {
2880  if (l->binding_state == FTS_FREE) {
2881  if (i == FREE_LEASES)
2882  p->free_leases++;
2883  else if (i != RESERVED_LEASES)
2884  log_fatal("Impossible case "
2885  "at %s:%d.", MDL);
2886  } else if (l->binding_state == FTS_BACKUP) {
2887  if (i == BACKUP_LEASES)
2888  p->backup_leases++;
2889  else if (i != RESERVED_LEASES)
2890  log_fatal("Impossible case "
2891  "at %s:%d.", MDL);
2892  }
2893  }
2894 #if defined (FAILOVER_PROTOCOL)
2895  if (p -> failover_peer &&
2896  l -> tstp > l -> atsfp &&
2897  !(l -> flags & ON_UPDATE_QUEUE)) {
2900  }
2901 #endif
2902  }
2903  }
2904  }
2905  }
2906 
2907  /* turn off startup phase */
2908  server_starting = 0;
2909 }
2910 
2912 {
2913  struct lease *l;
2914  struct shared_network *s;
2915  struct subnet *n;
2916  struct pool *p;
2918  int i;
2919 
2920  log_info ("Subnets:");
2921  for (n = subnets; n; n = n -> next_subnet) {
2922  log_debug (" Subnet %s", piaddr (n -> net));
2923  log_debug (" netmask %s",
2924  piaddr (n -> netmask));
2925  }
2926  log_info ("Shared networks:");
2927  for (s = shared_networks; s; s = s -> next) {
2928  log_info (" %s", s -> name);
2929  for (p = s -> pools; p; p = p -> next) {
2930  lptr [FREE_LEASES] = &p -> free;
2931  lptr [ACTIVE_LEASES] = &p -> active;
2932  lptr [EXPIRED_LEASES] = &p -> expired;
2933  lptr [ABANDONED_LEASES] = &p -> abandoned;
2934  lptr [BACKUP_LEASES] = &p -> backup;
2935  lptr [RESERVED_LEASES] = &p->reserved;
2936 
2937  for (i = FREE_LEASES; i <= RESERVED_LEASES; i++) {
2938  for (l = LEASE_GET_FIRSTP(lptr[i]);
2939  l != NULL;
2940  l = LEASE_GET_NEXTP(lptr[i], l)) {
2941  print_lease (l);
2942  }
2943  }
2944  }
2945  }
2946 }
2947 
2948 HASH_FUNCTIONS(lease_ip, const unsigned char *, struct lease, lease_ip_hash_t,
2949  lease_reference, lease_dereference, do_ip4_hash)
2950 HASH_FUNCTIONS(lease_id, const unsigned char *, struct lease, lease_id_hash_t,
2951  lease_reference, lease_dereference, do_id_hash)
2952 HASH_FUNCTIONS (host, const unsigned char *, struct host_decl, host_hash_t,
2953  host_reference, host_dereference, do_string_hash)
2954 HASH_FUNCTIONS (class, const char *, struct class, class_hash_t,
2955  class_reference, class_dereference, do_string_hash)
2956 
2957 #if defined (DEBUG_MEMORY_LEAKAGE) && \
2958  defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
2959 extern struct hash_table *dns_zone_hash;
2960 extern struct interface_info **interface_vector;
2961 extern int interface_count;
2963 extern struct hash_table *auth_key_hash;
2964 struct hash_table *universe_hash;
2965 struct universe **universes;
2967 #if 0
2968 extern int end;
2969 #endif
2970 
2971 #if defined (COMPACT_LEASES)
2972 extern struct lease *lease_hunks;
2973 #endif
2974 
2975 void free_everything(void)
2976 {
2977  struct subnet *sc = (struct subnet *)0, *sn = (struct subnet *)0;
2978  struct shared_network *nc = (struct shared_network *)0,
2979  *nn = (struct shared_network *)0;
2980  struct pool *pc = (struct pool *)0, *pn = (struct pool *)0;
2981  struct lease *lc = NULL, *ln = NULL, *ltemp = NULL;
2982  struct interface_info *ic = (struct interface_info *)0,
2983  *in = (struct interface_info *)0;
2984  struct class *cc = (struct class *)0, *cn = (struct class *)0;
2985  struct collection *lp;
2986  int i;
2987 
2988  /* Get rid of all the hash tables. */
2989  if (host_hw_addr_hash)
2990  host_free_hash_table (&host_hw_addr_hash, MDL);
2991  host_hw_addr_hash = 0;
2992  if (host_uid_hash)
2993  host_free_hash_table (&host_uid_hash, MDL);
2994  host_uid_hash = 0;
2995  if (lease_uid_hash)
2996  lease_id_free_hash_table (&lease_uid_hash, MDL);
2997  lease_uid_hash = 0;
2998  if (lease_ip_addr_hash)
2999  lease_ip_free_hash_table (&lease_ip_addr_hash, MDL);
3000  lease_ip_addr_hash = 0;
3001  if (lease_hw_addr_hash)
3002  lease_id_free_hash_table (&lease_hw_addr_hash, MDL);
3003  lease_hw_addr_hash = 0;
3004  if (host_name_hash)
3005  host_free_hash_table (&host_name_hash, MDL);
3006  host_name_hash = 0;
3007  if (dns_zone_hash)
3008  dns_zone_free_hash_table (&dns_zone_hash, MDL);
3009  dns_zone_hash = 0;
3010 
3011  while (host_id_info != NULL) {
3012  host_id_info_t *tmp;
3014  host_free_hash_table(&host_id_info->values_hash, MDL);
3015  tmp = host_id_info->next;
3017  host_id_info = tmp;
3018  }
3019 #if 0
3020  if (auth_key_hash)
3021  auth_key_free_hash_table (&auth_key_hash, MDL);
3022 #endif
3023  auth_key_hash = 0;
3024 
3026  MDL);
3027 
3028  for (lp = collections; lp; lp = lp -> next) {
3029  if (lp -> classes) {
3030  class_reference (&cn, lp -> classes, MDL);
3031  do {
3032  if (cn) {
3033  class_reference (&cc, cn, MDL);
3034  class_dereference (&cn, MDL);
3035  }
3036  if (cc -> nic) {
3037  class_reference (&cn, cc -> nic, MDL);
3038  class_dereference (&cc -> nic, MDL);
3039  }
3040  group_dereference (&cc -> group, MDL);
3041  if (cc -> hash) {
3042  class_free_hash_table (&cc -> hash, MDL);
3043  cc -> hash = (struct hash_table *)0;
3044  }
3045  class_dereference (&cc, MDL);
3046  } while (cn);
3047  class_dereference (&lp -> classes, MDL);
3048  }
3049  }
3050 
3051  if (interface_vector) {
3052  for (i = 0; i < interface_count; i++) {
3053  if (interface_vector [i])
3054  interface_dereference (&interface_vector [i], MDL);
3055  }
3057  interface_vector = 0;
3058  }
3059 
3060  if (interfaces) {
3061  interface_reference (&in, interfaces, MDL);
3062  do {
3063  if (in) {
3064  interface_reference (&ic, in, MDL);
3065  interface_dereference (&in, MDL);
3066  }
3067  if (ic -> next) {
3068  interface_reference (&in, ic -> next, MDL);
3069  interface_dereference (&ic -> next, MDL);
3070  }
3072  if (ic -> shared_network) {
3073  if (ic -> shared_network -> interface)
3074  interface_dereference
3075  (&ic -> shared_network -> interface, MDL);
3076  shared_network_dereference (&ic -> shared_network, MDL);
3077  }
3078  interface_dereference (&ic, MDL);
3079  } while (in);
3080  interface_dereference (&interfaces, MDL);
3081  }
3082 
3083  /* Subnets are complicated because of the extra links. */
3084  if (subnets) {
3085  subnet_reference (&sn, subnets, MDL);
3086  do {
3087  if (sn) {
3088  subnet_reference (&sc, sn, MDL);
3089  subnet_dereference (&sn, MDL);
3090  }
3091  if (sc -> next_subnet) {
3092  subnet_reference (&sn, sc -> next_subnet, MDL);
3093  subnet_dereference (&sc -> next_subnet, MDL);
3094  }
3095  if (sc -> next_sibling)
3096  subnet_dereference (&sc -> next_sibling, MDL);
3097  if (sc -> shared_network)
3098  shared_network_dereference (&sc -> shared_network, MDL);
3099  group_dereference (&sc -> group, MDL);
3100  if (sc -> interface)
3101  interface_dereference (&sc -> interface, MDL);
3102  subnet_dereference (&sc, MDL);
3103  } while (sn);
3104  subnet_dereference (&subnets, MDL);
3105  }
3106 
3107  /* So are shared networks. */
3108  /* XXX: this doesn't work presently, but i'm ok just filtering
3109  * it out of the noise (you get a bigger spike on the real leaks).
3110  * It would be good to fix this, but it is not a "real bug," so not
3111  * today. This hack is incomplete, it doesn't trim out sub-values.
3112  */
3113  if (shared_networks) {
3114  shared_network_dereference (&shared_networks, MDL);
3115  /* This is the old method (tries to free memory twice, broken) */
3116  } else if (0) {
3117  shared_network_reference (&nn, shared_networks, MDL);
3118  do {
3119  if (nn) {
3120  shared_network_reference (&nc, nn, MDL);
3121  shared_network_dereference (&nn, MDL);
3122  }
3123  if (nc -> next) {
3124  shared_network_reference (&nn, nc -> next, MDL);
3125  shared_network_dereference (&nc -> next, MDL);
3126  }
3127 
3128  /* As are pools. */
3129  if (nc -> pools) {
3130  pool_reference (&pn, nc -> pools, MDL);
3131  do {
3133 
3134  if (pn) {
3135  pool_reference (&pc, pn, MDL);
3136  pool_dereference (&pn, MDL);
3137  }
3138  if (pc -> next) {
3139  pool_reference (&pn, pc -> next, MDL);
3140  pool_dereference (&pc -> next, MDL);
3141  }
3142 
3143  lptr [FREE_LEASES] = &pc -> free;
3144  lptr [ACTIVE_LEASES] = &pc -> active;
3145  lptr [EXPIRED_LEASES] = &pc -> expired;
3146  lptr [ABANDONED_LEASES] = &pc -> abandoned;
3147  lptr [BACKUP_LEASES] = &pc -> backup;
3148  lptr [RESERVED_LEASES] = &pc->reserved;
3149 
3150  /* As (sigh) are leases. */
3151  for (i = FREE_LEASES ; i <= RESERVED_LEASES ; i++) {
3152  if (LEASE_NOT_EMPTYP(lptr[i])) {
3153  lease_reference(&ln, LEASE_GET_FIRSTP(lptr[i]), MDL);
3154  do {
3155  /* save a pointer to the current lease */
3156  lease_reference (&lc, ln, MDL);
3157  lease_dereference (&ln, MDL);
3158 
3159  /* get the next lease if there is one */
3160  ltemp = LEASE_GET_NEXTP(lptr[i], lc);
3161  if (ltemp != NULL) {
3162  lease_reference(&ln, ltemp, MDL);
3163  }
3164 
3165  /* remove the current lease from the queue */
3166  LEASE_REMOVEP(lptr[i], lc);
3167 
3168  if (lc -> billing_class)
3169  class_dereference (&lc -> billing_class,
3170  MDL);
3171  if (lc -> state)
3172  free_lease_state (lc -> state, MDL);
3173  lc -> state = (struct lease_state *)0;
3174  if (lc -> n_hw)
3175  lease_dereference (&lc -> n_hw, MDL);
3176  if (lc -> n_uid)
3177  lease_dereference (&lc -> n_uid, MDL);
3178  lease_dereference (&lc, MDL);
3179  } while (ln);
3180  }
3181  }
3182  if (pc -> group)
3183  group_dereference (&pc -> group, MDL);
3184  if (pc -> shared_network)
3185  shared_network_dereference (&pc -> shared_network,
3186  MDL);
3187  pool_dereference (&pc, MDL);
3188  } while (pn);
3189  pool_dereference (&nc -> pools, MDL);
3190  }
3191  /* Because of a circular reference, we need to nuke this
3192  manually. */
3193  group_dereference (&nc -> group, MDL);
3194  shared_network_dereference (&nc, MDL);
3195  } while (nn);
3196  shared_network_dereference (&shared_networks, MDL);
3197  }
3198 
3201 #if defined(DELAYED_ACK)
3202  relinquish_ackqueue();
3203 #endif
3204  trace_free_all ();
3207 
3214 
3216 
3217  universe_free_hash_table (&universe_hash, MDL);
3218  for (i = 0; i < universe_count; i++) {
3219 #if 0
3220  union {
3221  const char *c;
3222  char *s;
3223  } foo;
3224 #endif
3225  if (universes [i]) {
3226  if (universes[i]->name_hash)
3227  option_name_free_hash_table(
3228  &universes[i]->name_hash,
3229  MDL);
3230  if (universes[i]->code_hash)
3231  option_code_free_hash_table(
3232  &universes[i]->code_hash,
3233  MDL);
3234 #if 0
3235  if (universes [i] -> name > (char *)&end) {
3236  foo.c = universes [i] -> name;
3237  dfree (foo.s, MDL);
3238  }
3239  if (universes [i] > (struct universe *)&end)
3240  dfree (universes [i], MDL);
3241 #endif
3242  }
3243  }
3244  dfree (universes, MDL);
3245 
3246  relinquish_free_lease_states ();
3247  relinquish_free_pairs ();
3248  relinquish_free_expressions ();
3249  relinquish_free_binding_values ();
3250  relinquish_free_option_caches ();
3251  relinquish_free_packets ();
3252 #if defined(COMPACT_LEASES)
3254 #endif
3257 }
3258 #endif /* DEBUG_MEMORY_LEAKAGE_ON_EXIT */
#define FTS_ABANDONED
Definition: dhcpd.h:538
#define FTS_LAST
Definition: dhcpd.h:544
#define GROUP_OBJECT_DYNAMIC
Definition: dhcpd.h:927
LEASE_STRUCT reserved
Definition: dhcpd.h:1011
struct leasechain * lc
Definition: dhcpd.h:562
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:1074
void enter_shared_network(struct shared_network *share)
Definition: mdb.c:1033
void unbill_class(struct lease *lease)
Definition: dhclient.c:1442
struct lease * new_leases(unsigned, const char *, int)
#define SS_QFOLLOW
Definition: mdb.c:120
const char int line
Definition: dhcpd.h:3725
LEASE_STRUCT expired
Definition: dhcpd.h:1007
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:580
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:2112
struct host_id_info host_id_info_t
lease_id_hash_t * lease_hw_addr_hash
Definition: mdb.c:39
Definition: dhcpd.h:557
unsigned len
Definition: tree.h:80
int executable_statement_dereference(struct executable_statement **ptr, const char *file, int line)
Definition: execute.c:623
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:534
struct dhcp_ddns_cb * ddns_cb
Definition: dhcpd.h:647
unsigned do_id_hash(const void *, unsigned, unsigned)
Definition: hash.c:292
unsigned char * uid
Definition: dhcpd.h:582
#define LEASE_REMOVEP(LQ, LEASE)
Definition: dhcpd.h:263
#define DHO_PXE_CLIENT_ID
Definition: dhcp.h:162
char name[IFNAMSIZ]
Definition: dhcpd.h:1376
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
struct class * superclass
Definition: dhcpd.h:1075
Definition: dhcpd.h:1045
int execute_statements(struct binding_value **result, struct packet *packet, struct lease *lease, struct client_state *client_state, struct option_state *in_options, struct option_state *out_options, struct binding_scope **scope, struct executable_statement *statements, struct on_star *on_star)
Definition: execute.c:35
void dhcp_failover_pool_check(struct pool *)
struct iaddr ip_addr(struct iaddr subnet, struct iaddr mask, u_int32_t host_address)
Definition: inet.c:63
isc_result_t unlink_class(struct class **class)
Definition: class.c:217
void dump_subnets()
Definition: mdb.c:2911
#define MDL
Definition: omapip.h:568
#define HOST_DECL_DYNAMIC
Definition: dhcpd.h:963
unsigned char iabuf[16]
Definition: inet.h:33
void lease_remove(struct lease **lq, struct lease *comp)
Definition: mdb.c:2559
#define print_hex_1(len, data, limit)
Definition: dhcpd.h:2577
struct subnet * subnets
Definition: mdb.c:32
void expire_all_pools()
Definition: mdb.c:2813
#define DHCP_R_INVALIDARG
Definition: result.h:49
class_hash_t * hash
Definition: dhcpd.h:1088
#define HASH_FUNCTIONS(name, bufarg, type, hashtype, ref, deref, hasher)
Definition: hash.h:89
#define FTS_RELEASED
Definition: dhcpd.h:537
#define CLASS_DECL_DELETED
Definition: dhcpd.h:1104
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:2657
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:553
unsigned end
Definition: tree.h:336
void pool_timer(void *vpool)
Definition: mdb.c:1892
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 option_cache * fixed_addr
Definition: dhcpd.h:956
struct class * billing_class
Definition: dhcpd.h:576
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:2030
struct data_string hash_string
Definition: dhcpd.h:1089
int log_error(const char *,...) __attribute__((__format__(__printf__
struct collection * collections
Definition: dhcpd.h:3185
#define HOST_DECL_DELETED
Definition: dhcpd.h:962
#define FTS_EXPIRED
Definition: dhcpd.h:536
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:593
void add_timeout(struct timeval *when, void(*)(void *) where, void *what, tvref_t ref, tvunref_t unref)
Definition: dispatch.c:206
unsigned short uid_max
Definition: dhcpd.h:584
void(* tvunref_t)(void *, const char *, int)
Definition: dhcpd.h:1421
void relinquish_lease_hunks(void)
unsigned len
Definition: inet.h:32
dhcp_failover_state_t * failover_peer
Definition: dhcpd.h:1021
struct shared_network * shared_networks
Definition: mdb.c:33
struct data_string client_identifier
Definition: dhcpd.h:950
void(* tvref_t)(void *, void *, const char *, int)
Definition: dhcpd.h:1420
const char * binding_state_print(enum failover_state state)
Definition: failover.c:6496
struct option_state * options
Definition: dhcpd.h:449
Definition: dhcpd.h:288
Definition: tree.h:302
char * name
Definition: dhcpd.h:1076
LEASE_STRUCT free
Definition: dhcpd.h:1008
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:559
isc_result_t omapi_io_state_foreach(isc_result_t(*func)(omapi_object_t *, void *), void *p)
calls a given function on every object
Definition: dispatch.c:905
struct executable_statement * statements
Definition: dhcpd.h:940
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:2371
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:586
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:2309
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:964
int write_host(struct host_decl *host)
Definition: dhclient.c:2016
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:567
#define MAX_V6RELAY_HOPS
Definition: dhcp6.h:244
#define MIN_TIME
Definition: dhcpd.h:1599
void lease_remove_all(struct lease **lq)
Definition: mdb.c:2520
#define LEASE_NOT_EMPTYP(LQ)
Definition: dhcpd.h:265
Definition: dhcpd.h:999
unsigned do_string_hash(const void *, unsigned, unsigned)
Definition: hash.c:268
binding_state_t binding_state
Definition: dhcpd.h:620
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:1052
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:2010
int group_dereference(struct group **ptr, const char *file, int line)
Definition: alloc.c:205
#define EXPIRED_LEASES
#define FTS_BACKUP
Definition: dhcpd.h:540
Definition: dhcpd.h:405
isc_result_t omapi_object_dereference(omapi_object_t **, const char *, int)
Definition: alloc.c:593
struct pool * pool
Definition: dhcpd.h:575
char * name
Definition: dhcpd.h:948
TIME atsfp
Definition: dhcpd.h:636
#define cur_time
Definition: dhcpd.h:2079
struct lease * n_hw
Definition: dhcpd.h:564
int free_leases
Definition: dhcpd.h:1014
Definition: ip.h:47
struct lease * n_uid
Definition: dhcpd.h:564
#define BACKUP_LEASES
TIME starts
Definition: dhcpd.h:567
u_int8_t flags
Definition: dhcpd.h:588
void dfree(void *, const char *, int)
Definition: alloc.c:145
int find_lease_by_uid(struct lease **lp, const unsigned char *uid, unsigned len, const char *file, int line)
Definition: mdb.c:2037
int lease_count
Definition: dhcpd.h:1013
struct host_decl * n_ipaddr
Definition: dhcpd.h:946
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 data_string host_id
Definition: dhcpd.h:952
struct option_cache * lookup_option(struct universe *universe, struct option_state *options, unsigned code)
Definition: options.c:2448
#define FTS_RESET
Definition: dhcpd.h:539
#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:574
#define GROUP_OBJECT_DELETED
Definition: dhcpd.h:926
struct class * classes
Definition: dhcpd.h:1062
void * dmalloc(size_t, const char *, int)
Definition: alloc.c:57
struct interface_info * interfaces
Definition: discover.c:42
u_int32_t flags
Definition: dhcpd.h:1390
#define PERSISTENT_FLAGS
Definition: dhcpd.h:600
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 executable_statement_foreach(struct executable_statement *stmt, int(*callback)(struct executable_statement *, void *, int), void *vp, int condp)
Definition: execute.c:1113
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:1047
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:637
struct universe ** universes
Definition: tables.c:963
struct lease * prev
Definition: dhcpd.h:561
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:583
struct iaddr ip_addr
Definition: dhcpd.h:566
u_int32_t host_addr(struct iaddr addr, struct iaddr mask)
Definition: inet.c:138
#define EPHEMERAL_FLAGS
Definition: dhcpd.h:602
Definition: dhcpd.h:932
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:1441
#define RESERVED_LEASE
Definition: dhcpd.h:591
#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:623
TIME tstp
Definition: dhcpd.h:634
struct interface_info * next
Definition: dhcpd.h:1351
isc_result_t dhcp_io_shutdown(omapi_object_t *, void *)
Definition: dhcpd.c:1443
void hw_hash_add(struct lease *lease)
Definition: mdb.c:2229
host_hash_t * values_hash
Definition: mdb.c:61
struct host_decl * host
Definition: dhcpd.h:573
#define SS_NOSYNC
Definition: mdb.c:119
struct iaddr netmask
Definition: dhcpd.h:1053
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:1422
struct option * host_id_option
Definition: dhcpd.h:951
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:622
void relinquish_hash_bucket_hunks(void)
struct subnet * next_sibling
Definition: dhcpd.h:1048
dns_zone_hash_t * dns_zone_hash
Definition: dns.c:136
int dhcp_failover_write_all_states(void)
int commit_leases()
Definition: dhclient.c:2005
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:635
#define RESERVED_LEASES
int flags
Definition: dhcpd.h:925
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:2045
int flags
Definition: dhcpd.h:1109
#define STATIC_LEASE
Definition: dhcpd.h:589
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:559
#define MAX_TIME
Definition: dhcpd.h:1598
#define HOST_HASH_SIZE
Definition: dhcpd.h:186
int write_leases()
Definition: mdb.c:2412
isc_result_t lease_instantiate(const void *key, unsigned len, void *object)
Definition: mdb.c:2743
#define FREE_LEASES
struct ipv6_pool ** pools
TIME next_event_time
Definition: dhcpd.h:1012
void lc_init_growth(struct leasechain *lc, size_t growth)
int flags
Definition: dhcpd.h:961
int relays
Definition: mdb.c:62
unsigned char uid_buf[7]
Definition: dhcpd.h:585
#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:551
struct shared_network * next
Definition: dhcpd.h:1029
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:3725
#define DHO_DHCP_CLIENT_IDENTIFIER
Definition: dhcp.h:153
char * name
Definition: dhcpd.h:1030
int universe_max
Definition: tables.c:964
LEASE_STRUCT active
Definition: dhcpd.h:1006
#define ACTIVE_LEASES
struct collection * next
Definition: dhcpd.h:1059
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:552
#define LEASE_GET_NEXTP(LQ, LEASE)
Definition: dhcpd.h:261
Definition: dhcpd.h:1072
const unsigned char * data
Definition: tree.h:79
TIME ends
Definition: dhcpd.h:567
struct binding_scope * scope
Definition: dhcpd.h:572
struct hardware interface
Definition: dhcpd.h:949
LEASE_STRUCT backup
Definition: dhcpd.h:1009
int relays
Definition: dhcpd.h:968
int parse_warn(struct parse *cfile, const char *fmt,...)
Definition: parse.c:5617
void uid_hash_delete(struct lease *lease)
Definition: mdb.c:2179
u_int32_t abandon_lease_time
Definition: dhcpd.c:85
binding_state_t next_binding_state
Definition: dhcpd.h:621
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:1010
struct pool * pools
Definition: dhcpd.h:1037
#define GROUP_OBJECT_STATIC
Definition: dhcpd.h:928
#define INTERFACE_REQUESTED
Definition: dhcpd.h:1391
int universe_count
Definition: tables.c:964
struct group * group
Definition: dhcpd.h:958
struct buffer * buffer
Definition: tree.h:78
struct pool * next
Definition: dhcpd.h:1001
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:2597
char * client_hostname
Definition: dhcpd.h:571
void trace_free_all(void)
int backup_leases
Definition: dhcpd.h:1015
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:535