]> git.ipfire.org Git - thirdparty/dhcp.git/blob - client/dhc6.c
copy rights update
[thirdparty/dhcp.git] / client / dhc6.c
1 /* dhc6.c - DHCPv6 client routines. */
2
3 /*
4 * Copyright (C) 2012-2022 Internet Systems Consortium, Inc. ("ISC")
5 * Copyright (c) 2006-2010 by Internet Systems Consortium, Inc. ("ISC")
6 *
7 * This Source Code Form is subject to the terms of the Mozilla Public
8 * License, v. 2.0. If a copy of the MPL was not distributed with this
9 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
17 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 *
19 * Internet Systems Consortium, Inc.
20 * PO Box 360
21 * Newmarket, NH 03857 USA
22 * <info@isc.org>
23 * https://www.isc.org/
24 */
25
26 #include "dhcpd.h"
27
28 #ifdef DHCPv6
29
30 struct sockaddr_in6 DHCPv6DestAddr;
31
32 /*
33 * Option definition structures that are used by the software - declared
34 * here once and assigned at startup to save lookups.
35 */
36 struct option *clientid_option = NULL;
37 struct option *elapsed_option = NULL;
38 struct option *ia_na_option = NULL;
39 struct option *ia_ta_option = NULL;
40 struct option *ia_pd_option = NULL;
41 struct option *iaaddr_option = NULL;
42 struct option *iaprefix_option = NULL;
43 struct option *oro_option = NULL;
44 struct option *irt_option = NULL;
45
46 static struct dhc6_lease *dhc6_dup_lease(struct dhc6_lease *lease,
47 const char *file, int line);
48 static struct dhc6_ia *dhc6_dup_ia(struct dhc6_ia *ia,
49 const char *file, int line);
50 static struct dhc6_addr *dhc6_dup_addr(struct dhc6_addr *addr,
51 const char *file, int line);
52 static void dhc6_ia_destroy(struct dhc6_ia **src, const char *file, int line);
53 static isc_result_t dhc6_parse_ia_na(struct dhc6_ia **pia,
54 struct packet *packet,
55 struct option_state *options,
56 unsigned code);
57 static isc_result_t dhc6_parse_ia_ta(struct dhc6_ia **pia,
58 struct packet *packet,
59 struct option_state *options,
60 unsigned code);
61 static isc_result_t dhc6_parse_ia_pd(struct dhc6_ia **pia,
62 struct packet *packet,
63 struct option_state *options,
64 unsigned code);
65 static isc_result_t dhc6_parse_addrs(struct dhc6_addr **paddr,
66 struct packet *packet,
67 struct option_state *options);
68 static isc_result_t dhc6_parse_prefixes(struct dhc6_addr **ppref,
69 struct packet *packet,
70 struct option_state *options);
71 static struct dhc6_ia *find_ia(struct dhc6_ia *head,
72 u_int16_t type, const char *id);
73 static struct dhc6_addr *find_addr(struct dhc6_addr *head,
74 struct iaddr *address);
75 static struct dhc6_addr *find_pref(struct dhc6_addr *head,
76 struct iaddr *prefix, u_int8_t plen);
77 void init_handler(struct packet *packet, struct client_state *client);
78 void info_request_handler(struct packet *packet, struct client_state *client);
79 void rapid_commit_handler(struct packet *packet, struct client_state *client);
80 void do_init6(void *input);
81 void do_info_request6(void *input);
82 void do_confirm6(void *input);
83 void reply_handler(struct packet *packet, struct client_state *client);
84 static isc_result_t dhc6_create_iaid(struct client_state *client,
85 struct data_string *ia,
86 int idx,
87 unsigned len);
88 static int dhc6_count_ia(struct dhc6_lease *lease,
89 u_int16_t ia_type);
90 static isc_result_t dhc6_bare_ia_xx(struct client_state *client,
91 struct data_string *packet,
92 int wanted,
93 u_int16_t ia_type);
94 static isc_result_t dhc6_add_ia_na(struct client_state *client,
95 struct data_string *packet,
96 struct dhc6_lease *lease,
97 u_int8_t message,
98 int wanted,
99 int *added);
100 static isc_result_t dhc6_add_ia_ta(struct client_state *client,
101 struct data_string *packet,
102 struct dhc6_lease *lease,
103 u_int8_t message,
104 int wanted,
105 int *added);
106 static isc_result_t dhc6_add_ia_pd(struct client_state *client,
107 struct data_string *packet,
108 struct dhc6_lease *lease,
109 u_int8_t message,
110 int wanted,
111 int *added);
112 static isc_boolean_t stopping_finished(void);
113 static void dhc6_merge_lease(struct dhc6_lease *src, struct dhc6_lease *dst);
114 void do_select6(void *input);
115 void do_refresh6(void *input);
116 static void do_release6(void *input);
117 static void start_bound(struct client_state *client);
118 static void start_decline6(struct client_state *client);
119 static void do_decline6(void *input);
120 static void start_informed(struct client_state *client);
121 void informed_handler(struct packet *packet, struct client_state *client);
122 void bound_handler(struct packet *packet, struct client_state *client);
123 void start_renew6(void *input);
124 void start_rebind6(void *input);
125 void do_depref(void *input);
126 void do_expire(void *input);
127 static void make_client6_options(struct client_state *client,
128 struct option_state **op,
129 struct dhc6_lease *lease, u_int8_t message);
130 static void script_write_params6(struct client_state *client,
131 const char *prefix,
132 struct option_state *options);
133 static void script_write_requested6(struct client_state *client);
134 static isc_boolean_t active_prefix(struct client_state *client);
135
136 static int check_timing6(struct client_state *client, u_int8_t msg_type,
137 char *msg_str, struct dhc6_lease *lease,
138 struct data_string *ds);
139 static isc_result_t dhc6_get_status_code(struct option_state *options,
140 unsigned *code,
141 struct data_string *msg);
142 static isc_result_t dhc6_check_status(isc_result_t rval,
143 struct option_state *options,
144 const char *scope,
145 unsigned *code);
146 static int dhc6_score_lease(struct client_state *client,
147 struct dhc6_lease *lease);
148 static isc_result_t dhc6_add_ia_na_decline(struct client_state *client,
149 struct data_string *packet,
150 struct dhc6_lease *lease);
151 static int drop_declined_addrs(struct dhc6_lease *lease);
152 static isc_boolean_t unexpired_address_in_lease(struct dhc6_lease *lease);
153
154 extern int onetry;
155 extern int stateless;
156 extern int prefix_len_hint;
157 extern int address_prefix_len;
158
159 /*
160 * Assign DHCPv6 port numbers as a client.
161 */
162 void
163 dhcpv6_client_assignments(void)
164 {
165 struct servent *ent;
166 unsigned code;
167
168 if (path_dhclient_pid == NULL)
169 path_dhclient_pid = _PATH_DHCLIENT6_PID;
170 if (path_dhclient_db == NULL)
171 path_dhclient_db = _PATH_DHCLIENT6_DB;
172
173 if (local_port == 0) {
174 ent = getservbyname("dhcpv6-client", "udp");
175 if (ent == NULL)
176 local_port = htons(546);
177 else
178 local_port = ent->s_port;
179 }
180
181 if (remote_port == 0) {
182 ent = getservbyname("dhcpv6-server", "udp");
183 if (ent == NULL)
184 remote_port = htons(547);
185 else
186 remote_port = ent->s_port;
187 }
188
189 memset(&DHCPv6DestAddr, 0, sizeof(DHCPv6DestAddr));
190 DHCPv6DestAddr.sin6_family = AF_INET6;
191 DHCPv6DestAddr.sin6_port = remote_port;
192 if (inet_pton(AF_INET6, All_DHCP_Relay_Agents_and_Servers,
193 &DHCPv6DestAddr.sin6_addr) <= 0) {
194 log_fatal("Bad address %s", All_DHCP_Relay_Agents_and_Servers);
195 }
196
197 code = D6O_CLIENTID;
198 if (!option_code_hash_lookup(&clientid_option,
199 dhcpv6_universe.code_hash, &code, 0, MDL))
200 log_fatal("Unable to find the CLIENTID option definition.");
201
202 code = D6O_ELAPSED_TIME;
203 if (!option_code_hash_lookup(&elapsed_option,
204 dhcpv6_universe.code_hash, &code, 0, MDL))
205 log_fatal("Unable to find the ELAPSED_TIME option definition.");
206
207 code = D6O_IA_NA;
208 if (!option_code_hash_lookup(&ia_na_option, dhcpv6_universe.code_hash,
209 &code, 0, MDL))
210 log_fatal("Unable to find the IA_NA option definition.");
211
212 code = D6O_IA_TA;
213 if (!option_code_hash_lookup(&ia_ta_option, dhcpv6_universe.code_hash,
214 &code, 0, MDL))
215 log_fatal("Unable to find the IA_TA option definition.");
216
217 code = D6O_IA_PD;
218 if (!option_code_hash_lookup(&ia_pd_option, dhcpv6_universe.code_hash,
219 &code, 0, MDL))
220 log_fatal("Unable to find the IA_PD option definition.");
221
222 code = D6O_IAADDR;
223 if (!option_code_hash_lookup(&iaaddr_option, dhcpv6_universe.code_hash,
224 &code, 0, MDL))
225 log_fatal("Unable to find the IAADDR option definition.");
226
227 code = D6O_IAPREFIX;
228 if (!option_code_hash_lookup(&iaprefix_option,
229 dhcpv6_universe.code_hash,
230 &code, 0, MDL))
231 log_fatal("Unable to find the IAPREFIX option definition.");
232
233 code = D6O_ORO;
234 if (!option_code_hash_lookup(&oro_option, dhcpv6_universe.code_hash,
235 &code, 0, MDL))
236 log_fatal("Unable to find the ORO option definition.");
237
238 code = D6O_INFORMATION_REFRESH_TIME;
239 if (!option_code_hash_lookup(&irt_option, dhcpv6_universe.code_hash,
240 &code, 0, MDL))
241 log_fatal("Unable to find the IRT option definition.");
242
243 #ifndef __CYGWIN32__ /* XXX */
244 endservent();
245 #endif
246 }
247
248 /*
249 * Instead of implementing RFC3315 RAND (section 14) as a float "between"
250 * -0.1 and 0.1 non-inclusive, we implement it as an integer.
251 *
252 * The result is expected to follow this table:
253 *
254 * split range answer
255 * - ERROR - base <= 0
256 * 0 1 0..0 1 <= base <= 10
257 * 1 3 -1..1 11 <= base <= 20
258 * 2 5 -2..2 21 <= base <= 30
259 * 3 7 -3..3 31 <= base <= 40
260 * ...
261 *
262 * XXX: For this to make sense, we really need to do timing on a
263 * XXX: usec scale...we currently can assume zero for any value less than
264 * XXX: 11, which are very common in early stages of transmission for most
265 * XXX: messages.
266 */
267 static TIME
268 dhc6_rand(TIME base)
269 {
270 TIME rval;
271 TIME range;
272 TIME split;
273
274 /*
275 * A zero or less timeout is a bad thing...we don't want to
276 * DHCP-flood anyone.
277 */
278 if (base <= 0)
279 log_fatal("Impossible condition at %s:%d.", MDL);
280
281 /*
282 * The first thing we do is count how many random integers we want
283 * in either direction (best thought of as the maximum negative
284 * integer, as we will subtract this potentially from a random 0).
285 */
286 split = (base - 1) / 10;
287
288 /* Don't bother with the rest of the math if we know we'll get 0. */
289 if (split == 0)
290 return 0;
291
292 /*
293 * Then we count the total number of integers in this set. This
294 * is twice the number of integers in positive and negative
295 * directions, plus zero (-1, 0, 1 is 3, -2..2 adds 2 to 5, so forth).
296 */
297 range = (split * 2) + 1;
298
299 /* Take a random number from [0..(range-1)]. */
300 rval = random();
301 rval %= range;
302
303 /* Offset it to uncover potential negative values. */
304 rval -= split;
305
306 return rval;
307 }
308
309 /* Initialize message exchange timers (set RT from Initial-RT). */
310 static void
311 dhc6_retrans_init(struct client_state *client)
312 {
313 int xid;
314
315 /* Initialize timers. */
316 client->txcount = 0;
317 client->RT = client->IRT + dhc6_rand(client->IRT);
318
319 /* Generate a new random 24-bit transaction ID for this exchange. */
320
321 #if (RAND_MAX >= 0x00ffffff)
322 xid = random();
323 #elif (RAND_MAX >= 0x0000ffff)
324 xid = (random() << 16) ^ random();
325 #elif (RAND_MAX >= 0x000000ff)
326 xid = (random() << 16) ^ (random() << 8) ^ random();
327 #else
328 # error "Random number generator of less than 8 bits not supported."
329 #endif
330
331 client->dhcpv6_transaction_id[0] = (xid >> 16) & 0xff;
332 client->dhcpv6_transaction_id[1] = (xid >> 8) & 0xff;
333 client->dhcpv6_transaction_id[2] = xid & 0xff;
334 }
335
336 /* Advance the DHCPv6 retransmission state once. */
337 static void
338 dhc6_retrans_advance(struct client_state *client)
339 {
340 struct timeval elapsed, elapsed_plus_rt;
341
342 /* elapsed = cur - start */
343 elapsed.tv_sec = cur_tv.tv_sec - client->start_time.tv_sec;
344 elapsed.tv_usec = cur_tv.tv_usec - client->start_time.tv_usec;
345 if (elapsed.tv_usec < 0) {
346 elapsed.tv_sec -= 1;
347 elapsed.tv_usec += 1000000;
348 }
349 /* retrans_advance is called after consuming client->RT. */
350 /* elapsed += RT */
351 elapsed.tv_sec += client->RT / 100;
352 elapsed.tv_usec += (client->RT % 100) * 10000;
353 if (elapsed.tv_usec >= 1000000) {
354 elapsed.tv_sec += 1;
355 elapsed.tv_usec -= 1000000;
356 }
357 /*
358 * Save what the time will be after the current RT to determine
359 * what the delta to MRD will be.
360 */
361 elapsed_plus_rt.tv_sec = elapsed.tv_sec;
362 elapsed_plus_rt.tv_usec = elapsed.tv_usec;
363
364 /*
365 * RT for each subsequent message transmission is based on the previous
366 * value of RT:
367 *
368 * RT = 2*RTprev + RAND*RTprev
369 */
370 client->RT += client->RT + dhc6_rand(client->RT);
371
372 /*
373 * MRT specifies an upper bound on the value of RT (disregarding the
374 * randomization added by the use of RAND). If MRT has a value of 0,
375 * there is no upper limit on the value of RT. Otherwise:
376 *
377 * if (RT > MRT)
378 * RT = MRT + RAND*MRT
379 */
380 if ((client->MRT != 0) && (client->RT > client->MRT))
381 client->RT = client->MRT + dhc6_rand(client->MRT);
382
383 /*
384 * Further, if there's an MRD, we should wake up upon reaching
385 * the MRD rather than at some point after it.
386 */
387 if (client->MRD == 0) {
388 /* Done. */
389 client->txcount++;
390 return;
391 }
392 /* elapsed += client->RT */
393 elapsed.tv_sec += client->RT / 100;
394 elapsed.tv_usec += (client->RT % 100) * 10000;
395 if (elapsed.tv_usec >= 1000000) {
396 elapsed.tv_sec += 1;
397 elapsed.tv_usec -= 1000000;
398 }
399 if (elapsed.tv_sec >= client->MRD) {
400 /*
401 * The desired RT is the time that will be remaining in MRD
402 * when the current timeout finishes. We then have
403 * desired RT = MRD - (elapsed time + previous RT); or
404 * desired RT = MRD - elapsed_plut_rt;
405 */
406 client->RT = client->MRD - elapsed_plus_rt.tv_sec;
407 client->RT = (client->RT * 100) -
408 (elapsed_plus_rt.tv_usec / 10000);
409 if (client->RT < 0)
410 client->RT = 0;
411 }
412 client->txcount++;
413 }
414
415 /* Quick validation of DHCPv6 ADVERTISE packet contents. */
416 static int
417 valid_reply(struct packet *packet, struct client_state *client)
418 {
419 struct data_string sid, cid;
420 struct option_cache *oc;
421 int rval = ISC_TRUE;
422
423 memset(&sid, 0, sizeof(sid));
424 memset(&cid, 0, sizeof(cid));
425
426 if (!lookup_option(&dhcpv6_universe, packet->options, D6O_SERVERID)) {
427 log_error("Response without a server identifier received.");
428 rval = ISC_FALSE;
429 }
430
431 oc = lookup_option(&dhcpv6_universe, packet->options, D6O_CLIENTID);
432 if (!oc ||
433 !evaluate_option_cache(&sid, packet, NULL, client, packet->options,
434 client->sent_options, &global_scope, oc,
435 MDL)) {
436 log_error("Response without a client identifier.");
437 rval = ISC_FALSE;
438 }
439
440 oc = lookup_option(&dhcpv6_universe, client->sent_options,
441 D6O_CLIENTID);
442 if (!oc ||
443 !evaluate_option_cache(&cid, packet, NULL, client,
444 client->sent_options, NULL, &global_scope,
445 oc, MDL)) {
446 log_error("Local client identifier is missing!");
447 rval = ISC_FALSE;
448 }
449
450 if (sid.len == 0 ||
451 sid.len != cid.len ||
452 memcmp(sid.data, cid.data, sid.len)) {
453 log_error("Advertise with matching transaction ID, but "
454 "mismatching client id.");
455 rval = ISC_FALSE;
456 }
457
458 /* clean up pointers to the strings */
459 if (sid.data != NULL)
460 data_string_forget(&sid, MDL);
461 if (cid.data != NULL)
462 data_string_forget(&cid, MDL);
463
464 return rval;
465 }
466
467 /*
468 * Create a complete copy of a DHCPv6 lease structure.
469 */
470 static struct dhc6_lease *
471 dhc6_dup_lease(struct dhc6_lease *lease, const char *file, int line)
472 {
473 struct dhc6_lease *copy;
474 struct dhc6_ia **insert_ia, *ia;
475
476 copy = dmalloc(sizeof(*copy), file, line);
477 if (copy == NULL) {
478 log_error("Out of memory for v6 lease structure.");
479 return NULL;
480 }
481
482 data_string_copy(&copy->server_id, &lease->server_id, file, line);
483 copy->pref = lease->pref;
484
485 memcpy(copy->dhcpv6_transaction_id, lease->dhcpv6_transaction_id,
486 sizeof(copy->dhcpv6_transaction_id));
487
488 option_state_reference(&copy->options, lease->options, file, line);
489
490 insert_ia = &copy->bindings;
491 for (ia = lease->bindings ; ia != NULL ; ia = ia->next) {
492 *insert_ia = dhc6_dup_ia(ia, file, line);
493
494 if (*insert_ia == NULL) {
495 dhc6_lease_destroy(&copy, file, line);
496 return NULL;
497 }
498
499 insert_ia = &(*insert_ia)->next;
500 }
501
502 return copy;
503 }
504
505 /*
506 * Duplicate an IA structure.
507 */
508 static struct dhc6_ia *
509 dhc6_dup_ia(struct dhc6_ia *ia, const char *file, int line)
510 {
511 struct dhc6_ia *copy;
512 struct dhc6_addr **insert_addr, *addr;
513
514 copy = dmalloc(sizeof(*ia), file, line);
515 if (copy == NULL) {
516 log_error("Out of memory for v6 duplicate IA structure.");
517 return NULL;
518 }
519
520 memcpy(copy->iaid, ia->iaid, sizeof(copy->iaid));
521
522 copy->ia_type = ia->ia_type;
523 copy->starts = ia->starts;
524 copy->renew = ia->renew;
525 copy->rebind = ia->rebind;
526
527 insert_addr = &copy->addrs;
528 for (addr = ia->addrs ; addr != NULL ; addr = addr->next) {
529 *insert_addr = dhc6_dup_addr(addr, file, line);
530
531 if (*insert_addr == NULL) {
532 dhc6_ia_destroy(&copy, file, line);
533 return NULL;
534 }
535
536 insert_addr = &(*insert_addr)->next;
537 }
538
539 if (ia->options != NULL)
540 option_state_reference(&copy->options, ia->options,
541 file, line);
542
543 return copy;
544 }
545
546 /*
547 * Duplicate an IAADDR or IAPREFIX structure.
548 */
549 static struct dhc6_addr *
550 dhc6_dup_addr(struct dhc6_addr *addr, const char *file, int line)
551 {
552 struct dhc6_addr *copy;
553
554 copy = dmalloc(sizeof(*addr), file, line);
555
556 if (copy == NULL)
557 return NULL;
558
559 memcpy(&copy->address, &addr->address, sizeof(copy->address));
560
561 copy->plen = addr->plen;
562 copy->flags = addr->flags;
563 copy->starts = addr->starts;
564 copy->preferred_life = addr->preferred_life;
565 copy->max_life = addr->max_life;
566
567 if (addr->options != NULL)
568 option_state_reference(&copy->options, addr->options,
569 file, line);
570
571 return copy;
572 }
573
574 /*
575 * Form a DHCPv6 lease structure based upon packet contents. Creates and
576 * populates IA's and any IAADDR/IAPREFIX's they contain.
577 * Parsed options are deleted in order to not save them in the lease file.
578 *
579 * If we get a status code of NoAddrs or NoPrefix we toss the affected
580 * IAs. If it as at the top level we toss all IAs of that type. If it
581 * is in an IA we only toss that one. According to the spec we shouldn't
582 * get a NoPrefix status at the top level but we will allow it.
583 *
584 */
585 static struct dhc6_lease *
586 dhc6_leaseify(struct packet *packet, struct client_state* client)
587 {
588 struct data_string ds;
589 struct dhc6_lease *lease;
590 struct option_cache *oc;
591 unsigned code;
592
593 lease = dmalloc(sizeof(*lease), MDL);
594 if (lease == NULL) {
595 log_error("Out of memory for v6 lease structure.");
596 return NULL;
597 }
598
599 memcpy(lease->dhcpv6_transaction_id, packet->dhcpv6_transaction_id, 3);
600 option_state_reference(&lease->options, packet->options, MDL);
601
602 memset(&ds, 0, sizeof(ds));
603
604 /* Determine preference (default zero). */
605 oc = lookup_option(&dhcpv6_universe, lease->options, D6O_PREFERENCE);
606 if (oc &&
607 evaluate_option_cache(&ds, packet, NULL, NULL, lease->options,
608 NULL, &global_scope, oc, MDL)) {
609 if (ds.len != 1) {
610 log_error("Invalid length of DHCPv6 Preference option "
611 "(%d != 1)", ds.len);
612 data_string_forget(&ds, MDL);
613 dhc6_lease_destroy(&lease, MDL);
614 return NULL;
615 } else {
616 lease->pref = ds.data[0];
617 log_debug("RCV: X-- Preference %u.",
618 (unsigned)lease->pref);
619 }
620
621 data_string_forget(&ds, MDL);
622 }
623 delete_option(&dhcpv6_universe, lease->options, D6O_PREFERENCE);
624
625 /* Get the top level status code. If the code is NoAddrsAvail
626 * or NoPrefixAvail strip it from the options as we don't
627 * want it to show up in check_[advertise reply]. We
628 * pass it along to the parse_ia_xx routines and they
629 * will drop the affected IAs for NoAddrs or NoPrefix,
630 * other status codes will be ignored and handled by
631 * the check_[advertise reply] routines.
632 */
633 code = STATUS_Success;
634 if ((dhc6_get_status_code(lease->options, &code, NULL) == ISC_R_SUCCESS)
635 &&
636 ((code == STATUS_NoAddrsAvail) || (code == STATUS_NoPrefixAvail))) {
637 delete_option(&dhcpv6_universe, lease->options,
638 D6O_STATUS_CODE);
639 }
640
641 /*
642 * Dig into recursive DHCPv6 pockets for IA_NA and contained IAADDR
643 * options.
644 */
645 if (dhc6_parse_ia_na(&lease->bindings, packet,
646 lease->options, code) != ISC_R_SUCCESS) {
647 /* Error conditions are logged by the caller. */
648 dhc6_lease_destroy(&lease, MDL);
649 return NULL;
650 }
651 /*
652 * Dig into recursive DHCPv6 pockets for IA_TA and contained IAADDR
653 * options.
654 */
655 if (dhc6_parse_ia_ta(&lease->bindings, packet,
656 lease->options, code) != ISC_R_SUCCESS) {
657 /* Error conditions are logged by the caller. */
658 dhc6_lease_destroy(&lease, MDL);
659 return NULL;
660 }
661 /*
662 * Dig into recursive DHCPv6 pockets for IA_PD and contained IAPREFIX
663 * options.
664 */
665 if (dhc6_parse_ia_pd(&lease->bindings, packet,
666 lease->options, code) != ISC_R_SUCCESS) {
667 /* Error conditions are logged by the caller. */
668 dhc6_lease_destroy(&lease, MDL);
669 return NULL;
670 }
671
672 /*
673 * This is last because in the future we may want to make a different
674 * key based upon additional information from the packet (we may need
675 * to allow multiple leases in one client state per server, but we're
676 * not sure based on what additional keys now).
677 */
678 oc = lookup_option(&dhcpv6_universe, packet->options, D6O_SERVERID);
679 if ((oc == NULL) ||
680 !evaluate_option_cache(&lease->server_id, packet, NULL, NULL,
681 lease->options, NULL, &global_scope,
682 oc, MDL) ||
683 lease->server_id.len == 0) {
684 /* This should be impossible due to validation checks earlier.
685 */
686 log_error("Invalid SERVERID option cache.");
687 dhc6_lease_destroy(&lease, MDL);
688 return NULL;
689 } else {
690 log_debug("RCV: X-- Server ID: %s",
691 print_hex_1(lease->server_id.len,
692 lease->server_id.data, 52));
693 }
694
695 execute_statements_in_scope(NULL, (struct packet *)packet, NULL,
696 client, lease->options, lease->options,
697 &global_scope, client->config->on_receipt,
698 NULL, NULL);
699
700 return lease;
701 }
702
703 static isc_result_t
704 dhc6_parse_ia_na(struct dhc6_ia **pia, struct packet *packet,
705 struct option_state *options, unsigned code)
706 {
707 struct data_string ds;
708 struct dhc6_ia *ia;
709 struct option_cache *oc;
710 isc_result_t result;
711 unsigned ia_code;
712
713 memset(&ds, 0, sizeof(ds));
714
715 oc = lookup_option(&dhcpv6_universe, options, D6O_IA_NA);
716 for ( ; oc != NULL ; oc = oc->next) {
717 ia = dmalloc(sizeof(*ia), MDL);
718 if (ia == NULL) {
719 log_error("Out of memory allocating IA_NA structure.");
720 return ISC_R_NOMEMORY;
721 } else if (evaluate_option_cache(&ds, packet, NULL, NULL,
722 options, NULL,
723 &global_scope, oc, MDL) &&
724 ds.len >= 12) {
725 memcpy(ia->iaid, ds.data, 4);
726 ia->ia_type = D6O_IA_NA;
727 ia->starts = cur_time;
728 ia->renew = getULong(ds.data + 4);
729 ia->rebind = getULong(ds.data + 8);
730
731 log_debug("RCV: X-- IA_NA %s",
732 print_hex_1(4, ia->iaid, 59));
733 /* XXX: This should be the printed time I think. */
734 log_debug("RCV: | X-- starts %u",
735 (unsigned)ia->starts);
736 log_debug("RCV: | X-- t1 - renew +%u", ia->renew);
737 log_debug("RCV: | X-- t2 - rebind +%u", ia->rebind);
738
739 /*
740 * RFC3315 section 22.4, discard IA_NA's that
741 * have t1 greater than t2, and both not zero.
742 * Since RFC3315 defines this behaviour, it is not
743 * an error - just normal operation.
744 *
745 * Note that RFC3315 says we MUST honor these values
746 * if they are not zero. So insane values are
747 * totally OK.
748 */
749 if ((ia->renew > 0) && (ia->rebind > 0) &&
750 (ia->renew > ia->rebind)) {
751 log_debug("RCV: | !-- INVALID renew/rebind "
752 "times, IA_NA discarded.");
753 dfree(ia, MDL);
754 data_string_forget(&ds, MDL);
755 continue;
756 }
757
758 if (ds.len > 12) {
759 log_debug("RCV: | X-- [Options]");
760
761 if (!option_state_allocate(&ia->options,
762 MDL)) {
763 log_error("Out of memory allocating "
764 "IA_NA option state.");
765 dfree(ia, MDL);
766 data_string_forget(&ds, MDL);
767 return ISC_R_NOMEMORY;
768 }
769
770 if (!parse_option_buffer(ia->options,
771 ds.data + 12,
772 ds.len - 12,
773 &dhcpv6_universe)) {
774 log_error("Corrupt IA_NA options.");
775 option_state_dereference(&ia->options,
776 MDL);
777 dfree(ia, MDL);
778 data_string_forget(&ds, MDL);
779 return DHCP_R_BADPARSE;
780 }
781 }
782 data_string_forget(&ds, MDL);
783
784 if (ia->options != NULL) {
785 result = dhc6_parse_addrs(&ia->addrs, packet,
786 ia->options);
787 if (result != ISC_R_SUCCESS) {
788 option_state_dereference(&ia->options,
789 MDL);
790 dfree(ia, MDL);
791 return result;
792 }
793 }
794
795 /* If we have no addresses or the top level status code
796 * or the status code in this IA indicate no addresses
797 * toss the IA.
798 */
799 ia_code = STATUS_Success;
800 if ((ia->addrs == NULL) ||
801 (code == STATUS_NoAddrsAvail) ||
802 ((ia->options != NULL) &&
803 (dhc6_get_status_code(ia->options, &ia_code, NULL)
804 == ISC_R_SUCCESS) &&
805 (ia_code == STATUS_NoAddrsAvail))) {
806 log_debug("RCV: | !-- Status code of "
807 "no addrs, IA_NA discarded.");
808 dhc6_ia_destroy(&ia, MDL);
809 continue;
810 }
811
812 while (*pia != NULL)
813 pia = &(*pia)->next;
814 *pia = ia;
815 pia = &ia->next;
816 } else {
817 log_error("Invalid IA_NA option cache.");
818 dfree(ia, MDL);
819 data_string_forget(&ds, MDL);
820 return ISC_R_UNEXPECTED;
821 }
822 }
823 delete_option(&dhcpv6_universe, options, D6O_IA_NA);
824
825 return ISC_R_SUCCESS;
826 }
827
828 static isc_result_t
829 dhc6_parse_ia_ta(struct dhc6_ia **pia, struct packet *packet,
830 struct option_state *options, unsigned code)
831 {
832 struct data_string ds;
833 struct dhc6_ia *ia;
834 struct option_cache *oc;
835 isc_result_t result;
836 unsigned ia_code;
837
838 memset(&ds, 0, sizeof(ds));
839
840 oc = lookup_option(&dhcpv6_universe, options, D6O_IA_TA);
841 for ( ; oc != NULL ; oc = oc->next) {
842 ia = dmalloc(sizeof(*ia), MDL);
843 if (ia == NULL) {
844 log_error("Out of memory allocating IA_TA structure.");
845 return ISC_R_NOMEMORY;
846 } else if (evaluate_option_cache(&ds, packet, NULL, NULL,
847 options, NULL,
848 &global_scope, oc, MDL) &&
849 ds.len >= 4) {
850 memcpy(ia->iaid, ds.data, 4);
851 ia->ia_type = D6O_IA_TA;
852 ia->starts = cur_time;
853
854 log_debug("RCV: X-- IA_TA %s",
855 print_hex_1(4, ia->iaid, 59));
856 /* XXX: This should be the printed time I think. */
857 log_debug("RCV: | X-- starts %u",
858 (unsigned)ia->starts);
859
860 if (ds.len > 4) {
861 log_debug("RCV: | X-- [Options]");
862
863 if (!option_state_allocate(&ia->options,
864 MDL)) {
865 log_error("Out of memory allocating "
866 "IA_TA option state.");
867 dfree(ia, MDL);
868 data_string_forget(&ds, MDL);
869 return ISC_R_NOMEMORY;
870 }
871
872 if (!parse_option_buffer(ia->options,
873 ds.data + 4,
874 ds.len - 4,
875 &dhcpv6_universe)) {
876 log_error("Corrupt IA_TA options.");
877 option_state_dereference(&ia->options,
878 MDL);
879 dfree(ia, MDL);
880 data_string_forget(&ds, MDL);
881 return DHCP_R_BADPARSE;
882 }
883 }
884 data_string_forget(&ds, MDL);
885
886 if (ia->options != NULL) {
887 result = dhc6_parse_addrs(&ia->addrs, packet,
888 ia->options);
889 if (result != ISC_R_SUCCESS) {
890 option_state_dereference(&ia->options,
891 MDL);
892 dfree(ia, MDL);
893 return result;
894 }
895 }
896
897 /* If we have no addresses or the top level status code
898 * or the status code in this IA indicate no addresses
899 * toss the IA.
900 */
901 ia_code = STATUS_Success;
902 if ((ia->addrs == NULL) ||
903 (code == STATUS_NoAddrsAvail) ||
904 ((ia->options != NULL) &&
905 (dhc6_get_status_code(ia->options, &ia_code, NULL)
906 == ISC_R_SUCCESS) &&
907 (ia_code == STATUS_NoAddrsAvail))) {
908 log_debug("RCV: | !-- Status code of "
909 "no addrs, IA_TA discarded.");
910 dhc6_ia_destroy(&ia, MDL);
911 continue;
912 }
913
914 while (*pia != NULL)
915 pia = &(*pia)->next;
916 *pia = ia;
917 pia = &ia->next;
918 } else {
919 log_error("Invalid IA_TA option cache.");
920 dfree(ia, MDL);
921 data_string_forget(&ds, MDL);
922 return ISC_R_UNEXPECTED;
923 }
924 }
925 delete_option(&dhcpv6_universe, options, D6O_IA_TA);
926
927 return ISC_R_SUCCESS;
928 }
929
930 static isc_result_t
931 dhc6_parse_ia_pd(struct dhc6_ia **pia, struct packet *packet,
932 struct option_state *options, unsigned code)
933 {
934 struct data_string ds;
935 struct dhc6_ia *ia;
936 struct option_cache *oc;
937 isc_result_t result;
938 unsigned ia_code;
939
940 memset(&ds, 0, sizeof(ds));
941
942 oc = lookup_option(&dhcpv6_universe, options, D6O_IA_PD);
943 for ( ; oc != NULL ; oc = oc->next) {
944 ia = dmalloc(sizeof(*ia), MDL);
945 if (ia == NULL) {
946 log_error("Out of memory allocating IA_PD structure.");
947 return ISC_R_NOMEMORY;
948 } else if (evaluate_option_cache(&ds, packet, NULL, NULL,
949 options, NULL,
950 &global_scope, oc, MDL) &&
951 ds.len >= 12) {
952 memcpy(ia->iaid, ds.data, 4);
953 ia->ia_type = D6O_IA_PD;
954 ia->starts = cur_time;
955 ia->renew = getULong(ds.data + 4);
956 ia->rebind = getULong(ds.data + 8);
957
958 log_debug("RCV: X-- IA_PD %s",
959 print_hex_1(4, ia->iaid, 59));
960 /* XXX: This should be the printed time I think. */
961 log_debug("RCV: | X-- starts %u",
962 (unsigned)ia->starts);
963 log_debug("RCV: | X-- t1 - renew +%u", ia->renew);
964 log_debug("RCV: | X-- t2 - rebind +%u", ia->rebind);
965
966 /*
967 * RFC3633 section 9, discard IA_PD's that
968 * have t1 greater than t2, and both not zero.
969 * Since RFC3633 defines this behaviour, it is not
970 * an error - just normal operation.
971 */
972 if ((ia->renew > 0) && (ia->rebind > 0) &&
973 (ia->renew > ia->rebind)) {
974 log_debug("RCV: | !-- INVALID renew/rebind "
975 "times, IA_PD discarded.");
976 dfree(ia, MDL);
977 data_string_forget(&ds, MDL);
978 continue;
979 }
980
981 if (ds.len > 12) {
982 log_debug("RCV: | X-- [Options]");
983
984 if (!option_state_allocate(&ia->options,
985 MDL)) {
986 log_error("Out of memory allocating "
987 "IA_PD option state.");
988 dfree(ia, MDL);
989 data_string_forget(&ds, MDL);
990 return ISC_R_NOMEMORY;
991 }
992
993 if (!parse_option_buffer(ia->options,
994 ds.data + 12,
995 ds.len - 12,
996 &dhcpv6_universe)) {
997 log_error("Corrupt IA_PD options.");
998 option_state_dereference(&ia->options,
999 MDL);
1000 dfree(ia, MDL);
1001 data_string_forget(&ds, MDL);
1002 return DHCP_R_BADPARSE;
1003 }
1004 }
1005 data_string_forget(&ds, MDL);
1006
1007 if (ia->options != NULL) {
1008 result = dhc6_parse_prefixes(&ia->addrs,
1009 packet,
1010 ia->options);
1011 if (result != ISC_R_SUCCESS) {
1012 option_state_dereference(&ia->options,
1013 MDL);
1014 dfree(ia, MDL);
1015 return result;
1016 }
1017 }
1018
1019 /* If we have no prefixes or the top level status code
1020 * or the status code in this IA indicate no prefixes
1021 * toss the IA.
1022 */
1023 ia_code = STATUS_Success;
1024 if ((ia->addrs == NULL) ||
1025 (code == STATUS_NoPrefixAvail) ||
1026 ((ia->options != NULL) &&
1027 (dhc6_get_status_code(ia->options, &ia_code, NULL)
1028 == ISC_R_SUCCESS) &&
1029 (ia_code == STATUS_NoPrefixAvail))) {
1030 log_debug("RCV: | !-- Status code of "
1031 "no prefix, IA_PD discarded.");
1032 dhc6_ia_destroy(&ia, MDL);
1033 continue;
1034 }
1035
1036 while (*pia != NULL)
1037 pia = &(*pia)->next;
1038 *pia = ia;
1039 pia = &ia->next;
1040 } else {
1041 log_error("Invalid IA_PD option cache.");
1042 dfree(ia, MDL);
1043 data_string_forget(&ds, MDL);
1044 return ISC_R_UNEXPECTED;
1045 }
1046 }
1047 delete_option(&dhcpv6_universe, options, D6O_IA_PD);
1048
1049 return ISC_R_SUCCESS;
1050 }
1051
1052
1053 static isc_result_t
1054 dhc6_parse_addrs(struct dhc6_addr **paddr, struct packet *packet,
1055 struct option_state *options)
1056 {
1057 struct data_string ds;
1058 struct option_cache *oc;
1059 struct dhc6_addr *addr;
1060 isc_result_t rval = ISC_R_SUCCESS;
1061 unsigned code;
1062
1063 memset(&ds, 0, sizeof(ds));
1064
1065 oc = lookup_option(&dhcpv6_universe, options, D6O_IAADDR);
1066 for ( ; oc != NULL ; oc = oc->next) {
1067 addr = dmalloc(sizeof(*addr), MDL);
1068 if (addr == NULL) {
1069 log_error("Out of memory allocating "
1070 "address structure.");
1071 return ISC_R_NOMEMORY;
1072 } else if (evaluate_option_cache(&ds, packet, NULL, NULL,
1073 options, NULL, &global_scope,
1074 oc, MDL) &&
1075 (ds.len >= 24)) {
1076
1077 addr->address.len = 16;
1078 memcpy(addr->address.iabuf, ds.data, 16);
1079 addr->starts = cur_time;
1080 addr->preferred_life = getULong(ds.data + 16);
1081 addr->max_life = getULong(ds.data + 20);
1082
1083 log_debug("RCV: | | X-- IAADDR %s",
1084 piaddr(addr->address));
1085 log_debug("RCV: | | | X-- Preferred lifetime %u.",
1086 addr->preferred_life);
1087 log_debug("RCV: | | | X-- Max lifetime %u.",
1088 addr->max_life);
1089
1090 /*
1091 * RFC 3315 section 22.6 says we must discard
1092 * addresses whose pref is later than valid.
1093 */
1094 if ((addr->preferred_life > addr->max_life)) {
1095 log_debug("RCV: | | | !-- INVALID lifetimes, "
1096 "IAADDR discarded. Check your "
1097 "server configuration.");
1098 dfree(addr, MDL);
1099 data_string_forget(&ds, MDL);
1100 continue;
1101 }
1102
1103 /*
1104 * Fortunately this is the last recursion in the
1105 * protocol.
1106 */
1107 if (ds.len > 24) {
1108 if (!option_state_allocate(&addr->options,
1109 MDL)) {
1110 log_error("Out of memory allocating "
1111 "IAADDR option state.");
1112 dfree(addr, MDL);
1113 data_string_forget(&ds, MDL);
1114 return ISC_R_NOMEMORY;
1115 }
1116
1117 if (!parse_option_buffer(addr->options,
1118 ds.data + 24,
1119 ds.len - 24,
1120 &dhcpv6_universe)) {
1121 log_error("Corrupt IAADDR options.");
1122 option_state_dereference(&addr->options,
1123 MDL);
1124 dfree(addr, MDL);
1125 data_string_forget(&ds, MDL);
1126 return DHCP_R_BADPARSE;
1127 }
1128 }
1129
1130 data_string_forget(&ds, MDL);
1131
1132 if (addr->options != NULL) {
1133 log_debug("RCV: | | | X-- [Options]");
1134
1135 /* Get the status code if the return value
1136 * indicates an error or the status code
1137 * indicates no address toss the address
1138 */
1139 code = STATUS_Success;
1140 rval = dhc6_check_status(ISC_R_SUCCESS,
1141 addr->options,
1142 "IAADDR", &code);
1143 if (rval != ISC_R_SUCCESS) {
1144 log_debug("RCV: | | | X-- Status code"
1145 " issue, IAADDR discarded.");
1146 option_state_dereference(&addr->options,
1147 MDL);
1148 dfree(addr, MDL);
1149 continue;
1150 }
1151 }
1152
1153 *paddr = addr;
1154 paddr = &addr->next;
1155 } else {
1156 log_error("Invalid IAADDR option cache.");
1157 dfree(addr, MDL);
1158 data_string_forget(&ds, MDL);
1159 return ISC_R_UNEXPECTED;
1160 }
1161 }
1162 delete_option(&dhcpv6_universe, options, D6O_IAADDR);
1163
1164 return ISC_R_SUCCESS;
1165 }
1166
1167 static isc_result_t
1168 dhc6_parse_prefixes(struct dhc6_addr **ppfx, struct packet *packet,
1169 struct option_state *options)
1170 {
1171 struct data_string ds;
1172 struct option_cache *oc;
1173 struct dhc6_addr *pfx;
1174 isc_result_t rval = ISC_R_SUCCESS;
1175 unsigned code;
1176
1177 memset(&ds, 0, sizeof(ds));
1178
1179 oc = lookup_option(&dhcpv6_universe, options, D6O_IAPREFIX);
1180 for ( ; oc != NULL ; oc = oc->next) {
1181 pfx = dmalloc(sizeof(*pfx), MDL);
1182 if (pfx == NULL) {
1183 log_error("Out of memory allocating "
1184 "prefix structure.");
1185 return ISC_R_NOMEMORY;
1186 } else if (evaluate_option_cache(&ds, packet, NULL, NULL,
1187 options, NULL, &global_scope,
1188 oc, MDL) &&
1189 (ds.len >= 25)) {
1190
1191 pfx->preferred_life = getULong(ds.data);
1192 pfx->max_life = getULong(ds.data + 4);
1193 pfx->plen = getUChar(ds.data + 8);
1194 pfx->address.len = 16;
1195 memcpy(pfx->address.iabuf, ds.data + 9, 16);
1196 pfx->starts = cur_time;
1197
1198 log_debug("RCV: | | X-- IAPREFIX %s/%d",
1199 piaddr(pfx->address), (int)pfx->plen);
1200 log_debug("RCV: | | | X-- Preferred lifetime %u.",
1201 pfx->preferred_life);
1202 log_debug("RCV: | | | X-- Max lifetime %u.",
1203 pfx->max_life);
1204
1205 /* Sanity check over the prefix length */
1206 if ((pfx->plen < 4) || (pfx->plen > 128)) {
1207 log_debug("RCV: | | | !-- INVALID prefix "
1208 "length, IAPREFIX discarded. "
1209 "Check your server configuration.");
1210 dfree(pfx, MDL);
1211 data_string_forget(&ds, MDL);
1212 continue;
1213 }
1214 /*
1215 * RFC 3633 section 10 says we must discard
1216 * prefixes whose pref is later than valid.
1217 */
1218 if ((pfx->preferred_life > pfx->max_life)) {
1219 log_debug("RCV: | | | !-- INVALID lifetimes, "
1220 "IAPREFIX discarded. Check your "
1221 "server configuration.");
1222 dfree(pfx, MDL);
1223 data_string_forget(&ds, MDL);
1224 continue;
1225 }
1226
1227 /*
1228 * Fortunately this is the last recursion in the
1229 * protocol.
1230 */
1231 if (ds.len > 25) {
1232 if (!option_state_allocate(&pfx->options,
1233 MDL)) {
1234 log_error("Out of memory allocating "
1235 "IAPREFIX option state.");
1236 dfree(pfx, MDL);
1237 data_string_forget(&ds, MDL);
1238 return ISC_R_NOMEMORY;
1239 }
1240
1241 if (!parse_option_buffer(pfx->options,
1242 ds.data + 25,
1243 ds.len - 25,
1244 &dhcpv6_universe)) {
1245 log_error("Corrupt IAPREFIX options.");
1246 option_state_dereference(&pfx->options,
1247 MDL);
1248 dfree(pfx, MDL);
1249 data_string_forget(&ds, MDL);
1250 return DHCP_R_BADPARSE;
1251 }
1252 }
1253
1254 data_string_forget(&ds, MDL);
1255
1256 if (pfx->options != NULL) {
1257 log_debug("RCV: | | | X-- [Options]");
1258
1259 /* Get the status code if the return value
1260 * indicates an error or the status code
1261 * indicates no prefix toss the prefix
1262 */
1263 code = STATUS_Success;
1264 rval = dhc6_check_status(ISC_R_SUCCESS,
1265 pfx->options,
1266 "IAPREFIX", &code);
1267 if (rval != ISC_R_SUCCESS) {
1268 log_debug("RCV: | | | X-- Status code"
1269 " issue IAPREFIX discarded.");
1270 option_state_dereference(&pfx->options,
1271 MDL);
1272 dfree(pfx, MDL);
1273 continue;
1274 }
1275 }
1276
1277 *ppfx = pfx;
1278 ppfx = &pfx->next;
1279 } else {
1280 log_error("Invalid IAPREFIX option cache.");
1281 dfree(pfx, MDL);
1282 data_string_forget(&ds, MDL);
1283 return ISC_R_UNEXPECTED;
1284 }
1285 }
1286 delete_option(&dhcpv6_universe, options, D6O_IAPREFIX);
1287
1288 return ISC_R_SUCCESS;
1289 }
1290
1291 /* Clean up a lease object, deallocate all its parts, and set it to NULL. */
1292 void
1293 dhc6_lease_destroy(struct dhc6_lease **src, const char *file, int line)
1294 {
1295 struct dhc6_ia *ia, *nia;
1296 struct dhc6_lease *lease;
1297
1298 if (src == NULL || *src == NULL) {
1299 log_error("Attempt to destroy null lease.");
1300 return;
1301 }
1302 lease = *src;
1303
1304 data_string_forget(&lease->server_id, file, line);
1305 for (ia = lease->bindings ; ia != NULL ; ia = nia) {
1306 nia = ia->next;
1307
1308 dhc6_ia_destroy(&ia, file, line);
1309 }
1310
1311 if (lease->options != NULL)
1312 option_state_dereference(&lease->options, file, line);
1313
1314 dfree(lease, file, line);
1315 *src = NULL;
1316 }
1317
1318 /*
1319 * Traverse the addresses list, and destroy their contents, and NULL the
1320 * list pointer.
1321 */
1322 static void
1323 dhc6_ia_destroy(struct dhc6_ia **src, const char *file, int line)
1324 {
1325 struct dhc6_addr *addr, *naddr;
1326 struct dhc6_ia *ia;
1327
1328 if (src == NULL || *src == NULL) {
1329 log_error("Attempt to destroy null IA.");
1330 return;
1331 }
1332 ia = *src;
1333
1334 for (addr = ia->addrs ; addr != NULL ; addr = naddr) {
1335 naddr = addr->next;
1336
1337 if (addr->options != NULL)
1338 option_state_dereference(&addr->options, file, line);
1339
1340 dfree(addr, file, line);
1341 }
1342
1343 if (ia->options != NULL)
1344 option_state_dereference(&ia->options, file, line);
1345
1346 dfree(ia, file, line);
1347 *src = NULL;
1348 }
1349
1350 /*
1351 * For a given lease, insert it into the tail of the lease list. Upon
1352 * finding a duplicate by server id, remove it and take over its position.
1353 */
1354 static void
1355 insert_lease(struct dhc6_lease **head, struct dhc6_lease *new)
1356 {
1357 while (*head != NULL) {
1358 if ((*head)->server_id.len == new->server_id.len &&
1359 memcmp((*head)->server_id.data, new->server_id.data,
1360 new->server_id.len) == 0) {
1361 new->next = (*head)->next;
1362 dhc6_lease_destroy(head, MDL);
1363 break;
1364 }
1365
1366 head= &(*head)->next;
1367 }
1368
1369 *head = new;
1370 return;
1371 }
1372
1373 /*!
1374 *
1375 * \brief Determine a score for a lease. We use this to
1376 * compare and choose leases if we receive multiple candidates.
1377 *
1378 * We originally started with scores of 50 for a binding and 100 for
1379 * an address. This would select multiple adresses over multiple
1380 * bindings. As part of the 7550 work I've changed this to be
1381 * 10000 for a binding, 100 for an address and 1 for an option.
1382 * This will cause us to choose a lease with more bindings over
1383 * a lease with less bindings but more addresses which seems
1384 * to be the best selection criteria to me.
1385 * In theory we could end up with a lease with enough addresses
1386 * or options being better but at 100 to 1 I don't think it's likely.
1387 *
1388 * \param client = the state of the entire client
1389 * \param lease = the lease to score.
1390 *
1391 * \retrun the score of the lease
1392 */
1393
1394 /* The scores for individual items. */
1395 #ifdef USE_ORIGINAL_CLIENT_LEASE_WEIGHTS
1396 #define SCORE_BINDING 50
1397 #define SCORE_ADDRESS 100
1398 #else
1399 #define SCORE_BINDING 10000
1400 #define SCORE_ADDRESS 100
1401 #endif
1402
1403 #define SCORE_OPTION 1
1404 /* We need a lease with at least 1 binding and 1 address */
1405 #define SCORE_MIN (SCORE_BINDING + SCORE_ADDRESS)
1406
1407 static int
1408 dhc6_score_lease(struct client_state *client, struct dhc6_lease *lease)
1409 {
1410 struct dhc6_ia *ia;
1411 struct dhc6_addr *addr;
1412 struct option **req;
1413 int i;
1414
1415 if (lease->score)
1416 return lease->score;
1417
1418 lease->score = SCORE_OPTION;
1419
1420 /* If this lease lacks a required option, dump it. */
1421 /* XXX: we should be able to cache the failure... */
1422 req = client->config->required_options;
1423 if (req != NULL) {
1424 for (i = 0 ; req[i] != NULL ; i++) {
1425 if (lookup_option(&dhcpv6_universe, lease->options,
1426 req[i]->code) == NULL) {
1427 lease->score = 0;
1428 return lease->score;
1429 }
1430 }
1431 }
1432
1433 /* If this lease contains a requested option, improve its score. */
1434 req = client->config->requested_options;
1435 if (req != NULL) {
1436 for (i = 0 ; req[i] != NULL ; i++) {
1437 if (lookup_option(&dhcpv6_universe, lease->options,
1438 req[i]->code) != NULL)
1439 lease->score += SCORE_OPTION;
1440 }
1441 }
1442
1443 for (ia = lease->bindings ; ia != NULL ; ia = ia->next) {
1444 lease->score += SCORE_BINDING;
1445
1446 for (addr = ia->addrs ; addr != NULL ; addr = addr->next) {
1447 lease->score += SCORE_ADDRESS;
1448 }
1449 }
1450
1451 return lease->score;
1452 }
1453
1454 /*
1455 * start_init6() kicks off the process, transmitting a packet and
1456 * scheduling a retransmission event.
1457 */
1458 void
1459 start_init6(struct client_state *client)
1460 {
1461 struct timeval tv;
1462
1463 log_debug("PRC: Soliciting for leases (INIT).");
1464 client->state = S_INIT;
1465
1466 /* Initialize timers, RFC3315 section 17.1.2. */
1467 client->IRT = SOL_TIMEOUT * 100;
1468 client->MRT = SOL_MAX_RT * 100;
1469 client->MRC = 0;
1470 /* Default is 0 (no max) but -1 changes this. */
1471 if (!onetry)
1472 client->MRD = 0;
1473 else
1474 client->MRD = client->config->timeout;
1475
1476 dhc6_retrans_init(client);
1477
1478 /*
1479 * RFC3315 section 17.1.2 goes out of its way:
1480 * Also, the first RT MUST be selected to be strictly greater than IRT
1481 * by choosing RAND to be strictly greater than 0.
1482 */
1483 /* if RAND < 0 then RAND = -RAND */
1484 if (client->RT <= client->IRT)
1485 client->RT = client->IRT + (client->IRT - client->RT);
1486 /* if RAND == 0 then RAND = 1 */
1487 if (client->RT <= client->IRT)
1488 client->RT = client->IRT + 1;
1489
1490 client->v6_handler = init_handler;
1491
1492 /*
1493 * RFC3315 section 17.1.2 says we MUST start the first packet
1494 * between 0 and SOL_MAX_DELAY seconds. The good news is
1495 * SOL_MAX_DELAY is 1.
1496 */
1497 tv.tv_sec = cur_tv.tv_sec;
1498 tv.tv_usec = cur_tv.tv_usec;
1499 tv.tv_usec += (random() % (SOL_MAX_DELAY * 100)) * 10000;
1500 if (tv.tv_usec >= 1000000) {
1501 tv.tv_sec += 1;
1502 tv.tv_usec -= 1000000;
1503 }
1504 add_timeout(&tv, do_init6, client, NULL, NULL);
1505
1506 if (nowait)
1507 detach();
1508 }
1509
1510 /*
1511 * start_info_request6() kicks off the process, transmitting an info
1512 * request packet and scheduling a retransmission event.
1513 */
1514 void
1515 start_info_request6(struct client_state *client)
1516 {
1517 struct timeval tv;
1518
1519 log_debug("PRC: Requesting information (INIT).");
1520 client->state = S_INIT;
1521
1522 /* Initialize timers, RFC3315 section 18.1.5. */
1523 client->IRT = INF_TIMEOUT * 100;
1524 client->MRT = INF_MAX_RT * 100;
1525 client->MRC = 0;
1526 /* Default is 0 (no max) but -1 changes this. */
1527 if (!onetry)
1528 client->MRD = 0;
1529 else
1530 client->MRD = client->config->timeout;
1531
1532 dhc6_retrans_init(client);
1533
1534 client->v6_handler = info_request_handler;
1535
1536 /*
1537 * RFC3315 section 18.1.5 says we MUST start the first packet
1538 * between 0 and INF_MAX_DELAY seconds. The good news is
1539 * INF_MAX_DELAY is 1.
1540 */
1541 tv.tv_sec = cur_tv.tv_sec;
1542 tv.tv_usec = cur_tv.tv_usec;
1543 tv.tv_usec += (random() % (INF_MAX_DELAY * 100)) * 10000;
1544 if (tv.tv_usec >= 1000000) {
1545 tv.tv_sec += 1;
1546 tv.tv_usec -= 1000000;
1547 }
1548 add_timeout(&tv, do_info_request6, client, NULL, NULL);
1549
1550 if (nowait)
1551 detach();
1552 }
1553
1554 /*
1555 * start_confirm6() kicks off an "init-reboot" version of the process, at
1556 * startup to find out if old bindings are 'fair' and at runtime whenever
1557 * a link cycles state we'll eventually want to do this.
1558 */
1559 void
1560 start_confirm6(struct client_state *client)
1561 {
1562 struct timeval tv;
1563
1564 /* If there is no active lease, there is nothing to check. */
1565 if ((client->active_lease == NULL) ||
1566 !active_prefix(client) ||
1567 client->active_lease->released ||
1568 !unexpired_address_in_lease(client->active_lease)) {
1569 dhc6_lease_destroy(&client->active_lease, MDL);
1570 start_init6(client);
1571 return;
1572 }
1573
1574 log_debug("PRC: Confirming active lease (INIT-REBOOT).");
1575 client->state = S_REBOOTING;
1576
1577 /* Initialize timers, RFC3315 section 17.1.3. */
1578 client->IRT = CNF_TIMEOUT * 100;
1579 client->MRT = CNF_MAX_RT * 100;
1580 client->MRC = 0;
1581 client->MRD = CNF_MAX_RD;
1582
1583 dhc6_retrans_init(client);
1584
1585 client->v6_handler = reply_handler;
1586
1587 /*
1588 * RFC3315 section 18.1.2 says we MUST start the first packet
1589 * between 0 and CNF_MAX_DELAY seconds. The good news is
1590 * CNF_MAX_DELAY is 1.
1591 */
1592 tv.tv_sec = cur_tv.tv_sec;
1593 tv.tv_usec = cur_tv.tv_usec;
1594 tv.tv_usec += (random() % (CNF_MAX_DELAY * 100)) * 10000;
1595 if (tv.tv_usec >= 1000000) {
1596 tv.tv_sec += 1;
1597 tv.tv_usec -= 1000000;
1598 }
1599
1600 /* We do a rebind instead of a confirm if the user
1601 * is requesting PDs or previously requesed PDs or
1602 * increased the number of NAs or TAs they want
1603 * Confirms don't tell us if PDs are still on-link and
1604 * we won't add new IAs on a confirm.
1605 */
1606
1607 if ((wanted_ia_pd != 0) ||
1608 (dhc6_count_ia(client->active_lease, D6O_IA_PD) != 0) ||
1609 (dhc6_count_ia(client->active_lease, D6O_IA_NA) < wanted_ia_na) ||
1610 (dhc6_count_ia(client->active_lease, D6O_IA_TA) < wanted_ia_ta)) {
1611 client->state = S_REBINDING;
1612 client->refresh_type = DHCPV6_REBIND;
1613 add_timeout(&tv, do_refresh6, client, NULL, NULL);
1614 } else
1615 add_timeout(&tv, do_confirm6, client, NULL, NULL);
1616 }
1617
1618 /*
1619 * check_timing6() check on the timing for sending a v6 message
1620 * and then do the basic initialization for a v6 message.
1621 */
1622 #define CHK_TIM_SUCCESS 0
1623 #define CHK_TIM_MRC_EXCEEDED 1
1624 #define CHK_TIM_MRD_EXCEEDED 2
1625 #define CHK_TIM_ALLOC_FAILURE 3
1626
1627 int
1628 check_timing6 (struct client_state *client, u_int8_t msg_type,
1629 char *msg_str, struct dhc6_lease *lease,
1630 struct data_string *ds)
1631 {
1632 struct timeval elapsed;
1633
1634 /*
1635 * Start_time starts at the first transmission.
1636 */
1637 if (client->txcount == 0) {
1638 client->start_time.tv_sec = cur_tv.tv_sec;
1639 client->start_time.tv_usec = cur_tv.tv_usec;
1640 } else if ((client->MRC != 0) && (client->txcount > client->MRC)) {
1641 log_info("Max retransmission count exceeded.");
1642 return(CHK_TIM_MRC_EXCEEDED);
1643 }
1644
1645 /* elapsed = cur - start */
1646 elapsed.tv_sec = cur_tv.tv_sec - client->start_time.tv_sec;
1647 elapsed.tv_usec = cur_tv.tv_usec - client->start_time.tv_usec;
1648 if (elapsed.tv_usec < 0) {
1649 elapsed.tv_sec -= 1;
1650 elapsed.tv_usec += 1000000;
1651 }
1652
1653 /* Check if finished (-1 argument). */
1654 if ((client->MRD != 0) && (elapsed.tv_sec >= client->MRD)) {
1655 log_info("Max retransmission duration exceeded.");
1656 return(CHK_TIM_MRD_EXCEEDED);
1657 }
1658
1659 memset(ds, 0, sizeof(*ds));
1660 if (!buffer_allocate(&(ds->buffer), 4, MDL)) {
1661 log_error("Unable to allocate memory for %s.", msg_str);
1662 return(CHK_TIM_ALLOC_FAILURE);
1663 }
1664 ds->data = ds->buffer->data;
1665 ds->len = 4;
1666
1667 ds->buffer->data[0] = msg_type;
1668 memcpy(ds->buffer->data + 1, client->dhcpv6_transaction_id, 3);
1669
1670 /* Form an elapsed option. */
1671 /* Maximum value is 65535 1/100s coded as 0xffff. */
1672 if ((elapsed.tv_sec < 0) || (elapsed.tv_sec > 655) ||
1673 ((elapsed.tv_sec == 655) && (elapsed.tv_usec > 350000))) {
1674 client->elapsed = 0xffff;
1675 } else {
1676 client->elapsed = elapsed.tv_sec * 100;
1677 client->elapsed += elapsed.tv_usec / 10000;
1678 }
1679
1680 if (client->elapsed == 0)
1681 log_debug("XMT: Forming %s, 0 ms elapsed.", msg_str);
1682 else
1683 log_debug("XMT: Forming %s, %u0 ms elapsed.", msg_str,
1684 (unsigned)client->elapsed);
1685
1686 client->elapsed = htons(client->elapsed);
1687
1688 make_client6_options(client, &client->sent_options, lease, msg_type);
1689
1690 return(CHK_TIM_SUCCESS);
1691 }
1692
1693 /*!
1694 *
1695 * \brief Create an iaid from information from the client.
1696 *
1697 * \param client = the state of the entire client
1698 * \param ia = the ia to fill in
1699 * \param idx = index of the ia in case we are doing multiples
1700 * \param len = length of the base IA (4 for TA, 12 for NA & PD)
1701 *
1702 * \return ISC_R_SUCCESS - all is well continue, any other return indicates
1703 * an error and the packet should be tossed
1704 */
1705
1706 static isc_result_t
1707 dhc6_create_iaid(struct client_state *client,
1708 struct data_string *ia,
1709 int idx,
1710 unsigned len)
1711 {
1712 int start_idx, copy_len;
1713
1714 memset(ia, 0, sizeof(*ia));
1715 if (!buffer_allocate(&ia->buffer, len, MDL)) {
1716 return (ISC_R_NOMEMORY);
1717 }
1718 ia->data = ia->buffer->data;
1719 ia->len = len;
1720
1721 /*
1722 * A simple IAID is the last 4 bytes
1723 * of the hardware address.
1724 */
1725 if (client->interface->hw_address.hlen > 4) {
1726 start_idx = client->interface->hw_address.hlen - 4;
1727 copy_len = 4;
1728 } else {
1729 start_idx = 0;
1730 copy_len = client->interface->hw_address.hlen;
1731 }
1732 memcpy(ia->buffer->data,
1733 client->interface->hw_address.hbuf + start_idx,
1734 copy_len);
1735 if (idx)
1736 ia->buffer->data[3] += idx;
1737
1738 return (ISC_R_SUCCESS);
1739 }
1740
1741 /*!
1742 *
1743 * \brief Add bare IA_NAs, IA_TAs or IA_PDs to the packet we are building.
1744 *
1745 * Attempt to add the number of bare IAs indicated by wanted to
1746 * the packet. As we have already added a number of IAs based
1747 * on what is in the current lease after we create an IAID we check
1748 * it against the current lease and skip any that are already in use.
1749 *
1750 * \param client = the state of the entire client
1751 * \param packet = the packet we are building and where we
1752 * shall append the IA_NA, IA_TA or IA_PDs we create
1753 * \param wanted = the number of IA_NA, IA_TA or IA_PDs we want to create
1754 * \param ia_type = the type of the IAs we want to create: NA, TA or PD.
1755 *
1756 * \return ISC_R_SUCCESS - all is well continue, any other return indicates
1757 * an error and the packet should be tossed
1758 */
1759 static isc_result_t
1760 dhc6_bare_ia_xx(struct client_state *client,
1761 struct data_string *packet,
1762 int wanted,
1763 u_int16_t ia_type)
1764 {
1765 struct dhc6_ia *old_ia;
1766 struct data_string ia;
1767 u_int32_t t1, t2;
1768 int i, len;
1769 isc_result_t rval;
1770 char *type_string;
1771 struct option *type_option;
1772
1773 /* figure out what type of option we are working with */
1774 switch (ia_type) {
1775 case D6O_IA_NA:
1776 type_string = "IA_NA";
1777 type_option = ia_na_option;
1778 len = IA_NA_OFFSET;
1779 break;
1780 case D6O_IA_TA:
1781 type_string = "IA_TA";
1782 type_option = ia_ta_option;
1783 len = IA_TA_OFFSET;
1784 break;
1785 case D6O_IA_PD:
1786 type_string = "IA_PD";
1787 type_option = ia_pd_option;
1788 len = IA_PD_OFFSET;
1789 if (prefix_len_hint > 0) {
1790 len += IASUBOPT_PD_LEN;
1791 }
1792 break;
1793
1794 default:
1795 return (ISC_R_FAILURE);
1796 }
1797
1798 for (i = 0; wanted != 0; i++) {
1799 rval = dhc6_create_iaid(client, &ia, i, len);
1800 if (rval != ISC_R_SUCCESS) {
1801 log_error("Unable to allocate memory for %s.",
1802 type_string);
1803 return (rval);
1804 }
1805
1806 /* If we are already using this IAID, skip it and try again */
1807 if ((client->active_lease != NULL) &&
1808 ((old_ia = find_ia(client->active_lease->bindings,
1809 ia_type,
1810 (char *)ia.buffer->data)) != NULL)) {
1811 data_string_forget(&ia, MDL);
1812 continue;
1813 }
1814
1815 /* We have a good IAID, log it */
1816 log_debug("XMT: X-- %s %s",
1817 type_string, print_hex_1(4, ia.buffer->data, 55));
1818
1819 /* If we are requesting an NA or a PD we also want to add
1820 * the renew and rebind times we are requesting.
1821 */
1822 if (ia_type != D6O_IA_TA) {
1823 t1 = client->config->requested_lease / 2;
1824 t2 = t1 + (t1 / 2);
1825 putULong(ia.buffer->data + 4, t1);
1826 putULong(ia.buffer->data + 8, t2);
1827
1828 log_debug("XMT: | X-- Request renew in +%u",
1829 (unsigned)t1);
1830 log_debug("XMT: | X-- Request rebind in +%u",
1831 (unsigned)t2);
1832 }
1833
1834 if (ia_type == D6O_IA_PD && prefix_len_hint > 0) {
1835 unsigned char *ptr = ia.buffer->data + IA_NA_OFFSET;
1836 putUShort(ptr, D6O_IAPREFIX);
1837 ptr += 2;
1838 putUShort(ptr, IASUBOPT_PD_LEN);
1839 ptr += 2;
1840 putUChar(ptr + IASUBOPT_PD_PREFLEN_OFFSET,
1841 prefix_len_hint);
1842 log_debug("XMT: | | X-- Request prefix ::/%u.",
1843 prefix_len_hint);
1844 }
1845
1846 /* and append it to the packet */
1847 append_option(packet, &dhcpv6_universe, type_option, &ia);
1848 data_string_forget(&ia, MDL);
1849
1850 /* decrement the number of IAs we want */
1851 wanted--;
1852 }
1853
1854 return (ISC_R_SUCCESS);
1855 }
1856
1857 /*
1858 * do_init6() marshals and transmits a solicit.
1859 */
1860 void
1861 do_init6(void *input)
1862 {
1863 struct client_state *client;
1864 struct dhc6_ia *old_ia;
1865 struct dhc6_addr *old_addr;
1866 struct data_string ds;
1867 struct data_string ia;
1868 struct data_string addr;
1869 struct timeval tv;
1870 u_int32_t t1, t2;
1871 int i, send_ret;
1872
1873 client = input;
1874
1875 /*
1876 * In RFC3315 section 17.1.2, the retransmission timer is
1877 * used as the selecting timer.
1878 */
1879 if (client->advertised_leases != NULL) {
1880 start_selecting6(client);
1881 return;
1882 }
1883
1884 switch(check_timing6(client, DHCPV6_SOLICIT, "Solicit", NULL, &ds)) {
1885 case CHK_TIM_MRC_EXCEEDED:
1886 case CHK_TIM_ALLOC_FAILURE:
1887 return;
1888 case CHK_TIM_MRD_EXCEEDED:
1889 client->state = S_STOPPED;
1890 if (client->active_lease != NULL) {
1891 dhc6_lease_destroy(&client->active_lease, MDL);
1892 client->active_lease = NULL;
1893 }
1894 /* Stop if and only if this is the last client. */
1895 if (stopping_finished())
1896 finish(2);
1897 return;
1898 }
1899
1900 /*
1901 * Fetch any configured 'sent' options (includes DUID) in wire format.
1902 */
1903 dhcpv6_universe.encapsulate(&ds, NULL, NULL, client,
1904 NULL, client->sent_options, &global_scope,
1905 &dhcpv6_universe);
1906
1907 /* Use a specific handler with rapid-commit. */
1908 if (lookup_option(&dhcpv6_universe, client->sent_options,
1909 D6O_RAPID_COMMIT) != NULL) {
1910 client->v6_handler = rapid_commit_handler;
1911 }
1912
1913 /* Append IA_NA. */
1914 for (i = 0; i < wanted_ia_na; i++) {
1915 /*
1916 * XXX: maybe the IA_NA('s) should be put into the sent_options
1917 * cache. They'd have to be pulled down as they also contain
1918 * different option caches in the same universe...
1919 */
1920 if (dhc6_create_iaid(client, &ia, i, 12) != ISC_R_SUCCESS) {
1921 log_error("Unable to allocate memory for IA_NA.");
1922 data_string_forget(&ds, MDL);
1923 return;
1924 }
1925
1926 t1 = client->config->requested_lease / 2;
1927 t2 = t1 + (t1 / 2);
1928 putULong(ia.buffer->data + 4, t1);
1929 putULong(ia.buffer->data + 8, t2);
1930
1931 log_debug("XMT: X-- IA_NA %s",
1932 print_hex_1(4, ia.buffer->data, 55));
1933 log_debug("XMT: | X-- Request renew in +%u", (unsigned)t1);
1934 log_debug("XMT: | X-- Request rebind in +%u", (unsigned)t2);
1935
1936 if ((client->active_lease != NULL) &&
1937 ((old_ia = find_ia(client->active_lease->bindings,
1938 D6O_IA_NA,
1939 (char *)ia.buffer->data)) != NULL)) {
1940 /*
1941 * For each address in the old IA_NA,
1942 * request a binding.
1943 */
1944 memset(&addr, 0, sizeof(addr));
1945 for (old_addr = old_ia->addrs ; old_addr != NULL ;
1946 old_addr = old_addr->next) {
1947 if (old_addr->address.len != 16) {
1948 log_error("Invalid IPv6 address "
1949 "length %d. "
1950 "Ignoring. (%s:%d)",
1951 old_addr->address.len,
1952 MDL);
1953 continue;
1954 }
1955
1956 if (!buffer_allocate(&addr.buffer, 24, MDL)) {
1957 log_error("Unable to allocate memory "
1958 "for IAADDR.");
1959 data_string_forget(&ia, MDL);
1960 data_string_forget(&ds, MDL);
1961 return;
1962 }
1963 addr.data = addr.buffer->data;
1964 addr.len = 24;
1965
1966 memcpy(addr.buffer->data,
1967 old_addr->address.iabuf,
1968 16);
1969
1970 t1 = client->config->requested_lease;
1971 t2 = t1 + (t1 / 2);
1972 putULong(addr.buffer->data + 16, t1);
1973 putULong(addr.buffer->data + 20, t2);
1974
1975 log_debug("XMT: | X-- Request address %s.",
1976 piaddr(old_addr->address));
1977 log_debug("XMT: | | X-- Request "
1978 "preferred in +%u",
1979 (unsigned)t1);
1980 log_debug("XMT: | | X-- Request valid "
1981 "in +%u",
1982 (unsigned)t2);
1983
1984 append_option(&ia, &dhcpv6_universe,
1985 iaaddr_option,
1986 &addr);
1987
1988 data_string_forget(&addr, MDL);
1989 }
1990 }
1991
1992 append_option(&ds, &dhcpv6_universe, ia_na_option, &ia);
1993 data_string_forget(&ia, MDL);
1994 }
1995
1996 /* Append IA_TA. */
1997 for (i = 0; i < wanted_ia_ta; i++) {
1998 /*
1999 * XXX: maybe the IA_TA('s) should be put into the sent_options
2000 * cache. They'd have to be pulled down as they also contain
2001 * different option caches in the same universe...
2002 */
2003 if (dhc6_create_iaid(client, &ia, i, 4) != ISC_R_SUCCESS) {
2004 log_error("Unable to allocate memory for IA_TA.");
2005 data_string_forget(&ds, MDL);
2006 return;
2007 }
2008
2009 log_debug("XMT: X-- IA_TA %s",
2010 print_hex_1(4, ia.buffer->data, 55));
2011
2012 if ((client->active_lease != NULL) &&
2013 ((old_ia = find_ia(client->active_lease->bindings,
2014 D6O_IA_TA,
2015 (char *)ia.buffer->data)) != NULL)) {
2016 /*
2017 * For each address in the old IA_TA,
2018 * request a binding.
2019 */
2020 memset(&addr, 0, sizeof(addr));
2021 for (old_addr = old_ia->addrs ; old_addr != NULL ;
2022 old_addr = old_addr->next) {
2023 if (old_addr->address.len != 16) {
2024 log_error("Invalid IPv6 address "
2025 "length %d. "
2026 "Ignoring. (%s:%d)",
2027 old_addr->address.len,
2028 MDL);
2029 continue;
2030 }
2031
2032 if (!buffer_allocate(&addr.buffer, 24, MDL)) {
2033 log_error("Unable to allocate memory "
2034 "for IAADDR.");
2035 data_string_forget(&ia, MDL);
2036 data_string_forget(&ds, MDL);
2037 return;
2038 }
2039 addr.data = addr.buffer->data;
2040 addr.len = 24;
2041
2042 memcpy(addr.buffer->data,
2043 old_addr->address.iabuf,
2044 16);
2045
2046 t1 = client->config->requested_lease;
2047 t2 = t1 + (t1 / 2);
2048 putULong(addr.buffer->data + 16, t1);
2049 putULong(addr.buffer->data + 20, t2);
2050
2051 log_debug("XMT: | X-- Request address %s.",
2052 piaddr(old_addr->address));
2053 log_debug("XMT: | | X-- Request "
2054 "preferred in +%u",
2055 (unsigned)t1);
2056 log_debug("XMT: | | X-- Request valid "
2057 "in +%u",
2058 (unsigned)t2);
2059
2060 append_option(&ia, &dhcpv6_universe,
2061 iaaddr_option,
2062 &addr);
2063
2064 data_string_forget(&addr, MDL);
2065 }
2066 }
2067
2068 append_option(&ds, &dhcpv6_universe, ia_ta_option, &ia);
2069 data_string_forget(&ia, MDL);
2070 }
2071
2072 /* Append IA_PD. */
2073 for (i = 0; i < wanted_ia_pd; i++) {
2074 /*
2075 * XXX: maybe the IA_PD('s) should be put into the sent_options
2076 * cache. They'd have to be pulled down as they also contain
2077 * different option caches in the same universe...
2078 */
2079 memset(&ia, 0, sizeof(ia));
2080 if (dhc6_create_iaid(client, &ia, i, 12) != ISC_R_SUCCESS) {
2081 log_error("Unable to allocate memory for IA_PD.");
2082 data_string_forget(&ds, MDL);
2083 return;
2084 }
2085
2086 t1 = client->config->requested_lease / 2;
2087 t2 = t1 + (t1 / 2);
2088 putULong(ia.buffer->data + 4, t1);
2089 putULong(ia.buffer->data + 8, t2);
2090
2091 log_debug("XMT: X-- IA_PD %s",
2092 print_hex_1(4, ia.buffer->data, 55));
2093 log_debug("XMT: | X-- Request renew in +%u", (unsigned)t1);
2094 log_debug("XMT: | X-- Request rebind in +%u", (unsigned)t2);
2095
2096 if ((client->active_lease != NULL) &&
2097 ((old_ia = find_ia(client->active_lease->bindings,
2098 D6O_IA_PD,
2099 (char *)ia.buffer->data)) != NULL)) {
2100 /*
2101 * For each prefix in the old IA_PD,
2102 * request a binding.
2103 */
2104 memset(&addr, 0, sizeof(addr));
2105 for (old_addr = old_ia->addrs ; old_addr != NULL ;
2106 old_addr = old_addr->next) {
2107 if (old_addr->address.len != 16) {
2108 log_error("Invalid IPv6 prefix, "
2109 "Ignoring. (%s:%d)",
2110 MDL);
2111 continue;
2112 }
2113
2114 if (!buffer_allocate(&addr.buffer, 25, MDL)) {
2115 log_error("Unable to allocate memory "
2116 "for IAPREFIX.");
2117 data_string_forget(&ia, MDL);
2118 data_string_forget(&ds, MDL);
2119 return;
2120 }
2121 addr.data = addr.buffer->data;
2122 addr.len = 25;
2123
2124 t1 = client->config->requested_lease;
2125 t2 = t1 + (t1 / 2);
2126 putULong(addr.buffer->data, t1);
2127 putULong(addr.buffer->data + 4, t2);
2128
2129 putUChar(addr.buffer->data + 8,
2130 old_addr->plen);
2131 memcpy(addr.buffer->data + 9,
2132 old_addr->address.iabuf,
2133 16);
2134
2135 log_debug("XMT: | X-- Request prefix %s/%u.",
2136 piaddr(old_addr->address),
2137 (unsigned) old_addr->plen);
2138 log_debug("XMT: | | X-- Request "
2139 "preferred in +%u",
2140 (unsigned)t1);
2141 log_debug("XMT: | | X-- Request valid "
2142 "in +%u",
2143 (unsigned)t2);
2144
2145 append_option(&ia, &dhcpv6_universe,
2146 iaprefix_option,
2147 &addr);
2148
2149 data_string_forget(&addr, MDL);
2150 }
2151 } else if (prefix_len_hint > 0) {
2152 memset(&addr, 0, sizeof(addr));
2153 if (!buffer_allocate(&addr.buffer, 25, MDL)) {
2154 log_error("Unable to allocate memory "
2155 "for IAPREFIX.");
2156 data_string_forget(&ia, MDL);
2157 data_string_forget(&ds, MDL);
2158 return;
2159 }
2160
2161 addr.data = addr.buffer->data;
2162 addr.len = 25;
2163
2164 putUChar(addr.buffer->data + 8, prefix_len_hint);
2165 log_debug("XMT: | | X-- Request prefix ::/%u.",
2166 prefix_len_hint);
2167 append_option(&ia, &dhcpv6_universe, iaprefix_option,
2168 &addr);
2169 data_string_forget(&addr, MDL);
2170 }
2171
2172 append_option(&ds, &dhcpv6_universe, ia_pd_option, &ia);
2173 data_string_forget(&ia, MDL);
2174 }
2175
2176 /* Transmit and wait. */
2177
2178 log_info("XMT: Solicit on %s, interval %ld0ms.",
2179 client->name ? client->name : client->interface->name,
2180 (long int)client->RT);
2181
2182 send_ret = send_packet6(client->interface,
2183 ds.data, ds.len, &DHCPv6DestAddr);
2184 if (send_ret != ds.len) {
2185 log_error("dhc6: send_packet6() sent %d of %d bytes",
2186 send_ret, ds.len);
2187 }
2188
2189 data_string_forget(&ds, MDL);
2190
2191 /* Wait RT */
2192 tv.tv_sec = cur_tv.tv_sec + client->RT / 100;
2193 tv.tv_usec = cur_tv.tv_usec + (client->RT % 100) * 10000;
2194 if (tv.tv_usec >= 1000000) {
2195 tv.tv_sec += 1;
2196 tv.tv_usec -= 1000000;
2197 }
2198 add_timeout(&tv, do_init6, client, NULL, NULL);
2199
2200 dhc6_retrans_advance(client);
2201 }
2202
2203 /* do_info_request6() marshals and transmits an information-request. */
2204 void
2205 do_info_request6(void *input)
2206 {
2207 struct client_state *client;
2208 struct data_string ds;
2209 struct timeval tv;
2210 int send_ret;
2211
2212 client = input;
2213
2214 switch(check_timing6(client, DHCPV6_INFORMATION_REQUEST,
2215 "Info-Request", NULL, &ds)) {
2216 case CHK_TIM_MRC_EXCEEDED:
2217 case CHK_TIM_ALLOC_FAILURE:
2218 return;
2219 case CHK_TIM_MRD_EXCEEDED:
2220 finish(2);
2221 case CHK_TIM_SUCCESS:
2222 break;
2223 }
2224
2225 /* Fetch any configured 'sent' options (includes DUID) in wire format.
2226 */
2227 dhcpv6_universe.encapsulate(&ds, NULL, NULL, client,
2228 NULL, client->sent_options, &global_scope,
2229 &dhcpv6_universe);
2230
2231 /* Transmit and wait. */
2232
2233 log_info("XMT: Info-Request on %s, interval %ld0ms.",
2234 client->name ? client->name : client->interface->name,
2235 (long int)client->RT);
2236
2237 send_ret = send_packet6(client->interface,
2238 ds.data, ds.len, &DHCPv6DestAddr);
2239 if (send_ret != ds.len) {
2240 log_error("dhc6: send_packet6() sent %d of %d bytes",
2241 send_ret, ds.len);
2242 }
2243
2244 data_string_forget(&ds, MDL);
2245
2246 /* Wait RT */
2247 tv.tv_sec = cur_tv.tv_sec + client->RT / 100;
2248 tv.tv_usec = cur_tv.tv_usec + (client->RT % 100) * 10000;
2249 if (tv.tv_usec >= 1000000) {
2250 tv.tv_sec += 1;
2251 tv.tv_usec -= 1000000;
2252 }
2253 add_timeout(&tv, do_info_request6, client, NULL, NULL);
2254
2255 dhc6_retrans_advance(client);
2256 }
2257
2258 /* do_confirm6() creates a Confirm packet and transmits it. This function
2259 * is called on every timeout to (re)transmit.
2260 */
2261 void
2262 do_confirm6(void *input)
2263 {
2264 struct client_state *client;
2265 struct data_string ds;
2266 int send_ret, added;
2267 struct timeval tv;
2268
2269 client = input;
2270
2271 if (client->active_lease == NULL)
2272 log_fatal("Impossible condition at %s:%d.", MDL);
2273
2274 /* In section 17.1.3, it is said:
2275 *
2276 * If the client receives no responses before the message
2277 * transmission process terminates, as described in section 14,
2278 * the client SHOULD continue to use any IP addresses, using the
2279 * last known lifetimes for those addresses, and SHOULD continue
2280 * to use any other previously obtained configuration parameters.
2281 *
2282 * So if confirm times out, we go active.
2283 *
2284 * XXX: Should we reduce all IA's t1 to 0, so that we renew and
2285 * stick there until we get a reply?
2286 */
2287
2288 switch(check_timing6(client, DHCPV6_CONFIRM, "Confirm",
2289 client->active_lease, &ds)) {
2290 case CHK_TIM_MRC_EXCEEDED:
2291 case CHK_TIM_MRD_EXCEEDED:
2292 start_bound(client);
2293 return;
2294 case CHK_TIM_ALLOC_FAILURE:
2295 return;
2296 case CHK_TIM_SUCCESS:
2297 break;
2298 }
2299
2300 /* Fetch any configured 'sent' options (includes DUID') in wire format.
2301 */
2302 dhcpv6_universe.encapsulate(&ds, NULL, NULL, client, NULL,
2303 client->sent_options, &global_scope,
2304 &dhcpv6_universe);
2305
2306 /* Append IA's. */
2307 if (wanted_ia_na &&
2308 dhc6_add_ia_na(client, &ds, client->active_lease,
2309 DHCPV6_CONFIRM, 0, &added) != ISC_R_SUCCESS) {
2310 data_string_forget(&ds, MDL);
2311 return;
2312 }
2313 if (wanted_ia_ta &&
2314 dhc6_add_ia_ta(client, &ds, client->active_lease,
2315 DHCPV6_CONFIRM, 0, &added) != ISC_R_SUCCESS) {
2316 data_string_forget(&ds, MDL);
2317 return;
2318 }
2319
2320 /* Transmit and wait. */
2321
2322 log_info("XMT: Confirm on %s, interval %ld0ms.",
2323 client->name ? client->name : client->interface->name,
2324 (long int)client->RT);
2325
2326 send_ret = send_packet6(client->interface, ds.data, ds.len,
2327 &DHCPv6DestAddr);
2328 if (send_ret != ds.len) {
2329 log_error("dhc6: sendpacket6() sent %d of %d bytes",
2330 send_ret, ds.len);
2331 }
2332
2333 data_string_forget(&ds, MDL);
2334
2335 /* Wait RT */
2336 tv.tv_sec = cur_tv.tv_sec + client->RT / 100;
2337 tv.tv_usec = cur_tv.tv_usec + (client->RT % 100) * 10000;
2338 if (tv.tv_usec >= 1000000) {
2339 tv.tv_sec += 1;
2340 tv.tv_usec -= 1000000;
2341 }
2342 add_timeout(&tv, do_confirm6, client, NULL, NULL);
2343
2344 dhc6_retrans_advance(client);
2345 }
2346
2347 /*
2348 * Release addresses.
2349 */
2350 void
2351 start_release6(struct client_state *client)
2352 {
2353 /* Cancel any pending transmissions */
2354 cancel_timeout(do_confirm6, client);
2355 cancel_timeout(do_select6, client);
2356 cancel_timeout(do_refresh6, client);
2357 cancel_timeout(do_release6, client);
2358 cancel_timeout(do_decline6, client);
2359 client->state = S_STOPPED;
2360
2361 /*
2362 * It is written: "The client MUST NOT use any of the addresses it
2363 * is releasing as the source address in the Release message or in
2364 * any subsequently transmitted message." So unconfigure now.
2365 */
2366 unconfigure6(client, "RELEASE6");
2367
2368 /* Note this in the lease file. */
2369 if (client->active_lease == NULL)
2370 return;
2371 client->active_lease->released = ISC_TRUE;
2372 write_client6_lease(client, client->active_lease, 0, 1);
2373
2374 /* Set timers per RFC3315 section 18.1.6. */
2375 client->IRT = REL_TIMEOUT * 100;
2376 client->MRT = 0;
2377 client->MRC = REL_MAX_RC;
2378 client->MRD = 0;
2379
2380 dhc6_retrans_init(client);
2381 client->v6_handler = reply_handler;
2382
2383 do_release6(client);
2384 }
2385 /*
2386 * do_release6() creates a Release packet and transmits it.
2387 */
2388 static void
2389 do_release6(void *input)
2390 {
2391 struct client_state *client;
2392 struct data_string ds;
2393 int send_ret, added;
2394 struct timeval tv;
2395
2396 client = input;
2397
2398 if ((client->active_lease == NULL) || !active_prefix(client))
2399 return;
2400
2401 switch(check_timing6(client, DHCPV6_RELEASE, "Release",
2402 client->active_lease, &ds)) {
2403 case CHK_TIM_MRC_EXCEEDED:
2404 case CHK_TIM_ALLOC_FAILURE:
2405 case CHK_TIM_MRD_EXCEEDED:
2406 goto release_done;
2407 case CHK_TIM_SUCCESS:
2408 break;
2409 }
2410
2411 /*
2412 * Don't use unicast as we don't know if we still have an
2413 * available address with enough scope.
2414 */
2415
2416 dhcpv6_universe.encapsulate(&ds, NULL, NULL, client, NULL,
2417 client->sent_options, &global_scope,
2418 &dhcpv6_universe);
2419
2420 /* Append IA's (but don't release temporary addresses). */
2421 if (wanted_ia_na &&
2422 dhc6_add_ia_na(client, &ds, client->active_lease,
2423 DHCPV6_RELEASE, 0, &added) != ISC_R_SUCCESS) {
2424 data_string_forget(&ds, MDL);
2425 goto release_done;
2426 }
2427 if (wanted_ia_pd &&
2428 dhc6_add_ia_pd(client, &ds, client->active_lease,
2429 DHCPV6_RELEASE, 0, &added) != ISC_R_SUCCESS) {
2430 data_string_forget(&ds, MDL);
2431 goto release_done;
2432 }
2433
2434 /* Transmit and wait. */
2435 log_info("XMT: Release on %s, interval %ld0ms.",
2436 client->name ? client->name : client->interface->name,
2437 (long int)client->RT);
2438
2439 send_ret = send_packet6(client->interface, ds.data, ds.len,
2440 &DHCPv6DestAddr);
2441 if (send_ret != ds.len) {
2442 log_error("dhc6: sendpacket6() sent %d of %d bytes",
2443 send_ret, ds.len);
2444 }
2445
2446 data_string_forget(&ds, MDL);
2447
2448 /* Wait RT */
2449 tv.tv_sec = cur_tv.tv_sec + client->RT / 100;
2450 tv.tv_usec = cur_tv.tv_usec + (client->RT % 100) * 10000;
2451 if (tv.tv_usec >= 1000000) {
2452 tv.tv_sec += 1;
2453 tv.tv_usec -= 1000000;
2454 }
2455 add_timeout(&tv, do_release6, client, NULL, NULL);
2456 dhc6_retrans_advance(client);
2457 return;
2458
2459 release_done:
2460 dhc6_lease_destroy(&client->active_lease, MDL);
2461 client->active_lease = NULL;
2462 if (stopping_finished())
2463 finish(0);
2464 }
2465
2466 /* status_log() just puts a status code into displayable form and logs it
2467 * to info level.
2468 */
2469 static void
2470 status_log(int code, const char *scope, const char *additional, int len)
2471 {
2472 const char *msg = NULL;
2473
2474 switch(code) {
2475 case STATUS_Success:
2476 msg = "Success";
2477 break;
2478
2479 case STATUS_UnspecFail:
2480 msg = "UnspecFail";
2481 break;
2482
2483 case STATUS_NoAddrsAvail:
2484 msg = "NoAddrsAvail";
2485 break;
2486
2487 case STATUS_NoBinding:
2488 msg = "NoBinding";
2489 break;
2490
2491 case STATUS_NotOnLink:
2492 msg = "NotOnLink";
2493 break;
2494
2495 case STATUS_UseMulticast:
2496 msg = "UseMulticast";
2497 break;
2498
2499 case STATUS_NoPrefixAvail:
2500 msg = "NoPrefixAvail";
2501 break;
2502
2503 default:
2504 msg = "UNKNOWN";
2505 break;
2506 }
2507
2508 if (len > 0)
2509 log_info("%s status code %s: %s", scope, msg,
2510 print_hex_1(len,
2511 (const unsigned char *)additional, 50));
2512 else
2513 log_info("%s status code %s.", scope, msg);
2514 }
2515
2516 /* Acquire a status code.
2517 */
2518 static isc_result_t
2519 dhc6_get_status_code(struct option_state *options, unsigned *code,
2520 struct data_string *msg)
2521 {
2522 struct option_cache *oc;
2523 struct data_string ds;
2524 isc_result_t rval = ISC_R_SUCCESS;
2525
2526 if ((options == NULL) || (code == NULL))
2527 return DHCP_R_INVALIDARG;
2528
2529 if ((msg != NULL) && (msg->len != 0))
2530 return DHCP_R_INVALIDARG;
2531
2532 memset(&ds, 0, sizeof(ds));
2533
2534 /* Assume success if there is no option. */
2535 *code = STATUS_Success;
2536
2537 oc = lookup_option(&dhcpv6_universe, options, D6O_STATUS_CODE);
2538 if ((oc != NULL) &&
2539 evaluate_option_cache(&ds, NULL, NULL, NULL, options,
2540 NULL, &global_scope, oc, MDL)) {
2541 if (ds.len < 2) {
2542 log_error("Invalid status code length %d.", ds.len);
2543 rval = DHCP_R_FORMERR;
2544 } else
2545 *code = getUShort(ds.data);
2546
2547 if ((msg != NULL) && (ds.len > 2)) {
2548 data_string_copy(msg, &ds, MDL);
2549 msg->data += 2;
2550 msg->len -= 2;
2551 }
2552
2553 data_string_forget(&ds, MDL);
2554 return rval;
2555 }
2556
2557 return ISC_R_NOTFOUND;
2558 }
2559
2560 /* Look at status codes in an advertise, and reform the return value.
2561 */
2562 static isc_result_t
2563 dhc6_check_status(isc_result_t rval, struct option_state *options,
2564 const char *scope, unsigned *code)
2565 {
2566 struct data_string msg;
2567 isc_result_t status;
2568
2569 if ((scope == NULL) || (code == NULL))
2570 return DHCP_R_INVALIDARG;
2571
2572 /* If we don't find a code, we assume success. */
2573 *code = STATUS_Success;
2574
2575 /* If there is no options cache, then there is no code. */
2576 if (options != NULL) {
2577 memset(&msg, 0, sizeof(msg));
2578 status = dhc6_get_status_code(options, code, &msg);
2579
2580 if (status == ISC_R_SUCCESS) {
2581 status_log(*code, scope, (char *)msg.data, msg.len);
2582 data_string_forget(&msg, MDL);
2583
2584 if (*code != STATUS_Success)
2585 rval = ISC_R_FAILURE;
2586
2587 } else if (status != ISC_R_NOTFOUND)
2588 rval = status;
2589 }
2590
2591 return rval;
2592 }
2593
2594 /* Determine if this packet could provide usable information.
2595 * We check the status codes at the top level and at the IA level,
2596 * IAADDRS have already been checked in the leaseify step and any with
2597 * a bad format or status code that wasn't success have been dropped.
2598 *
2599 * leaseify has also already removed any IAs for which the top level status
2600 * code or the IA status code indicated no addresses or prefixes were
2601 * available.
2602 */
2603 static isc_result_t
2604 dhc6_check_advertise(struct dhc6_lease *lease)
2605 {
2606 struct dhc6_ia *ia;
2607 isc_result_t rval = ISC_R_SUCCESS;
2608 int have_addrs = ISC_FALSE;
2609 unsigned code;
2610 const char *scope;
2611 int got_na = 0, got_ta = 0, got_pd = 0;
2612
2613 rval = dhc6_check_status(rval, lease->options, "message", &code);
2614
2615 for (ia = lease->bindings ; ia != NULL ; ia = ia->next) {
2616 switch (ia->ia_type) {
2617 case D6O_IA_NA:
2618 scope = "IA_NA";
2619 got_na++;
2620 break;
2621 case D6O_IA_TA:
2622 scope = "IA_TA";
2623 got_ta++;
2624 break;
2625 case D6O_IA_PD:
2626 scope = "IA_PD";
2627 got_pd++;
2628 break;
2629 default:
2630 log_error("dhc6_check_advertise: no type.");
2631 return ISC_R_FAILURE;
2632 }
2633 /* Currently we toss packets if we have an error getting a
2634 * status code or if the status code isn't success, so
2635 * no need to loop through the addresses */
2636 rval = dhc6_check_status(rval, ia->options, scope, &code);
2637 if (rval != ISC_R_SUCCESS)
2638 continue;
2639
2640 /* We don't need to check status on IAADDRS here as we already
2641 * did it as part of the leaseify step and tossed bad IAADDRS.
2642 * We are just checking to see if we have any addrs.
2643 * Should we check the addr itself for usability?
2644 */
2645 if (ia->addrs != NULL) {
2646 have_addrs = ISC_TRUE;
2647 }
2648 }
2649
2650 /* If we didn't get some addrs or the user required us to
2651 * get all of the requested IAs and we didn't return an error
2652 */
2653 if ((have_addrs != ISC_TRUE) ||
2654 ((require_all_ias != 0) &&
2655 ((got_na < wanted_ia_na) ||
2656 (got_ta < wanted_ia_ta) ||
2657 (got_pd < wanted_ia_pd))))
2658 rval = ISC_R_ADDRNOTAVAIL;
2659
2660 return rval;
2661 }
2662
2663 /* status code <-> action matrix for the client in INIT state
2664 * (rapid/commit). Returns always false as no action is defined.
2665 */
2666 static isc_boolean_t
2667 dhc6_init_action(struct client_state *client, isc_result_t *rvalp,
2668 unsigned code)
2669 {
2670 if (rvalp == NULL)
2671 log_fatal("Impossible condition at %s:%d.", MDL);
2672
2673 if (client == NULL) {
2674 *rvalp = DHCP_R_INVALIDARG;
2675 return ISC_FALSE;
2676 }
2677
2678 if (*rvalp == ISC_R_SUCCESS)
2679 return ISC_FALSE;
2680
2681 /* No possible action in any case... */
2682 return ISC_FALSE;
2683 }
2684
2685 /* status code <-> action matrix for the client in SELECT state
2686 * (request/reply). Returns true if action was taken (and the
2687 * packet should be ignored), or false if no action was taken.
2688 */
2689 static isc_boolean_t
2690 dhc6_select_action(struct client_state *client, isc_result_t *rvalp,
2691 unsigned code)
2692 {
2693 struct dhc6_lease *lease;
2694 isc_result_t rval;
2695
2696 if (rvalp == NULL)
2697 log_fatal("Impossible condition at %s:%d.", MDL);
2698
2699 if (client == NULL) {
2700 *rvalp = DHCP_R_INVALIDARG;
2701 return ISC_FALSE;
2702 }
2703 rval = *rvalp;
2704
2705 if (rval == ISC_R_SUCCESS)
2706 return ISC_FALSE;
2707
2708 switch (code) {
2709 /* We may have an earlier failure status code (so no
2710 * success rval), and a success code now. This
2711 * doesn't upgrade the rval to success, but it does
2712 * mean we take no action here.
2713 */
2714 case STATUS_Success:
2715 /* Gimpy server, or possibly an attacker. */
2716 case STATUS_NoBinding:
2717 case STATUS_UseMulticast:
2718 /* Take no action. */
2719 return ISC_FALSE;
2720
2721 /* If the server can't deal with us, either try the
2722 * next advertised server, or continue retrying if there
2723 * weren't any.
2724 */
2725 default:
2726 case STATUS_UnspecFail:
2727 if (client->advertised_leases != NULL) {
2728 dhc6_lease_destroy(&client->selected_lease, MDL);
2729 client->selected_lease = NULL;
2730
2731 start_selecting6(client);
2732
2733 break;
2734 } else /* Take no action - continue to retry. */
2735 return ISC_FALSE;
2736
2737 /* If the server has no addresses, try other servers if
2738 * we got some, otherwise go to INIT to hope for more
2739 * servers.
2740 */
2741 case STATUS_NoAddrsAvail:
2742 case STATUS_NoPrefixAvail:
2743 if (client->state == S_REBOOTING)
2744 return ISC_FALSE;
2745
2746 if (client->selected_lease == NULL)
2747 log_fatal("Impossible case at %s:%d.", MDL);
2748
2749 dhc6_lease_destroy(&client->selected_lease, MDL);
2750 client->selected_lease = NULL;
2751
2752 if (client->advertised_leases != NULL)
2753 start_selecting6(client);
2754 else
2755 start_init6(client);
2756
2757 break;
2758
2759 /* If we got a NotOnLink from a Confirm, then we're not
2760 * on link. Kill the old-active binding and start over.
2761 *
2762 * If we got a NotOnLink from our Request, something weird
2763 * happened. Start over from scratch anyway.
2764 */
2765 case STATUS_NotOnLink:
2766 if (client->state == S_REBOOTING) {
2767 if (client->active_lease == NULL)
2768 log_fatal("Impossible case at %s:%d.", MDL);
2769
2770 dhc6_lease_destroy(&client->active_lease, MDL);
2771 } else {
2772 if (client->selected_lease == NULL)
2773 log_fatal("Impossible case at %s:%d.", MDL);
2774
2775 dhc6_lease_destroy(&client->selected_lease, MDL);
2776 client->selected_lease = NULL;
2777
2778 while (client->advertised_leases != NULL) {
2779 lease = client->advertised_leases;
2780 client->advertised_leases = lease->next;
2781
2782 dhc6_lease_destroy(&lease, MDL);
2783 }
2784 }
2785
2786 start_init6(client);
2787 break;
2788 }
2789
2790 return ISC_TRUE;
2791 }
2792
2793 static void
2794 dhc6_withdraw_lease(struct client_state *client)
2795 {
2796 struct dhc6_ia *ia;
2797 struct dhc6_addr *addr;
2798
2799 if ((client == NULL) || (client->active_lease == NULL))
2800 return;
2801
2802 for (ia = client->active_lease->bindings ; ia != NULL ;
2803 ia = ia->next) {
2804 for (addr = ia->addrs ; addr != NULL ; addr = addr->next) {
2805 addr->max_life = addr->preferred_life = 0;
2806 }
2807 }
2808
2809 /* Perform expiry. */
2810 do_expire(client);
2811 }
2812
2813 /* status code <-> action matrix for the client in BOUND state
2814 * (request/reply). Returns true if action was taken (and the
2815 * packet should be ignored), or false if no action was taken.
2816 */
2817 static isc_boolean_t
2818 dhc6_reply_action(struct client_state *client, isc_result_t *rvalp,
2819 unsigned code)
2820 {
2821 isc_result_t rval;
2822
2823 if (rvalp == NULL)
2824 log_fatal("Impossible condition at %s:%d.", MDL);
2825
2826 if (client == NULL) {
2827 *rvalp = DHCP_R_INVALIDARG;
2828 return ISC_FALSE;
2829 }
2830 rval = *rvalp;
2831
2832 if (rval == ISC_R_SUCCESS)
2833 return ISC_FALSE;
2834
2835 switch (code) {
2836 /* It's possible an earlier status code set rval to a failure
2837 * code, and we've encountered a later success.
2838 */
2839 case STATUS_Success:
2840 /* In "refreshes" (where we get replies), we probably
2841 * still have a valid lease. So "take no action" and
2842 * the upper levels will keep retrying until the lease
2843 * expires (or we rebind).
2844 */
2845 case STATUS_UnspecFail:
2846 /* For unknown codes...it's a soft (retryable) error. */
2847 default:
2848 return ISC_FALSE;
2849
2850 /* The server is telling us to use a multicast address, so
2851 * we have to delete the unicast option from the active
2852 * lease, then allow retransmission to occur normally.
2853 * (XXX: It might be preferable in this case to retransmit
2854 * sooner than the current interval, but for now we don't.)
2855 */
2856 case STATUS_UseMulticast:
2857 if (client->active_lease != NULL)
2858 delete_option(&dhcp_universe,
2859 client->active_lease->options,
2860 D6O_UNICAST);
2861 return ISC_FALSE;
2862
2863 /* "When the client receives a NotOnLink status from the
2864 * server in response to a Request, the client can either
2865 * re-issue the Request without specifying any addresses
2866 * or restart the DHCP server discovery process."
2867 *
2868 * This is strange. If competing server evaluation is
2869 * useful (and therefore in the protocol), then why would
2870 * a client's first reaction be to request from the same
2871 * server on a different link? Surely you'd want to
2872 * re-evaluate your server selection.
2873 *
2874 * Well, I guess that's the answer.
2875 */
2876 case STATUS_NotOnLink:
2877 /* In this case, we need to rescind all current active
2878 * bindings (just 'expire' them all normally, if early).
2879 * They're no use to us on the wrong link. Then head back
2880 * to init, redo server selection and get new addresses.
2881 */
2882 dhc6_withdraw_lease(client);
2883 break;
2884
2885 /* "If the status code is NoAddrsAvail, the client has
2886 * received no usable addresses in the IA and may choose
2887 * to try obtaining addresses for the IA from another
2888 * server."
2889 */
2890 case STATUS_NoAddrsAvail:
2891 case STATUS_NoPrefixAvail:
2892 /* Head back to init, keeping any active bindings (!). */
2893 start_init6(client);
2894 break;
2895
2896 /* - sends a Request message if the IA contained a Status
2897 * Code option with the NoBinding status (and does not
2898 * send any additional Renew/Rebind messages)
2899 */
2900 case STATUS_NoBinding:
2901 if (client->advertised_leases != NULL)
2902 log_fatal("Impossible condition at %s:%d.", MDL);
2903
2904 client->advertised_leases =
2905 dhc6_dup_lease(client->active_lease, MDL);
2906 start_selecting6(client);
2907 break;
2908 }
2909
2910 return ISC_TRUE;
2911 }
2912
2913 /* status code <-> action matrix for the client in STOPPED state
2914 * (release/decline). Returns true if action was taken (and the
2915 * packet should be ignored), or false if no action was taken.
2916 * NoBinding is translated into Success.
2917 */
2918 static isc_boolean_t
2919 dhc6_stop_action(struct client_state *client, isc_result_t *rvalp,
2920 unsigned code)
2921 {
2922 isc_result_t rval;
2923
2924 if (rvalp == NULL)
2925 log_fatal("Impossible condition at %s:%d.", MDL);
2926
2927 if (client == NULL) {
2928 *rvalp = DHCP_R_INVALIDARG;
2929 return ISC_FALSE;
2930 }
2931 rval = *rvalp;
2932
2933 if (rval == ISC_R_SUCCESS)
2934 return ISC_FALSE;
2935
2936 switch (code) {
2937 /* It's possible an earlier status code set rval to a failure
2938 * code, and we've encountered a later success.
2939 */
2940 case STATUS_Success:
2941 /* For unknown codes...it's a soft (retryable) error. */
2942 case STATUS_UnspecFail:
2943 default:
2944 return ISC_FALSE;
2945
2946 /* NoBinding is not an error */
2947 case STATUS_NoBinding:
2948 if (rval == ISC_R_FAILURE)
2949 *rvalp = ISC_R_SUCCESS;
2950 return ISC_FALSE;
2951
2952 /* Should not happen */
2953 case STATUS_NoAddrsAvail:
2954 case STATUS_NoPrefixAvail:
2955 break;
2956
2957 /* Give up on it */
2958 case STATUS_NotOnLink:
2959 break;
2960
2961 /* The server is telling us to use a multicast address, so
2962 * we have to delete the unicast option from the active
2963 * lease, then allow retransmission to occur normally.
2964 * (XXX: It might be preferable in this case to retransmit
2965 * sooner than the current interval, but for now we don't.)
2966 */
2967 case STATUS_UseMulticast:
2968 if (client->active_lease != NULL)
2969 delete_option(&dhcp_universe,
2970 client->active_lease->options,
2971 D6O_UNICAST);
2972 return ISC_FALSE;
2973 }
2974
2975 return ISC_TRUE;
2976 }
2977
2978 static isc_boolean_t
2979 dhc6_decline_action(struct client_state *client, isc_result_t *rvalp,
2980 unsigned code)
2981 {
2982 isc_result_t rval;
2983
2984 if (rvalp == NULL)
2985 log_fatal("Impossible condition at %s:%d.", MDL);
2986
2987 if (client == NULL) {
2988 *rvalp = DHCP_R_INVALIDARG;
2989 return ISC_FALSE;
2990 }
2991 rval = *rvalp;
2992
2993 if (rval == ISC_R_SUCCESS) {
2994 return ISC_FALSE;
2995 }
2996
2997 switch (code) {
2998 case STATUS_UseMulticast:
2999 /* The server is telling us to use a multicast address, so
3000 * we have to delete the unicast option from the active
3001 * lease, then allow retransmission to occur normally.
3002 * (XXX: It might be preferable in this case to retransmit
3003 * sooner than the current interval, but for now we don't.)
3004 */
3005 if (client->active_lease != NULL)
3006 delete_option(&dhcp_universe,
3007 client->active_lease->options,
3008 D6O_UNICAST);
3009 return ISC_FALSE;
3010 default:
3011 /* Anything else is basically meaningless */
3012 break;
3013 }
3014
3015 return ISC_TRUE;
3016 }
3017
3018
3019 /* Look at a new and old lease, and make sure the new information is not
3020 * losing us any state.
3021 */
3022 static isc_result_t
3023 dhc6_check_reply(struct client_state *client, struct dhc6_lease *new)
3024 {
3025 isc_boolean_t (*action)(struct client_state *,
3026 isc_result_t *, unsigned);
3027 struct dhc6_ia *ia;
3028 isc_result_t rval = ISC_R_SUCCESS;
3029 unsigned code;
3030 const char *scope;
3031 int nscore, sscore;
3032 int have_addrs = ISC_FALSE;
3033 int got_na = 0, got_ta = 0, got_pd = 0;
3034
3035 if ((client == NULL) || (new == NULL))
3036 return DHCP_R_INVALIDARG;
3037
3038 switch (client->state) {
3039 case S_INIT:
3040 action = dhc6_init_action;
3041 break;
3042
3043 case S_SELECTING:
3044 case S_REBOOTING:
3045 action = dhc6_select_action;
3046 break;
3047
3048 case S_RENEWING:
3049 case S_REBINDING:
3050 action = dhc6_reply_action;
3051 break;
3052
3053 case S_STOPPED:
3054 action = dhc6_stop_action;
3055 break;
3056
3057 case S_DECLINING:
3058 action = dhc6_decline_action;
3059 break;
3060
3061 default:
3062 log_fatal("Impossible condition at %s:%d.", MDL);
3063 return ISC_R_CANCELED;
3064 }
3065
3066 /* If there is a code to extract, and if there is some
3067 * action to take based on that code, then take the action
3068 * and do not continue.
3069 */
3070 rval = dhc6_check_status(rval, new->options, "message", &code);
3071 if (action(client, &rval, code))
3072 return ISC_R_CANCELED;
3073
3074 for (ia = new->bindings ; ia != NULL ; ia = ia->next) {
3075 switch (ia->ia_type) {
3076 case D6O_IA_NA:
3077 scope = "IA_NA";
3078 got_na++;
3079 break;
3080 case D6O_IA_TA:
3081 scope = "IA_TA";
3082 got_ta++;
3083 break;
3084 case D6O_IA_PD:
3085 scope = "IA_PD";
3086 got_pd++;
3087 break;
3088 default:
3089 log_error("dhc6_check_reply: no type.");
3090 return DHCP_R_INVALIDARG;
3091 }
3092 rval = dhc6_check_status(rval, ia->options, scope, &code);
3093
3094 if (action(client, &rval, code))
3095 return ISC_R_CANCELED;
3096
3097 if (ia->addrs != NULL) {
3098 have_addrs = ISC_TRUE;
3099 }
3100 }
3101
3102 /* A Confirm->Reply is unsuitable for comparison to the old lease. */
3103 if (client->state == S_REBOOTING)
3104 return rval;
3105
3106 /* We expect the lease to have at least one address and if
3107 * required all of the requested IAs if not flag it as
3108 * NoAddrs and call the action routine to try again.
3109 *
3110 * Currently we don't completely handle TAs in all cases
3111 * so we don't check them for requires. I've left the
3112 * check in and commented it as I eventually do want
3113 * us to check for TAs as well. SAR
3114 */
3115 if ((have_addrs != ISC_TRUE) ||
3116 ((require_all_ias != 0) &&
3117 ((got_na < wanted_ia_na) ||
3118 /*(got_ta < wanted_ia_ta) ||*/
3119 (got_pd < wanted_ia_pd)))) {
3120 rval = ISC_R_FAILURE;
3121 if (action(client, &rval, STATUS_NoAddrsAvail) == ISC_TRUE) {
3122 return ISC_R_CANCELED;
3123 }
3124 }
3125
3126 /* No old lease in rapid-commit. */
3127 if (client->state == S_INIT)
3128 return rval;
3129
3130 switch (client->state) {
3131 case S_SELECTING:
3132 /* Compare the new lease with the selected lease to make
3133 * sure there is no risky business.
3134 */
3135 nscore = dhc6_score_lease(client, new);
3136 sscore = dhc6_score_lease(client, client->selected_lease);
3137 if ((client->advertised_leases != NULL) &&
3138 (nscore < (sscore / 2))) {
3139 /* XXX: An attacker might reply this way to make
3140 * XXX: sure we latch onto their configuration.
3141 * XXX: We might want to ignore the packet and
3142 * XXX: schedule re-selection at the next timeout?
3143 */
3144 log_error("PRC: BAIT AND SWITCH detected. Score of "
3145 "supplied lease (%d) is substantially "
3146 "smaller than the advertised score (%d). "
3147 "Trying other servers.",
3148 nscore, sscore);
3149
3150 dhc6_lease_destroy(&client->selected_lease, MDL);
3151 client->selected_lease = NULL;
3152
3153 start_selecting6(client);
3154
3155 return ISC_R_CANCELED;
3156 }
3157 break;
3158
3159 case S_RENEWING:
3160 case S_REBINDING:
3161 /* This leaves one RFC3315 status check unimplemented:
3162 *
3163 * - sends a Renew/Rebind if the IA is not in the Reply
3164 * message
3165 *
3166 * We rely on the scheduling system to note that the IA has
3167 * not left Renewal/Rebinding/whatever since it still carries
3168 * old times from the last successful binding. So this is
3169 * implemented actually, just not explicitly.
3170 */
3171 break;
3172
3173 case S_STOPPED:
3174 case S_DECLINING:
3175 /* Nothing critical to do at this stage. */
3176 break;
3177
3178 default:
3179 log_fatal("REALLY impossible condition at %s:%d.", MDL);
3180 return ISC_R_CANCELED;
3181 }
3182
3183 return rval;
3184 }
3185
3186 /* While in init state, we only collect advertisements. If there happens
3187 * to be an advertisement with a preference option of 255, that's an
3188 * automatic exit. Otherwise, we collect advertisements until our timeout
3189 * expires (client->RT).
3190 */
3191 void
3192 init_handler(struct packet *packet, struct client_state *client)
3193 {
3194 struct dhc6_lease *lease;
3195
3196 /* In INIT state, we send solicits, we only expect to get
3197 * advertises (rapid commit has its own handler).
3198 */
3199 if (packet->dhcpv6_msg_type != DHCPV6_ADVERTISE)
3200 return;
3201
3202 /* RFC3315 section 15.3 validation (same as 15.10 since we
3203 * always include a client id).
3204 */
3205 if (!valid_reply(packet, client)) {
3206 log_error("Invalid Advertise - rejecting.");
3207 return;
3208 }
3209
3210 lease = dhc6_leaseify(packet, client);
3211
3212 /* Out of memory or corrupt packet condition...hopefully a temporary
3213 * problem. Returning now makes us try to retransmit later.
3214 */
3215 if (lease == NULL)
3216 return;
3217
3218 if (dhc6_check_advertise(lease) != ISC_R_SUCCESS) {
3219 log_debug("PRC: Lease failed to satisfy.");
3220 dhc6_lease_destroy(&lease, MDL);
3221 return;
3222 }
3223
3224 int lease_score = dhc6_score_lease(client, lease);
3225 #ifdef ENFORCE_DHCPV6_CLIENT_REQUIRE
3226 if (lease_score == 0) {
3227 log_debug("RCV:Advertised lease scored 0, toss it.");
3228 dhc6_lease_destroy(&lease, MDL);
3229 return;
3230 }
3231 #endif
3232
3233 insert_lease(&client->advertised_leases, lease);
3234
3235 /* According to RFC3315 section 17.1.2, the client MUST wait for
3236 * the first RT before selecting a lease. But on the 400th RT,
3237 * we dont' want to wait the full timeout if we finally get an
3238 * advertise. We could probably wait a second, but ohwell,
3239 * RFC3315 doesn't say so.
3240 *
3241 * If the lease is highest possible preference, 255, RFC3315 claims
3242 * we should continue immediately even on the first RT. We probably
3243 * should not if the advertise contains less than one IA and address.
3244 */
3245 if ((client->txcount > 1) ||
3246 ((lease->pref == 255) && (lease_score > SCORE_MIN))) {
3247 log_debug("RCV: Advertisement immediately selected.");
3248 cancel_timeout(do_init6, client);
3249 start_selecting6(client);
3250 } else
3251 log_debug("RCV: Advertisement recorded.");
3252 }
3253
3254 /* info_request_handler() accepts a Reply to an Info-request.
3255 */
3256 void
3257 info_request_handler(struct packet *packet, struct client_state *client)
3258 {
3259 isc_result_t check_status;
3260 unsigned code;
3261
3262 if (packet->dhcpv6_msg_type != DHCPV6_REPLY)
3263 return;
3264
3265 /* RFC3315 section 15.10 validation (same as 15.3 since we
3266 * always include a client id).
3267 */
3268 if (!valid_reply(packet, client)) {
3269 log_error("Invalid Reply - rejecting.");
3270 return;
3271 }
3272
3273 check_status = dhc6_check_status(ISC_R_SUCCESS, packet->options,
3274 "message", &code);
3275
3276 if (check_status != ISC_R_SUCCESS) {
3277 /* If no action was taken, but there is an error, then
3278 * we wait for a retransmission.
3279 */
3280 if (check_status != ISC_R_CANCELED)
3281 return;
3282 }
3283
3284 /* We're done retransmitting at this point. */
3285 cancel_timeout(do_info_request6, client);
3286
3287 /* Action was taken, so now that we've torn down our scheduled
3288 * retransmissions, return.
3289 */
3290 if (check_status == ISC_R_CANCELED)
3291 return;
3292
3293 /* Cleanup if a previous attempt to go bound failed. */
3294 if (client->old_lease != NULL) {
3295 dhc6_lease_destroy(&client->old_lease, MDL);
3296 client->old_lease = NULL;
3297 }
3298
3299 /* Cache options in the active_lease. */
3300 if (client->active_lease != NULL)
3301 client->old_lease = client->active_lease;
3302 client->active_lease = dmalloc(sizeof(struct dhc6_lease), MDL);
3303 if (client->active_lease == NULL)
3304 log_fatal("Out of memory for v6 lease structure.");
3305 option_state_reference(&client->active_lease->options,
3306 packet->options, MDL);
3307
3308 execute_statements_in_scope(NULL, (struct packet *)packet, NULL, client,
3309 client->active_lease->options,
3310 client->active_lease->options,
3311 &global_scope, client->config->on_receipt,
3312 NULL, NULL);
3313
3314 start_informed(client);
3315 }
3316
3317 /* Specific version of init_handler() for rapid-commit.
3318 */
3319 void
3320 rapid_commit_handler(struct packet *packet, struct client_state *client)
3321 {
3322 struct dhc6_lease *lease;
3323 isc_result_t check_status;
3324
3325 /* On ADVERTISE just fall back to the init_handler().
3326 */
3327 if (packet->dhcpv6_msg_type == DHCPV6_ADVERTISE) {
3328 init_handler(packet, client);
3329 return;
3330 } else if (packet->dhcpv6_msg_type != DHCPV6_REPLY)
3331 return;
3332
3333 /* RFC3315 section 15.10 validation (same as 15.3 since we
3334 * always include a client id).
3335 */
3336 if (!valid_reply(packet, client)) {
3337 log_error("Invalid Reply - rejecting.");
3338 return;
3339 }
3340
3341 /* A rapid-commit option MUST be here. */
3342 if (lookup_option(&dhcpv6_universe, packet->options,
3343 D6O_RAPID_COMMIT) == 0) {
3344 log_error("Reply without Rapid-Commit - rejecting.");
3345 return;
3346 }
3347
3348 lease = dhc6_leaseify(packet, client);
3349
3350 /* Out of memory or corrupt packet condition...hopefully a temporary
3351 * problem. Returning now makes us try to retransmit later.
3352 */
3353 if (lease == NULL)
3354 return;
3355
3356 check_status = dhc6_check_reply(client, lease);
3357 if (check_status != ISC_R_SUCCESS) {
3358 dhc6_lease_destroy(&lease, MDL);
3359 return;
3360 }
3361
3362 /* Jump to the selecting state. */
3363 cancel_timeout(do_init6, client);
3364 client->state = S_SELECTING;
3365
3366 /* Merge any bindings in the active lease (if there is one) into
3367 * the new active lease.
3368 */
3369 dhc6_merge_lease(client->active_lease, lease);
3370
3371 /* Cleanup if a previous attempt to go bound failed. */
3372 if (client->old_lease != NULL) {
3373 dhc6_lease_destroy(&client->old_lease, MDL);
3374 client->old_lease = NULL;
3375 }
3376
3377 /* Make this lease active and BIND to it. */
3378 if (client->active_lease != NULL)
3379 client->old_lease = client->active_lease;
3380 client->active_lease = lease;
3381
3382 /* We're done with the ADVERTISEd leases, if any. */
3383 while(client->advertised_leases != NULL) {
3384 lease = client->advertised_leases;
3385 client->advertised_leases = lease->next;
3386
3387 dhc6_lease_destroy(&lease, MDL);
3388 }
3389
3390 start_bound(client);
3391 }
3392
3393 /* Find the 'best' lease in the cache of advertised leases (usually). From
3394 * RFC3315 Section 17.1.3:
3395 *
3396 * Upon receipt of one or more valid Advertise messages, the client
3397 * selects one or more Advertise messages based upon the following
3398 * criteria.
3399 *
3400 * - Those Advertise messages with the highest server preference value
3401 * are preferred over all other Advertise messages.
3402 *
3403 * - Within a group of Advertise messages with the same server
3404 * preference value, a client MAY select those servers whose
3405 * Advertise messages advertise information of interest to the
3406 * client. For example, the client may choose a server that returned
3407 * an advertisement with configuration options of interest to the
3408 * client.
3409 *
3410 * - The client MAY choose a less-preferred server if that server has a
3411 * better set of advertised parameters, such as the available
3412 * addresses advertised in IAs.
3413 *
3414 * Note that the first and third contradict each other. The third should
3415 * probably be taken to mean that the client should prefer answers that
3416 * offer bindings, even if that violates the preference rule.
3417 *
3418 * The above also isn't deterministic where there are ties. So the final
3419 * tiebreaker we add, if all other values are equal, is to compare the
3420 * server identifiers and to select the numerically lower one.
3421 */
3422 static struct dhc6_lease *
3423 dhc6_best_lease(struct client_state *client, struct dhc6_lease **head)
3424 {
3425 struct dhc6_lease **rpos, *rval, **candp, *cand;
3426 int cscore, rscore;
3427
3428 if (head == NULL || *head == NULL)
3429 return NULL;
3430
3431 rpos = head;
3432 rval = *rpos;
3433 rscore = dhc6_score_lease(client, rval);
3434 candp = &rval->next;
3435 cand = *candp;
3436
3437 log_debug("PRC: Considering best lease.");
3438 log_debug("PRC: X-- Initial candidate %s (s: %d, p: %u).",
3439 print_hex_1(rval->server_id.len,
3440 rval->server_id.data, 48),
3441 rscore, (unsigned)rval->pref);
3442
3443 for (; cand != NULL ; candp = &cand->next, cand = *candp) {
3444 cscore = dhc6_score_lease(client, cand);
3445
3446 log_debug("PRC: X-- Candidate %s (s: %d, p: %u).",
3447 print_hex_1(cand->server_id.len,
3448 cand->server_id.data, 48),
3449 cscore, (unsigned)cand->pref);
3450
3451 /* Above you'll find quoted RFC3315 Section 17.1.3.
3452 *
3453 * The third clause tells us to give up on leases that
3454 * have no bindings even if their preference is better.
3455 * So where our 'selected' lease's score is less than
3456 * SCORE_MIN (1 ia + 1 addr), choose any candidate >= SCORE_MIN.
3457 *
3458 * The first clause tells us to make preference the primary
3459 * deciding factor. So if it's lower, reject, if it's
3460 * higher, select.
3461 *
3462 * The second clause tells us where the preference is
3463 * equal, we should use 'our judgement' of what we like
3464 * to see in an advertisement primarily.
3465 *
3466 * But there can still be a tie. To make this deterministic,
3467 * we compare the server identifiers and select the binary
3468 * lowest.
3469 *
3470 * Since server id's are unique in this list, there is
3471 * no further tie to break.
3472 */
3473 if ((rscore < SCORE_MIN) && (cscore >= SCORE_MIN)) {
3474 log_debug("PRC: | X-- Selected, has bindings.");
3475 } else if (cand->pref < rval->pref) {
3476 log_debug("PRC: | X-- Rejected, lower preference.");
3477 continue;
3478 } else if (cand->pref > rval->pref) {
3479 log_debug("PRC: | X-- Selected, higher preference.");
3480 } else if (cscore > rscore) {
3481 log_debug("PRC: | X-- Selected, equal preference, "
3482 "higher score.");
3483 } else if (cscore < rscore) {
3484 log_debug("PRC: | X-- Rejected, equal preference, "
3485 "lower score.");
3486 continue;
3487 } else if ((cand->server_id.len < rval->server_id.len) ||
3488 ((cand->server_id.len == rval->server_id.len) &&
3489 (memcmp(cand->server_id.data,
3490 rval->server_id.data,
3491 cand->server_id.len) < 0))) {
3492 log_debug("PRC: | X-- Selected, equal preference, "
3493 "equal score, binary lesser server ID.");
3494 } else {
3495 log_debug("PRC: | X-- Rejected, equal preference, "
3496 "equal score, binary greater server ID.");
3497 continue;
3498 }
3499
3500 rpos = candp;
3501 rval = cand;
3502 rscore = cscore;
3503 }
3504
3505 /* Remove the selected lease from the chain. */
3506 *rpos = rval->next;
3507
3508 return rval;
3509 }
3510
3511 /* Select a lease out of the advertised leases and setup state to try and
3512 * acquire that lease.
3513 */
3514 void
3515 start_selecting6(struct client_state *client)
3516 {
3517 struct dhc6_lease *lease;
3518
3519 if (client->advertised_leases == NULL) {
3520 log_error("Can not enter DHCPv6 SELECTING state with no "
3521 "leases to select from!");
3522 return;
3523 }
3524
3525 log_debug("PRC: Selecting best advertised lease.");
3526 client->state = S_SELECTING;
3527
3528 lease = dhc6_best_lease(client, &client->advertised_leases);
3529
3530 if (lease == NULL)
3531 log_fatal("Impossible error at %s:%d.", MDL);
3532
3533 client->selected_lease = lease;
3534
3535 /* Set timers per RFC3315 section 18.1.1. */
3536 client->IRT = REQ_TIMEOUT * 100;
3537 client->MRT = REQ_MAX_RT * 100;
3538 client->MRC = REQ_MAX_RC;
3539 client->MRD = 0;
3540
3541 dhc6_retrans_init(client);
3542
3543 client->v6_handler = reply_handler;
3544
3545 /* ("re")transmit the first packet. */
3546 do_select6(client);
3547 }
3548
3549 /* Transmit a Request to select a lease offered in Advertisements. In
3550 * the event of failure, either move on to the next-best advertised lease,
3551 * or head back to INIT state if there are none.
3552 */
3553 void
3554 do_select6(void *input)
3555 {
3556 struct client_state *client;
3557 struct dhc6_lease *lease;
3558 struct data_string ds;
3559 struct timeval tv;
3560 int send_ret, added;
3561
3562 client = input;
3563
3564 /* 'lease' is fewer characters to type. */
3565 lease = client->selected_lease;
3566 if (lease == NULL || lease->bindings == NULL) {
3567 log_error("Illegal to attempt selection without selecting "
3568 "a lease.");
3569 return;
3570 }
3571
3572 switch(check_timing6(client, DHCPV6_REQUEST, "Request", lease, &ds)) {
3573 case CHK_TIM_MRC_EXCEEDED:
3574 case CHK_TIM_MRD_EXCEEDED:
3575 log_debug("PRC: Lease %s failed.",
3576 print_hex_1(lease->server_id.len,
3577 lease->server_id.data, 56));
3578
3579 /* Get rid of the lease that timed/counted out. */
3580 dhc6_lease_destroy(&lease, MDL);
3581 client->selected_lease = NULL;
3582
3583 /* If there are more leases great. If not, get more. */
3584 if (client->advertised_leases != NULL)
3585 start_selecting6(client);
3586 else
3587 start_init6(client);
3588 return;
3589 case CHK_TIM_ALLOC_FAILURE:
3590 return;
3591 case CHK_TIM_SUCCESS:
3592 break;
3593 }
3594
3595 /* Now make a packet that looks suspiciously like the one we
3596 * got from the server. But different.
3597 *
3598 * XXX: I guess IAID is supposed to be something the client
3599 * indicates and uses as a key to its internal state. It is
3600 * kind of odd to ask the server for IA's whose IAID the client
3601 * did not manufacture. We first need a formal dhclient.conf
3602 * construct for the iaid, then we can delve into this matter
3603 * more properly. In the time being, this will work.
3604 */
3605
3606 /* Fetch any configured 'sent' options (includes DUID) in wire format.
3607 */
3608 dhcpv6_universe.encapsulate(&ds, NULL, NULL, client,
3609 NULL, client->sent_options, &global_scope,
3610 &dhcpv6_universe);
3611
3612 /* Now append any IA's, and within them any IAADDR/IAPREFIXs.
3613 * For each type of IA (na, ta, pd) we start with the ones for
3614 * which we already have addresses (dhc6_add_ia_xx) and then
3615 * if we still want more we add aditional IAs (dhc6_bare_ia_xx)
3616 */
3617 if (wanted_ia_na &&
3618 ((dhc6_add_ia_na(client, &ds, lease, DHCPV6_REQUEST,
3619 wanted_ia_na, &added) != ISC_R_SUCCESS) ||
3620 (dhc6_bare_ia_xx(client, &ds, wanted_ia_na - added,
3621 D6O_IA_NA) != ISC_R_SUCCESS))) {
3622 data_string_forget(&ds, MDL);
3623 return;
3624 }
3625 if (wanted_ia_ta &&
3626 ((dhc6_add_ia_ta(client, &ds, lease, DHCPV6_REQUEST,
3627 wanted_ia_ta, &added) != ISC_R_SUCCESS) ||
3628 (dhc6_bare_ia_xx(client, &ds, wanted_ia_ta - added,
3629 D6O_IA_TA) != ISC_R_SUCCESS))) {
3630 data_string_forget(&ds, MDL);
3631 return;
3632 }
3633 if (wanted_ia_pd &&
3634 ((dhc6_add_ia_pd(client, &ds, lease, DHCPV6_REQUEST,
3635 wanted_ia_pd, &added) != ISC_R_SUCCESS) ||
3636 (dhc6_bare_ia_xx(client, &ds, wanted_ia_pd - added,
3637 D6O_IA_PD) != ISC_R_SUCCESS))) {
3638 data_string_forget(&ds, MDL);
3639 return;
3640 }
3641
3642 log_info("XMT: Request on %s, interval %ld0ms.",
3643 client->name ? client->name : client->interface->name,
3644 (long int)client->RT);
3645
3646 send_ret = send_packet6(client->interface,
3647 ds.data, ds.len, &DHCPv6DestAddr);
3648 if (send_ret != ds.len) {
3649 log_error("dhc6: send_packet6() sent %d of %d bytes",
3650 send_ret, ds.len);
3651 }
3652
3653 data_string_forget(&ds, MDL);
3654
3655 /* Wait RT */
3656 tv.tv_sec = cur_tv.tv_sec + client->RT / 100;
3657 tv.tv_usec = cur_tv.tv_usec + (client->RT % 100) * 10000;
3658 if (tv.tv_usec >= 1000000) {
3659 tv.tv_sec += 1;
3660 tv.tv_usec -= 1000000;
3661 }
3662 add_timeout(&tv, do_select6, client, NULL, NULL);
3663
3664 dhc6_retrans_advance(client);
3665 }
3666
3667 /*!
3668 *
3669 * \brief Count the number of IAs in the bindings
3670 *
3671 * \param lease the lease to count
3672 * \param ia_type the type of the IA we wish to count
3673 *
3674 * \return The number of IAs of the specified type we found
3675 */
3676 static int
3677 dhc6_count_ia(struct dhc6_lease *lease, u_int16_t ia_type)
3678 {
3679 struct dhc6_ia *ia;
3680 int i = 0;
3681
3682 for (ia = lease->bindings; ia != NULL; ia = ia->next) {
3683 if (ia->ia_type == ia_type)
3684 /* bump the counter for the correct types */
3685 i++;
3686 }
3687
3688 return (i);
3689 }
3690
3691 /*!
3692 *
3693 * \brief Add IA_NA information from the lease to the packet
3694 * we are building.
3695 *
3696 * Walk through the lease and for each IA_NA in the lease
3697 * and for each address in the IA_NA append that information
3698 * onto the packet-so-far. If wanted is 0 include all IA_NAs
3699 * in the lease if wanted is non-zero include only that many
3700 * IA_NAs (this may occur if sommebody restarts a client with
3701 * arugments for a smaller number of NAs than before).
3702 *
3703 * \param client = the state of the entire client
3704 * \param packet = the packet we are building and where we
3705 * shall append the IA_NAs we create
3706 * \param lease = the current lease
3707 * \param message = the type of the packet
3708 * \param wanted = the number of IA_NAs to include in the packet
3709 * 0 means include all
3710 * \param added = the number of IA_NAs that were added to the packet
3711 *
3712 * \return ISC_R_SUCCESS - all is well continue, any other return
3713 * indicates an error (most likely memory issues)
3714 * and the packet should be tossed.
3715 */
3716 static isc_result_t
3717 dhc6_add_ia_na(struct client_state *client, struct data_string *packet,
3718 struct dhc6_lease *lease, u_int8_t message,
3719 int wanted, int *added)
3720 {
3721 struct data_string iads;
3722 struct data_string addrds;
3723 struct dhc6_addr *addr;
3724 struct dhc6_ia *ia;
3725 isc_result_t rval = ISC_R_SUCCESS;
3726 TIME t1, t2;
3727 int i;
3728
3729 *added = 0;
3730 memset(&iads, 0, sizeof(iads));
3731 memset(&addrds, 0, sizeof(addrds));
3732 for (ia = lease->bindings, i = 0;
3733 ia != NULL && rval == ISC_R_SUCCESS && (wanted == 0 || i < wanted);
3734 ia = ia->next) {
3735 if (ia->ia_type != D6O_IA_NA)
3736 continue;
3737
3738 /* Now that we know this is an NA bump the counter */
3739 i++;
3740
3741 if (!buffer_allocate(&iads.buffer, 12, MDL)) {
3742 log_error("Unable to allocate memory for IA_NA.");
3743 rval = ISC_R_NOMEMORY;
3744 break;
3745 }
3746
3747 /* Copy the IAID into the packet buffer. */
3748 memcpy(iads.buffer->data, ia->iaid, 4);
3749 iads.data = iads.buffer->data;
3750 iads.len = 12;
3751
3752 switch (message) {
3753 case DHCPV6_REQUEST:
3754 case DHCPV6_RENEW:
3755 case DHCPV6_REBIND:
3756
3757 t1 = client->config->requested_lease / 2;
3758 t2 = t1 + (t1 / 2);
3759 #if MAX_TIME > 0xffffffff
3760 if (t1 > 0xffffffff)
3761 t1 = 0xffffffff;
3762 if (t2 > 0xffffffff)
3763 t2 = 0xffffffff;
3764 #endif
3765 putULong(iads.buffer->data + 4, t1);
3766 putULong(iads.buffer->data + 8, t2);
3767
3768 log_debug("XMT: X-- IA_NA %s",
3769 print_hex_1(4, iads.data, 59));
3770 log_debug("XMT: | X-- Requested renew +%u",
3771 (unsigned) t1);
3772 log_debug("XMT: | X-- Requested rebind +%u",
3773 (unsigned) t2);
3774 break;
3775
3776 case DHCPV6_CONFIRM:
3777 case DHCPV6_RELEASE:
3778 case DHCPV6_DECLINE:
3779 /* Set t1 and t2 to zero; server will ignore them */
3780 memset(iads.buffer->data + 4, 0, 8);
3781 log_debug("XMT: X-- IA_NA %s",
3782 print_hex_1(4, iads.buffer->data, 55));
3783
3784 break;
3785
3786 default:
3787 log_fatal("Impossible condition at %s:%d.", MDL);
3788 }
3789
3790 for (addr = ia->addrs ; addr != NULL ; addr = addr->next) {
3791 /*
3792 * Do not confirm expired addresses, do not request
3793 * expired addresses (but we keep them around for
3794 * solicit).
3795 */
3796 if (addr->flags & DHC6_ADDR_EXPIRED)
3797 continue;
3798
3799 if (addr->address.len != 16) {
3800 log_error("Illegal IPv6 address length (%d), "
3801 "ignoring. (%s:%d)",
3802 addr->address.len, MDL);
3803 continue;
3804 }
3805
3806 if (!buffer_allocate(&addrds.buffer, 24, MDL)) {
3807 log_error("Unable to allocate memory for "
3808 "IAADDR.");
3809 rval = ISC_R_NOMEMORY;
3810 break;
3811 }
3812
3813 addrds.data = addrds.buffer->data;
3814 addrds.len = 24;
3815
3816 /* Copy the address into the packet buffer. */
3817 memcpy(addrds.buffer->data, addr->address.iabuf, 16);
3818
3819 /* Copy in additional information as appropriate */
3820 switch (message) {
3821 case DHCPV6_REQUEST:
3822 case DHCPV6_RENEW:
3823 case DHCPV6_REBIND:
3824 t1 = client->config->requested_lease;
3825 t2 = t1 + 300;
3826 putULong(addrds.buffer->data + 16, t1);
3827 putULong(addrds.buffer->data + 20, t2);
3828
3829 log_debug("XMT: | | X-- IAADDR %s",
3830 piaddr(addr->address));
3831 log_debug("XMT: | | | X-- Preferred "
3832 "lifetime +%u", (unsigned)t1);
3833 log_debug("XMT: | | | X-- Max lifetime +%u",
3834 (unsigned)t2);
3835
3836 break;
3837
3838 case DHCPV6_CONFIRM:
3839 /*
3840 * Set preferred and max life to zero,
3841 * per 17.1.3.
3842 */
3843 memset(addrds.buffer->data + 16, 0, 8);
3844 log_debug("XMT: | X-- Confirm Address %s",
3845 piaddr(addr->address));
3846 break;
3847
3848 case DHCPV6_RELEASE:
3849 /* Preferred and max life are irrelevant */
3850 memset(addrds.buffer->data + 16, 0, 8);
3851 log_debug("XMT: | X-- Release Address %s",
3852 piaddr(addr->address));
3853 break;
3854
3855 case DHCPV6_DECLINE:
3856 /* Preferred and max life are irrelevant */
3857 memset(addrds.buffer->data + 16, 0, 8);
3858 log_debug("XMT: | X-- Decline Address %s",
3859 piaddr(addr->address));
3860 break;
3861
3862 default:
3863 log_fatal("Impossible condition at %s:%d.",
3864 MDL);
3865 }
3866
3867 append_option(&iads, &dhcpv6_universe, iaaddr_option,
3868 &addrds);
3869 data_string_forget(&addrds, MDL);
3870 }
3871
3872 /*
3873 * It doesn't make sense to make a request without an
3874 * address.
3875 */
3876 if (ia->addrs == NULL) {
3877 log_debug("!!!: V IA_NA has no IAADDRs - removed.");
3878 rval = ISC_R_FAILURE;
3879 } else if (rval == ISC_R_SUCCESS) {
3880 log_debug("XMT: V IA_NA appended.");
3881 append_option(packet, &dhcpv6_universe, ia_na_option,
3882 &iads);
3883 }
3884
3885 data_string_forget(&iads, MDL);
3886 }
3887
3888 if (rval == ISC_R_SUCCESS)
3889 *added = i;
3890
3891 return (rval);
3892 }
3893
3894 /*!
3895 *
3896 * \brief Add IA_TA information from the lease to the packet
3897 * we are building.
3898 *
3899 * Walk through the lease and for each IA_TA in the lease
3900 * and for each address in the IA_TA append that information
3901 * onto the packet-so-far. If wanted is 0 include all IA_TAs
3902 * in the lease if wanted is non-zero include only that many
3903 * IA_TAs (this may occur if sommebody restarts a client with
3904 * arugments for a smaller number of TAs than before).
3905 *
3906 * \param client = the state of the entire client
3907 * \param packet = the packet we are building and where we
3908 * shall append the IA_TAs we create
3909 * \param lease = the current lease
3910 * \param message = the type of the packet
3911 * \param wanted = the number of IA_TAs to include in the packet
3912 * 0 means include all
3913 * \param added = the number of IA_TAs that were added to the packet
3914 *
3915 * \return ISC_R_SUCCESS - all is well continue, any other return
3916 * indicates an error (most likely memory issues)
3917 * and the packet should be tossed.
3918 */
3919 static isc_result_t
3920 dhc6_add_ia_ta(struct client_state *client, struct data_string *packet,
3921 struct dhc6_lease *lease, u_int8_t message,
3922 int wanted, int *added)
3923 {
3924 struct data_string iads;
3925 struct data_string addrds;
3926 struct dhc6_addr *addr;
3927 struct dhc6_ia *ia;
3928 isc_result_t rval = ISC_R_SUCCESS;
3929 TIME t1, t2;
3930 int i;
3931
3932 *added = 0;
3933 memset(&iads, 0, sizeof(iads));
3934 memset(&addrds, 0, sizeof(addrds));
3935 for (ia = lease->bindings, i = 0;
3936 ia != NULL && rval == ISC_R_SUCCESS && (wanted == 0 || i < wanted);
3937 ia = ia->next) {
3938 if (ia->ia_type != D6O_IA_TA)
3939 continue;
3940
3941 /* Now that we know this is an TA bump the counter */
3942 i++;
3943
3944 if (!buffer_allocate(&iads.buffer, 4, MDL)) {
3945 log_error("Unable to allocate memory for IA_TA.");
3946 rval = ISC_R_NOMEMORY;
3947 break;
3948 }
3949
3950 /* Copy the IAID into the packet buffer. */
3951 memcpy(iads.buffer->data, ia->iaid, 4);
3952 iads.data = iads.buffer->data;
3953 iads.len = 4;
3954
3955 log_debug("XMT: X-- IA_TA %s",
3956 print_hex_1(4, iads.buffer->data, 55));
3957
3958 for (addr = ia->addrs ; addr != NULL ; addr = addr->next) {
3959 /*
3960 * Do not confirm expired addresses, do not request
3961 * expired addresses (but we keep them around for
3962 * solicit).
3963 */
3964 if (addr->flags & DHC6_ADDR_EXPIRED)
3965 continue;
3966
3967 if (addr->address.len != 16) {
3968 log_error("Illegal IPv6 address length (%d), "
3969 "ignoring. (%s:%d)",
3970 addr->address.len, MDL);
3971 continue;
3972 }
3973
3974 if (!buffer_allocate(&addrds.buffer, 24, MDL)) {
3975 log_error("Unable to allocate memory for "
3976 "IAADDR.");
3977 rval = ISC_R_NOMEMORY;
3978 break;
3979 }
3980
3981 addrds.data = addrds.buffer->data;
3982 addrds.len = 24;
3983
3984 /* Copy the address into the packet buffer. */
3985 memcpy(addrds.buffer->data, addr->address.iabuf, 16);
3986
3987 /* Copy in additional information as appropriate */
3988 switch (message) {
3989 case DHCPV6_REQUEST:
3990 case DHCPV6_RENEW:
3991 case DHCPV6_REBIND:
3992 t1 = client->config->requested_lease;
3993 t2 = t1 + 300;
3994 putULong(addrds.buffer->data + 16, t1);
3995 putULong(addrds.buffer->data + 20, t2);
3996
3997 log_debug("XMT: | | X-- IAADDR %s",
3998 piaddr(addr->address));
3999 log_debug("XMT: | | | X-- Preferred "
4000 "lifetime +%u", (unsigned)t1);
4001 log_debug("XMT: | | | X-- Max lifetime +%u",
4002 (unsigned)t2);
4003
4004 break;
4005
4006 case DHCPV6_CONFIRM:
4007 /*
4008 * Set preferred and max life to zero,
4009 * per 17.1.3.
4010 */
4011 memset(addrds.buffer->data + 16, 0, 8);
4012 log_debug("XMT: | X-- Confirm Address %s",
4013 piaddr(addr->address));
4014 break;
4015
4016 case DHCPV6_RELEASE:
4017 /* Preferred and max life are irrelevant */
4018 memset(addrds.buffer->data + 16, 0, 8);
4019 log_debug("XMT: | X-- Release Address %s",
4020 piaddr(addr->address));
4021 break;
4022
4023 default:
4024 log_fatal("Impossible condition at %s:%d.",
4025 MDL);
4026 }
4027
4028 append_option(&iads, &dhcpv6_universe, iaaddr_option,
4029 &addrds);
4030 data_string_forget(&addrds, MDL);
4031 }
4032
4033 /*
4034 * It doesn't make sense to make a request without an
4035 * address.
4036 */
4037 if (ia->addrs == NULL) {
4038 log_debug("!!!: V IA_TA has no IAADDRs - removed.");
4039 rval = ISC_R_FAILURE;
4040 } else if (rval == ISC_R_SUCCESS) {
4041 log_debug("XMT: V IA_TA appended.");
4042 append_option(packet, &dhcpv6_universe, ia_ta_option,
4043 &iads);
4044 }
4045
4046 data_string_forget(&iads, MDL);
4047 }
4048
4049 if (rval == ISC_R_SUCCESS)
4050 *added = i;
4051
4052 return (rval);
4053 }
4054
4055 /*!
4056 *
4057 * \brief Add IA_PD information from the lease to the packet
4058 * we are building.
4059 *
4060 * Walk through the lease and for each IA_PD in the lease
4061 * and for each address in the IA_PD append that information
4062 * onto the packet-so-far. If wanted is 0 include all IA_PDs
4063 * in the lease if wanted is non-zero include only that many
4064 * IA_PDs (this may occur if sommebody restarts a client with
4065 * arugments for a smaller number of PDs than before).
4066 *
4067 * \param client = the state of the entire client
4068 * \param packet = the packet we are building and where we
4069 * shall append the IA_PDs we create
4070 * \param lease = the current lease
4071 * \param message = the type of the packet
4072 * \param wanted = the number of IA_PDs to include in the packet
4073 * 0 means include all
4074 * \param added = the number of IA_PDs that were added to the packet
4075 *
4076 * \return ISC_R_SUCCESS - all is well continue, any other return
4077 * indicates an error (most likely memory issues)
4078 * and the packet should be tossed.
4079 */
4080 static isc_result_t
4081 dhc6_add_ia_pd(struct client_state *client, struct data_string *packet,
4082 struct dhc6_lease *lease, u_int8_t message,
4083 int wanted, int *added)
4084 {
4085 struct data_string iads;
4086 struct data_string prefds;
4087 struct dhc6_addr *pref;
4088 struct dhc6_ia *ia;
4089 isc_result_t rval = ISC_R_SUCCESS;
4090 TIME t1, t2;
4091 int i;
4092
4093 *added = 0;
4094 memset(&iads, 0, sizeof(iads));
4095 memset(&prefds, 0, sizeof(prefds));
4096 for (ia = lease->bindings, i = 0;
4097 ia != NULL && rval == ISC_R_SUCCESS && (wanted == 0 || i < wanted);
4098 ia = ia->next) {
4099 if (ia->ia_type != D6O_IA_PD)
4100 continue;
4101
4102 /* Now that we know this is an PD bump the counter */
4103 i++;
4104
4105 if (!buffer_allocate(&iads.buffer, 12, MDL)) {
4106 log_error("Unable to allocate memory for IA_PD.");
4107 rval = ISC_R_NOMEMORY;
4108 break;
4109 }
4110
4111 /* Copy the IAID into the packet buffer. */
4112 memcpy(iads.buffer->data, ia->iaid, 4);
4113 iads.data = iads.buffer->data;
4114 iads.len = 12;
4115
4116 switch (message) {
4117 case DHCPV6_REQUEST:
4118 case DHCPV6_RENEW:
4119 case DHCPV6_REBIND:
4120
4121 t1 = client->config->requested_lease / 2;
4122 t2 = t1 + (t1 / 2);
4123 #if MAX_TIME > 0xffffffff
4124 if (t1 > 0xffffffff)
4125 t1 = 0xffffffff;
4126 if (t2 > 0xffffffff)
4127 t2 = 0xffffffff;
4128 #endif
4129 putULong(iads.buffer->data + 4, t1);
4130 putULong(iads.buffer->data + 8, t2);
4131
4132 log_debug("XMT: X-- IA_PD %s",
4133 print_hex_1(4, iads.data, 59));
4134 log_debug("XMT: | X-- Requested renew +%u",
4135 (unsigned) t1);
4136 log_debug("XMT: | X-- Requested rebind +%u",
4137 (unsigned) t2);
4138 break;
4139
4140 case DHCPV6_RELEASE:
4141 /* Set t1 and t2 to zero; server will ignore them */
4142 memset(iads.buffer->data + 4, 0, 8);
4143 log_debug("XMT: X-- IA_PD %s",
4144 print_hex_1(4, iads.buffer->data, 55));
4145
4146 break;
4147
4148 default:
4149 log_fatal("Impossible condition at %s:%d.", MDL);
4150 }
4151
4152 for (pref = ia->addrs ; pref != NULL ; pref = pref->next) {
4153 /*
4154 * Do not confirm expired prefixes, do not request
4155 * expired prefixes (but we keep them around for
4156 * solicit).
4157 */
4158 if (pref->flags & DHC6_ADDR_EXPIRED)
4159 continue;
4160
4161 if (pref->address.len != 16) {
4162 log_error("Illegal IPv6 prefix "
4163 "ignoring. (%s:%d)",
4164 MDL);
4165 continue;
4166 }
4167
4168 if (pref->plen == 0) {
4169 log_info("Null IPv6 prefix, "
4170 "ignoring. (%s:%d)",
4171 MDL);
4172 }
4173
4174 if (!buffer_allocate(&prefds.buffer, 25, MDL)) {
4175 log_error("Unable to allocate memory for "
4176 "IAPREFIX.");
4177 rval = ISC_R_NOMEMORY;
4178 break;
4179 }
4180
4181 prefds.data = prefds.buffer->data;
4182 prefds.len = 25;
4183
4184 /* Copy the prefix into the packet buffer. */
4185 putUChar(prefds.buffer->data + 8, pref->plen);
4186 memcpy(prefds.buffer->data + 9,
4187 pref->address.iabuf,
4188 16);
4189
4190 /* Copy in additional information as appropriate */
4191 switch (message) {
4192 case DHCPV6_REQUEST:
4193 case DHCPV6_RENEW:
4194 case DHCPV6_REBIND:
4195 t1 = client->config->requested_lease;
4196 t2 = t1 + 300;
4197 putULong(prefds.buffer->data, t1);
4198 putULong(prefds.buffer->data + 4, t2);
4199
4200 log_debug("XMT: | | X-- IAPREFIX %s/%u",
4201 piaddr(pref->address),
4202 (unsigned) pref->plen);
4203 log_debug("XMT: | | | X-- Preferred "
4204 "lifetime +%u", (unsigned)t1);
4205 log_debug("XMT: | | | X-- Max lifetime +%u",
4206 (unsigned)t2);
4207
4208 break;
4209
4210 case DHCPV6_RELEASE:
4211 /* Preferred and max life are irrelevant */
4212 memset(prefds.buffer->data, 0, 8);
4213 log_debug("XMT: | X-- Release Prefix %s/%u",
4214 piaddr(pref->address),
4215 (unsigned) pref->plen);
4216 break;
4217
4218 default:
4219 log_fatal("Impossible condition at %s:%d.",
4220 MDL);
4221 }
4222
4223 append_option(&iads, &dhcpv6_universe,
4224 iaprefix_option, &prefds);
4225 data_string_forget(&prefds, MDL);
4226 }
4227
4228 /*
4229 * It doesn't make sense to make a request without an
4230 * address.
4231 */
4232 if (ia->addrs == NULL) {
4233 log_debug("!!!: V IA_PD has no IAPREFIXs - removed.");
4234 rval = ISC_R_FAILURE;
4235 } else if (rval == ISC_R_SUCCESS) {
4236 log_debug("XMT: V IA_PD appended.");
4237 append_option(packet, &dhcpv6_universe,
4238 ia_pd_option, &iads);
4239 }
4240
4241 data_string_forget(&iads, MDL);
4242 }
4243
4244 if (rval == ISC_R_SUCCESS)
4245 *added = i;
4246
4247 return (rval);
4248 }
4249
4250 /* stopping_finished() checks if there is a remaining work to do.
4251 */
4252 static isc_boolean_t
4253 stopping_finished(void)
4254 {
4255 struct interface_info *ip;
4256 struct client_state *client;
4257
4258 for (ip = interfaces; ip; ip = ip -> next) {
4259 for (client = ip -> client; client; client = client -> next) {
4260 if (client->state != S_STOPPED)
4261 return ISC_FALSE;
4262 if (client->active_lease != NULL)
4263 return ISC_FALSE;
4264 }
4265 }
4266 return ISC_TRUE;
4267 }
4268
4269 /* reply_handler() accepts a Reply while we're attempting Select or Renew or
4270 * Rebind. Basically any Reply packet.
4271 */
4272 void
4273 reply_handler(struct packet *packet, struct client_state *client)
4274 {
4275 struct dhc6_lease *lease;
4276 isc_result_t check_status;
4277
4278 if (packet->dhcpv6_msg_type != DHCPV6_REPLY)
4279 return;
4280
4281 /* RFC3315 section 15.10 validation (same as 15.3 since we
4282 * always include a client id).
4283 */
4284 if (!valid_reply(packet, client)) {
4285 log_error("Invalid Reply - rejecting.");
4286 return;
4287 }
4288
4289 lease = dhc6_leaseify(packet, client);
4290
4291 /* Out of memory or corrupt packet condition...hopefully a temporary
4292 * problem. Returning now makes us try to retransmit later.
4293 */
4294 if (lease == NULL)
4295 return;
4296
4297 check_status = dhc6_check_reply(client, lease);
4298 if (check_status != ISC_R_SUCCESS) {
4299 dhc6_lease_destroy(&lease, MDL);
4300
4301 /* If no action was taken, but there is an error, then
4302 * we wait for a retransmission.
4303 */
4304 if (check_status != ISC_R_CANCELED)
4305 return;
4306 }
4307
4308 /* We're done retransmitting at this point. */
4309 cancel_timeout(do_confirm6, client);
4310 cancel_timeout(do_select6, client);
4311 cancel_timeout(do_refresh6, client);
4312 cancel_timeout(do_release6, client);
4313 cancel_timeout(do_decline6, client);
4314
4315 /* If this is in response to a Release, clean up and return. */
4316 if (client->state == S_STOPPED) {
4317 if (client->active_lease != NULL) {
4318 dhc6_lease_destroy(&client->active_lease, MDL);
4319 client->active_lease = NULL;
4320 /* We should never wait for nothing!? */
4321 if (stopping_finished()) {
4322 finish(0);
4323 }
4324 }
4325
4326 return;
4327 }
4328
4329 if (client->state == S_DECLINING) {
4330 /* Weed thru the lease and delete all declined addresses.
4331 * Toss the lease if there aren't any addresses left */
4332 int live_cnt = drop_declined_addrs(client->active_lease);
4333 if (live_cnt == 0) {
4334 dhc6_lease_destroy(&client->active_lease, MDL);
4335 client->active_lease = NULL;
4336 }
4337
4338 /* Solicit with any live addresses we have so far, and
4339 * add additional empty NA iasubopts for those we had
4340 * to decline. */
4341 start_init6(client);
4342 return;
4343 }
4344
4345 /* Action was taken, so now that we've torn down our scheduled
4346 * retransmissions, return.
4347 */
4348 if (check_status == ISC_R_CANCELED)
4349 return;
4350
4351 if (client->selected_lease != NULL) {
4352 dhc6_lease_destroy(&client->selected_lease, MDL);
4353 client->selected_lease = NULL;
4354 }
4355
4356 /* If this is in response to a confirm, we use the lease we've
4357 * already got, not the reply we were sent.
4358 */
4359 if (client->state == S_REBOOTING) {
4360 if (client->active_lease == NULL)
4361 log_fatal("Impossible condition at %s:%d.", MDL);
4362
4363 dhc6_lease_destroy(&lease, MDL);
4364 start_bound(client);
4365 return;
4366 }
4367
4368 /* Merge any bindings in the active lease (if there is one) into
4369 * the new active lease.
4370 */
4371 dhc6_merge_lease(client->active_lease, lease);
4372
4373 /* Cleanup if a previous attempt to go bound failed. */
4374 if (client->old_lease != NULL) {
4375 dhc6_lease_destroy(&client->old_lease, MDL);
4376 client->old_lease = NULL;
4377 }
4378
4379 /* Make this lease active and BIND to it. */
4380 if (client->active_lease != NULL)
4381 client->old_lease = client->active_lease;
4382 client->active_lease = lease;
4383
4384 /* We're done with the ADVERTISEd leases, if any. */
4385 while(client->advertised_leases != NULL) {
4386 lease = client->advertised_leases;
4387 client->advertised_leases = lease->next;
4388
4389 dhc6_lease_destroy(&lease, MDL);
4390 }
4391
4392 start_bound(client);
4393 }
4394
4395 /* DHCPv6 packets are a little sillier than they needed to be - the root
4396 * packet contains options, then IA's which contain options, then within
4397 * that IAADDR's which contain options.
4398 *
4399 * To sort this out at dhclient-script time (which fetches config parameters
4400 * in environment variables), start_bound() iterates over each IAADDR, and
4401 * calls this function to marshall an environment variable set that includes
4402 * the most-specific option values related to that IAADDR in particular.
4403 *
4404 * To achieve this, we load environment variables for the root options space,
4405 * then the IA, then the IAADDR. Any duplicate option names will be
4406 * over-written by the later versions.
4407 */
4408 static void
4409 dhc6_marshall_values(const char *prefix, struct client_state *client,
4410 struct dhc6_lease *lease, struct dhc6_ia *ia,
4411 struct dhc6_addr *addr)
4412 {
4413 /* Option cache contents, in descending order of
4414 * scope.
4415 */
4416 if ((lease != NULL) && (lease->options != NULL))
4417 script_write_params6(client, prefix, lease->options);
4418 if ((ia != NULL) && (ia->options != NULL))
4419 script_write_params6(client, prefix, ia->options);
4420 if ((addr != NULL) && (addr->options != NULL))
4421 script_write_params6(client, prefix, addr->options);
4422
4423 /* addr fields. */
4424 if (addr != NULL) {
4425 if ((ia != NULL) && (ia->ia_type == D6O_IA_PD)) {
4426 client_envadd(client, prefix,
4427 "ip6_prefix", "%s/%u",
4428 piaddr(addr->address),
4429 (unsigned) addr->plen);
4430 } else {
4431 client_envadd(client, prefix, "ip6_prefixlen",
4432 "%d", address_prefix_len);
4433 client_envadd(client, prefix, "ip6_address",
4434 "%s", piaddr(addr->address));
4435 }
4436 if ((ia != NULL) && (ia->ia_type == D6O_IA_TA)) {
4437 client_envadd(client, prefix,
4438 "ip6_type", "temporary");
4439 }
4440 client_envadd(client, prefix, "life_starts", "%d",
4441 (int)(addr->starts));
4442 client_envadd(client, prefix, "preferred_life", "%u",
4443 addr->preferred_life);
4444 client_envadd(client, prefix, "max_life", "%u",
4445 addr->max_life);
4446 }
4447
4448 /* ia fields. */
4449 if (ia != NULL) {
4450 client_envadd(client, prefix, "iaid", "%s",
4451 print_hex_1(4, ia->iaid, 12));
4452 client_envadd(client, prefix, "starts", "%d",
4453 (int)(ia->starts));
4454 client_envadd(client, prefix, "renew", "%u", ia->renew);
4455 client_envadd(client, prefix, "rebind", "%u", ia->rebind);
4456 }
4457 }
4458
4459 /* Look at where the client's active lease is sitting. If it's looking to
4460 * time out on renew, rebind, depref, or expiration, do those things.
4461 */
4462 static void
4463 dhc6_check_times(struct client_state *client)
4464 {
4465 struct dhc6_lease *lease;
4466 struct dhc6_ia *ia;
4467 struct dhc6_addr *addr;
4468 TIME renew=MAX_TIME, rebind=MAX_TIME, depref=MAX_TIME,
4469 lo_expire=MAX_TIME, hi_expire=0, max_ia_starts = 0, tmp;
4470 int has_addrs = ISC_FALSE;
4471 int has_preferred_addrs = ISC_FALSE;
4472 struct timeval tv;
4473
4474 lease = client->active_lease;
4475
4476 /* Bit spammy. We should probably keep record of scheduled
4477 * events instead.
4478 */
4479 cancel_timeout(start_renew6, client);
4480 cancel_timeout(start_rebind6, client);
4481 cancel_timeout(do_depref, client);
4482 cancel_timeout(do_expire, client);
4483
4484 for(ia = lease->bindings ; ia != NULL ; ia = ia->next) {
4485 TIME this_ia_lo_expire, this_ia_hi_expire, use_expire;
4486
4487 this_ia_lo_expire = MAX_TIME;
4488 this_ia_hi_expire = 0;
4489
4490 for (addr = ia->addrs ; addr != NULL ; addr = addr->next) {
4491 if(!(addr->flags & DHC6_ADDR_DEPREFFED)) {
4492 if (addr->preferred_life == 0xffffffff)
4493 tmp = MAX_TIME;
4494 else
4495 tmp = addr->starts +
4496 addr->preferred_life;
4497
4498 if (tmp < depref)
4499 depref = tmp;
4500
4501 if (!(addr->flags & DHC6_ADDR_EXPIRED)) {
4502 has_preferred_addrs = ISC_TRUE;
4503 }
4504 }
4505
4506 if (!(addr->flags & DHC6_ADDR_EXPIRED)) {
4507 /* Find EPOCH-relative expiration. */
4508 if (addr->max_life == 0xffffffff)
4509 tmp = MAX_TIME;
4510 else
4511 tmp = addr->starts + addr->max_life;
4512
4513 /* Make the times ia->starts relative. */
4514 tmp -= ia->starts;
4515
4516 if (tmp > this_ia_hi_expire)
4517 this_ia_hi_expire = tmp;
4518 if (tmp < this_ia_lo_expire)
4519 this_ia_lo_expire = tmp;
4520
4521 has_addrs = ISC_TRUE;
4522 }
4523 }
4524
4525 /* These times are ia->starts relative. */
4526 if (this_ia_lo_expire <= (this_ia_hi_expire / 2))
4527 use_expire = this_ia_hi_expire;
4528 else
4529 use_expire = this_ia_lo_expire;
4530
4531 /*
4532 * If the auto-selected expiration time is "infinite", or
4533 * zero, assert a reasonable default.
4534 */
4535 if ((use_expire == MAX_TIME) || (use_expire <= 1))
4536 use_expire = client->config->requested_lease / 2;
4537 else
4538 use_expire /= 2;
4539
4540 /* Don't renew/rebind temporary addresses. */
4541 /* For NA and PD we find the most recent IA and the smallest
4542 * values for the renew and rebind then base the timer on
4543 * the sum of the them.
4544 * Normally all the IAs will have the same time as they
4545 * are requested and served as a group but in some cases the
4546 * client isn't asking for all of the IAs (for example
4547 * restarted with a different set of arguments) or the server
4548 * isn't updating the client on all of them (probably a
4549 * broken server).
4550 */
4551 if (ia->ia_type != D6O_IA_TA) {
4552 if (ia->starts > max_ia_starts)
4553 max_ia_starts = ia->starts;
4554
4555 if (ia->renew == 0) {
4556 tmp = use_expire;
4557 } else if (ia->renew == 0xffffffff)
4558 tmp = MAX_TIME;
4559 else
4560 tmp = ia->renew;
4561
4562 if (tmp < renew)
4563 renew = tmp;
4564
4565 if (ia->rebind == 0) {
4566 /* Set rebind to 3/4 expiration interval. */
4567 tmp = use_expire + (use_expire / 2);
4568 } else if (ia->rebind == 0xffffffff)
4569 tmp = MAX_TIME;
4570 else
4571 tmp = ia->rebind;
4572
4573 if (tmp < rebind)
4574 rebind = tmp;
4575 }
4576
4577 /*
4578 * Return expiration ranges to EPOCH relative for event
4579 * scheduling (add_timeout()).
4580 */
4581 this_ia_hi_expire += ia->starts;
4582 this_ia_lo_expire += ia->starts;
4583
4584 if (this_ia_hi_expire > hi_expire)
4585 hi_expire = this_ia_hi_expire;
4586 if (this_ia_lo_expire < lo_expire)
4587 lo_expire = this_ia_lo_expire;
4588 }
4589
4590 /* If there are no addresses, give up, go to INIT.
4591 * Note that if an address is unexpired with a date in the past,
4592 * we're scheduling an expiration event to ocurr in the past. We
4593 * could probably optimize this to expire now (but then there's
4594 * recursion).
4595 *
4596 * In the future, we may decide that we're done here, or to
4597 * schedule a future request (using 4-pkt info-request model).
4598 */
4599 if (has_addrs == ISC_FALSE) {
4600 dhc6_lease_destroy(&client->active_lease, MDL);
4601 client->active_lease = NULL;
4602
4603 /* Go back to the beginning. */
4604 start_init6(client);
4605 return;
4606 }
4607
4608 /* Second part of calculating the renew and rebind times.
4609 * We have the start time and the desired periods for renew
4610 * and rebind, just add them to get the desired end time.
4611 */
4612 if (renew != MAX_TIME)
4613 renew += max_ia_starts;
4614 if (rebind != MAX_TIME)
4615 rebind += max_ia_starts;
4616
4617 switch(client->state) {
4618 case S_BOUND:
4619 /* We'd like to hit renewing, but if rebinding has already
4620 * passed (time warp), head straight there.
4621 */
4622 if ((rebind > cur_time) && (renew < rebind)) {
4623 log_debug("PRC: Renewal event scheduled in %d seconds, "
4624 "to run for %u seconds.",
4625 (int)(renew - cur_time),
4626 (unsigned)(rebind - renew));
4627 client->next_MRD = rebind;
4628 tv.tv_sec = renew;
4629 tv.tv_usec = 0;
4630 add_timeout(&tv, start_renew6, client, NULL, NULL);
4631
4632 break;
4633 }
4634 /* FALL THROUGH */
4635 case S_RENEWING:
4636 /* While actively renewing, MRD is bounded by the time
4637 * we stop renewing and start rebinding. This helps us
4638 * process the state change on time.
4639 */
4640 client->MRD = rebind - cur_time;
4641 if (rebind != MAX_TIME) {
4642 log_debug("PRC: Rebind event scheduled in %d seconds, "
4643 "to run for %d seconds.",
4644 (int)(rebind - cur_time),
4645 (int)(hi_expire - rebind));
4646 client->next_MRD = hi_expire;
4647 tv.tv_sec = rebind;
4648 tv.tv_usec = 0;
4649 add_timeout(&tv, start_rebind6, client, NULL, NULL);
4650 }
4651 break;
4652
4653 case S_REBINDING:
4654 /* For now, we rebind up until the last lease expires. In
4655 * the future, we might want to start SOLICITing when we've
4656 * depreffed an address.
4657 */
4658 client->MRD = hi_expire - cur_time;
4659 break;
4660
4661 default:
4662 if (has_preferred_addrs) {
4663 log_fatal("Impossible condition, state %d at %s:%d.",
4664 client->state, MDL);
4665 }
4666 }
4667
4668 /* Separately, set a time at which we will depref and expire
4669 * leases. This might happen with multiple addresses while we
4670 * keep trying to refresh.
4671 */
4672 if (depref != MAX_TIME) {
4673 log_debug("PRC: Depreference scheduled in %d seconds.",
4674 (int)(depref - cur_time));
4675 tv.tv_sec = depref;
4676 tv.tv_usec = 0;
4677 add_timeout(&tv, do_depref, client, NULL, NULL);
4678 }
4679 if (lo_expire != MAX_TIME) {
4680 log_debug("PRC: Expiration scheduled in %d seconds.",
4681 (int)(lo_expire - cur_time));
4682 tv.tv_sec = lo_expire;
4683 tv.tv_usec = 0;
4684 add_timeout(&tv, do_expire, client, NULL, NULL);
4685 }
4686 }
4687
4688 /* In a given IA chain, find the IA with the same type and 'iaid'. */
4689 static struct dhc6_ia *
4690 find_ia(struct dhc6_ia *head, u_int16_t type, const char *id)
4691 {
4692 struct dhc6_ia *ia;
4693
4694 for (ia = head ; ia != NULL ; ia = ia->next) {
4695 if (ia->ia_type != type)
4696 continue;
4697 if (memcmp(ia->iaid, id, 4) == 0)
4698 return ia;
4699 }
4700
4701 return NULL;
4702 }
4703
4704 /* In a given address chain, find a matching address. */
4705 static struct dhc6_addr *
4706 find_addr(struct dhc6_addr *head, struct iaddr *address)
4707 {
4708 struct dhc6_addr *addr;
4709
4710 for (addr = head ; addr != NULL ; addr = addr->next) {
4711 if ((addr->address.len == address->len) &&
4712 (memcmp(addr->address.iabuf, address->iabuf,
4713 address->len) == 0))
4714 return addr;
4715 }
4716
4717 return NULL;
4718 }
4719
4720 /* In a given prefix chain, find a matching prefix. */
4721 static struct dhc6_addr *
4722 find_pref(struct dhc6_addr *head, struct iaddr *prefix, u_int8_t plen)
4723 {
4724 struct dhc6_addr *pref;
4725
4726 for (pref = head ; pref != NULL ; pref = pref->next) {
4727 if ((pref->address.len == prefix->len) &&
4728 (pref->plen == plen) &&
4729 (memcmp(pref->address.iabuf, prefix->iabuf,
4730 prefix->len) == 0))
4731 return pref;
4732 }
4733
4734 return NULL;
4735 }
4736
4737 /*
4738 *
4739 * \brief Merge the bindings from the source lease into the destination
4740 * lease structure, where they are missing.
4741 *
4742 * This is used to merge any extra information we have in the current
4743 * (older, src) lease into the lease we have just received. For example
4744 * the src lease might include a binding for an NA that is still usable
4745 * but that we didn't request or that the server is no longer serving.
4746 * We want to keep that information until we toss the binding (expire,
4747 * release) so we move it to the new lease.
4748 *
4749 * We have to copy the stateful objects rather than move them over,
4750 * because later code needs to be able to compare new versus old if
4751 * they contain any bindings.
4752 *
4753 * \param src The older lease to copy the objects from
4754 * \param dst The newer lease to copy the objects to
4755 */
4756 static void
4757 dhc6_merge_lease(struct dhc6_lease *src, struct dhc6_lease *dst)
4758 {
4759 struct dhc6_ia *sia, *dia, *tia, **eia;
4760 struct dhc6_addr *saddr, *daddr, *taddr;
4761 int changes = 0;
4762
4763 if ((dst == NULL) || (src == NULL))
4764 return;
4765
4766 for (sia = src->bindings ; sia != NULL ; sia = sia->next) {
4767 dia = find_ia(dst->bindings, sia->ia_type, (char *)sia->iaid);
4768
4769 if (dia == NULL) {
4770 tia = dhc6_dup_ia(sia, MDL);
4771
4772 if (tia == NULL)
4773 log_fatal("Out of memory merging lease - "
4774 "Unable to continue without losing "
4775 "state! (%s:%d)", MDL);
4776
4777 /* Put any bindings that aren't in the new lease at the
4778 * end of the list. If the user or server reduces the
4779 * number of IAs the ones in use will be at the front
4780 * and will be used when building the next requests
4781 * We could be more efficient by finding the end
4782 * of the list once but we don't expect to do this
4783 * often.
4784 */
4785 for (eia = &dst->bindings;
4786 *eia != NULL;
4787 eia = &(*eia)->next) {
4788 ; /* no work just find the end */
4789 }
4790 *eia = tia;
4791 changes = 1;
4792 } else {
4793 for (saddr = sia->addrs ; saddr != NULL ;
4794 saddr = saddr->next) {
4795 if (sia->ia_type != D6O_IA_PD)
4796 daddr = find_addr(dia->addrs,
4797 &saddr->address);
4798 else
4799 daddr = find_pref(dia->addrs,
4800 &saddr->address,
4801 saddr->plen);
4802
4803 if (daddr == NULL) {
4804 taddr = dhc6_dup_addr(saddr, MDL);
4805
4806 if (taddr == NULL)
4807 log_fatal("Out of memory "
4808 "merging lease - "
4809 "Unable to continue "
4810 "without losing "
4811 "state! (%s:%d)",
4812 MDL);
4813
4814 /* XXX: consider sorting? */
4815 taddr->next = dia->addrs;
4816 dia->addrs = taddr;
4817 changes = 1;
4818 }
4819 }
4820 }
4821 }
4822
4823 /* If we made changes, reset the score to 0 so it is recalculated. */
4824 if (changes)
4825 dst->score = 0;
4826 }
4827
4828 /* We've either finished selecting or succeeded in Renew or Rebinding our
4829 * lease. In all cases we got a Reply. Give dhclient-script a tickle
4830 * to inform it about the new values, and then lay in wait for the next
4831 * event.
4832 */
4833 static void
4834 start_bound(struct client_state *client)
4835 {
4836 struct dhc6_ia *ia, *oldia;
4837 struct dhc6_addr *addr, *oldaddr;
4838 struct dhc6_lease *lease, *old;
4839 const char *reason;
4840 int decline_cnt = 0;
4841 #if defined (NSUPDATE)
4842 TIME dns_update_offset = 1;
4843 #endif
4844
4845 lease = client->active_lease;
4846 if (lease == NULL) {
4847 log_error("Cannot enter bound state unless an active lease "
4848 "is selected.");
4849 return;
4850 }
4851 lease->released = ISC_FALSE;
4852 old = client->old_lease;
4853
4854 client->v6_handler = bound_handler;
4855
4856 switch (client->state) {
4857 case S_SELECTING:
4858 case S_REBOOTING: /* Pretend we got bound. */
4859 reason = "BOUND6";
4860 break;
4861
4862 case S_RENEWING:
4863 reason = "RENEW6";
4864 break;
4865
4866 case S_REBINDING:
4867 reason = "REBIND6";
4868 break;
4869
4870 default:
4871 log_fatal("Impossible condition at %s:%d.", MDL);
4872 /* Silence compiler warnings. */
4873 return;
4874 }
4875
4876 log_debug("PRC: Bound to lease %s.",
4877 print_hex_1(client->active_lease->server_id.len,
4878 client->active_lease->server_id.data, 55));
4879 client->state = S_BOUND;
4880
4881 write_client6_lease(client, lease, 0, 1);
4882
4883 oldia = NULL;
4884 for (ia = lease->bindings ; ia != NULL ; ia = ia->next) {
4885 if (old != NULL)
4886 oldia = find_ia(old->bindings,
4887 ia->ia_type,
4888 (char *)ia->iaid);
4889 else
4890 oldia = NULL;
4891
4892 for (addr = ia->addrs ; addr != NULL ; addr = addr->next) {
4893 /* Don't try to use the address if it's already expired */
4894 if (addr->flags & DHC6_ADDR_EXPIRED)
4895 continue;
4896
4897 if (oldia != NULL) {
4898 if (ia->ia_type != D6O_IA_PD)
4899 oldaddr = find_addr(oldia->addrs,
4900 &addr->address);
4901 else
4902 oldaddr = find_pref(oldia->addrs,
4903 &addr->address,
4904 addr->plen);
4905 } else
4906 oldaddr = NULL;
4907
4908 #if defined (NSUPDATE)
4909 if ((oldaddr == NULL) && (ia->ia_type == D6O_IA_NA))
4910 dhclient_schedule_updates(client,
4911 &addr->address,
4912 dns_update_offset++);
4913 #endif
4914
4915 /* Shell out to setup the new binding. */
4916 script_init(client, reason, NULL);
4917
4918 if (old != NULL)
4919 dhc6_marshall_values("old_", client, old,
4920 oldia, oldaddr);
4921 dhc6_marshall_values("new_", client, lease, ia, addr);
4922 script_write_requested6(client);
4923
4924 /* When script returns 3, DAD failed */
4925 if (script_go(client) == 3) {
4926 if (ia->ia_type == D6O_IA_NA) {
4927 addr->flags |= DHC6_ADDR_DECLINED;
4928 log_debug ("Flag address declined:%s",
4929 piaddr(addr->address));
4930 decline_cnt++;
4931 }
4932 }
4933 }
4934
4935 /* If the client script DAD failed any addresses we need
4936 * build and issue a DECLINE */
4937 if (decline_cnt) {
4938 start_decline6(client);
4939 return;
4940 }
4941
4942 /* XXX: maybe we should loop on the old values instead? */
4943 if (ia->addrs == NULL) {
4944 script_init(client, reason, NULL);
4945
4946 if (old != NULL)
4947 dhc6_marshall_values("old_", client, old,
4948 oldia,
4949 oldia != NULL ?
4950 oldia->addrs : NULL);
4951
4952 dhc6_marshall_values("new_", client, lease, ia,
4953 NULL);
4954 script_write_requested6(client);
4955
4956 script_go(client);
4957 }
4958 }
4959
4960 /* XXX: maybe we should loop on the old values instead? */
4961 if (lease->bindings == NULL) {
4962 script_init(client, reason, NULL);
4963
4964 if (old != NULL)
4965 dhc6_marshall_values("old_", client, old,
4966 old->bindings,
4967 (old->bindings != NULL) ?
4968 old->bindings->addrs : NULL);
4969
4970 dhc6_marshall_values("new_", client, lease, NULL, NULL);
4971 script_write_requested6(client);
4972
4973 script_go(client);
4974 }
4975
4976 #ifdef DHCP4o6
4977 if (dhcpv4_over_dhcpv6)
4978 dhcp4o6_start();
4979 #endif
4980
4981 detach();
4982
4983 if (client->old_lease != NULL) {
4984 dhc6_lease_destroy(&client->old_lease, MDL);
4985 client->old_lease = NULL;
4986 }
4987
4988 /* Schedule events. */
4989 dhc6_check_times(client);
4990 }
4991
4992 /* While bound, ignore packets. In the future we'll want to answer
4993 * Reconfigure-Request messages and the like.
4994 */
4995 void
4996 bound_handler(struct packet *packet, struct client_state *client)
4997 {
4998 log_debug("RCV: Input packets are ignored once bound.");
4999 }
5000
5001 /*
5002 * start_decline6() kicks off the decline process, transmitting
5003 * an decline packet and scheduling a retransmission event.
5004 */
5005 void
5006 start_decline6(struct client_state *client)
5007 {
5008 /* Cancel any pending transmissions */
5009 cancel_timeout(do_confirm6, client);
5010 cancel_timeout(do_select6, client);
5011 cancel_timeout(do_refresh6, client);
5012 cancel_timeout(do_release6, client);
5013 cancel_timeout(do_decline6, client);
5014 client->state = S_DECLINING;
5015
5016 if (client->active_lease == NULL)
5017 return;
5018
5019 /* Set timers per RFC3315 section 18.1.7. */
5020 client->IRT = DEC_TIMEOUT * 100;
5021 client->MRT = 0;
5022 client->MRC = DEC_MAX_RC;
5023 client->MRD = 0;
5024
5025 dhc6_retrans_init(client);
5026 client->v6_handler = reply_handler;
5027
5028 client->refresh_type = DHCPV6_DECLINE;
5029 do_decline6(client);
5030 }
5031
5032 /*
5033 * do_decline6() creates a Decline packet and transmits it.
5034 * The decline will contain an IA_NA with iasubopt(s) for
5035 * each IA_NA containing declined address(es) in the active
5036 * lease.
5037 */
5038 static void
5039 do_decline6(void *input)
5040 {
5041 struct client_state *client;
5042 struct data_string ds;
5043 int send_ret;
5044 struct timeval elapsed, tv;
5045
5046 client = input;
5047 if (client == NULL || client->active_lease == NULL) {
5048 return;
5049 }
5050
5051 if ((client->MRC != 0) && (client->txcount > client->MRC)) {
5052 log_info("Max retransmission count exceeded.");
5053 goto decline_done;
5054 }
5055
5056 /*
5057 * Start_time starts at the first transmission.
5058 */
5059 if (client->txcount == 0) {
5060 client->start_time.tv_sec = cur_tv.tv_sec;
5061 client->start_time.tv_usec = cur_tv.tv_usec;
5062 }
5063
5064 /* elapsed = cur - start */
5065 elapsed.tv_sec = cur_tv.tv_sec - client->start_time.tv_sec;
5066 elapsed.tv_usec = cur_tv.tv_usec - client->start_time.tv_usec;
5067 if (elapsed.tv_usec < 0) {
5068 elapsed.tv_sec -= 1;
5069 elapsed.tv_usec += 1000000;
5070 }
5071
5072 memset(&ds, 0, sizeof(ds));
5073 if (!buffer_allocate(&ds.buffer, 4, MDL)) {
5074 log_error("Unable to allocate memory for Decline.");
5075 goto decline_done;
5076 }
5077
5078 ds.data = ds.buffer->data;
5079 ds.len = 4;
5080 ds.buffer->data[0] = DHCPV6_DECLINE;
5081 memcpy(ds.buffer->data + 1, client->dhcpv6_transaction_id, 3);
5082
5083 /* Form an elapsed option. */
5084 /* Maximum value is 65535 1/100s coded as 0xffff. */
5085 if ((elapsed.tv_sec < 0) || (elapsed.tv_sec > 655) ||
5086 ((elapsed.tv_sec == 655) && (elapsed.tv_usec > 350000))) {
5087 client->elapsed = 0xffff;
5088 } else {
5089 client->elapsed = elapsed.tv_sec * 100;
5090 client->elapsed += elapsed.tv_usec / 10000;
5091 }
5092
5093 client->elapsed = htons(client->elapsed);
5094
5095 log_debug("XMT: Forming Decline.");
5096 make_client6_options(client, &client->sent_options,
5097 client->active_lease, DHCPV6_DECLINE);
5098 dhcpv6_universe.encapsulate(&ds, NULL, NULL, client, NULL,
5099 client->sent_options, &global_scope,
5100 &dhcpv6_universe);
5101
5102 /* Append IA_NA's. */
5103 if (dhc6_add_ia_na_decline(client, &ds, client->active_lease)
5104 != ISC_R_SUCCESS) {
5105 data_string_forget(&ds, MDL);
5106 goto decline_done;
5107 }
5108
5109 /* Transmit and wait. */
5110 log_info("XMT: Decline on %s, interval %ld0ms.",
5111 client->name ? client->name : client->interface->name,
5112 (long int)client->RT);
5113
5114 send_ret = send_packet6(client->interface, ds.data, ds.len,
5115 &DHCPv6DestAddr);
5116 if (send_ret != ds.len) {
5117 log_error("dhc6: sendpacket6() sent %d of %d bytes",
5118 send_ret, ds.len);
5119 }
5120
5121 data_string_forget(&ds, MDL);
5122
5123 /* Wait RT */
5124 tv.tv_sec = cur_tv.tv_sec + client->RT / 100;
5125 tv.tv_usec = cur_tv.tv_usec + (client->RT % 100) * 10000;
5126 if (tv.tv_usec >= 1000000) {
5127 tv.tv_sec += 1;
5128 tv.tv_usec -= 1000000;
5129 }
5130 add_timeout(&tv, do_decline6, client, NULL, NULL);
5131 dhc6_retrans_advance(client);
5132 return;
5133
5134 decline_done:
5135 /* We here because we've exhausted our retry limits or
5136 * something else has gone wrong with the decline process.
5137 * So let's just toss the existing lease and start over. */
5138 dhc6_lease_destroy(&client->active_lease, MDL);
5139 client->active_lease = NULL;
5140
5141 start_init6(client);
5142 return;
5143 }
5144
5145 /* start_renew6() gets us all ready to go to start transmitting Renew packets.
5146 * Note that client->next_MRD must be set before entering this function -
5147 * it must be set to the time at which the client should start Rebinding.
5148 */
5149 void
5150 start_renew6(void *input)
5151 {
5152 struct client_state *client;
5153
5154 client = (struct client_state *)input;
5155
5156 log_info("PRC: Renewing lease on %s.",
5157 client->name ? client->name : client->interface->name);
5158 client->state = S_RENEWING;
5159
5160 client->v6_handler = reply_handler;
5161
5162 /* Times per RFC3315 section 18.1.3. */
5163 client->IRT = REN_TIMEOUT * 100;
5164 client->MRT = REN_MAX_RT * 100;
5165 client->MRC = 0;
5166 /* MRD is special in renew - we need to set it by checking timer
5167 * state.
5168 */
5169 client->MRD = client->next_MRD - cur_time;
5170
5171 dhc6_retrans_init(client);
5172
5173 client->refresh_type = DHCPV6_RENEW;
5174 do_refresh6(client);
5175 }
5176
5177 /* do_refresh6() transmits one DHCPv6 packet, be it a Renew or Rebind, and
5178 * gives the retransmission state a bump for the next time. Note that
5179 * client->refresh_type must be set before entering this function.
5180 */
5181 void
5182 do_refresh6(void *input)
5183 {
5184 struct option_cache *oc;
5185 struct sockaddr_in6 unicast, *dest_addr = &DHCPv6DestAddr;
5186 struct data_string ds;
5187 struct client_state *client;
5188 struct dhc6_lease *lease;
5189 struct timeval elapsed, tv;
5190 int send_ret, added;
5191
5192 client = (struct client_state *)input;
5193 memset(&ds, 0, sizeof(ds));
5194
5195 lease = client->active_lease;
5196 if (lease == NULL) {
5197 log_error("Cannot renew without an active binding.");
5198 return;
5199 }
5200
5201 /* Ensure we're emitting a valid message type. */
5202 switch (client->refresh_type) {
5203 case DHCPV6_RENEW:
5204 case DHCPV6_REBIND:
5205 break;
5206
5207 default:
5208 log_fatal("Internal inconsistency (%d) at %s:%d.",
5209 client->refresh_type, MDL);
5210 }
5211
5212 /*
5213 * Start_time starts at the first transmission.
5214 */
5215 if (client->txcount == 0) {
5216 client->start_time.tv_sec = cur_tv.tv_sec;
5217 client->start_time.tv_usec = cur_tv.tv_usec;
5218 }
5219
5220 /* elapsed = cur - start */
5221 elapsed.tv_sec = cur_tv.tv_sec - client->start_time.tv_sec;
5222 elapsed.tv_usec = cur_tv.tv_usec - client->start_time.tv_usec;
5223 if (elapsed.tv_usec < 0) {
5224 elapsed.tv_sec -= 1;
5225 elapsed.tv_usec += 1000000;
5226 }
5227 if (((client->MRC != 0) && (client->txcount > client->MRC)) ||
5228 ((client->MRD != 0) && (elapsed.tv_sec >= client->MRD))) {
5229 /* We're done. Move on to the next phase, if any. */
5230 dhc6_check_times(client);
5231 return;
5232 }
5233
5234 /*
5235 * Check whether the server has sent a unicast option; if so, we can
5236 * use the address it specified for RENEWs.
5237 */
5238 oc = lookup_option(&dhcpv6_universe, lease->options, D6O_UNICAST);
5239 if (oc && evaluate_option_cache(&ds, NULL, NULL, NULL,
5240 lease->options, NULL, &global_scope,
5241 oc, MDL)) {
5242 if (ds.len < 16) {
5243 log_error("Invalid unicast option length %d.", ds.len);
5244 } else {
5245 memset(&unicast, 0, sizeof(DHCPv6DestAddr));
5246 unicast.sin6_family = AF_INET6;
5247 unicast.sin6_port = remote_port;
5248 memcpy(&unicast.sin6_addr, ds.data, 16);
5249 if (client->refresh_type == DHCPV6_RENEW) {
5250 dest_addr = &unicast;
5251 }
5252 }
5253
5254 data_string_forget(&ds, MDL);
5255 }
5256
5257 /* Commence forming a renew packet. */
5258 memset(&ds, 0, sizeof(ds));
5259 if (!buffer_allocate(&ds.buffer, 4, MDL)) {
5260 log_error("Unable to allocate memory for packet.");
5261 return;
5262 }
5263 ds.data = ds.buffer->data;
5264 ds.len = 4;
5265
5266 ds.buffer->data[0] = client->refresh_type;
5267 memcpy(ds.buffer->data + 1, client->dhcpv6_transaction_id, 3);
5268
5269 /* Form an elapsed option. */
5270 /* Maximum value is 65535 1/100s coded as 0xffff. */
5271 if ((elapsed.tv_sec < 0) || (elapsed.tv_sec > 655) ||
5272 ((elapsed.tv_sec == 655) && (elapsed.tv_usec > 350000))) {
5273 client->elapsed = 0xffff;
5274 } else {
5275 client->elapsed = elapsed.tv_sec * 100;
5276 client->elapsed += elapsed.tv_usec / 10000;
5277 }
5278
5279 if (client->elapsed == 0)
5280 log_debug("XMT: Forming %s, 0 ms elapsed.",
5281 dhcpv6_type_names[client->refresh_type]);
5282 else
5283 log_debug("XMT: Forming %s, %u0 ms elapsed.",
5284 dhcpv6_type_names[client->refresh_type],
5285 (unsigned)client->elapsed);
5286
5287 client->elapsed = htons(client->elapsed);
5288
5289 make_client6_options(client, &client->sent_options, lease,
5290 client->refresh_type);
5291
5292 /* Put in any options from the sent cache. */
5293 dhcpv6_universe.encapsulate(&ds, NULL, NULL, client, NULL,
5294 client->sent_options, &global_scope,
5295 &dhcpv6_universe);
5296
5297 /* Now append any IA's, and within them any IAADDR/IAPREFIXs.
5298 * For each type of IA (na, ta, pd) we start with the ones for
5299 * which we already have addresses (dhc6_add_ia_xx) and then
5300 * if we still want more we add aditional IAs (dhc6_bare_ia_xx)
5301 */
5302 if (wanted_ia_na &&
5303 ((dhc6_add_ia_na(client, &ds, lease, client->refresh_type,
5304 wanted_ia_na, &added) != ISC_R_SUCCESS) ||
5305 (dhc6_bare_ia_xx(client, &ds, wanted_ia_na - added,
5306 D6O_IA_NA) != ISC_R_SUCCESS))) {
5307 data_string_forget(&ds, MDL);
5308 return;
5309 }
5310 if (wanted_ia_pd &&
5311 ((dhc6_add_ia_pd(client, &ds, lease, client->refresh_type,
5312 wanted_ia_pd, &added) != ISC_R_SUCCESS) ||
5313 (dhc6_bare_ia_xx(client, &ds, wanted_ia_pd - added,
5314 D6O_IA_PD) != ISC_R_SUCCESS))) {
5315 data_string_forget(&ds, MDL);
5316 return;
5317 }
5318
5319 log_info("XMT: %s on %s, interval %ld0ms.",
5320 dhcpv6_type_names[client->refresh_type],
5321 client->name ? client->name : client->interface->name,
5322 (long int)client->RT);
5323
5324 send_ret = send_packet6(client->interface, ds.data, ds.len, dest_addr);
5325
5326 if (send_ret != ds.len) {
5327 log_error("dhc6: send_packet6() sent %d of %d bytes",
5328 send_ret, ds.len);
5329 }
5330
5331 data_string_forget(&ds, MDL);
5332
5333 /* Wait RT */
5334 tv.tv_sec = cur_tv.tv_sec + client->RT / 100;
5335 tv.tv_usec = cur_tv.tv_usec + (client->RT % 100) * 10000;
5336 if (tv.tv_usec >= 1000000) {
5337 tv.tv_sec += 1;
5338 tv.tv_usec -= 1000000;
5339 }
5340 add_timeout(&tv, do_refresh6, client, NULL, NULL);
5341
5342 dhc6_retrans_advance(client);
5343 }
5344
5345 /* start_rebind6() gets us all set up to go and rebind a lease. Note that
5346 * client->next_MRD must be set before entering this function. In this case,
5347 * MRD must be set to the maximum time any address in the packet will
5348 * expire.
5349 */
5350 void
5351 start_rebind6(void *input)
5352 {
5353 struct client_state *client;
5354
5355 client = (struct client_state *)input;
5356
5357 log_info("PRC: Rebinding lease on %s.",
5358 client->name ? client->name : client->interface->name);
5359 client->state = S_REBINDING;
5360
5361 client->v6_handler = reply_handler;
5362
5363 /* Times per RFC3315 section 18.1.4. */
5364 client->IRT = REB_TIMEOUT * 100;
5365 client->MRT = REB_MAX_RT * 100;
5366 client->MRC = 0;
5367 /* MRD is special in rebind - it's determined by the timer
5368 * state.
5369 */
5370 client->MRD = client->next_MRD - cur_time;
5371
5372 dhc6_retrans_init(client);
5373
5374 client->refresh_type = DHCPV6_REBIND;
5375 do_refresh6(client);
5376 }
5377
5378 /* do_depref() runs through a given lease's addresses, for each that has
5379 * not yet been depreffed, shells out to the dhclient-script to inform it
5380 * of the status change. The dhclient-script should then do...something...
5381 * to encourage applications to move off the address and onto one of the
5382 * remaining 'preferred' addresses.
5383 */
5384 void
5385 do_depref(void *input)
5386 {
5387 struct client_state *client;
5388 struct dhc6_lease *lease;
5389 struct dhc6_ia *ia;
5390 struct dhc6_addr *addr;
5391
5392 client = (struct client_state *)input;
5393
5394 lease = client->active_lease;
5395 if (lease == NULL)
5396 return;
5397
5398 for (ia = lease->bindings ; ia != NULL ; ia = ia->next) {
5399 for (addr = ia->addrs ; addr != NULL ; addr = addr->next) {
5400 if (addr->flags & DHC6_ADDR_DEPREFFED)
5401 continue;
5402
5403 if (addr->starts + addr->preferred_life <= cur_time) {
5404 script_init(client, "DEPREF6", NULL);
5405 dhc6_marshall_values("cur_", client, lease,
5406 ia, addr);
5407 script_write_requested6(client);
5408 script_go(client);
5409
5410 addr->flags |= DHC6_ADDR_DEPREFFED;
5411
5412 if (ia->ia_type != D6O_IA_PD)
5413 log_info("PRC: Address %s depreferred.",
5414 piaddr(addr->address));
5415 else
5416 log_info("PRC: Prefix %s/%u depreferred.",
5417 piaddr(addr->address),
5418 (unsigned) addr->plen);
5419
5420 #if defined (NSUPDATE)
5421 /* Remove DDNS bindings at depref time. */
5422 if ((ia->ia_type == D6O_IA_NA) &&
5423 client->config->do_forward_update)
5424 client_dns_remove(client,
5425 &addr->address);
5426 #endif
5427 }
5428 }
5429 }
5430
5431 dhc6_check_times(client);
5432 }
5433
5434 /* do_expire() searches through all the addresses on a given lease, and
5435 * expires/removes any addresses that are no longer valid.
5436 */
5437 void
5438 do_expire(void *input)
5439 {
5440 struct client_state *client;
5441 struct dhc6_lease *lease;
5442 struct dhc6_ia *ia, **tia;
5443 struct dhc6_addr *addr;
5444 int has_addrs = ISC_FALSE;
5445 int ia_has_addrs = ISC_FALSE;
5446
5447 client = (struct client_state *)input;
5448
5449 lease = client->active_lease;
5450 if (lease == NULL)
5451 return;
5452
5453 for (ia = lease->bindings, tia = &lease->bindings; ia != NULL ; ) {
5454 ia_has_addrs = ISC_FALSE;
5455 for (addr = ia->addrs ; addr != NULL ; addr = addr->next) {
5456 if (addr->flags & DHC6_ADDR_EXPIRED)
5457 continue;
5458
5459 if (addr->starts + addr->max_life <= cur_time) {
5460 script_init(client, "EXPIRE6", NULL);
5461 dhc6_marshall_values("old_", client, lease,
5462 ia, addr);
5463 script_write_requested6(client);
5464 script_go(client);
5465
5466 addr->flags |= DHC6_ADDR_EXPIRED;
5467
5468 if (ia->ia_type != D6O_IA_PD)
5469 log_info("PRC: Address %s expired.",
5470 piaddr(addr->address));
5471 else
5472 log_info("PRC: Prefix %s/%u expired.",
5473 piaddr(addr->address),
5474 (unsigned) addr->plen);
5475
5476 #if defined (NSUPDATE)
5477 /* We remove DNS records at depref time, but
5478 * it is possible that we might get here
5479 * without depreffing.
5480 */
5481 if ((ia->ia_type == D6O_IA_NA) &&
5482 client->config->do_forward_update &&
5483 !(addr->flags & DHC6_ADDR_DEPREFFED))
5484 client_dns_remove(client,
5485 &addr->address);
5486 #endif
5487
5488 continue;
5489 }
5490
5491 ia_has_addrs = ISC_TRUE;
5492 has_addrs = ISC_TRUE;
5493 }
5494
5495 /* Update to the next ia and git rid of this ia
5496 * if it doesn't have any leases.
5497 */
5498 if (ia_has_addrs == ISC_TRUE) {
5499 /* leases, just advance the list pointer */
5500 tia = &(*tia)->next;
5501 } else {
5502 /* no leases, update the list pointer
5503 * and free the ia
5504 */
5505 *tia = ia->next;
5506 dhc6_ia_destroy(&ia, MDL);
5507 }
5508 /* lastly update the ia pointer to our new ia */
5509 ia = *tia;
5510 }
5511
5512 /* Clean up empty leases. */
5513 if (has_addrs == ISC_FALSE) {
5514 log_info("PRC: Bound lease is devoid of active addresses."
5515 " Re-initializing.");
5516
5517 dhc6_lease_destroy(&lease, MDL);
5518 client->active_lease = NULL;
5519
5520 start_init6(client);
5521 return;
5522 }
5523
5524 /* Schedule the next run through. */
5525 dhc6_check_times(client);
5526 }
5527
5528 /*
5529 * Run client script to unconfigure interface.
5530 * Called with reason STOP6 when dhclient -x is run, or with reason
5531 * RELEASE6 when server has replied to a Release message.
5532 * Stateless is a special case.
5533 */
5534 void
5535 unconfigure6(struct client_state *client, const char *reason)
5536 {
5537 struct dhc6_ia *ia;
5538 struct dhc6_addr *addr;
5539
5540 if (stateless) {
5541 script_init(client, reason, NULL);
5542 if (client->active_lease != NULL)
5543 script_write_params6(client, "old_",
5544 client->active_lease->options);
5545 script_write_requested6(client);
5546 script_go(client);
5547 return;
5548 }
5549
5550 if (client->active_lease == NULL)
5551 return;
5552
5553 for (ia = client->active_lease->bindings ; ia != NULL ; ia = ia->next) {
5554 if (ia->ia_type == D6O_IA_TA)
5555 continue;
5556
5557 for (addr = ia->addrs ; addr != NULL ; addr = addr->next) {
5558 script_init(client, reason, NULL);
5559 dhc6_marshall_values("old_", client,
5560 client->active_lease, ia, addr);
5561 script_write_requested6(client);
5562 script_go(client);
5563
5564 #if defined (NSUPDATE)
5565 if ((ia->ia_type == D6O_IA_NA) &&
5566 client->config->do_forward_update)
5567 client_dns_remove(client, &addr->address);
5568 #endif
5569 }
5570 }
5571 }
5572
5573 void
5574 refresh_info_request6(void *input)
5575 {
5576 struct client_state *client;
5577
5578 client = (struct client_state *)input;
5579 start_info_request6(client);
5580 }
5581
5582 /* Timeout for Information-Request (using the IRT option).
5583 */
5584 static void
5585 dhc6_check_irt(struct client_state *client)
5586 {
5587 struct option **req;
5588 struct option_cache *oc;
5589 TIME expire = MAX_TIME;
5590 struct timeval tv;
5591 int i;
5592 isc_boolean_t found = ISC_FALSE;
5593
5594 cancel_timeout(refresh_info_request6, client);
5595
5596 req = client->config->requested_options;
5597 for (i = 0; req[i] != NULL; i++) {
5598 if (req[i] == irt_option) {
5599 found = ISC_TRUE;
5600 break;
5601 }
5602 }
5603 /* Simply return gives a endless loop waiting for nothing. */
5604 if (!found) {
5605 #ifdef DHCP4o6
5606 if (!dhcpv4_over_dhcpv6)
5607 #endif
5608 finish(0);
5609 }
5610
5611 oc = lookup_option(&dhcpv6_universe, client->active_lease->options,
5612 D6O_INFORMATION_REFRESH_TIME);
5613 if (oc != NULL) {
5614 struct data_string irt;
5615
5616 memset(&irt, 0, sizeof(irt));
5617 if (!evaluate_option_cache(&irt, NULL, NULL, client,
5618 client->active_lease->options,
5619 NULL, &global_scope, oc, MDL) ||
5620 (irt.len < 4)) {
5621 log_error("Can't evaluate IRT.");
5622 } else {
5623 expire = getULong(irt.data);
5624 if (expire < IRT_MINIMUM)
5625 expire = IRT_MINIMUM;
5626 if (expire == 0xffffffff)
5627 expire = MAX_TIME;
5628 }
5629 data_string_forget(&irt, MDL);
5630 } else
5631 expire = IRT_DEFAULT;
5632
5633 if (expire != MAX_TIME) {
5634 log_debug("PRC: Refresh event scheduled in %u seconds.",
5635 (unsigned) expire);
5636 tv.tv_sec = cur_time + expire;
5637 tv.tv_usec = 0;
5638 add_timeout(&tv, refresh_info_request6, client, NULL, NULL);
5639 }
5640 }
5641
5642 /* We got a Reply. Give dhclient-script a tickle to inform it about
5643 * the new values, and then lay in wait for the next event.
5644 */
5645 static void
5646 start_informed(struct client_state *client)
5647 {
5648 client->v6_handler = informed_handler;
5649
5650 log_debug("PRC: Done.");
5651
5652 client->state = S_BOUND;
5653
5654 script_init(client, "RENEW6", NULL);
5655 if (client->old_lease != NULL)
5656 script_write_params6(client, "old_",
5657 client->old_lease->options);
5658 script_write_params6(client, "new_", client->active_lease->options);
5659 script_write_requested6(client);
5660 script_go(client);
5661
5662 #ifdef DHCP4o6
5663 if (dhcpv4_over_dhcpv6)
5664 dhcp4o6_start();
5665 #endif
5666
5667 detach();
5668
5669 if (client->old_lease != NULL) {
5670 dhc6_lease_destroy(&client->old_lease, MDL);
5671 client->old_lease = NULL;
5672 }
5673
5674 /* Schedule events. */
5675 dhc6_check_irt(client);
5676 }
5677
5678 /* While informed, ignore packets.
5679 */
5680 void
5681 informed_handler(struct packet *packet, struct client_state *client)
5682 {
5683 log_debug("RCV: Input packets are ignored once bound.");
5684 }
5685
5686 /* make_client6_options() fetches option caches relevant to the client's
5687 * scope and places them into the sent_options cache. This cache is later
5688 * used to populate DHCPv6 output packets with options.
5689 */
5690 static void
5691 make_client6_options(struct client_state *client, struct option_state **op,
5692 struct dhc6_lease *lease, u_int8_t message)
5693 {
5694 struct option_cache *oc;
5695 struct option **req;
5696 struct buffer *buffer;
5697 int buflen, i, oro_len;
5698
5699 if ((op == NULL) || (client == NULL))
5700 return;
5701
5702 if (*op)
5703 option_state_dereference(op, MDL);
5704
5705 /* Create a cache to carry options to transmission. */
5706 option_state_allocate(op, MDL);
5707
5708 /* Create and store an 'elapsed time' option in the cache. */
5709 oc = NULL;
5710 if (option_cache_allocate(&oc, MDL)) {
5711 const unsigned char *cdata;
5712
5713 cdata = (unsigned char *)&client->elapsed;
5714
5715 if (make_const_data(&oc->expression, cdata, 2, 0, 0, MDL)) {
5716 option_reference(&oc->option, elapsed_option, MDL);
5717 save_option(&dhcpv6_universe, *op, oc);
5718 }
5719
5720 option_cache_dereference(&oc, MDL);
5721 }
5722
5723 /* Bring in any configured options to send. */
5724 if (client->config->on_transmission)
5725 execute_statements_in_scope(NULL, NULL, NULL, client,
5726 lease ? lease->options : NULL,
5727 *op, &global_scope,
5728 client->config->on_transmission,
5729 NULL, NULL);
5730
5731 /* Rapid-commit is only for SOLICITs. */
5732 if (message != DHCPV6_SOLICIT)
5733 delete_option(&dhcpv6_universe, *op, D6O_RAPID_COMMIT);
5734
5735 /* See if the user configured a DUID in a relevant scope. If not,
5736 * introduce our default manufactured id.
5737 */
5738 if ((oc = lookup_option(&dhcpv6_universe, *op,
5739 D6O_CLIENTID)) == NULL) {
5740 if (!option_cache(&oc, &default_duid, NULL, clientid_option,
5741 MDL))
5742 log_fatal("Failure assembling a DUID.");
5743
5744 save_option(&dhcpv6_universe, *op, oc);
5745 option_cache_dereference(&oc, MDL);
5746 }
5747
5748 /* In cases where we're responding to a single server, put the
5749 * server's id in the response.
5750 *
5751 * Note that lease is NULL for SOLICIT or INFO request messages,
5752 * and otherwise MUST be present.
5753 */
5754 if (lease == NULL) {
5755 if ((message != DHCPV6_SOLICIT) &&
5756 (message != DHCPV6_INFORMATION_REQUEST))
5757 log_fatal("Impossible condition at %s:%d.", MDL);
5758 } else if ((message != DHCPV6_REBIND) &&
5759 (message != DHCPV6_CONFIRM)) {
5760 oc = lookup_option(&dhcpv6_universe, lease->options,
5761 D6O_SERVERID);
5762 if (oc != NULL)
5763 save_option(&dhcpv6_universe, *op, oc);
5764 }
5765
5766 /* 'send dhcp6.oro foo;' syntax we used in 4.0.0a1/a2 has been
5767 * deprecated by adjustments to the 'request' syntax also used for
5768 * DHCPv4.
5769 */
5770 if (lookup_option(&dhcpv6_universe, *op, D6O_ORO) != NULL)
5771 log_error("'send dhcp6.oro' syntax is deprecated, please "
5772 "use the 'request' syntax (\"man dhclient.conf\").");
5773
5774 /* Construct and store an ORO (Option Request Option). It is a
5775 * fatal error to fail to send an ORO (of at least zero length).
5776 *
5777 * Discussion: RFC3315 appears to be inconsistent in its statements
5778 * of whether or not the ORO is mandatory. In section 18.1.1
5779 * ("Creation and Transmission of Request Messages"):
5780 *
5781 * The client MUST include an Option Request option (see section
5782 * 22.7) to indicate the options the client is interested in
5783 * receiving. The client MAY include options with data values as
5784 * hints to the server about parameter values the client would like
5785 * to have returned.
5786 *
5787 * This MUST is missing from the creation/transmission of other
5788 * messages (such as Renew and Rebind), and the section 22.7 ("Option
5789 * Request Option" format and definition):
5790 *
5791 * A client MAY include an Option Request option in a Solicit,
5792 * Request, Renew, Rebind, Confirm or Information-request message to
5793 * inform the server about options the client wants the server to
5794 * send to the client. A server MAY include an Option Request
5795 * option in a Reconfigure option to indicate which options the
5796 * client should request from the server.
5797 *
5798 * seems to relax the requirement from MUST to MAY (and still other
5799 * language in RFC3315 supports this).
5800 *
5801 * In lieu of a clarification of RFC3315, we will conform with the
5802 * MUST. Instead of an absent ORO, we will if there are no options
5803 * to request supply an empty ORO. Theoretically, an absent ORO is
5804 * difficult to interpret (does the client want all options or no
5805 * options?). A zero-length ORO is intuitively clear: requesting
5806 * nothing.
5807 */
5808 buffer = NULL;
5809 oro_len = 0;
5810 buflen = 32;
5811 if (!buffer_allocate(&buffer, buflen, MDL))
5812 log_fatal("Out of memory constructing DHCPv6 ORO.");
5813 req = client->config->requested_options;
5814 if (req != NULL) {
5815 for (i = 0 ; req[i] != NULL ; i++) {
5816 if (buflen == oro_len) {
5817 struct buffer *tmpbuf = NULL;
5818
5819 buflen += 32;
5820
5821 /* Shell game. */
5822 buffer_reference(&tmpbuf, buffer, MDL);
5823 buffer_dereference(&buffer, MDL);
5824
5825 if (!buffer_allocate(&buffer, buflen, MDL))
5826 log_fatal("Out of memory resizing "
5827 "DHCPv6 ORO buffer.");
5828
5829 memcpy(buffer->data, tmpbuf->data, oro_len);
5830
5831 buffer_dereference(&tmpbuf, MDL);
5832 }
5833
5834 if (req[i]->universe == &dhcpv6_universe) {
5835 /* Append the code to the ORO. */
5836 putUShort(buffer->data + oro_len,
5837 req[i]->code);
5838 oro_len += 2;
5839 }
5840 }
5841 }
5842
5843 oc = NULL;
5844 if (make_const_option_cache(&oc, &buffer, NULL, oro_len,
5845 oro_option, MDL)) {
5846 save_option(&dhcpv6_universe, *op, oc);
5847 } else {
5848 log_fatal("Unable to create ORO option cache.");
5849 }
5850
5851 /*
5852 * Note: make_const_option_cache() consumes the buffer, we do not
5853 * need to dereference it (XXX).
5854 */
5855 option_cache_dereference(&oc, MDL);
5856 }
5857
5858 /* A clone of the DHCPv4 script_write_params() minus the DHCPv4-specific
5859 * filename, server-name, etc specifics.
5860 *
5861 * Simply, store all values present in all universes of the option state
5862 * (probably derived from a DHCPv6 packet) into environment variables
5863 * named after the option names (and universe names) but with the 'prefix'
5864 * prepended.
5865 *
5866 * Later, dhclient-script may compare for example "new_time_servers" and
5867 * "old_time_servers" for differences, and only upon detecting a change
5868 * bother to rewrite ntp.conf and restart it. Or something along those
5869 * generic lines.
5870 */
5871 static void
5872 script_write_params6(struct client_state *client, const char *prefix,
5873 struct option_state *options)
5874 {
5875 struct envadd_state es;
5876 int i;
5877
5878 if (options == NULL)
5879 return;
5880
5881 es.client = client;
5882 es.prefix = prefix;
5883
5884 for (i = 0 ; i < options->universe_count ; i++) {
5885 option_space_foreach(NULL, NULL, client, NULL, options,
5886 &global_scope, universes[i], &es,
5887 client_option_envadd);
5888 }
5889 }
5890
5891 /*
5892 * A clone of the DHCPv4 routine.
5893 * Write out the environment variables for the objects that the
5894 * client requested. If the object was requested the variable will be:
5895 * requested_<option_name>=1
5896 * If it wasn't requested there won't be a variable.
5897 */
5898 static void script_write_requested6(client)
5899 struct client_state *client;
5900 {
5901 int i;
5902 struct option **req;
5903 char name[256];
5904 req = client->config->requested_options;
5905
5906 if (req == NULL)
5907 return;
5908
5909 for (i = 0 ; req[i] != NULL ; i++) {
5910 if ((req[i]->universe == &dhcpv6_universe) &&
5911 dhcp_option_ev_name (name, sizeof(name), req[i])) {
5912 client_envadd(client, "requested_", name, "%d", 1);
5913 }
5914 }
5915 }
5916
5917 /*
5918 * Check if there is something not fully defined in the active lease.
5919 */
5920 static isc_boolean_t
5921 active_prefix(struct client_state *client)
5922 {
5923 struct dhc6_lease *lease;
5924 struct dhc6_ia *ia;
5925 struct dhc6_addr *pref;
5926 char zeros[16];
5927
5928 lease = client->active_lease;
5929 if (lease == NULL)
5930 return ISC_FALSE;
5931 memset(zeros, 0, 16);
5932 for (ia = lease->bindings; ia != NULL; ia = ia->next) {
5933 if (ia->ia_type != D6O_IA_PD)
5934 continue;
5935 for (pref = ia->addrs; pref != NULL; pref = pref->next) {
5936 if (pref->plen == 0)
5937 return ISC_FALSE;
5938 if (pref->address.len != 16)
5939 return ISC_FALSE;
5940 if (memcmp(pref->address.iabuf, zeros, 16) == 0)
5941 return ISC_FALSE;
5942 }
5943 }
5944 return ISC_TRUE;
5945 }
5946
5947 /* Adds a leases's declined addreses to the outbound packet
5948 *
5949 * For each IA_NA in the lease that contains one or more declined
5950 * addresses, an IA_NA option with an iasubopt for each declined
5951 * address is added to the outbound packet.
5952 *
5953 * We skip PDs and TAs as declines are undefined for them.
5954 */
5955 static isc_result_t
5956 dhc6_add_ia_na_decline(struct client_state *client, struct data_string *packet,
5957 struct dhc6_lease *lease) {
5958 struct data_string iads;
5959 struct data_string addrds;
5960 struct dhc6_addr *addr;
5961 struct dhc6_ia *ia;
5962 isc_result_t rval = ISC_R_SUCCESS;
5963
5964 memset(&iads, 0, sizeof(iads));
5965 memset(&addrds, 0, sizeof(addrds));
5966 for (ia = lease->bindings; ia != NULL && rval == ISC_R_SUCCESS;
5967 ia = ia->next) {
5968 if (ia->ia_type != D6O_IA_NA)
5969 continue;
5970
5971 int start_new_ia = 1;
5972 for (addr = ia->addrs ; addr != NULL ; addr = addr->next) {
5973 /*
5974 * Do not confirm expired addresses, do not request
5975 * expired addresses (but we keep them around for
5976 * solicit).
5977 */
5978 if (!(addr->flags & DHC6_ADDR_DECLINED)) {
5979 continue;
5980 }
5981
5982 if (start_new_ia) {
5983 if (!buffer_allocate(&iads.buffer, 12, MDL)) {
5984 log_error("Unable to allocate memory"
5985 " for IA_NA.");
5986 rval = ISC_R_NOMEMORY;
5987 break;
5988 }
5989
5990 /* Copy the IAID into the packet buffer. */
5991 memcpy(iads.buffer->data, ia->iaid, 4);
5992 iads.data = iads.buffer->data;
5993 iads.len = 12;
5994
5995 /* Set t1/t2 to zero; server will ignore them */
5996 memset(iads.buffer->data + 4, 0, 8);
5997 log_debug("XMT: X-- IA_NA %s",
5998 print_hex_1(4, iads.buffer->data, 55));
5999 start_new_ia = 0;
6000 }
6001
6002 if (addr->address.len != 16) {
6003 log_error("Illegal IPv6 address length (%d), "
6004 "ignoring. (%s:%d)",
6005 addr->address.len, MDL);
6006 continue;
6007 }
6008
6009 if (!buffer_allocate(&addrds.buffer, 24, MDL)) {
6010 log_error("Unable to allocate memory for "
6011 "IAADDR.");
6012 rval = ISC_R_NOMEMORY;
6013 break;
6014 }
6015
6016 addrds.data = addrds.buffer->data;
6017 addrds.len = 24;
6018
6019 /* Copy the address into the packet buffer. */
6020 memcpy(addrds.buffer->data, addr->address.iabuf, 16);
6021
6022 /* Preferred and max life are irrelevant */
6023 memset(addrds.buffer->data + 16, 0, 8);
6024 log_debug("XMT: | X-- Decline Address %s",
6025 piaddr(addr->address));
6026
6027 append_option(&iads, &dhcpv6_universe, iaaddr_option,
6028 &addrds);
6029 data_string_forget(&addrds, MDL);
6030 }
6031
6032 /*
6033 * It doesn't make sense to make a request without an
6034 * address.
6035 */
6036 if (ia->addrs == NULL) {
6037 log_debug("!!!: V IA_NA has no IAADDRs - removed.");
6038 rval = ISC_R_FAILURE;
6039 } else if (rval == ISC_R_SUCCESS) {
6040 log_debug("XMT: V IA_NA appended.");
6041 append_option(packet, &dhcpv6_universe, ia_na_option,
6042 &iads);
6043 }
6044
6045 data_string_forget(&iads, MDL);
6046 }
6047
6048 return (rval);
6049 }
6050
6051 /*
6052 * Remove any declined NA addresses from the lease.
6053 *
6054 * Returns zero if the all of the bindings on the lease
6055 * were removed, non-zero if there are PD, TA, or usuable NA
6056 * bindings
6057 */
6058 int drop_declined_addrs(struct dhc6_lease *lease) {
6059 struct dhc6_ia *ia;
6060 int live_cnt = 0;
6061
6062 for (ia = lease->bindings; ia != NULL; ia = ia->next) {
6063 struct dhc6_addr* prev_addr;
6064 struct dhc6_addr* addr;
6065 struct dhc6_addr* next;
6066
6067 /* If it's a PD or TA, we assume it has at least
6068 * one usuable binding */
6069 if (ia->ia_type != D6O_IA_NA) {
6070 live_cnt++;
6071 continue;
6072 }
6073
6074 prev_addr = NULL;
6075 for (addr = ia->addrs ; addr != NULL ; ) {
6076 if (!(addr->flags & DHC6_ADDR_DECLINED)) {
6077 live_cnt++;
6078 addr = addr->next;
6079 prev_addr = addr;
6080 continue;
6081 }
6082
6083 /* If we're deleting head, move it up one */
6084 if (ia->addrs == addr) {
6085 ia->addrs = addr->next;
6086 prev_addr = addr->next;
6087 } else {
6088 prev_addr->next = addr->next;
6089 }
6090
6091 if (addr->options != NULL) {
6092 option_state_dereference(&addr->options, MDL);
6093 }
6094
6095 next = addr->next;
6096 dfree(addr, MDL);
6097 addr = next;
6098 }
6099 }
6100
6101 return (live_cnt);
6102 }
6103
6104 /* Run through the addresses in lease and return true if there's any unexpired.
6105 * Return false otherwise.
6106 */
6107 static isc_boolean_t
6108 unexpired_address_in_lease(struct dhc6_lease *lease)
6109 {
6110 struct dhc6_ia *ia;
6111 struct dhc6_addr *addr;
6112
6113 if (lease == NULL) {
6114 return ISC_FALSE;
6115 }
6116
6117 for (ia = lease->bindings ; ia != NULL ; ia = ia->next) {
6118 for (addr = ia->addrs ; addr != NULL ; addr = addr->next) {
6119 if (!(addr->flags & DHC6_ADDR_EXPIRED) &&
6120 (addr->starts + addr->max_life > cur_time)) {
6121 return ISC_TRUE;
6122 }
6123 }
6124 }
6125
6126 log_debug("PRC: Previous lease is devoid of active addresses.");
6127 return ISC_FALSE;
6128 }
6129 #endif /* DHCPv6 */