]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/libsystemd-network/sd-dhcp-client.c
Merge pull request #30513 from rpigott/resolved-ede
[thirdparty/systemd.git] / src / libsystemd-network / sd-dhcp-client.c
1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2 /***
3 Copyright © 2013 Intel Corporation. All rights reserved.
4 ***/
5
6 #include <errno.h>
7 #include <net/ethernet.h>
8 #include <net/if_arp.h>
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <sys/ioctl.h>
12 #include <linux/if_infiniband.h>
13
14 #include "sd-dhcp-client.h"
15
16 #include "alloc-util.h"
17 #include "device-util.h"
18 #include "dhcp-client-id-internal.h"
19 #include "dhcp-client-internal.h"
20 #include "dhcp-lease-internal.h"
21 #include "dhcp-network.h"
22 #include "dhcp-option.h"
23 #include "dhcp-packet.h"
24 #include "dns-domain.h"
25 #include "ether-addr-util.h"
26 #include "event-util.h"
27 #include "fd-util.h"
28 #include "hostname-util.h"
29 #include "iovec-util.h"
30 #include "memory-util.h"
31 #include "network-common.h"
32 #include "random-util.h"
33 #include "set.h"
34 #include "sort-util.h"
35 #include "string-table.h"
36 #include "string-util.h"
37 #include "strv.h"
38 #include "time-util.h"
39 #include "utf8.h"
40 #include "web-util.h"
41
42 #define MAX_MAC_ADDR_LEN CONST_MAX(INFINIBAND_ALEN, ETH_ALEN)
43
44 #define RESTART_AFTER_NAK_MIN_USEC (1 * USEC_PER_SEC)
45 #define RESTART_AFTER_NAK_MAX_USEC (30 * USEC_PER_MINUTE)
46
47 #define TRANSIENT_FAILURE_ATTEMPTS 3 /* Arbitrary limit: how many attempts are considered enough to report
48 * transient failure. */
49
50 struct sd_dhcp_client {
51 unsigned n_ref;
52
53 DHCPState state;
54 sd_event *event;
55 int event_priority;
56 sd_event_source *timeout_resend;
57
58 int ifindex;
59 char *ifname;
60
61 sd_device *dev;
62
63 int fd;
64 uint16_t port;
65 union sockaddr_union link;
66 sd_event_source *receive_message;
67 bool request_broadcast;
68 Set *req_opts;
69 bool anonymize;
70 bool rapid_commit;
71 be32_t last_addr;
72 struct hw_addr_data hw_addr;
73 struct hw_addr_data bcast_addr;
74 uint16_t arp_type;
75 sd_dhcp_client_id client_id;
76 char *hostname;
77 char *vendor_class_identifier;
78 char *mudurl;
79 char **user_class;
80 uint32_t mtu;
81 usec_t fallback_lease_lifetime;
82 uint32_t xid;
83 usec_t start_time;
84 usec_t t1_time;
85 usec_t t2_time;
86 usec_t expire_time;
87 uint64_t attempt;
88 uint64_t max_attempts;
89 OrderedHashmap *extra_options;
90 OrderedHashmap *vendor_options;
91 sd_event_source *timeout_t1;
92 sd_event_source *timeout_t2;
93 sd_event_source *timeout_expire;
94 sd_event_source *timeout_ipv6_only_mode;
95 sd_dhcp_client_callback_t callback;
96 void *userdata;
97 sd_dhcp_client_callback_t state_callback;
98 void *state_userdata;
99 sd_dhcp_lease *lease;
100 usec_t start_delay;
101 int ip_service_type;
102 int socket_priority;
103 bool socket_priority_set;
104 bool ipv6_acquired;
105 };
106
107 static const uint8_t default_req_opts[] = {
108 SD_DHCP_OPTION_SUBNET_MASK,
109 SD_DHCP_OPTION_ROUTER,
110 SD_DHCP_OPTION_HOST_NAME,
111 SD_DHCP_OPTION_DOMAIN_NAME,
112 SD_DHCP_OPTION_DOMAIN_NAME_SERVER,
113 };
114
115 /* RFC7844 section 3:
116 MAY contain the Parameter Request List option.
117 RFC7844 section 3.6:
118 The client intending to protect its privacy SHOULD only request a
119 minimal number of options in the PRL and SHOULD also randomly shuffle
120 the ordering of option codes in the PRL. If this random ordering
121 cannot be implemented, the client MAY order the option codes in the
122 PRL by option code number (lowest to highest).
123 */
124 /* NOTE: using PRL options that Windows 10 RFC7844 implementation uses */
125 static const uint8_t default_req_opts_anonymize[] = {
126 SD_DHCP_OPTION_SUBNET_MASK, /* 1 */
127 SD_DHCP_OPTION_ROUTER, /* 3 */
128 SD_DHCP_OPTION_DOMAIN_NAME_SERVER, /* 6 */
129 SD_DHCP_OPTION_DOMAIN_NAME, /* 15 */
130 SD_DHCP_OPTION_ROUTER_DISCOVERY, /* 31 */
131 SD_DHCP_OPTION_STATIC_ROUTE, /* 33 */
132 SD_DHCP_OPTION_VENDOR_SPECIFIC, /* 43 */
133 SD_DHCP_OPTION_NETBIOS_NAME_SERVER, /* 44 */
134 SD_DHCP_OPTION_NETBIOS_NODE_TYPE, /* 46 */
135 SD_DHCP_OPTION_NETBIOS_SCOPE, /* 47 */
136 SD_DHCP_OPTION_CLASSLESS_STATIC_ROUTE, /* 121 */
137 SD_DHCP_OPTION_PRIVATE_CLASSLESS_STATIC_ROUTE, /* 249 */
138 SD_DHCP_OPTION_PRIVATE_PROXY_AUTODISCOVERY, /* 252 */
139 };
140
141 static int client_receive_message_raw(
142 sd_event_source *s,
143 int fd,
144 uint32_t revents,
145 void *userdata);
146 static int client_receive_message_udp(
147 sd_event_source *s,
148 int fd,
149 uint32_t revents,
150 void *userdata);
151 static void client_stop(sd_dhcp_client *client, int error);
152
153 int dhcp_client_set_state_callback(
154 sd_dhcp_client *client,
155 sd_dhcp_client_callback_t cb,
156 void *userdata) {
157
158 assert_return(client, -EINVAL);
159
160 client->state_callback = cb;
161 client->state_userdata = userdata;
162
163 return 0;
164 }
165
166 int sd_dhcp_client_set_callback(
167 sd_dhcp_client *client,
168 sd_dhcp_client_callback_t cb,
169 void *userdata) {
170
171 assert_return(client, -EINVAL);
172
173 client->callback = cb;
174 client->userdata = userdata;
175
176 return 0;
177 }
178
179 int sd_dhcp_client_set_request_broadcast(sd_dhcp_client *client, int broadcast) {
180 assert_return(client, -EINVAL);
181 assert_return(!sd_dhcp_client_is_running(client), -EBUSY);
182
183 client->request_broadcast = broadcast;
184
185 return 0;
186 }
187
188 int sd_dhcp_client_set_request_option(sd_dhcp_client *client, uint8_t option) {
189 assert_return(client, -EINVAL);
190 assert_return(!sd_dhcp_client_is_running(client), -EBUSY);
191
192 switch (option) {
193
194 case SD_DHCP_OPTION_PAD:
195 case SD_DHCP_OPTION_OVERLOAD:
196 case SD_DHCP_OPTION_MESSAGE_TYPE:
197 case SD_DHCP_OPTION_PARAMETER_REQUEST_LIST:
198 case SD_DHCP_OPTION_END:
199 return -EINVAL;
200
201 default:
202 break;
203 }
204
205 return set_ensure_put(&client->req_opts, NULL, UINT8_TO_PTR(option));
206 }
207
208 static int client_request_contains(sd_dhcp_client *client, uint8_t option) {
209 assert(client);
210
211 return set_contains(client->req_opts, UINT8_TO_PTR(option));
212 }
213
214 int sd_dhcp_client_set_request_address(
215 sd_dhcp_client *client,
216 const struct in_addr *last_addr) {
217
218 assert_return(client, -EINVAL);
219 assert_return(!sd_dhcp_client_is_running(client), -EBUSY);
220
221 if (last_addr)
222 client->last_addr = last_addr->s_addr;
223 else
224 client->last_addr = INADDR_ANY;
225
226 return 0;
227 }
228
229 int sd_dhcp_client_set_ifindex(sd_dhcp_client *client, int ifindex) {
230 assert_return(client, -EINVAL);
231 assert_return(!sd_dhcp_client_is_running(client), -EBUSY);
232 assert_return(ifindex > 0, -EINVAL);
233
234 client->ifindex = ifindex;
235 return 0;
236 }
237
238 int sd_dhcp_client_set_ifname(sd_dhcp_client *client, const char *ifname) {
239 assert_return(client, -EINVAL);
240 assert_return(ifname, -EINVAL);
241
242 if (!ifname_valid_full(ifname, IFNAME_VALID_ALTERNATIVE))
243 return -EINVAL;
244
245 return free_and_strdup(&client->ifname, ifname);
246 }
247
248 int sd_dhcp_client_get_ifname(sd_dhcp_client *client, const char **ret) {
249 int r;
250
251 assert_return(client, -EINVAL);
252
253 r = get_ifname(client->ifindex, &client->ifname);
254 if (r < 0)
255 return r;
256
257 if (ret)
258 *ret = client->ifname;
259
260 return 0;
261 }
262
263 int sd_dhcp_client_set_mac(
264 sd_dhcp_client *client,
265 const uint8_t *hw_addr,
266 const uint8_t *bcast_addr,
267 size_t addr_len,
268 uint16_t arp_type) {
269
270 assert_return(client, -EINVAL);
271 assert_return(!sd_dhcp_client_is_running(client), -EBUSY);
272 assert_return(IN_SET(arp_type, ARPHRD_ETHER, ARPHRD_INFINIBAND), -EINVAL);
273 assert_return(hw_addr, -EINVAL);
274 assert_return(addr_len == (arp_type == ARPHRD_ETHER ? ETH_ALEN : INFINIBAND_ALEN), -EINVAL);
275
276 client->arp_type = arp_type;
277 hw_addr_set(&client->hw_addr, hw_addr, addr_len);
278 hw_addr_set(&client->bcast_addr, bcast_addr, bcast_addr ? addr_len : 0);
279
280 return 0;
281 }
282
283 int sd_dhcp_client_get_client_id(sd_dhcp_client *client, const sd_dhcp_client_id **ret) {
284 assert_return(client, -EINVAL);
285 assert_return(ret, -EINVAL);
286
287 if (!sd_dhcp_client_id_is_set(&client->client_id))
288 return -ENODATA;
289
290 *ret = &client->client_id;
291 return 0;
292 }
293
294 int sd_dhcp_client_set_client_id(
295 sd_dhcp_client *client,
296 uint8_t type,
297 const uint8_t *data,
298 size_t data_len) {
299
300 assert_return(client, -EINVAL);
301 assert_return(!sd_dhcp_client_is_running(client), -EBUSY);
302 assert_return(data, -EINVAL);
303 assert_return(client_id_data_size_is_valid(data_len), -EINVAL);
304
305 /* For hardware types, log debug message about unexpected data length.
306 *
307 * Note that infiniband's INFINIBAND_ALEN is 20 bytes long, but only
308 * the last 8 bytes of the address are stable and suitable to put into
309 * the client-id. The caller is advised to account for that. */
310 if ((type == ARPHRD_ETHER && data_len != ETH_ALEN) ||
311 (type == ARPHRD_INFINIBAND && data_len != 8))
312 log_dhcp_client(client,
313 "Changing client ID to hardware type %u with unexpected address length %zu",
314 type, data_len);
315
316 return sd_dhcp_client_id_set(&client->client_id, type, data, data_len);
317 }
318
319 static int dhcp_client_set_iaid_duid(
320 sd_dhcp_client *client,
321 bool iaid_set,
322 uint32_t iaid,
323 sd_dhcp_duid *duid) {
324
325 int r;
326
327 if (!iaid_set) {
328 r = dhcp_identifier_set_iaid(client->dev, &client->hw_addr,
329 /* legacy_unstable_byteorder = */ true,
330 &iaid);
331 if (r < 0)
332 return r;
333
334 iaid = be32toh(iaid);
335 }
336
337 return sd_dhcp_client_id_set_iaid_duid(&client->client_id, iaid, duid);
338 }
339
340 int sd_dhcp_client_set_iaid_duid_llt(
341 sd_dhcp_client *client,
342 bool iaid_set,
343 uint32_t iaid,
344 usec_t llt_time) {
345
346 sd_dhcp_duid duid;
347 int r;
348
349 assert_return(client, -EINVAL);
350 assert_return(!sd_dhcp_client_is_running(client), -EBUSY);
351
352 r = sd_dhcp_duid_set_llt(&duid, client->hw_addr.bytes, client->hw_addr.length, client->arp_type, llt_time);
353 if (r < 0)
354 return r;
355
356 return dhcp_client_set_iaid_duid(client, iaid_set, iaid, &duid);
357 }
358
359 int sd_dhcp_client_set_iaid_duid_ll(
360 sd_dhcp_client *client,
361 bool iaid_set,
362 uint32_t iaid) {
363
364 sd_dhcp_duid duid;
365 int r;
366
367 assert_return(client, -EINVAL);
368 assert_return(!sd_dhcp_client_is_running(client), -EBUSY);
369
370 r = sd_dhcp_duid_set_ll(&duid, client->hw_addr.bytes, client->hw_addr.length, client->arp_type);
371 if (r < 0)
372 return r;
373
374 return dhcp_client_set_iaid_duid(client, iaid_set, iaid, &duid);
375 }
376
377 int sd_dhcp_client_set_iaid_duid_en(
378 sd_dhcp_client *client,
379 bool iaid_set,
380 uint32_t iaid) {
381
382 sd_dhcp_duid duid;
383 int r;
384
385 assert_return(client, -EINVAL);
386 assert_return(!sd_dhcp_client_is_running(client), -EBUSY);
387
388 r = sd_dhcp_duid_set_en(&duid);
389 if (r < 0)
390 return r;
391
392 return dhcp_client_set_iaid_duid(client, iaid_set, iaid, &duid);
393 }
394
395 int sd_dhcp_client_set_iaid_duid_uuid(
396 sd_dhcp_client *client,
397 bool iaid_set,
398 uint32_t iaid) {
399
400 sd_dhcp_duid duid;
401 int r;
402
403 assert_return(client, -EINVAL);
404 assert_return(!sd_dhcp_client_is_running(client), -EBUSY);
405
406 r = sd_dhcp_duid_set_uuid(&duid);
407 if (r < 0)
408 return r;
409
410 return dhcp_client_set_iaid_duid(client, iaid_set, iaid, &duid);
411 }
412
413 int sd_dhcp_client_set_iaid_duid_raw(
414 sd_dhcp_client *client,
415 bool iaid_set,
416 uint32_t iaid,
417 uint16_t duid_type,
418 const uint8_t *duid_data,
419 size_t duid_data_len) {
420
421 sd_dhcp_duid duid;
422 int r;
423
424 assert_return(client, -EINVAL);
425 assert_return(!sd_dhcp_client_is_running(client), -EBUSY);
426 assert_return(duid_data || duid_data_len == 0, -EINVAL);
427
428 r = sd_dhcp_duid_set(&duid, duid_type, duid_data, duid_data_len);
429 if (r < 0)
430 return r;
431
432 return dhcp_client_set_iaid_duid(client, iaid_set, iaid, &duid);
433 }
434
435 int sd_dhcp_client_set_rapid_commit(sd_dhcp_client *client, bool rapid_commit) {
436 assert_return(client, -EINVAL);
437
438 client->rapid_commit = !client->anonymize && rapid_commit;
439 return 0;
440 }
441
442 int sd_dhcp_client_set_hostname(
443 sd_dhcp_client *client,
444 const char *hostname) {
445
446 assert_return(client, -EINVAL);
447 assert_return(!sd_dhcp_client_is_running(client), -EBUSY);
448
449 /* Make sure hostnames qualify as DNS and as Linux hostnames */
450 if (hostname &&
451 !(hostname_is_valid(hostname, 0) && dns_name_is_valid(hostname) > 0))
452 return -EINVAL;
453
454 return free_and_strdup(&client->hostname, hostname);
455 }
456
457 int sd_dhcp_client_set_vendor_class_identifier(
458 sd_dhcp_client *client,
459 const char *vci) {
460
461 assert_return(client, -EINVAL);
462 assert_return(!sd_dhcp_client_is_running(client), -EBUSY);
463
464 return free_and_strdup(&client->vendor_class_identifier, vci);
465 }
466
467 int sd_dhcp_client_set_mud_url(
468 sd_dhcp_client *client,
469 const char *mudurl) {
470
471 assert_return(client, -EINVAL);
472 assert_return(!sd_dhcp_client_is_running(client), -EBUSY);
473 assert_return(mudurl, -EINVAL);
474 assert_return(strlen(mudurl) <= 255, -EINVAL);
475 assert_return(http_url_is_valid(mudurl), -EINVAL);
476
477 return free_and_strdup(&client->mudurl, mudurl);
478 }
479
480 int sd_dhcp_client_set_user_class(
481 sd_dhcp_client *client,
482 char * const *user_class) {
483
484 char **s = NULL;
485
486 assert_return(client, -EINVAL);
487 assert_return(!sd_dhcp_client_is_running(client), -EBUSY);
488 assert_return(!strv_isempty(user_class), -EINVAL);
489
490 STRV_FOREACH(p, user_class) {
491 size_t n = strlen(*p);
492
493 if (n > 255 || n == 0)
494 return -EINVAL;
495 }
496
497 s = strv_copy(user_class);
498 if (!s)
499 return -ENOMEM;
500
501 return strv_free_and_replace(client->user_class, s);
502 }
503
504 int sd_dhcp_client_set_client_port(
505 sd_dhcp_client *client,
506 uint16_t port) {
507
508 assert_return(client, -EINVAL);
509 assert_return(!sd_dhcp_client_is_running(client), -EBUSY);
510
511 client->port = port;
512
513 return 0;
514 }
515
516 int sd_dhcp_client_set_mtu(sd_dhcp_client *client, uint32_t mtu) {
517 assert_return(client, -EINVAL);
518 assert_return(mtu >= DHCP_MIN_PACKET_SIZE, -ERANGE);
519
520 /* MTU may be changed by the acquired lease. Hence, we cannot require that the client is stopped here.
521 * Please do not add assertion for !sd_dhcp_client_is_running(client) here. */
522
523 client->mtu = mtu;
524
525 return 0;
526 }
527
528 int sd_dhcp_client_set_max_attempts(sd_dhcp_client *client, uint64_t max_attempts) {
529 assert_return(client, -EINVAL);
530 assert_return(!sd_dhcp_client_is_running(client), -EBUSY);
531
532 client->max_attempts = max_attempts;
533
534 return 0;
535 }
536
537 int sd_dhcp_client_add_option(sd_dhcp_client *client, sd_dhcp_option *v) {
538 int r;
539
540 assert_return(client, -EINVAL);
541 assert_return(!sd_dhcp_client_is_running(client), -EBUSY);
542 assert_return(v, -EINVAL);
543
544 r = ordered_hashmap_ensure_put(&client->extra_options, &dhcp_option_hash_ops, UINT_TO_PTR(v->option), v);
545 if (r < 0)
546 return r;
547
548 sd_dhcp_option_ref(v);
549 return 0;
550 }
551
552 int sd_dhcp_client_add_vendor_option(sd_dhcp_client *client, sd_dhcp_option *v) {
553 int r;
554
555 assert_return(client, -EINVAL);
556 assert_return(!sd_dhcp_client_is_running(client), -EBUSY);
557 assert_return(v, -EINVAL);
558
559 r = ordered_hashmap_ensure_allocated(&client->vendor_options, &dhcp_option_hash_ops);
560 if (r < 0)
561 return -ENOMEM;
562
563 r = ordered_hashmap_put(client->vendor_options, v, v);
564 if (r < 0)
565 return r;
566
567 sd_dhcp_option_ref(v);
568
569 return 1;
570 }
571
572 int sd_dhcp_client_get_lease(sd_dhcp_client *client, sd_dhcp_lease **ret) {
573 assert_return(client, -EINVAL);
574
575 if (!client->lease)
576 return -EADDRNOTAVAIL;
577
578 if (ret)
579 *ret = client->lease;
580
581 return 0;
582 }
583
584 int sd_dhcp_client_set_service_type(sd_dhcp_client *client, int type) {
585 assert_return(client, -EINVAL);
586 assert_return(!sd_dhcp_client_is_running(client), -EBUSY);
587
588 client->ip_service_type = type;
589
590 return 0;
591 }
592
593 int sd_dhcp_client_set_socket_priority(sd_dhcp_client *client, int socket_priority) {
594 assert_return(client, -EINVAL);
595 assert_return(!sd_dhcp_client_is_running(client), -EBUSY);
596
597 client->socket_priority_set = true;
598 client->socket_priority = socket_priority;
599
600 return 0;
601 }
602
603 int sd_dhcp_client_set_fallback_lease_lifetime(sd_dhcp_client *client, uint64_t fallback_lease_lifetime) {
604 assert_return(client, -EINVAL);
605 assert_return(!sd_dhcp_client_is_running(client), -EBUSY);
606 assert_return(fallback_lease_lifetime > 0, -EINVAL);
607
608 assert_cc(sizeof(usec_t) == sizeof(uint64_t));
609 client->fallback_lease_lifetime = fallback_lease_lifetime;
610
611 return 0;
612 }
613
614 static void client_set_state(sd_dhcp_client *client, DHCPState state) {
615 assert(client);
616
617 if (client->state == state)
618 return;
619
620 log_dhcp_client(client, "State changed: %s -> %s",
621 dhcp_state_to_string(client->state), dhcp_state_to_string(state));
622
623 client->state = state;
624
625 if (client->state_callback)
626 client->state_callback(client, state, client->state_userdata);
627 }
628
629 int dhcp_client_get_state(sd_dhcp_client *client) {
630 assert_return(client, -EINVAL);
631
632 return client->state;
633 }
634
635 static int client_notify(sd_dhcp_client *client, int event) {
636 assert(client);
637
638 if (client->callback)
639 return client->callback(client, event, client->userdata);
640
641 return 0;
642 }
643
644 static int client_initialize(sd_dhcp_client *client) {
645 assert_return(client, -EINVAL);
646
647 client->receive_message = sd_event_source_disable_unref(client->receive_message);
648
649 client->fd = safe_close(client->fd);
650
651 (void) event_source_disable(client->timeout_resend);
652 (void) event_source_disable(client->timeout_t1);
653 (void) event_source_disable(client->timeout_t2);
654 (void) event_source_disable(client->timeout_expire);
655 (void) event_source_disable(client->timeout_ipv6_only_mode);
656
657 client->attempt = 0;
658
659 client_set_state(client, DHCP_STATE_STOPPED);
660 client->xid = 0;
661
662 client->lease = sd_dhcp_lease_unref(client->lease);
663
664 return 0;
665 }
666
667 static void client_stop(sd_dhcp_client *client, int error) {
668 assert(client);
669
670 if (error < 0)
671 log_dhcp_client_errno(client, error, "STOPPED: %m");
672 else if (error == SD_DHCP_CLIENT_EVENT_STOP)
673 log_dhcp_client(client, "STOPPED");
674 else
675 log_dhcp_client(client, "STOPPED: Unknown event");
676
677 client_notify(client, error);
678
679 client_initialize(client);
680 }
681
682 /* RFC2131 section 4.1:
683 * retransmission delays should include -1 to +1 sec of random 'fuzz'. */
684 #define RFC2131_RANDOM_FUZZ \
685 ((int64_t)(random_u64() % (2 * USEC_PER_SEC)) - (int64_t)USEC_PER_SEC)
686
687 /* RFC2131 section 4.1:
688 * for retransmission delays, timeout should start at 4s then double
689 * each attempt with max of 64s, with -1 to +1 sec of random 'fuzz' added.
690 * This assumes the first call will be using attempt 1. */
691 static usec_t client_compute_request_timeout(usec_t now, uint64_t attempt) {
692 usec_t timeout = (UINT64_C(1) << MIN(attempt + 1, UINT64_C(6))) * USEC_PER_SEC;
693
694 return usec_sub_signed(usec_add(now, timeout), RFC2131_RANDOM_FUZZ);
695 }
696
697 /* RFC2131 section 4.4.5:
698 * T1 defaults to (0.5 * duration_of_lease).
699 * T2 defaults to (0.875 * duration_of_lease). */
700 #define T1_DEFAULT(lifetime) ((lifetime) / 2)
701 #define T2_DEFAULT(lifetime) (((lifetime) * 7) / 8)
702
703 /* RFC2131 section 4.4.5:
704 * the client SHOULD wait one-half of the remaining time until T2 (in RENEWING state)
705 * and one-half of the remaining lease time (in REBINDING state), down to a minimum
706 * of 60 seconds.
707 * Note that while the default T1/T2 initial times do have random 'fuzz' applied,
708 * the RFC sec 4.4.5 does not mention adding any fuzz to retries. */
709 static usec_t client_compute_reacquisition_timeout(usec_t now, usec_t expire) {
710 return now + MAX(usec_sub_unsigned(expire, now) / 2, 60 * USEC_PER_SEC);
711 }
712
713 static int cmp_uint8(const uint8_t *a, const uint8_t *b) {
714 return CMP(*a, *b);
715 }
716
717 static int client_message_init(
718 sd_dhcp_client *client,
719 DHCPPacket **ret,
720 uint8_t type,
721 size_t *_optlen,
722 size_t *_optoffset) {
723
724 _cleanup_free_ DHCPPacket *packet = NULL;
725 size_t optlen, optoffset, size;
726 usec_t time_now;
727 uint16_t secs;
728 int r;
729
730 assert(client);
731 assert(client->start_time);
732 assert(ret);
733 assert(_optlen);
734 assert(_optoffset);
735 assert(IN_SET(type, DHCP_DISCOVER, DHCP_REQUEST, DHCP_RELEASE, DHCP_DECLINE));
736
737 optlen = DHCP_MIN_OPTIONS_SIZE;
738 size = sizeof(DHCPPacket) + optlen;
739
740 packet = malloc0(size);
741 if (!packet)
742 return -ENOMEM;
743
744 r = dhcp_message_init(&packet->dhcp, BOOTREQUEST, client->xid, type,
745 client->arp_type, client->hw_addr.length, client->hw_addr.bytes,
746 optlen, &optoffset);
747 if (r < 0)
748 return r;
749
750 /* Although 'secs' field is a SHOULD in RFC 2131, certain DHCP servers
751 refuse to issue an DHCP lease if 'secs' is set to zero */
752 r = sd_event_now(client->event, CLOCK_BOOTTIME, &time_now);
753 if (r < 0)
754 return r;
755 assert(time_now >= client->start_time);
756
757 /* seconds between sending first and last DISCOVER
758 * must always be strictly positive to deal with broken servers */
759 secs = ((time_now - client->start_time) / USEC_PER_SEC) ?: 1;
760 packet->dhcp.secs = htobe16(secs);
761
762 /* RFC2131 section 4.1
763 A client that cannot receive unicast IP datagrams until its protocol
764 software has been configured with an IP address SHOULD set the
765 BROADCAST bit in the 'flags' field to 1 in any DHCPDISCOVER or
766 DHCPREQUEST messages that client sends. The BROADCAST bit will
767 provide a hint to the DHCP server and BOOTP relay agent to broadcast
768 any messages to the client on the client's subnet.
769
770 Note: some interfaces needs this to be enabled, but some networks
771 needs this to be disabled as broadcasts are filteretd, so this
772 needs to be configurable */
773 if (client->request_broadcast || client->arp_type != ARPHRD_ETHER)
774 packet->dhcp.flags = htobe16(0x8000);
775
776 /* Some DHCP servers will refuse to issue an DHCP lease if the Client
777 Identifier option is not set */
778 r = dhcp_option_append(&packet->dhcp, optlen, &optoffset, 0,
779 SD_DHCP_OPTION_CLIENT_IDENTIFIER,
780 client->client_id.size,
781 client->client_id.raw);
782 if (r < 0)
783 return r;
784
785 /* RFC2131 section 3.5:
786 in its initial DHCPDISCOVER or DHCPREQUEST message, a
787 client may provide the server with a list of specific
788 parameters the client is interested in. If the client
789 includes a list of parameters in a DHCPDISCOVER message,
790 it MUST include that list in any subsequent DHCPREQUEST
791 messages.
792 */
793
794 /* RFC7844 section 3:
795 MAY contain the Parameter Request List option. */
796 /* NOTE: in case that there would be an option to do not send
797 * any PRL at all, the size should be checked before sending */
798 if (!set_isempty(client->req_opts) && type != DHCP_RELEASE) {
799 _cleanup_free_ uint8_t *opts = NULL;
800 size_t n_opts, i = 0;
801 void *val;
802
803 n_opts = set_size(client->req_opts);
804 opts = new(uint8_t, n_opts);
805 if (!opts)
806 return -ENOMEM;
807
808 SET_FOREACH(val, client->req_opts)
809 opts[i++] = PTR_TO_UINT8(val);
810 assert(i == n_opts);
811
812 /* For anonymizing the request, let's sort the options. */
813 typesafe_qsort(opts, n_opts, cmp_uint8);
814
815 r = dhcp_option_append(&packet->dhcp, optlen, &optoffset, 0,
816 SD_DHCP_OPTION_PARAMETER_REQUEST_LIST,
817 n_opts, opts);
818 if (r < 0)
819 return r;
820 }
821
822 /* RFC2131 section 3.5:
823 The client SHOULD include the ’maximum DHCP message size’ option to
824 let the server know how large the server may make its DHCP messages.
825
826 Note (from ConnMan): Some DHCP servers will send bigger DHCP packets
827 than the defined default size unless the Maximum Message Size option
828 is explicitly set
829
830 RFC3442 "Requirements to Avoid Sizing Constraints":
831 Because a full routing table can be quite large, the standard 576
832 octet maximum size for a DHCP message may be too short to contain
833 some legitimate Classless Static Route options. Because of this,
834 clients implementing the Classless Static Route option SHOULD send a
835 Maximum DHCP Message Size [4] option if the DHCP client's TCP/IP
836 stack is capable of receiving larger IP datagrams. In this case, the
837 client SHOULD set the value of this option to at least the MTU of the
838 interface that the client is configuring. The client MAY set the
839 value of this option higher, up to the size of the largest UDP packet
840 it is prepared to accept. (Note that the value specified in the
841 Maximum DHCP Message Size option is the total maximum packet size,
842 including IP and UDP headers.)
843 */
844 /* RFC7844 section 3:
845 SHOULD NOT contain any other option. */
846 if (!client->anonymize && IN_SET(type, DHCP_DISCOVER, DHCP_REQUEST)) {
847 be16_t max_size = htobe16(MIN(client->mtu - DHCP_IP_UDP_SIZE, (uint32_t) UINT16_MAX));
848 r = dhcp_option_append(&packet->dhcp, optlen, &optoffset, 0,
849 SD_DHCP_OPTION_MAXIMUM_MESSAGE_SIZE,
850 2, &max_size);
851 if (r < 0)
852 return r;
853 }
854
855 *_optlen = optlen;
856 *_optoffset = optoffset;
857 *ret = TAKE_PTR(packet);
858
859 return 0;
860 }
861
862 static int client_append_fqdn_option(
863 DHCPMessage *message,
864 size_t optlen,
865 size_t *optoffset,
866 const char *fqdn) {
867
868 uint8_t buffer[3 + DHCP_MAX_FQDN_LENGTH];
869 int r;
870
871 buffer[0] = DHCP_FQDN_FLAG_S | /* Request server to perform A RR DNS updates */
872 DHCP_FQDN_FLAG_E; /* Canonical wire format */
873 buffer[1] = 0; /* RCODE1 (deprecated) */
874 buffer[2] = 0; /* RCODE2 (deprecated) */
875
876 r = dns_name_to_wire_format(fqdn, buffer + 3, sizeof(buffer) - 3, false);
877 if (r > 0)
878 r = dhcp_option_append(message, optlen, optoffset, 0,
879 SD_DHCP_OPTION_FQDN, 3 + r, buffer);
880
881 return r;
882 }
883
884 static int dhcp_client_send_raw(
885 sd_dhcp_client *client,
886 DHCPPacket *packet,
887 size_t len) {
888
889 dhcp_packet_append_ip_headers(packet, INADDR_ANY, client->port,
890 INADDR_BROADCAST, DHCP_PORT_SERVER, len, client->ip_service_type);
891
892 return dhcp_network_send_raw_socket(client->fd, &client->link,
893 packet, len);
894 }
895
896 static int client_append_common_discover_request_options(sd_dhcp_client *client, DHCPPacket *packet, size_t *optoffset, size_t optlen) {
897 sd_dhcp_option *j;
898 int r;
899
900 assert(client);
901
902 if (client->hostname) {
903 /* According to RFC 4702 "clients that send the Client FQDN option in
904 their messages MUST NOT also send the Host Name option". Just send
905 one of the two depending on the hostname type.
906 */
907 if (dns_name_is_single_label(client->hostname)) {
908 /* it is unclear from RFC 2131 if client should send hostname in
909 DHCPDISCOVER but dhclient does and so we do as well
910 */
911 r = dhcp_option_append(&packet->dhcp, optlen, optoffset, 0,
912 SD_DHCP_OPTION_HOST_NAME,
913 strlen(client->hostname), client->hostname);
914 } else
915 r = client_append_fqdn_option(&packet->dhcp, optlen, optoffset,
916 client->hostname);
917 if (r < 0)
918 return r;
919 }
920
921 if (client->vendor_class_identifier) {
922 r = dhcp_option_append(&packet->dhcp, optlen, optoffset, 0,
923 SD_DHCP_OPTION_VENDOR_CLASS_IDENTIFIER,
924 strlen(client->vendor_class_identifier),
925 client->vendor_class_identifier);
926 if (r < 0)
927 return r;
928 }
929
930 if (client->mudurl) {
931 r = dhcp_option_append(&packet->dhcp, optlen, optoffset, 0,
932 SD_DHCP_OPTION_MUD_URL,
933 strlen(client->mudurl),
934 client->mudurl);
935 if (r < 0)
936 return r;
937 }
938
939 if (client->user_class) {
940 r = dhcp_option_append(&packet->dhcp, optlen, optoffset, 0,
941 SD_DHCP_OPTION_USER_CLASS,
942 strv_length(client->user_class),
943 client->user_class);
944 if (r < 0)
945 return r;
946 }
947
948 ORDERED_HASHMAP_FOREACH(j, client->extra_options) {
949 r = dhcp_option_append(&packet->dhcp, optlen, optoffset, 0,
950 j->option, j->length, j->data);
951 if (r < 0)
952 return r;
953 }
954
955 if (!ordered_hashmap_isempty(client->vendor_options)) {
956 r = dhcp_option_append(
957 &packet->dhcp, optlen, optoffset, 0,
958 SD_DHCP_OPTION_VENDOR_SPECIFIC,
959 ordered_hashmap_size(client->vendor_options), client->vendor_options);
960 if (r < 0)
961 return r;
962 }
963
964
965 return 0;
966 }
967
968 static int client_send_discover(sd_dhcp_client *client) {
969 _cleanup_free_ DHCPPacket *discover = NULL;
970 size_t optoffset, optlen;
971 int r;
972
973 assert(client);
974 assert(IN_SET(client->state, DHCP_STATE_INIT, DHCP_STATE_SELECTING));
975
976 r = client_message_init(client, &discover, DHCP_DISCOVER,
977 &optlen, &optoffset);
978 if (r < 0)
979 return r;
980
981 /* the client may suggest values for the network address
982 and lease time in the DHCPDISCOVER message. The client may include
983 the ’requested IP address’ option to suggest that a particular IP
984 address be assigned, and may include the ’IP address lease time’
985 option to suggest the lease time it would like.
986 */
987 /* RFC7844 section 3:
988 SHOULD NOT contain any other option. */
989 if (!client->anonymize && client->last_addr != INADDR_ANY) {
990 r = dhcp_option_append(&discover->dhcp, optlen, &optoffset, 0,
991 SD_DHCP_OPTION_REQUESTED_IP_ADDRESS,
992 4, &client->last_addr);
993 if (r < 0)
994 return r;
995 }
996
997 if (client->rapid_commit) {
998 r = dhcp_option_append(&discover->dhcp, optlen, &optoffset, 0,
999 SD_DHCP_OPTION_RAPID_COMMIT, 0, NULL);
1000 if (r < 0)
1001 return r;
1002 }
1003
1004 r = client_append_common_discover_request_options(client, discover, &optoffset, optlen);
1005 if (r < 0)
1006 return r;
1007
1008 r = dhcp_option_append(&discover->dhcp, optlen, &optoffset, 0,
1009 SD_DHCP_OPTION_END, 0, NULL);
1010 if (r < 0)
1011 return r;
1012
1013 /* We currently ignore:
1014 The client SHOULD wait a random time between one and ten seconds to
1015 desynchronize the use of DHCP at startup.
1016 */
1017 r = dhcp_client_send_raw(client, discover, sizeof(DHCPPacket) + optoffset);
1018 if (r < 0)
1019 return r;
1020
1021 log_dhcp_client(client, "DISCOVER");
1022
1023 return 0;
1024 }
1025
1026 static int client_send_request(sd_dhcp_client *client) {
1027 _cleanup_free_ DHCPPacket *request = NULL;
1028 size_t optoffset, optlen;
1029 int r;
1030
1031 assert(client);
1032
1033 r = client_message_init(client, &request, DHCP_REQUEST, &optlen, &optoffset);
1034 if (r < 0)
1035 return r;
1036
1037 switch (client->state) {
1038 /* See RFC2131 section 4.3.2 (note that there is a typo in the RFC,
1039 SELECTING should be REQUESTING)
1040 */
1041
1042 case DHCP_STATE_REQUESTING:
1043 /* Client inserts the address of the selected server in ’server
1044 identifier’, ’ciaddr’ MUST be zero, ’requested IP address’ MUST be
1045 filled in with the yiaddr value from the chosen DHCPOFFER.
1046 */
1047
1048 r = dhcp_option_append(&request->dhcp, optlen, &optoffset, 0,
1049 SD_DHCP_OPTION_SERVER_IDENTIFIER,
1050 4, &client->lease->server_address);
1051 if (r < 0)
1052 return r;
1053
1054 r = dhcp_option_append(&request->dhcp, optlen, &optoffset, 0,
1055 SD_DHCP_OPTION_REQUESTED_IP_ADDRESS,
1056 4, &client->lease->address);
1057 if (r < 0)
1058 return r;
1059
1060 break;
1061
1062 case DHCP_STATE_INIT_REBOOT:
1063 /* ’server identifier’ MUST NOT be filled in, ’requested IP address’
1064 option MUST be filled in with client’s notion of its previously
1065 assigned address. ’ciaddr’ MUST be zero.
1066 */
1067 r = dhcp_option_append(&request->dhcp, optlen, &optoffset, 0,
1068 SD_DHCP_OPTION_REQUESTED_IP_ADDRESS,
1069 4, &client->last_addr);
1070 if (r < 0)
1071 return r;
1072 break;
1073
1074 case DHCP_STATE_RENEWING:
1075 /* ’server identifier’ MUST NOT be filled in, ’requested IP address’
1076 option MUST NOT be filled in, ’ciaddr’ MUST be filled in with
1077 client’s IP address.
1078 */
1079
1080 case DHCP_STATE_REBINDING:
1081 /* ’server identifier’ MUST NOT be filled in, ’requested IP address’
1082 option MUST NOT be filled in, ’ciaddr’ MUST be filled in with
1083 client’s IP address.
1084
1085 This message MUST be broadcast to the 0xffffffff IP broadcast address.
1086 */
1087 request->dhcp.ciaddr = client->lease->address;
1088
1089 break;
1090
1091 case DHCP_STATE_INIT:
1092 case DHCP_STATE_SELECTING:
1093 case DHCP_STATE_REBOOTING:
1094 case DHCP_STATE_BOUND:
1095 case DHCP_STATE_STOPPED:
1096 default:
1097 return -EINVAL;
1098 }
1099
1100 r = client_append_common_discover_request_options(client, request, &optoffset, optlen);
1101 if (r < 0)
1102 return r;
1103
1104 r = dhcp_option_append(&request->dhcp, optlen, &optoffset, 0,
1105 SD_DHCP_OPTION_END, 0, NULL);
1106 if (r < 0)
1107 return r;
1108
1109 if (client->state == DHCP_STATE_RENEWING)
1110 r = dhcp_network_send_udp_socket(client->fd,
1111 client->lease->server_address,
1112 DHCP_PORT_SERVER,
1113 &request->dhcp,
1114 sizeof(DHCPMessage) + optoffset);
1115 else
1116 r = dhcp_client_send_raw(client, request, sizeof(DHCPPacket) + optoffset);
1117 if (r < 0)
1118 return r;
1119
1120 switch (client->state) {
1121
1122 case DHCP_STATE_REQUESTING:
1123 log_dhcp_client(client, "REQUEST (requesting)");
1124 break;
1125
1126 case DHCP_STATE_INIT_REBOOT:
1127 log_dhcp_client(client, "REQUEST (init-reboot)");
1128 break;
1129
1130 case DHCP_STATE_RENEWING:
1131 log_dhcp_client(client, "REQUEST (renewing)");
1132 break;
1133
1134 case DHCP_STATE_REBINDING:
1135 log_dhcp_client(client, "REQUEST (rebinding)");
1136 break;
1137
1138 default:
1139 log_dhcp_client(client, "REQUEST (invalid)");
1140 break;
1141 }
1142
1143 return 0;
1144 }
1145
1146 static int client_start(sd_dhcp_client *client);
1147
1148 static int client_timeout_resend(
1149 sd_event_source *s,
1150 uint64_t usec,
1151 void *userdata) {
1152
1153 sd_dhcp_client *client = ASSERT_PTR(userdata);
1154 DHCP_CLIENT_DONT_DESTROY(client);
1155 usec_t time_now, next_timeout;
1156 int r;
1157
1158 assert(s);
1159 assert(client->event);
1160
1161 r = sd_event_now(client->event, CLOCK_BOOTTIME, &time_now);
1162 if (r < 0)
1163 goto error;
1164
1165 switch (client->state) {
1166
1167 case DHCP_STATE_RENEWING:
1168 next_timeout = client_compute_reacquisition_timeout(time_now, client->t2_time);
1169 break;
1170
1171 case DHCP_STATE_REBINDING:
1172 next_timeout = client_compute_reacquisition_timeout(time_now, client->expire_time);
1173 break;
1174
1175 case DHCP_STATE_REBOOTING:
1176 /* start over as we did not receive a timely ack or nak */
1177 r = client_initialize(client);
1178 if (r < 0)
1179 goto error;
1180
1181 r = client_start(client);
1182 if (r < 0)
1183 goto error;
1184
1185 log_dhcp_client(client, "REBOOTED");
1186 return 0;
1187
1188 case DHCP_STATE_INIT:
1189 case DHCP_STATE_INIT_REBOOT:
1190 case DHCP_STATE_SELECTING:
1191 case DHCP_STATE_REQUESTING:
1192 case DHCP_STATE_BOUND:
1193 if (client->attempt >= client->max_attempts)
1194 goto error;
1195
1196 client->attempt++;
1197 next_timeout = client_compute_request_timeout(time_now, client->attempt);
1198 break;
1199
1200 case DHCP_STATE_STOPPED:
1201 r = -EINVAL;
1202 goto error;
1203
1204 default:
1205 assert_not_reached();
1206 }
1207
1208 r = event_reset_time(client->event, &client->timeout_resend,
1209 CLOCK_BOOTTIME,
1210 next_timeout, 10 * USEC_PER_MSEC,
1211 client_timeout_resend, client,
1212 client->event_priority, "dhcp4-resend-timer", true);
1213 if (r < 0)
1214 goto error;
1215
1216 switch (client->state) {
1217 case DHCP_STATE_INIT:
1218 r = client_send_discover(client);
1219 if (r >= 0) {
1220 client_set_state(client, DHCP_STATE_SELECTING);
1221 client->attempt = 0;
1222 } else if (client->attempt >= client->max_attempts)
1223 goto error;
1224 break;
1225
1226 case DHCP_STATE_SELECTING:
1227 r = client_send_discover(client);
1228 if (r < 0 && client->attempt >= client->max_attempts)
1229 goto error;
1230 break;
1231
1232 case DHCP_STATE_INIT_REBOOT:
1233 case DHCP_STATE_REQUESTING:
1234 case DHCP_STATE_RENEWING:
1235 case DHCP_STATE_REBINDING:
1236 r = client_send_request(client);
1237 if (r < 0 && client->attempt >= client->max_attempts)
1238 goto error;
1239
1240 if (client->state == DHCP_STATE_INIT_REBOOT)
1241 client_set_state(client, DHCP_STATE_REBOOTING);
1242 break;
1243
1244 case DHCP_STATE_REBOOTING:
1245 case DHCP_STATE_BOUND:
1246 break;
1247
1248 case DHCP_STATE_STOPPED:
1249 default:
1250 r = -EINVAL;
1251 goto error;
1252 }
1253
1254 if (client->attempt >= TRANSIENT_FAILURE_ATTEMPTS)
1255 client_notify(client, SD_DHCP_CLIENT_EVENT_TRANSIENT_FAILURE);
1256
1257 return 0;
1258
1259 error:
1260 client_stop(client, r);
1261
1262 /* Errors were dealt with when stopping the client, don't spill
1263 errors into the event loop handler */
1264 return 0;
1265 }
1266
1267 static int client_initialize_io_events(
1268 sd_dhcp_client *client,
1269 sd_event_io_handler_t io_callback) {
1270
1271 int r;
1272
1273 assert(client);
1274 assert(client->event);
1275
1276 r = sd_event_add_io(client->event, &client->receive_message,
1277 client->fd, EPOLLIN, io_callback,
1278 client);
1279 if (r < 0)
1280 goto error;
1281
1282 r = sd_event_source_set_priority(client->receive_message,
1283 client->event_priority);
1284 if (r < 0)
1285 goto error;
1286
1287 r = sd_event_source_set_description(client->receive_message, "dhcp4-receive-message");
1288 if (r < 0)
1289 goto error;
1290
1291 error:
1292 if (r < 0)
1293 client_stop(client, r);
1294
1295 return 0;
1296 }
1297
1298 static int client_initialize_time_events(sd_dhcp_client *client) {
1299 usec_t usec = 0;
1300 int r;
1301
1302 assert(client);
1303 assert(client->event);
1304
1305 (void) event_source_disable(client->timeout_ipv6_only_mode);
1306
1307 if (client->start_delay > 0) {
1308 assert_se(sd_event_now(client->event, CLOCK_BOOTTIME, &usec) >= 0);
1309 usec = usec_add(usec, client->start_delay);
1310 }
1311
1312 r = event_reset_time(client->event, &client->timeout_resend,
1313 CLOCK_BOOTTIME,
1314 usec, 0,
1315 client_timeout_resend, client,
1316 client->event_priority, "dhcp4-resend-timer", true);
1317 if (r < 0)
1318 client_stop(client, r);
1319
1320 return 0;
1321
1322 }
1323
1324 static int client_initialize_events(sd_dhcp_client *client, sd_event_io_handler_t io_callback) {
1325 client_initialize_io_events(client, io_callback);
1326 client_initialize_time_events(client);
1327
1328 return 0;
1329 }
1330
1331 static int client_start_delayed(sd_dhcp_client *client) {
1332 int r;
1333
1334 assert_return(client, -EINVAL);
1335 assert_return(client->event, -EINVAL);
1336 assert_return(client->ifindex > 0, -EINVAL);
1337 assert_return(client->fd < 0, -EBUSY);
1338 assert_return(client->xid == 0, -EINVAL);
1339 assert_return(IN_SET(client->state, DHCP_STATE_STOPPED, DHCP_STATE_INIT_REBOOT), -EBUSY);
1340
1341 client->xid = random_u32();
1342
1343 r = dhcp_network_bind_raw_socket(client->ifindex, &client->link, client->xid,
1344 &client->hw_addr, &client->bcast_addr,
1345 client->arp_type, client->port,
1346 client->socket_priority_set, client->socket_priority);
1347 if (r < 0) {
1348 client_stop(client, r);
1349 return r;
1350 }
1351 client->fd = r;
1352
1353 client->start_time = now(CLOCK_BOOTTIME);
1354
1355 if (client->state == DHCP_STATE_STOPPED)
1356 client->state = DHCP_STATE_INIT;
1357
1358 return client_initialize_events(client, client_receive_message_raw);
1359 }
1360
1361 static int client_start(sd_dhcp_client *client) {
1362 client->start_delay = 0;
1363 return client_start_delayed(client);
1364 }
1365
1366 static int client_timeout_expire(sd_event_source *s, uint64_t usec, void *userdata) {
1367 sd_dhcp_client *client = userdata;
1368 DHCP_CLIENT_DONT_DESTROY(client);
1369
1370 log_dhcp_client(client, "EXPIRED");
1371
1372 client_notify(client, SD_DHCP_CLIENT_EVENT_EXPIRED);
1373
1374 /* lease was lost, start over if not freed or stopped in callback */
1375 if (client->state != DHCP_STATE_STOPPED) {
1376 client_initialize(client);
1377 client_start(client);
1378 }
1379
1380 return 0;
1381 }
1382
1383 static int client_timeout_t2(sd_event_source *s, uint64_t usec, void *userdata) {
1384 sd_dhcp_client *client = ASSERT_PTR(userdata);
1385 DHCP_CLIENT_DONT_DESTROY(client);
1386 int r;
1387
1388 client->receive_message = sd_event_source_disable_unref(client->receive_message);
1389 client->fd = safe_close(client->fd);
1390
1391 client_set_state(client, DHCP_STATE_REBINDING);
1392 client->attempt = 0;
1393
1394 r = dhcp_network_bind_raw_socket(client->ifindex, &client->link, client->xid,
1395 &client->hw_addr, &client->bcast_addr,
1396 client->arp_type, client->port,
1397 client->socket_priority_set, client->socket_priority);
1398 if (r < 0) {
1399 client_stop(client, r);
1400 return 0;
1401 }
1402 client->fd = r;
1403
1404 return client_initialize_events(client, client_receive_message_raw);
1405 }
1406
1407 static int client_timeout_t1(sd_event_source *s, uint64_t usec, void *userdata) {
1408 sd_dhcp_client *client = userdata;
1409 DHCP_CLIENT_DONT_DESTROY(client);
1410
1411 if (client->lease)
1412 client_set_state(client, DHCP_STATE_RENEWING);
1413 else if (client->state != DHCP_STATE_INIT)
1414 client_set_state(client, DHCP_STATE_INIT_REBOOT);
1415 client->attempt = 0;
1416
1417 return client_initialize_time_events(client);
1418 }
1419
1420 static int client_parse_message(
1421 sd_dhcp_client *client,
1422 DHCPMessage *message,
1423 size_t len,
1424 sd_dhcp_lease **ret) {
1425
1426 _cleanup_(sd_dhcp_lease_unrefp) sd_dhcp_lease *lease = NULL;
1427 _cleanup_free_ char *error_message = NULL;
1428 int r;
1429
1430 assert(client);
1431 assert(message);
1432 assert(ret);
1433
1434 r = dhcp_lease_new(&lease);
1435 if (r < 0)
1436 return r;
1437
1438 if (sd_dhcp_client_id_is_set(&client->client_id)) {
1439 r = dhcp_lease_set_client_id(lease, &client->client_id);
1440 if (r < 0)
1441 return r;
1442 }
1443
1444 r = dhcp_option_parse(message, len, dhcp_lease_parse_options, lease, &error_message);
1445 if (r < 0)
1446 return log_dhcp_client_errno(client, r, "Failed to parse DHCP options, ignoring: %m");
1447
1448 switch (client->state) {
1449 case DHCP_STATE_SELECTING:
1450 if (r == DHCP_ACK) {
1451 if (!client->rapid_commit)
1452 return log_dhcp_client_errno(client, SYNTHETIC_ERRNO(ENOMSG),
1453 "received unexpected ACK, ignoring.");
1454 if (!lease->rapid_commit)
1455 return log_dhcp_client_errno(client, SYNTHETIC_ERRNO(ENOMSG),
1456 "received rapid ACK without Rapid Commit option, ignoring.");
1457 } else if (r == DHCP_OFFER) {
1458 if (lease->rapid_commit) {
1459 /* Some RFC incompliant servers provides an OFFER with a rapid commit option.
1460 * See https://github.com/systemd/systemd/issues/29904.
1461 * Let's support such servers gracefully. */
1462 log_dhcp_client(client, "received OFFER with Rapid Commit option, ignoring.");
1463 lease->rapid_commit = false;
1464 }
1465 if (lease->lifetime == 0 && client->fallback_lease_lifetime > 0)
1466 lease->lifetime = client->fallback_lease_lifetime;
1467 } else
1468 return log_dhcp_client_errno(client, SYNTHETIC_ERRNO(ENOMSG),
1469 "received unexpected message, ignoring.");
1470
1471 break;
1472
1473 case DHCP_STATE_REBOOTING:
1474 case DHCP_STATE_REQUESTING:
1475 case DHCP_STATE_RENEWING:
1476 case DHCP_STATE_REBINDING:
1477 if (r == DHCP_NAK) {
1478 if (client->lease && client->lease->server_address != lease->server_address)
1479 return log_dhcp_client_errno(client, SYNTHETIC_ERRNO(ENOMSG),
1480 "NAK from unexpected server, ignoring: %s",
1481 strna(error_message));
1482 return log_dhcp_client_errno(client, SYNTHETIC_ERRNO(EADDRNOTAVAIL),
1483 "NAK: %s", strna(error_message));
1484 }
1485 if (r != DHCP_ACK)
1486 return log_dhcp_client_errno(client, SYNTHETIC_ERRNO(ENOMSG),
1487 "received message was not an ACK, ignoring.");
1488 break;
1489
1490 default:
1491 assert_not_reached();
1492 }
1493
1494 lease->next_server = message->siaddr;
1495 lease->address = message->yiaddr;
1496
1497 if (lease->address == 0 ||
1498 lease->server_address == 0 ||
1499 lease->lifetime == 0)
1500 return log_dhcp_client_errno(client, SYNTHETIC_ERRNO(ENOMSG),
1501 "received lease lacks address, server address or lease lifetime, ignoring.");
1502
1503 r = dhcp_lease_set_default_subnet_mask(lease);
1504 if (r < 0)
1505 return log_dhcp_client_errno(client, SYNTHETIC_ERRNO(ENOMSG),
1506 "received lease lacks subnet mask, and a fallback one cannot be generated, ignoring.");
1507
1508 /* RFC 8925 section 3.2
1509 * If the client did not include the IPv6-Only Preferred option code in the Parameter Request List in
1510 * the DHCPDISCOVER or DHCPREQUEST message, it MUST ignore the IPv6-Only Preferred option in any
1511 * messages received from the server. */
1512 if (lease->ipv6_only_preferred_usec > 0 &&
1513 !client_request_contains(client, SD_DHCP_OPTION_IPV6_ONLY_PREFERRED)) {
1514 log_dhcp_client(client, "Received message with unrequested IPv6-only preferred option, ignoring the option.");
1515 lease->ipv6_only_preferred_usec = 0;
1516 }
1517
1518 *ret = TAKE_PTR(lease);
1519 return 0;
1520 }
1521
1522 static int client_handle_offer_or_rapid_ack(sd_dhcp_client *client, DHCPMessage *message, size_t len, const triple_timestamp *timestamp) {
1523 _cleanup_(sd_dhcp_lease_unrefp) sd_dhcp_lease *lease = NULL;
1524 int r;
1525
1526 assert(client);
1527 assert(message);
1528
1529 r = client_parse_message(client, message, len, &lease);
1530 if (r < 0)
1531 return r;
1532
1533 dhcp_lease_set_timestamp(lease, timestamp);
1534
1535 dhcp_lease_unref_and_replace(client->lease, lease);
1536
1537 if (client->lease->rapid_commit) {
1538 log_dhcp_client(client, "ACK");
1539 return SD_DHCP_CLIENT_EVENT_IP_ACQUIRE;
1540 }
1541
1542 if (client_notify(client, SD_DHCP_CLIENT_EVENT_SELECTING) < 0)
1543 return -ENOMSG;
1544
1545 log_dhcp_client(client, "OFFER");
1546 return 0;
1547 }
1548
1549 static int client_enter_requesting_now(sd_dhcp_client *client) {
1550 assert(client);
1551
1552 client_set_state(client, DHCP_STATE_REQUESTING);
1553 client->attempt = 0;
1554
1555 return event_reset_time(client->event, &client->timeout_resend,
1556 CLOCK_BOOTTIME, 0, 0,
1557 client_timeout_resend, client,
1558 client->event_priority, "dhcp4-resend-timer",
1559 /* force_reset = */ true);
1560 }
1561
1562 static int client_enter_requesting_delayed(sd_event_source *s, uint64_t usec, void *userdata) {
1563 sd_dhcp_client *client = ASSERT_PTR(userdata);
1564 DHCP_CLIENT_DONT_DESTROY(client);
1565 int r;
1566
1567 r = client_enter_requesting_now(client);
1568 if (r < 0)
1569 client_stop(client, r);
1570
1571 return 0;
1572 }
1573
1574 static int client_enter_requesting(sd_dhcp_client *client) {
1575 assert(client);
1576 assert(client->lease);
1577
1578 (void) event_source_disable(client->timeout_resend);
1579
1580 if (client->lease->ipv6_only_preferred_usec > 0) {
1581 if (client->ipv6_acquired) {
1582 log_dhcp_client(client,
1583 "Received an OFFER with IPv6-only preferred option, and the host already acquired IPv6 connectivity, stopping DHCPv4 client.");
1584 return sd_dhcp_client_stop(client);
1585 }
1586
1587 log_dhcp_client(client,
1588 "Received an OFFER with IPv6-only preferred option, delaying to send REQUEST with %s.",
1589 FORMAT_TIMESPAN(client->lease->ipv6_only_preferred_usec, USEC_PER_SEC));
1590
1591 return event_reset_time_relative(client->event, &client->timeout_ipv6_only_mode,
1592 CLOCK_BOOTTIME,
1593 client->lease->ipv6_only_preferred_usec, 0,
1594 client_enter_requesting_delayed, client,
1595 client->event_priority, "dhcp4-ipv6-only-mode-timer",
1596 /* force_reset = */ true);
1597 }
1598
1599 return client_enter_requesting_now(client);
1600 }
1601
1602 static int client_handle_forcerenew(sd_dhcp_client *client, DHCPMessage *force, size_t len) {
1603 int r;
1604
1605 r = dhcp_option_parse(force, len, NULL, NULL, NULL);
1606 if (r != DHCP_FORCERENEW)
1607 return -ENOMSG;
1608
1609 #if 0
1610 log_dhcp_client(client, "FORCERENEW");
1611 return 0;
1612 #else
1613 /* FIXME: Ignore FORCERENEW requests until we implement RFC3118 (Authentication for DHCP
1614 * Messages) and/or RFC6704 (Forcerenew Nonce Authentication), as unauthenticated FORCERENEW
1615 * requests causes a security issue (TALOS-2020-1142, CVE-2020-13529). */
1616 return log_dhcp_client_errno(client, SYNTHETIC_ERRNO(ENOMSG),
1617 "Received FORCERENEW, ignoring.");
1618 #endif
1619 }
1620
1621 static bool lease_equal(const sd_dhcp_lease *a, const sd_dhcp_lease *b) {
1622 if (a->address != b->address)
1623 return false;
1624
1625 if (a->subnet_mask != b->subnet_mask)
1626 return false;
1627
1628 if (a->router_size != b->router_size)
1629 return false;
1630
1631 for (size_t i = 0; i < a->router_size; i++)
1632 if (a->router[i].s_addr != b->router[i].s_addr)
1633 return false;
1634
1635 return true;
1636 }
1637
1638 static int client_handle_ack(sd_dhcp_client *client, DHCPMessage *message, size_t len, const triple_timestamp *timestamp) {
1639 _cleanup_(sd_dhcp_lease_unrefp) sd_dhcp_lease *lease = NULL;
1640 int r;
1641
1642 assert(client);
1643 assert(message);
1644
1645 r = client_parse_message(client, message, len, &lease);
1646 if (r < 0)
1647 return r;
1648
1649 dhcp_lease_set_timestamp(lease, timestamp);
1650
1651 if (!client->lease)
1652 r = SD_DHCP_CLIENT_EVENT_IP_ACQUIRE;
1653 else if (lease_equal(client->lease, lease))
1654 r = SD_DHCP_CLIENT_EVENT_RENEW;
1655 else
1656 r = SD_DHCP_CLIENT_EVENT_IP_CHANGE;
1657
1658 dhcp_lease_unref_and_replace(client->lease, lease);
1659
1660 log_dhcp_client(client, "ACK");
1661 return r;
1662 }
1663
1664 static int client_set_lease_timeouts(sd_dhcp_client *client) {
1665 usec_t time_now;
1666 int r;
1667
1668 assert(client);
1669 assert(client->event);
1670 assert(client->lease);
1671 assert(client->lease->lifetime > 0);
1672 assert(triple_timestamp_is_set(&client->lease->timestamp));
1673
1674 /* don't set timers for infinite leases */
1675 if (client->lease->lifetime == USEC_INFINITY) {
1676 (void) event_source_disable(client->timeout_t1);
1677 (void) event_source_disable(client->timeout_t2);
1678 (void) event_source_disable(client->timeout_expire);
1679
1680 return 0;
1681 }
1682
1683 r = sd_event_now(client->event, CLOCK_BOOTTIME, &time_now);
1684 if (r < 0)
1685 return r;
1686
1687 /* verify that 0 < t2 < lifetime */
1688 if (client->lease->t2 == 0 || client->lease->t2 >= client->lease->lifetime)
1689 client->lease->t2 = T2_DEFAULT(client->lease->lifetime);
1690 /* verify that 0 < t1 < lifetime */
1691 if (client->lease->t1 == 0 || client->lease->t1 >= client->lease->t2)
1692 client->lease->t1 = T1_DEFAULT(client->lease->lifetime);
1693 /* now, if t1 >= t2, t1 *must* be T1_DEFAULT, since the previous check
1694 * could not evaluate to false if t1 >= t2; so setting t2 to T2_DEFAULT
1695 * guarantees t1 < t2. */
1696 if (client->lease->t1 >= client->lease->t2)
1697 client->lease->t2 = T2_DEFAULT(client->lease->lifetime);
1698
1699 assert(client->lease->t1 > 0);
1700 assert(client->lease->t1 < client->lease->t2);
1701 assert(client->lease->t2 < client->lease->lifetime);
1702
1703 r = sd_dhcp_lease_get_lifetime_timestamp(client->lease, CLOCK_BOOTTIME, &client->expire_time);
1704 if (r < 0)
1705 return r;
1706 r = sd_dhcp_lease_get_t1_timestamp(client->lease, CLOCK_BOOTTIME, &client->t1_time);
1707 if (r < 0)
1708 return r;
1709 r = sd_dhcp_lease_get_t2_timestamp(client->lease, CLOCK_BOOTTIME, &client->t2_time);
1710 if (r < 0)
1711 return r;
1712
1713 /* RFC2131 section 4.4.5:
1714 * Times T1 and T2 SHOULD be chosen with some random "fuzz".
1715 * Since the RFC doesn't specify here the exact 'fuzz' to use,
1716 * we use the range from section 4.1: -1 to +1 sec. */
1717 client->t1_time = usec_sub_signed(client->t1_time, RFC2131_RANDOM_FUZZ);
1718 client->t2_time = usec_sub_signed(client->t2_time, RFC2131_RANDOM_FUZZ);
1719
1720 /* after fuzzing, ensure t2 is still >= t1 */
1721 client->t2_time = MAX(client->t1_time, client->t2_time);
1722
1723 /* arm lifetime timeout */
1724 r = event_reset_time(client->event, &client->timeout_expire,
1725 CLOCK_BOOTTIME,
1726 client->expire_time, 10 * USEC_PER_MSEC,
1727 client_timeout_expire, client,
1728 client->event_priority, "dhcp4-lifetime", true);
1729 if (r < 0)
1730 return r;
1731
1732 /* don't arm earlier timeouts if this has already expired */
1733 if (client->expire_time <= time_now)
1734 return 0;
1735
1736 log_dhcp_client(client, "lease expires in %s",
1737 FORMAT_TIMESPAN(client->expire_time - time_now, USEC_PER_SEC));
1738
1739 /* arm T2 timeout */
1740 r = event_reset_time(client->event, &client->timeout_t2,
1741 CLOCK_BOOTTIME,
1742 client->t2_time, 10 * USEC_PER_MSEC,
1743 client_timeout_t2, client,
1744 client->event_priority, "dhcp4-t2-timeout", true);
1745 if (r < 0)
1746 return r;
1747
1748 /* don't arm earlier timeout if this has already expired */
1749 if (client->t2_time <= time_now)
1750 return 0;
1751
1752 log_dhcp_client(client, "T2 expires in %s",
1753 FORMAT_TIMESPAN(client->t2_time - time_now, USEC_PER_SEC));
1754
1755 /* arm T1 timeout */
1756 r = event_reset_time(client->event, &client->timeout_t1,
1757 CLOCK_BOOTTIME,
1758 client->t1_time, 10 * USEC_PER_MSEC,
1759 client_timeout_t1, client,
1760 client->event_priority, "dhcp4-t1-timer", true);
1761 if (r < 0)
1762 return r;
1763
1764 if (client->t1_time > time_now)
1765 log_dhcp_client(client, "T1 expires in %s",
1766 FORMAT_TIMESPAN(client->t1_time - time_now, USEC_PER_SEC));
1767
1768 return 0;
1769 }
1770
1771 static int client_enter_bound_now(sd_dhcp_client *client, int notify_event) {
1772 int r;
1773
1774 assert(client);
1775
1776 if (IN_SET(client->state, DHCP_STATE_REQUESTING, DHCP_STATE_REBOOTING))
1777 notify_event = SD_DHCP_CLIENT_EVENT_IP_ACQUIRE;
1778
1779 client_set_state(client, DHCP_STATE_BOUND);
1780 client->attempt = 0;
1781
1782 client->last_addr = client->lease->address;
1783
1784 r = client_set_lease_timeouts(client);
1785 if (r < 0)
1786 log_dhcp_client_errno(client, r, "could not set lease timeouts: %m");
1787
1788 r = dhcp_network_bind_udp_socket(client->ifindex, client->lease->address, client->port, client->ip_service_type);
1789 if (r < 0)
1790 return log_dhcp_client_errno(client, r, "could not bind UDP socket: %m");
1791
1792 client->receive_message = sd_event_source_disable_unref(client->receive_message);
1793 close_and_replace(client->fd, r);
1794 client_initialize_io_events(client, client_receive_message_udp);
1795
1796 client_notify(client, notify_event);
1797
1798 return 0;
1799 }
1800
1801 static int client_enter_bound_delayed(sd_event_source *s, uint64_t usec, void *userdata) {
1802 sd_dhcp_client *client = ASSERT_PTR(userdata);
1803 DHCP_CLIENT_DONT_DESTROY(client);
1804 int r;
1805
1806 r = client_enter_bound_now(client, SD_DHCP_CLIENT_EVENT_IP_ACQUIRE);
1807 if (r < 0)
1808 client_stop(client, r);
1809
1810 return 0;
1811 }
1812
1813 static int client_enter_bound(sd_dhcp_client *client, int notify_event) {
1814 assert(client);
1815 assert(client->lease);
1816
1817 client->start_delay = 0;
1818 (void) event_source_disable(client->timeout_resend);
1819
1820 /* RFC 8925 section 3.2
1821 * If the client is in the INIT-REBOOT state, it SHOULD stop the DHCPv4 configuration process or
1822 * disable the IPv4 stack completely for V6ONLY_WAIT seconds or until the network attachment event,
1823 * whichever happens first.
1824 *
1825 * In the below, the condition uses REBOOTING, instead of INIT-REBOOT, as the client state has
1826 * already transitioned from INIT-REBOOT to REBOOTING after sending a DHCPREQUEST message. */
1827 if (client->state == DHCP_STATE_REBOOTING && client->lease->ipv6_only_preferred_usec > 0) {
1828 if (client->ipv6_acquired) {
1829 log_dhcp_client(client,
1830 "Received an ACK with IPv6-only preferred option, and the host already acquired IPv6 connectivity, stopping DHCPv4 client.");
1831 return sd_dhcp_client_stop(client);
1832 }
1833
1834 log_dhcp_client(client,
1835 "Received an ACK with IPv6-only preferred option, delaying to enter bound state with %s.",
1836 FORMAT_TIMESPAN(client->lease->ipv6_only_preferred_usec, USEC_PER_SEC));
1837
1838 return event_reset_time_relative(client->event, &client->timeout_ipv6_only_mode,
1839 CLOCK_BOOTTIME,
1840 client->lease->ipv6_only_preferred_usec, 0,
1841 client_enter_bound_delayed, client,
1842 client->event_priority, "dhcp4-ipv6-only-mode",
1843 /* force_reset = */ true);
1844 }
1845
1846 return client_enter_bound_now(client, notify_event);
1847 }
1848
1849 static int client_restart(sd_dhcp_client *client) {
1850 int r;
1851 assert(client);
1852
1853 client_notify(client, SD_DHCP_CLIENT_EVENT_EXPIRED);
1854
1855 r = client_initialize(client);
1856 if (r < 0)
1857 return r;
1858
1859 r = client_start_delayed(client);
1860 if (r < 0)
1861 return r;
1862
1863 log_dhcp_client(client, "REBOOT in %s", FORMAT_TIMESPAN(client->start_delay, USEC_PER_SEC));
1864
1865 client->start_delay = CLAMP(client->start_delay * 2,
1866 RESTART_AFTER_NAK_MIN_USEC, RESTART_AFTER_NAK_MAX_USEC);
1867 return 0;
1868 }
1869
1870 static int client_verify_message_header(sd_dhcp_client *client, DHCPMessage *message, size_t len) {
1871 const uint8_t *expected_chaddr = NULL;
1872 uint8_t expected_hlen = 0;
1873
1874 assert(client);
1875 assert(message);
1876
1877 if (len < sizeof(DHCPMessage))
1878 return log_dhcp_client_errno(client, SYNTHETIC_ERRNO(EBADMSG),
1879 "Too small to be a DHCP message, ignoring.");
1880
1881 if (be32toh(message->magic) != DHCP_MAGIC_COOKIE)
1882 return log_dhcp_client_errno(client, SYNTHETIC_ERRNO(EBADMSG),
1883 "Not a DHCP message, ignoring.");
1884
1885 if (message->op != BOOTREPLY)
1886 return log_dhcp_client_errno(client, SYNTHETIC_ERRNO(EBADMSG),
1887 "Not a BOOTREPLY message, ignoring.");
1888
1889 if (message->htype != client->arp_type)
1890 return log_dhcp_client_errno(client, SYNTHETIC_ERRNO(EBADMSG),
1891 "Packet type does not match client type, ignoring.");
1892
1893 if (client->arp_type == ARPHRD_ETHER) {
1894 expected_hlen = ETH_ALEN;
1895 expected_chaddr = client->hw_addr.bytes;
1896 }
1897
1898 if (message->hlen != expected_hlen)
1899 return log_dhcp_client_errno(client, SYNTHETIC_ERRNO(EBADMSG),
1900 "Received packet hlen (%u) does not match expected (%u), ignoring.",
1901 message->hlen, expected_hlen);
1902
1903 if (memcmp_safe(message->chaddr, expected_chaddr, expected_hlen))
1904 return log_dhcp_client_errno(client, SYNTHETIC_ERRNO(EBADMSG),
1905 "Received chaddr does not match expected, ignoring.");
1906
1907 if (client->state != DHCP_STATE_BOUND &&
1908 be32toh(message->xid) != client->xid)
1909 /* in BOUND state, we may receive FORCERENEW with xid set by server,
1910 so ignore the xid in this case */
1911 return log_dhcp_client_errno(client, SYNTHETIC_ERRNO(EBADMSG),
1912 "Received xid (%u) does not match expected (%u), ignoring.",
1913 be32toh(message->xid), client->xid);
1914
1915 return 0;
1916 }
1917
1918 static int client_handle_message(sd_dhcp_client *client, DHCPMessage *message, size_t len, const triple_timestamp *timestamp) {
1919 DHCP_CLIENT_DONT_DESTROY(client);
1920 int r;
1921
1922 assert(client);
1923 assert(message);
1924 assert(timestamp);
1925
1926 if (client_verify_message_header(client, message, len) < 0)
1927 return 0;
1928
1929 switch (client->state) {
1930 case DHCP_STATE_SELECTING:
1931
1932 r = client_handle_offer_or_rapid_ack(client, message, len, timestamp);
1933 if (ERRNO_IS_NEG_RESOURCE(r))
1934 return r;
1935 if (r == -EADDRNOTAVAIL)
1936 /* got a rapid NAK, let's restart the client */
1937 return client_restart(client);
1938 if (r < 0)
1939 return 0; /* invalid message, let's ignore it */
1940
1941 if (client->lease->rapid_commit)
1942 /* got a successful rapid commit */
1943 return client_enter_bound(client, r);
1944
1945 return client_enter_requesting(client);
1946
1947 case DHCP_STATE_REBOOTING:
1948 case DHCP_STATE_REQUESTING:
1949 case DHCP_STATE_RENEWING:
1950 case DHCP_STATE_REBINDING:
1951
1952 r = client_handle_ack(client, message, len, timestamp);
1953 if (ERRNO_IS_NEG_RESOURCE(r))
1954 return r;
1955 if (r == -EADDRNOTAVAIL)
1956 /* got a NAK, let's restart the client */
1957 return client_restart(client);
1958 if (r < 0)
1959 return 0; /* invalid message, let's ignore it */
1960
1961 return client_enter_bound(client, r);
1962
1963 case DHCP_STATE_BOUND:
1964 r = client_handle_forcerenew(client, message, len);
1965 if (ERRNO_IS_NEG_RESOURCE(r))
1966 return r;
1967 if (r < 0)
1968 return 0; /* invalid message, let's ignore it */
1969
1970 return client_timeout_t1(NULL, 0, client);
1971
1972 case DHCP_STATE_INIT:
1973 case DHCP_STATE_INIT_REBOOT:
1974 log_dhcp_client(client, "Unexpectedly receive message without sending any requests, ignoring.");
1975 return 0;
1976
1977 default:
1978 assert_not_reached();
1979 }
1980
1981 return 0;
1982 }
1983
1984 static int client_receive_message_udp(
1985 sd_event_source *s,
1986 int fd,
1987 uint32_t revents,
1988 void *userdata) {
1989
1990 sd_dhcp_client *client = ASSERT_PTR(userdata);
1991 _cleanup_free_ DHCPMessage *message = NULL;
1992 ssize_t len, buflen;
1993 /* This needs to be initialized with zero. See #20741. */
1994 CMSG_BUFFER_TYPE(CMSG_SPACE_TIMEVAL) control = {};
1995 struct iovec iov;
1996 struct msghdr msg = {
1997 .msg_iov = &iov,
1998 .msg_iovlen = 1,
1999 .msg_control = &control,
2000 .msg_controllen = sizeof(control),
2001 };
2002 int r;
2003
2004 assert(s);
2005
2006 buflen = next_datagram_size_fd(fd);
2007 if (ERRNO_IS_NEG_TRANSIENT(buflen) || ERRNO_IS_NEG_DISCONNECT(buflen))
2008 return 0;
2009 if (buflen < 0) {
2010 log_dhcp_client_errno(client, buflen, "Failed to determine datagram size to read, ignoring: %m");
2011 return 0;
2012 }
2013
2014 message = malloc0(buflen);
2015 if (!message)
2016 return -ENOMEM;
2017
2018 iov = IOVEC_MAKE(message, buflen);
2019
2020 len = recvmsg_safe(fd, &msg, MSG_DONTWAIT);
2021 if (ERRNO_IS_NEG_TRANSIENT(len) || ERRNO_IS_NEG_DISCONNECT(len))
2022 return 0;
2023 if (len < 0) {
2024 log_dhcp_client_errno(client, len, "Could not receive message from UDP socket, ignoring: %m");
2025 return 0;
2026 }
2027
2028 log_dhcp_client(client, "Received message from UDP socket, processing.");
2029 r = client_handle_message(client, message, len, TRIPLE_TIMESTAMP_FROM_CMSG(&msg));
2030 if (r < 0)
2031 client_stop(client, r);
2032
2033 return 0;
2034 }
2035
2036 static int client_receive_message_raw(
2037 sd_event_source *s,
2038 int fd,
2039 uint32_t revents,
2040 void *userdata) {
2041
2042 sd_dhcp_client *client = ASSERT_PTR(userdata);
2043 _cleanup_free_ DHCPPacket *packet = NULL;
2044 /* This needs to be initialized with zero. See #20741. */
2045 CMSG_BUFFER_TYPE(CMSG_SPACE_TIMEVAL +
2046 CMSG_SPACE(sizeof(struct tpacket_auxdata))) control = {};
2047 struct iovec iov = {};
2048 struct msghdr msg = {
2049 .msg_iov = &iov,
2050 .msg_iovlen = 1,
2051 .msg_control = &control,
2052 .msg_controllen = sizeof(control),
2053 };
2054 bool checksum = true;
2055 ssize_t buflen, len;
2056 int r;
2057
2058 assert(s);
2059
2060 buflen = next_datagram_size_fd(fd);
2061 if (ERRNO_IS_NEG_TRANSIENT(buflen) || ERRNO_IS_NEG_DISCONNECT(buflen))
2062 return 0;
2063 if (buflen < 0) {
2064 log_dhcp_client_errno(client, buflen, "Failed to determine datagram size to read, ignoring: %m");
2065 return 0;
2066 }
2067
2068 packet = malloc0(buflen);
2069 if (!packet)
2070 return -ENOMEM;
2071
2072 iov = IOVEC_MAKE(packet, buflen);
2073
2074 len = recvmsg_safe(fd, &msg, 0);
2075 if (ERRNO_IS_NEG_TRANSIENT(len) || ERRNO_IS_NEG_DISCONNECT(len))
2076 return 0;
2077 if (len < 0) {
2078 log_dhcp_client_errno(client, len, "Could not receive message from raw socket, ignoring: %m");
2079 return 0;
2080 }
2081
2082 struct tpacket_auxdata *aux = CMSG_FIND_DATA(&msg, SOL_PACKET, PACKET_AUXDATA, struct tpacket_auxdata);
2083 if (aux)
2084 checksum = !(aux->tp_status & TP_STATUS_CSUMNOTREADY);
2085
2086 if (dhcp_packet_verify_headers(packet, len, checksum, client->port) < 0)
2087 return 0;
2088
2089 len -= DHCP_IP_UDP_SIZE;
2090
2091 log_dhcp_client(client, "Received message from RAW socket, processing.");
2092 r = client_handle_message(client, &packet->dhcp, len, TRIPLE_TIMESTAMP_FROM_CMSG(&msg));
2093 if (r < 0)
2094 client_stop(client, r);
2095
2096 return 0;
2097 }
2098
2099 int sd_dhcp_client_send_renew(sd_dhcp_client *client) {
2100 assert_return(client, -EINVAL);
2101 assert_return(sd_dhcp_client_is_running(client), -ESTALE);
2102 assert_return(client->fd >= 0, -EINVAL);
2103
2104 if (client->state != DHCP_STATE_BOUND)
2105 return 0;
2106
2107 assert(client->lease);
2108
2109 client->start_delay = 0;
2110 client->attempt = 1;
2111 client_set_state(client, DHCP_STATE_RENEWING);
2112
2113 return client_initialize_time_events(client);
2114 }
2115
2116 int sd_dhcp_client_is_running(sd_dhcp_client *client) {
2117 if (!client)
2118 return 0;
2119
2120 return client->state != DHCP_STATE_STOPPED;
2121 }
2122
2123 int sd_dhcp_client_start(sd_dhcp_client *client) {
2124 int r;
2125
2126 assert_return(client, -EINVAL);
2127
2128 /* Note, do not reset the flag in client_initialize(), as it is also called on expire. */
2129 client->ipv6_acquired = false;
2130
2131 r = client_initialize(client);
2132 if (r < 0)
2133 return r;
2134
2135 /* If no client identifier exists, construct an RFC 4361-compliant one */
2136 if (!sd_dhcp_client_id_is_set(&client->client_id)) {
2137 r = sd_dhcp_client_set_iaid_duid_en(client, /* iaid_set = */ false, /* iaid = */ 0);
2138 if (r < 0)
2139 return r;
2140 }
2141
2142 /* RFC7844 section 3.3:
2143 SHOULD perform a complete four-way handshake, starting with a
2144 DHCPDISCOVER, to obtain a new address lease. If the client can
2145 ascertain that this is exactly the same network to which it was
2146 previously connected, and if the link-layer address did not change,
2147 the client MAY issue a DHCPREQUEST to try to reclaim the current
2148 address. */
2149 if (client->last_addr && !client->anonymize)
2150 client_set_state(client, DHCP_STATE_INIT_REBOOT);
2151
2152 r = client_start(client);
2153 if (r >= 0)
2154 log_dhcp_client(client, "STARTED on ifindex %i", client->ifindex);
2155
2156 return r;
2157 }
2158
2159 int sd_dhcp_client_send_release(sd_dhcp_client *client) {
2160 assert_return(client, -EINVAL);
2161 assert_return(sd_dhcp_client_is_running(client), -ESTALE);
2162 assert_return(client->lease, -EUNATCH);
2163
2164 _cleanup_free_ DHCPPacket *release = NULL;
2165 size_t optoffset, optlen;
2166 int r;
2167
2168 r = client_message_init(client, &release, DHCP_RELEASE, &optlen, &optoffset);
2169 if (r < 0)
2170 return r;
2171
2172 /* Fill up release IP and MAC */
2173 release->dhcp.ciaddr = client->lease->address;
2174 memcpy(&release->dhcp.chaddr, client->hw_addr.bytes, client->hw_addr.length);
2175
2176 r = dhcp_option_append(&release->dhcp, optlen, &optoffset, 0,
2177 SD_DHCP_OPTION_END, 0, NULL);
2178 if (r < 0)
2179 return r;
2180
2181 r = dhcp_network_send_udp_socket(client->fd,
2182 client->lease->server_address,
2183 DHCP_PORT_SERVER,
2184 &release->dhcp,
2185 sizeof(DHCPMessage) + optoffset);
2186 if (r < 0)
2187 return r;
2188
2189 log_dhcp_client(client, "RELEASE");
2190
2191 return 0;
2192 }
2193
2194 int sd_dhcp_client_send_decline(sd_dhcp_client *client) {
2195 assert_return(client, -EINVAL);
2196 assert_return(sd_dhcp_client_is_running(client), -ESTALE);
2197 assert_return(client->lease, -EUNATCH);
2198
2199 _cleanup_free_ DHCPPacket *release = NULL;
2200 size_t optoffset, optlen;
2201 int r;
2202
2203 r = client_message_init(client, &release, DHCP_DECLINE, &optlen, &optoffset);
2204 if (r < 0)
2205 return r;
2206
2207 release->dhcp.ciaddr = client->lease->address;
2208 memcpy(&release->dhcp.chaddr, client->hw_addr.bytes, client->hw_addr.length);
2209
2210 r = dhcp_option_append(&release->dhcp, optlen, &optoffset, 0,
2211 SD_DHCP_OPTION_END, 0, NULL);
2212 if (r < 0)
2213 return r;
2214
2215 r = dhcp_network_send_udp_socket(client->fd,
2216 client->lease->server_address,
2217 DHCP_PORT_SERVER,
2218 &release->dhcp,
2219 sizeof(DHCPMessage) + optoffset);
2220 if (r < 0)
2221 return r;
2222
2223 log_dhcp_client(client, "DECLINE");
2224
2225 client_stop(client, SD_DHCP_CLIENT_EVENT_STOP);
2226
2227 if (client->state != DHCP_STATE_STOPPED) {
2228 r = sd_dhcp_client_start(client);
2229 if (r < 0)
2230 return r;
2231 }
2232
2233 return 0;
2234 }
2235
2236 int sd_dhcp_client_stop(sd_dhcp_client *client) {
2237 if (!client)
2238 return 0;
2239
2240 DHCP_CLIENT_DONT_DESTROY(client);
2241
2242 client_stop(client, SD_DHCP_CLIENT_EVENT_STOP);
2243
2244 return 0;
2245 }
2246
2247 int sd_dhcp_client_set_ipv6_connectivity(sd_dhcp_client *client, int have) {
2248 if (!client)
2249 return 0;
2250
2251 /* We have already received a message with IPv6-Only preferred option, and are waiting for IPv6
2252 * connectivity or timeout, let's stop the client. */
2253 if (have && sd_event_source_get_enabled(client->timeout_ipv6_only_mode, NULL) > 0)
2254 return sd_dhcp_client_stop(client);
2255
2256 /* Otherwise, save that the host already has IPv6 connectivity. */
2257 client->ipv6_acquired = have;
2258 return 0;
2259 }
2260
2261 int sd_dhcp_client_interrupt_ipv6_only_mode(sd_dhcp_client *client) {
2262 assert_return(client, -EINVAL);
2263 assert_return(sd_dhcp_client_is_running(client), -ESTALE);
2264 assert_return(client->fd >= 0, -EINVAL);
2265
2266 if (sd_event_source_get_enabled(client->timeout_ipv6_only_mode, NULL) <= 0)
2267 return 0;
2268
2269 client_initialize(client);
2270 return client_start(client);
2271 }
2272
2273 int sd_dhcp_client_attach_event(sd_dhcp_client *client, sd_event *event, int64_t priority) {
2274 int r;
2275
2276 assert_return(client, -EINVAL);
2277 assert_return(!client->event, -EBUSY);
2278 assert_return(!sd_dhcp_client_is_running(client), -EBUSY);
2279
2280 if (event)
2281 client->event = sd_event_ref(event);
2282 else {
2283 r = sd_event_default(&client->event);
2284 if (r < 0)
2285 return 0;
2286 }
2287
2288 client->event_priority = priority;
2289
2290 return 0;
2291 }
2292
2293 int sd_dhcp_client_detach_event(sd_dhcp_client *client) {
2294 assert_return(client, -EINVAL);
2295 assert_return(!sd_dhcp_client_is_running(client), -EBUSY);
2296
2297 client->event = sd_event_unref(client->event);
2298
2299 return 0;
2300 }
2301
2302 sd_event *sd_dhcp_client_get_event(sd_dhcp_client *client) {
2303 assert_return(client, NULL);
2304
2305 return client->event;
2306 }
2307
2308 int sd_dhcp_client_attach_device(sd_dhcp_client *client, sd_device *dev) {
2309 assert_return(client, -EINVAL);
2310
2311 return device_unref_and_replace(client->dev, dev);
2312 }
2313
2314 static sd_dhcp_client *dhcp_client_free(sd_dhcp_client *client) {
2315 if (!client)
2316 return NULL;
2317
2318 log_dhcp_client(client, "FREE");
2319
2320 client_initialize(client);
2321
2322 client->timeout_resend = sd_event_source_unref(client->timeout_resend);
2323 client->timeout_t1 = sd_event_source_unref(client->timeout_t1);
2324 client->timeout_t2 = sd_event_source_unref(client->timeout_t2);
2325 client->timeout_expire = sd_event_source_unref(client->timeout_expire);
2326
2327 sd_dhcp_client_detach_event(client);
2328
2329 sd_device_unref(client->dev);
2330
2331 set_free(client->req_opts);
2332 free(client->hostname);
2333 free(client->vendor_class_identifier);
2334 free(client->mudurl);
2335 client->user_class = strv_free(client->user_class);
2336 ordered_hashmap_free(client->extra_options);
2337 ordered_hashmap_free(client->vendor_options);
2338 free(client->ifname);
2339 return mfree(client);
2340 }
2341
2342 DEFINE_TRIVIAL_REF_UNREF_FUNC(sd_dhcp_client, sd_dhcp_client, dhcp_client_free);
2343
2344 int sd_dhcp_client_new(sd_dhcp_client **ret, int anonymize) {
2345 const uint8_t *opts;
2346 size_t n_opts;
2347 int r;
2348
2349 assert_return(ret, -EINVAL);
2350
2351 _cleanup_(sd_dhcp_client_unrefp) sd_dhcp_client *client = new(sd_dhcp_client, 1);
2352 if (!client)
2353 return -ENOMEM;
2354
2355 *client = (sd_dhcp_client) {
2356 .n_ref = 1,
2357 .state = DHCP_STATE_STOPPED,
2358 .ifindex = -1,
2359 .fd = -EBADF,
2360 .mtu = DHCP_MIN_PACKET_SIZE,
2361 .port = DHCP_PORT_CLIENT,
2362 .anonymize = !!anonymize,
2363 .max_attempts = UINT64_MAX,
2364 .ip_service_type = -1,
2365 };
2366 /* NOTE: this could be moved to a function. */
2367 if (anonymize) {
2368 n_opts = ELEMENTSOF(default_req_opts_anonymize);
2369 opts = default_req_opts_anonymize;
2370 } else {
2371 n_opts = ELEMENTSOF(default_req_opts);
2372 opts = default_req_opts;
2373 }
2374
2375 for (size_t i = 0; i < n_opts; i++) {
2376 r = sd_dhcp_client_set_request_option(client, opts[i]);
2377 if (r < 0)
2378 return r;
2379 }
2380
2381 *ret = TAKE_PTR(client);
2382
2383 return 0;
2384 }
2385
2386 static const char* const dhcp_state_table[_DHCP_STATE_MAX] = {
2387 [DHCP_STATE_STOPPED] = "stopped",
2388 [DHCP_STATE_INIT] = "initialization",
2389 [DHCP_STATE_SELECTING] = "selecting",
2390 [DHCP_STATE_INIT_REBOOT] = "init-reboot",
2391 [DHCP_STATE_REBOOTING] = "rebooting",
2392 [DHCP_STATE_REQUESTING] = "requesting",
2393 [DHCP_STATE_BOUND] = "bound",
2394 [DHCP_STATE_RENEWING] = "renewing",
2395 [DHCP_STATE_REBINDING] = "rebinding",
2396 };
2397
2398 DEFINE_STRING_TABLE_LOOKUP_TO_STRING(dhcp_state, DHCPState);