2 This file is part of systemd.
4 Copyright (C) 2013 Intel Corporation. All rights reserved.
6 systemd is free software; you can redistribute it and/or modify it
7 under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation; either version 2.1 of the License, or
9 (at your option) any later version.
11 systemd is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public License
17 along with systemd; If not, see <http://www.gnu.org/licenses/>.
24 #include <net/ethernet.h>
25 #include <net/if_arp.h>
26 #include <linux/if_infiniband.h>
27 #include <netinet/ether.h>
28 #include <sys/param.h>
29 #include <sys/ioctl.h>
36 #include "dhcp-protocol.h"
37 #include "dhcp-internal.h"
38 #include "dhcp-lease-internal.h"
39 #include "sd-dhcp-client.h"
41 #define MAX_CLIENT_ID_LEN 64 /* Arbitrary limit */
42 #define MAX_MAC_ADDR_LEN INFINIBAND_ALEN
44 struct sd_dhcp_client
{
50 sd_event_source
*timeout_resend
;
53 union sockaddr_union link
;
54 sd_event_source
*receive_message
;
55 bool request_broadcast
;
57 size_t req_opts_allocated
;
60 uint8_t mac_addr
[MAX_MAC_ADDR_LEN
];
65 uint8_t type
; /* 0: Generic (non-LL) (RFC 2132) */
66 uint8_t data
[MAX_CLIENT_ID_LEN
];
69 uint8_t type
; /* 1: Ethernet Link-Layer (RFC 2132) */
70 uint8_t haddr
[ETH_ALEN
];
73 uint8_t type
; /* 2 - 254: ARP/Link-Layer (RFC 2132) */
77 uint8_t type
; /* 255: Node-specific (RFC 4361) */
79 uint8_t duid
[MAX_CLIENT_ID_LEN
- 4];
83 uint8_t data
[MAX_CLIENT_ID_LEN
];
88 char *vendor_class_identifier
;
94 sd_event_source
*timeout_t1
;
95 sd_event_source
*timeout_t2
;
96 sd_event_source
*timeout_expire
;
97 sd_dhcp_client_cb_t cb
;
102 static const uint8_t default_req_opts
[] = {
103 DHCP_OPTION_SUBNET_MASK
,
105 DHCP_OPTION_HOST_NAME
,
106 DHCP_OPTION_DOMAIN_NAME
,
107 DHCP_OPTION_DOMAIN_NAME_SERVER
,
108 DHCP_OPTION_NTP_SERVER
,
111 static int client_receive_message_raw(sd_event_source
*s
, int fd
,
112 uint32_t revents
, void *userdata
);
113 static int client_receive_message_udp(sd_event_source
*s
, int fd
,
114 uint32_t revents
, void *userdata
);
115 static void client_stop(sd_dhcp_client
*client
, int error
);
117 int sd_dhcp_client_set_callback(sd_dhcp_client
*client
, sd_dhcp_client_cb_t cb
,
119 assert_return(client
, -EINVAL
);
122 client
->userdata
= userdata
;
127 int sd_dhcp_client_set_request_broadcast(sd_dhcp_client
*client
, int broadcast
) {
128 assert_return(client
, -EINVAL
);
130 client
->request_broadcast
= !!broadcast
;
135 int sd_dhcp_client_set_request_option(sd_dhcp_client
*client
, uint8_t option
) {
138 assert_return(client
, -EINVAL
);
139 assert_return (IN_SET(client
->state
, DHCP_STATE_INIT
,
140 DHCP_STATE_STOPPED
), -EBUSY
);
143 case DHCP_OPTION_PAD
:
144 case DHCP_OPTION_OVERLOAD
:
145 case DHCP_OPTION_MESSAGE_TYPE
:
146 case DHCP_OPTION_PARAMETER_REQUEST_LIST
:
147 case DHCP_OPTION_END
:
154 for (i
= 0; i
< client
->req_opts_size
; i
++)
155 if (client
->req_opts
[i
] == option
)
158 if (!GREEDY_REALLOC(client
->req_opts
, client
->req_opts_allocated
,
159 client
->req_opts_size
+ 1))
162 client
->req_opts
[client
->req_opts_size
++] = option
;
167 int sd_dhcp_client_set_request_address(sd_dhcp_client
*client
,
168 const struct in_addr
*last_addr
) {
169 assert_return(client
, -EINVAL
);
170 assert_return (IN_SET(client
->state
, DHCP_STATE_INIT
,
171 DHCP_STATE_STOPPED
), -EBUSY
);
174 client
->last_addr
= last_addr
->s_addr
;
176 client
->last_addr
= INADDR_ANY
;
181 int sd_dhcp_client_set_index(sd_dhcp_client
*client
, int interface_index
) {
182 assert_return(client
, -EINVAL
);
183 assert_return (IN_SET(client
->state
, DHCP_STATE_INIT
,
184 DHCP_STATE_STOPPED
), -EBUSY
);
185 assert_return(interface_index
> 0, -EINVAL
);
187 client
->index
= interface_index
;
192 int sd_dhcp_client_set_mac(sd_dhcp_client
*client
, const uint8_t *addr
,
193 size_t addr_len
, uint16_t arp_type
) {
194 DHCP_CLIENT_DONT_DESTROY(client
);
195 bool need_restart
= false;
197 assert_return(client
, -EINVAL
);
198 assert_return(addr
, -EINVAL
);
199 assert_return(addr_len
> 0 && addr_len
<= MAX_MAC_ADDR_LEN
, -EINVAL
);
200 assert_return(arp_type
> 0, -EINVAL
);
202 if (arp_type
== ARPHRD_ETHER
)
203 assert_return(addr_len
== ETH_ALEN
, -EINVAL
);
204 else if (arp_type
== ARPHRD_INFINIBAND
)
205 assert_return(addr_len
== INFINIBAND_ALEN
, -EINVAL
);
209 if (client
->mac_addr_len
== addr_len
&&
210 memcmp(&client
->mac_addr
, addr
, addr_len
) == 0)
213 if (!IN_SET(client
->state
, DHCP_STATE_INIT
, DHCP_STATE_STOPPED
)) {
214 log_dhcp_client(client
, "Changing MAC address on running DHCP "
215 "client, restarting");
217 client_stop(client
, DHCP_EVENT_STOP
);
220 memcpy(&client
->mac_addr
, addr
, addr_len
);
221 client
->mac_addr_len
= addr_len
;
222 client
->arp_type
= arp_type
;
224 if (need_restart
&& client
->state
!= DHCP_STATE_STOPPED
)
225 sd_dhcp_client_start(client
);
230 int sd_dhcp_client_get_client_id(sd_dhcp_client
*client
, uint8_t *type
,
231 const uint8_t **data
, size_t *data_len
) {
233 assert_return(client
, -EINVAL
);
234 assert_return(type
, -EINVAL
);
235 assert_return(data
, -EINVAL
);
236 assert_return(data_len
, -EINVAL
);
241 if (client
->client_id_len
) {
242 *type
= client
->client_id
.raw
.type
;
243 *data
= client
->client_id
.raw
.data
;
244 *data_len
= client
->client_id_len
-
245 sizeof (client
->client_id
.raw
.type
);
251 int sd_dhcp_client_set_client_id(sd_dhcp_client
*client
, uint8_t type
,
252 const uint8_t *data
, size_t data_len
) {
253 DHCP_CLIENT_DONT_DESTROY(client
);
254 bool need_restart
= false;
256 assert_return(client
, -EINVAL
);
257 assert_return(data
, -EINVAL
);
258 assert_return(data_len
> 0 && data_len
<= MAX_CLIENT_ID_LEN
, -EINVAL
);
262 if (data_len
!= ETH_ALEN
)
265 case ARPHRD_INFINIBAND
:
266 if (data_len
!= INFINIBAND_ALEN
)
273 if (client
->client_id_len
== data_len
+ sizeof (client
->client_id
.raw
.type
) &&
274 client
->client_id
.raw
.type
== type
&&
275 memcmp(&client
->client_id
.raw
.data
, data
, data_len
) == 0)
278 if (!IN_SET(client
->state
, DHCP_STATE_INIT
, DHCP_STATE_STOPPED
)) {
279 log_dhcp_client(client
, "Changing client ID on running DHCP "
280 "client, restarting");
282 client_stop(client
, DHCP_EVENT_STOP
);
285 client
->client_id
.raw
.type
= type
;
286 memcpy(&client
->client_id
.raw
.data
, data
, data_len
);
287 client
->client_id_len
= data_len
+ sizeof (client
->client_id
.raw
.type
);
289 if (need_restart
&& client
->state
!= DHCP_STATE_STOPPED
)
290 sd_dhcp_client_start(client
);
295 int sd_dhcp_client_set_hostname(sd_dhcp_client
*client
,
296 const char *hostname
) {
297 char *new_hostname
= NULL
;
299 assert_return(client
, -EINVAL
);
301 if (streq_ptr(client
->hostname
, hostname
))
305 new_hostname
= strdup(hostname
);
310 free(client
->hostname
);
311 client
->hostname
= new_hostname
;
316 int sd_dhcp_client_set_vendor_class_identifier(sd_dhcp_client
*client
,
318 char *new_vci
= NULL
;
320 assert_return(client
, -EINVAL
);
322 new_vci
= strdup(vci
);
326 free(client
->vendor_class_identifier
);
328 client
->vendor_class_identifier
= new_vci
;
333 int sd_dhcp_client_set_mtu(sd_dhcp_client
*client
, uint32_t mtu
) {
334 assert_return(client
, -EINVAL
);
335 assert_return(mtu
>= DHCP_DEFAULT_MIN_SIZE
, -ERANGE
);
342 int sd_dhcp_client_get_lease(sd_dhcp_client
*client
, sd_dhcp_lease
**ret
) {
343 assert_return(client
, -EINVAL
);
344 assert_return(ret
, -EINVAL
);
346 if (client
->state
!= DHCP_STATE_BOUND
&&
347 client
->state
!= DHCP_STATE_RENEWING
&&
348 client
->state
!= DHCP_STATE_REBINDING
)
349 return -EADDRNOTAVAIL
;
351 *ret
= sd_dhcp_lease_ref(client
->lease
);
356 static void client_notify(sd_dhcp_client
*client
, int event
) {
358 client
->cb(client
, event
, client
->userdata
);
361 static int client_initialize(sd_dhcp_client
*client
) {
362 assert_return(client
, -EINVAL
);
364 client
->receive_message
=
365 sd_event_source_unref(client
->receive_message
);
367 client
->fd
= asynchronous_close(client
->fd
);
369 client
->timeout_resend
= sd_event_source_unref(client
->timeout_resend
);
371 client
->timeout_t1
= sd_event_source_unref(client
->timeout_t1
);
372 client
->timeout_t2
= sd_event_source_unref(client
->timeout_t2
);
373 client
->timeout_expire
= sd_event_source_unref(client
->timeout_expire
);
377 client
->state
= DHCP_STATE_INIT
;
381 client
->lease
= sd_dhcp_lease_unref(client
->lease
);
386 static void client_stop(sd_dhcp_client
*client
, int error
) {
390 log_dhcp_client(client
, "STOPPED: %s", strerror(-error
));
391 else if (error
== DHCP_EVENT_STOP
)
392 log_dhcp_client(client
, "STOPPED");
394 log_dhcp_client(client
, "STOPPED: Unknown event");
396 client_notify(client
, error
);
398 client_initialize(client
);
401 static int client_message_init(sd_dhcp_client
*client
, DHCPPacket
**ret
,
402 uint8_t type
, size_t *_optlen
, size_t *_optoffset
) {
403 _cleanup_free_ DHCPPacket
*packet
;
404 size_t optlen
, optoffset
, size
;
411 assert(client
->start_time
);
415 assert(type
== DHCP_DISCOVER
|| type
== DHCP_REQUEST
);
417 optlen
= DHCP_MIN_OPTIONS_SIZE
;
418 size
= sizeof(DHCPPacket
) + optlen
;
420 packet
= malloc0(size
);
424 r
= dhcp_message_init(&packet
->dhcp
, BOOTREQUEST
, client
->xid
, type
,
425 client
->arp_type
, optlen
, &optoffset
);
429 /* Although 'secs' field is a SHOULD in RFC 2131, certain DHCP servers
430 refuse to issue an DHCP lease if 'secs' is set to zero */
431 r
= sd_event_now(client
->event
, clock_boottime_or_monotonic(), &time_now
);
434 assert(time_now
>= client
->start_time
);
436 /* seconds between sending first and last DISCOVER
437 * must always be strictly positive to deal with broken servers */
438 secs
= ((time_now
- client
->start_time
) / USEC_PER_SEC
) ? : 1;
439 packet
->dhcp
.secs
= htobe16(secs
);
441 /* RFC2132 section 4.1
442 A client that cannot receive unicast IP datagrams until its protocol
443 software has been configured with an IP address SHOULD set the
444 BROADCAST bit in the 'flags' field to 1 in any DHCPDISCOVER or
445 DHCPREQUEST messages that client sends. The BROADCAST bit will
446 provide a hint to the DHCP server and BOOTP relay agent to broadcast
447 any messages to the client on the client's subnet.
449 Note: some interfaces needs this to be enabled, but some networks
450 needs this to be disabled as broadcasts are filteretd, so this
451 needs to be configurable */
452 if (client
->request_broadcast
|| client
->arp_type
!= ARPHRD_ETHER
)
453 packet
->dhcp
.flags
= htobe16(0x8000);
455 /* RFC2132 section 4.1.1:
456 The client MUST include its hardware address in the ’chaddr’ field, if
457 necessary for delivery of DHCP reply messages. Non-Ethernet
458 interfaces will leave 'chaddr' empty and use the client identifier
459 instead (eg, RFC 4390 section 2.1).
461 if (client
->arp_type
== ARPHRD_ETHER
)
462 memcpy(&packet
->dhcp
.chaddr
, &client
->mac_addr
, ETH_ALEN
);
464 /* If no client identifier exists, construct one from an ethernet
465 address if present */
466 if (client
->client_id_len
== 0 && client
->arp_type
== ARPHRD_ETHER
) {
467 client
->client_id
.eth
.type
= ARPHRD_ETHER
;
468 memcpy(&client
->client_id
.eth
.haddr
, &client
->mac_addr
, ETH_ALEN
);
469 client
->client_id_len
= sizeof (client
->client_id
.eth
);
472 /* Some DHCP servers will refuse to issue an DHCP lease if the Client
473 Identifier option is not set */
474 if (client
->client_id_len
) {
475 r
= dhcp_option_append(&packet
->dhcp
, optlen
, &optoffset
, 0,
476 DHCP_OPTION_CLIENT_IDENTIFIER
,
477 client
->client_id_len
,
478 &client
->client_id
.raw
);
483 /* RFC2131 section 3.5:
484 in its initial DHCPDISCOVER or DHCPREQUEST message, a
485 client may provide the server with a list of specific
486 parameters the client is interested in. If the client
487 includes a list of parameters in a DHCPDISCOVER message,
488 it MUST include that list in any subsequent DHCPREQUEST
491 r
= dhcp_option_append(&packet
->dhcp
, optlen
, &optoffset
, 0,
492 DHCP_OPTION_PARAMETER_REQUEST_LIST
,
493 client
->req_opts_size
, client
->req_opts
);
497 /* RFC2131 section 3.5:
498 The client SHOULD include the ’maximum DHCP message size’ option to
499 let the server know how large the server may make its DHCP messages.
501 Note (from ConnMan): Some DHCP servers will send bigger DHCP packets
502 than the defined default size unless the Maximum Messge Size option
505 RFC3442 "Requirements to Avoid Sizing Constraints":
506 Because a full routing table can be quite large, the standard 576
507 octet maximum size for a DHCP message may be too short to contain
508 some legitimate Classless Static Route options. Because of this,
509 clients implementing the Classless Static Route option SHOULD send a
510 Maximum DHCP Message Size [4] option if the DHCP client's TCP/IP
511 stack is capable of receiving larger IP datagrams. In this case, the
512 client SHOULD set the value of this option to at least the MTU of the
513 interface that the client is configuring. The client MAY set the
514 value of this option higher, up to the size of the largest UDP packet
515 it is prepared to accept. (Note that the value specified in the
516 Maximum DHCP Message Size option is the total maximum packet size,
517 including IP and UDP headers.)
519 max_size
= htobe16(size
);
520 r
= dhcp_option_append(&packet
->dhcp
, client
->mtu
, &optoffset
, 0,
521 DHCP_OPTION_MAXIMUM_MESSAGE_SIZE
,
527 *_optoffset
= optoffset
;
534 static int dhcp_client_send_raw(sd_dhcp_client
*client
, DHCPPacket
*packet
,
536 dhcp_packet_append_ip_headers(packet
, INADDR_ANY
, DHCP_PORT_CLIENT
,
537 INADDR_BROADCAST
, DHCP_PORT_SERVER
, len
);
539 return dhcp_network_send_raw_socket(client
->fd
, &client
->link
,
543 static int client_send_discover(sd_dhcp_client
*client
) {
544 _cleanup_free_ DHCPPacket
*discover
= NULL
;
545 size_t optoffset
, optlen
;
549 assert(client
->state
== DHCP_STATE_INIT
||
550 client
->state
== DHCP_STATE_SELECTING
);
552 r
= client_message_init(client
, &discover
, DHCP_DISCOVER
,
553 &optlen
, &optoffset
);
557 /* the client may suggest values for the network address
558 and lease time in the DHCPDISCOVER message. The client may include
559 the ’requested IP address’ option to suggest that a particular IP
560 address be assigned, and may include the ’IP address lease time’
561 option to suggest the lease time it would like.
563 if (client
->last_addr
!= INADDR_ANY
) {
564 r
= dhcp_option_append(&discover
->dhcp
, optlen
, &optoffset
, 0,
565 DHCP_OPTION_REQUESTED_IP_ADDRESS
,
566 4, &client
->last_addr
);
571 /* it is unclear from RFC 2131 if client should send hostname in
572 DHCPDISCOVER but dhclient does and so we do as well
574 if (client
->hostname
) {
575 r
= dhcp_option_append(&discover
->dhcp
, optlen
, &optoffset
, 0,
576 DHCP_OPTION_HOST_NAME
,
577 strlen(client
->hostname
), client
->hostname
);
582 if (client
->vendor_class_identifier
) {
583 r
= dhcp_option_append(&discover
->dhcp
, optlen
, &optoffset
, 0,
584 DHCP_OPTION_VENDOR_CLASS_IDENTIFIER
,
585 strlen(client
->vendor_class_identifier
),
586 client
->vendor_class_identifier
);
591 r
= dhcp_option_append(&discover
->dhcp
, optlen
, &optoffset
, 0,
592 DHCP_OPTION_END
, 0, NULL
);
596 /* We currently ignore:
597 The client SHOULD wait a random time between one and ten seconds to
598 desynchronize the use of DHCP at startup.
600 r
= dhcp_client_send_raw(client
, discover
, sizeof(DHCPPacket
) + optoffset
);
604 log_dhcp_client(client
, "DISCOVER");
609 static int client_send_request(sd_dhcp_client
*client
) {
610 _cleanup_free_ DHCPPacket
*request
= NULL
;
611 size_t optoffset
, optlen
;
614 r
= client_message_init(client
, &request
, DHCP_REQUEST
,
615 &optlen
, &optoffset
);
619 switch (client
->state
) {
620 /* See RFC2131 section 4.3.2 (note that there is a typo in the RFC,
621 SELECTING should be REQUESTING)
624 case DHCP_STATE_REQUESTING
:
625 /* Client inserts the address of the selected server in ’server
626 identifier’, ’ciaddr’ MUST be zero, ’requested IP address’ MUST be
627 filled in with the yiaddr value from the chosen DHCPOFFER.
630 r
= dhcp_option_append(&request
->dhcp
, optlen
, &optoffset
, 0,
631 DHCP_OPTION_SERVER_IDENTIFIER
,
632 4, &client
->lease
->server_address
);
636 r
= dhcp_option_append(&request
->dhcp
, optlen
, &optoffset
, 0,
637 DHCP_OPTION_REQUESTED_IP_ADDRESS
,
638 4, &client
->lease
->address
);
644 case DHCP_STATE_INIT_REBOOT
:
645 /* ’server identifier’ MUST NOT be filled in, ’requested IP address’
646 option MUST be filled in with client’s notion of its previously
647 assigned address. ’ciaddr’ MUST be zero.
649 r
= dhcp_option_append(&request
->dhcp
, optlen
, &optoffset
, 0,
650 DHCP_OPTION_REQUESTED_IP_ADDRESS
,
651 4, &client
->last_addr
);
656 case DHCP_STATE_RENEWING
:
657 /* ’server identifier’ MUST NOT be filled in, ’requested IP address’
658 option MUST NOT be filled in, ’ciaddr’ MUST be filled in with
659 client’s IP address.
663 case DHCP_STATE_REBINDING
:
664 /* ’server identifier’ MUST NOT be filled in, ’requested IP address’
665 option MUST NOT be filled in, ’ciaddr’ MUST be filled in with
666 client’s IP address.
668 This message MUST be broadcast to the 0xffffffff IP broadcast address.
670 request
->dhcp
.ciaddr
= client
->lease
->address
;
674 case DHCP_STATE_INIT
:
675 case DHCP_STATE_SELECTING
:
676 case DHCP_STATE_REBOOTING
:
677 case DHCP_STATE_BOUND
:
678 case DHCP_STATE_STOPPED
:
682 if (client
->hostname
) {
683 r
= dhcp_option_append(&request
->dhcp
, optlen
, &optoffset
, 0,
684 DHCP_OPTION_HOST_NAME
,
685 strlen(client
->hostname
), client
->hostname
);
690 r
= dhcp_option_append(&request
->dhcp
, optlen
, &optoffset
, 0,
691 DHCP_OPTION_END
, 0, NULL
);
695 if (client
->state
== DHCP_STATE_RENEWING
) {
696 r
= dhcp_network_send_udp_socket(client
->fd
,
697 client
->lease
->server_address
,
700 sizeof(DHCPMessage
) + optoffset
);
702 r
= dhcp_client_send_raw(client
, request
, sizeof(DHCPPacket
) + optoffset
);
707 switch (client
->state
) {
708 case DHCP_STATE_REQUESTING
:
709 log_dhcp_client(client
, "REQUEST (requesting)");
711 case DHCP_STATE_INIT_REBOOT
:
712 log_dhcp_client(client
, "REQUEST (init-reboot)");
714 case DHCP_STATE_RENEWING
:
715 log_dhcp_client(client
, "REQUEST (renewing)");
717 case DHCP_STATE_REBINDING
:
718 log_dhcp_client(client
, "REQUEST (rebinding)");
721 log_dhcp_client(client
, "REQUEST (invalid)");
728 static int client_start(sd_dhcp_client
*client
);
730 static int client_timeout_resend(sd_event_source
*s
, uint64_t usec
,
732 sd_dhcp_client
*client
= userdata
;
733 DHCP_CLIENT_DONT_DESTROY(client
);
734 usec_t next_timeout
= 0;
741 assert(client
->event
);
743 r
= sd_event_now(client
->event
, clock_boottime_or_monotonic(), &time_now
);
747 switch (client
->state
) {
748 case DHCP_STATE_RENEWING
:
750 time_left
= (client
->lease
->t2
- client
->lease
->t1
) / 2;
754 next_timeout
= time_now
+ time_left
* USEC_PER_SEC
;
758 case DHCP_STATE_REBINDING
:
760 time_left
= (client
->lease
->lifetime
- client
->lease
->t2
) / 2;
764 next_timeout
= time_now
+ time_left
* USEC_PER_SEC
;
767 case DHCP_STATE_REBOOTING
:
768 /* start over as we did not receive a timely ack or nak */
769 r
= client_initialize(client
);
773 r
= client_start(client
);
777 log_dhcp_client(client
, "REBOOTED");
781 case DHCP_STATE_INIT
:
782 case DHCP_STATE_INIT_REBOOT
:
783 case DHCP_STATE_SELECTING
:
784 case DHCP_STATE_REQUESTING
:
785 case DHCP_STATE_BOUND
:
787 if (client
->attempt
< 64)
788 client
->attempt
*= 2;
790 next_timeout
= time_now
+ (client
->attempt
- 1) * USEC_PER_SEC
;
794 case DHCP_STATE_STOPPED
:
799 next_timeout
+= (random_u32() & 0x1fffff);
801 client
->timeout_resend
= sd_event_source_unref(client
->timeout_resend
);
803 r
= sd_event_add_time(client
->event
,
804 &client
->timeout_resend
,
805 clock_boottime_or_monotonic(),
806 next_timeout
, 10 * USEC_PER_MSEC
,
807 client_timeout_resend
, client
);
811 r
= sd_event_source_set_priority(client
->timeout_resend
,
812 client
->event_priority
);
816 r
= sd_event_source_set_description(client
->timeout_resend
, "dhcp4-resend-timer");
820 switch (client
->state
) {
821 case DHCP_STATE_INIT
:
822 r
= client_send_discover(client
);
824 client
->state
= DHCP_STATE_SELECTING
;
827 if (client
->attempt
>= 64)
833 case DHCP_STATE_SELECTING
:
834 r
= client_send_discover(client
);
835 if (r
< 0 && client
->attempt
>= 64)
840 case DHCP_STATE_INIT_REBOOT
:
841 case DHCP_STATE_REQUESTING
:
842 case DHCP_STATE_RENEWING
:
843 case DHCP_STATE_REBINDING
:
844 r
= client_send_request(client
);
845 if (r
< 0 && client
->attempt
>= 64)
848 if (client
->state
== DHCP_STATE_INIT_REBOOT
)
849 client
->state
= DHCP_STATE_REBOOTING
;
851 client
->request_sent
= time_now
;
855 case DHCP_STATE_REBOOTING
:
856 case DHCP_STATE_BOUND
:
860 case DHCP_STATE_STOPPED
:
868 client_stop(client
, r
);
870 /* Errors were dealt with when stopping the client, don't spill
871 errors into the event loop handler */
875 static int client_initialize_io_events(sd_dhcp_client
*client
,
876 sd_event_io_handler_t io_callback
) {
880 assert(client
->event
);
882 r
= sd_event_add_io(client
->event
, &client
->receive_message
,
883 client
->fd
, EPOLLIN
, io_callback
,
888 r
= sd_event_source_set_priority(client
->receive_message
,
889 client
->event_priority
);
893 r
= sd_event_source_set_description(client
->receive_message
, "dhcp4-receive-message");
899 client_stop(client
, r
);
904 static int client_initialize_time_events(sd_dhcp_client
*client
) {
908 assert(client
->event
);
910 client
->timeout_resend
= sd_event_source_unref(client
->timeout_resend
);
912 r
= sd_event_add_time(client
->event
,
913 &client
->timeout_resend
,
914 clock_boottime_or_monotonic(),
916 client_timeout_resend
, client
);
920 r
= sd_event_source_set_priority(client
->timeout_resend
,
921 client
->event_priority
);
923 r
= sd_event_source_set_description(client
->timeout_resend
, "dhcp4-resend-timer");
929 client_stop(client
, r
);
935 static int client_initialize_events(sd_dhcp_client
*client
,
936 sd_event_io_handler_t io_callback
) {
937 client_initialize_io_events(client
, io_callback
);
938 client_initialize_time_events(client
);
943 static int client_start(sd_dhcp_client
*client
) {
946 assert_return(client
, -EINVAL
);
947 assert_return(client
->event
, -EINVAL
);
948 assert_return(client
->index
> 0, -EINVAL
);
949 assert_return(client
->fd
< 0, -EBUSY
);
950 assert_return(client
->xid
== 0, -EINVAL
);
951 assert_return(client
->state
== DHCP_STATE_INIT
||
952 client
->state
== DHCP_STATE_INIT_REBOOT
, -EBUSY
);
954 client
->xid
= random_u32();
956 r
= dhcp_network_bind_raw_socket(client
->index
, &client
->link
,
957 client
->xid
, client
->mac_addr
,
958 client
->mac_addr_len
, client
->arp_type
);
960 client_stop(client
, r
);
965 if (client
->state
== DHCP_STATE_INIT
|| client
->state
== DHCP_STATE_INIT_REBOOT
)
966 client
->start_time
= now(clock_boottime_or_monotonic());
968 return client_initialize_events(client
, client_receive_message_raw
);
971 static int client_timeout_expire(sd_event_source
*s
, uint64_t usec
,
973 sd_dhcp_client
*client
= userdata
;
974 DHCP_CLIENT_DONT_DESTROY(client
);
976 log_dhcp_client(client
, "EXPIRED");
978 client_notify(client
, DHCP_EVENT_EXPIRED
);
980 /* lease was lost, start over if not freed or stopped in callback */
981 if (client
->state
!= DHCP_STATE_STOPPED
) {
982 client_initialize(client
);
983 client_start(client
);
989 static int client_timeout_t2(sd_event_source
*s
, uint64_t usec
, void *userdata
) {
990 sd_dhcp_client
*client
= userdata
;
991 DHCP_CLIENT_DONT_DESTROY(client
);
994 client
->receive_message
= sd_event_source_unref(client
->receive_message
);
995 client
->fd
= asynchronous_close(client
->fd
);
997 client
->state
= DHCP_STATE_REBINDING
;
1000 r
= dhcp_network_bind_raw_socket(client
->index
, &client
->link
,
1001 client
->xid
, client
->mac_addr
,
1002 client
->mac_addr_len
, client
->arp_type
);
1004 client_stop(client
, r
);
1009 return client_initialize_events(client
, client_receive_message_raw
);
1012 static int client_timeout_t1(sd_event_source
*s
, uint64_t usec
,
1014 sd_dhcp_client
*client
= userdata
;
1015 DHCP_CLIENT_DONT_DESTROY(client
);
1017 client
->state
= DHCP_STATE_RENEWING
;
1018 client
->attempt
= 1;
1020 return client_initialize_time_events(client
);
1023 static int client_handle_offer(sd_dhcp_client
*client
, DHCPMessage
*offer
,
1025 _cleanup_dhcp_lease_unref_ sd_dhcp_lease
*lease
= NULL
;
1028 r
= dhcp_lease_new(&lease
);
1032 r
= dhcp_option_parse(offer
, len
, dhcp_lease_parse_options
, lease
);
1033 if (r
!= DHCP_OFFER
) {
1034 log_dhcp_client(client
, "received message was not an OFFER, ignoring");
1038 lease
->next_server
= offer
->siaddr
;
1040 lease
->address
= offer
->yiaddr
;
1042 if (lease
->address
== INADDR_ANY
||
1043 lease
->server_address
== INADDR_ANY
||
1044 lease
->lifetime
== 0) {
1045 log_dhcp_client(client
, "received lease lacks address, server "
1046 "address or lease lifetime, ignoring");
1050 if (lease
->subnet_mask
== INADDR_ANY
) {
1051 r
= dhcp_lease_set_default_subnet_mask(lease
);
1053 log_dhcp_client(client
, "received lease lacks subnet "
1054 "mask, and a fallback one can not be "
1055 "generated, ignoring");
1060 sd_dhcp_lease_unref(client
->lease
);
1061 client
->lease
= lease
;
1064 log_dhcp_client(client
, "OFFER");
1069 static int client_handle_forcerenew(sd_dhcp_client
*client
, DHCPMessage
*force
,
1073 r
= dhcp_option_parse(force
, len
, NULL
, NULL
);
1074 if (r
!= DHCP_FORCERENEW
)
1077 log_dhcp_client(client
, "FORCERENEW");
1082 static int client_handle_ack(sd_dhcp_client
*client
, DHCPMessage
*ack
,
1084 _cleanup_dhcp_lease_unref_ sd_dhcp_lease
*lease
= NULL
;
1087 r
= dhcp_lease_new(&lease
);
1091 r
= dhcp_option_parse(ack
, len
, dhcp_lease_parse_options
, lease
);
1092 if (r
== DHCP_NAK
) {
1093 log_dhcp_client(client
, "NAK");
1094 return -EADDRNOTAVAIL
;
1097 if (r
!= DHCP_ACK
) {
1098 log_dhcp_client(client
, "received message was not an ACK, ignoring");
1102 lease
->next_server
= ack
->siaddr
;
1104 lease
->address
= ack
->yiaddr
;
1106 if (lease
->address
== INADDR_ANY
||
1107 lease
->server_address
== INADDR_ANY
||
1108 lease
->lifetime
== 0) {
1109 log_dhcp_client(client
, "received lease lacks address, server "
1110 "address or lease lifetime, ignoring");
1114 if (lease
->subnet_mask
== INADDR_ANY
) {
1115 r
= dhcp_lease_set_default_subnet_mask(lease
);
1117 log_dhcp_client(client
, "received lease lacks subnet "
1118 "mask, and a fallback one can not be "
1119 "generated, ignoring");
1124 r
= DHCP_EVENT_IP_ACQUIRE
;
1125 if (client
->lease
) {
1126 if (client
->lease
->address
!= lease
->address
||
1127 client
->lease
->subnet_mask
!= lease
->subnet_mask
||
1128 client
->lease
->router
!= lease
->router
) {
1129 r
= DHCP_EVENT_IP_CHANGE
;
1131 r
= DHCP_EVENT_RENEW
;
1133 client
->lease
= sd_dhcp_lease_unref(client
->lease
);
1136 client
->lease
= lease
;
1139 log_dhcp_client(client
, "ACK");
1144 static uint64_t client_compute_timeout(sd_dhcp_client
*client
,
1145 uint32_t lifetime
, double factor
) {
1147 assert(client
->request_sent
);
1150 return client
->request_sent
+ ((lifetime
- 3) * USEC_PER_SEC
* factor
) +
1151 + (random_u32() & 0x1fffff);
1154 static int client_set_lease_timeouts(sd_dhcp_client
*client
) {
1156 uint64_t lifetime_timeout
;
1157 uint64_t t2_timeout
;
1158 uint64_t t1_timeout
;
1159 char time_string
[FORMAT_TIMESPAN_MAX
];
1163 assert(client
->event
);
1164 assert(client
->lease
);
1165 assert(client
->lease
->lifetime
);
1167 client
->timeout_t1
= sd_event_source_unref(client
->timeout_t1
);
1168 client
->timeout_t2
= sd_event_source_unref(client
->timeout_t2
);
1169 client
->timeout_expire
= sd_event_source_unref(client
->timeout_expire
);
1171 /* don't set timers for infinite leases */
1172 if (client
->lease
->lifetime
== 0xffffffff)
1175 r
= sd_event_now(client
->event
, clock_boottime_or_monotonic(), &time_now
);
1178 assert(client
->request_sent
<= time_now
);
1180 /* convert the various timeouts from relative (secs) to absolute (usecs) */
1181 lifetime_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 1);
1182 if (client
->lease
->t1
&& client
->lease
->t2
) {
1183 /* both T1 and T2 are given */
1184 if (client
->lease
->t1
< client
->lease
->t2
&&
1185 client
->lease
->t2
< client
->lease
->lifetime
) {
1186 /* they are both valid */
1187 t2_timeout
= client_compute_timeout(client
, client
->lease
->t2
, 1);
1188 t1_timeout
= client_compute_timeout(client
, client
->lease
->t1
, 1);
1191 t2_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 7.0 / 8.0);
1192 client
->lease
->t2
= (client
->lease
->lifetime
* 7) / 8;
1193 t1_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 0.5);
1194 client
->lease
->t1
= client
->lease
->lifetime
/ 2;
1196 } else if (client
->lease
->t2
&& client
->lease
->t2
< client
->lease
->lifetime
) {
1197 /* only T2 is given, and it is valid */
1198 t2_timeout
= client_compute_timeout(client
, client
->lease
->t2
, 1);
1199 t1_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 0.5);
1200 client
->lease
->t1
= client
->lease
->lifetime
/ 2;
1201 if (t2_timeout
<= t1_timeout
) {
1202 /* the computed T1 would be invalid, so discard T2 */
1203 t2_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 7.0 / 8.0);
1204 client
->lease
->t2
= (client
->lease
->lifetime
* 7) / 8;
1206 } else if (client
->lease
->t1
&& client
->lease
->t1
< client
->lease
->lifetime
) {
1207 /* only T1 is given, and it is valid */
1208 t1_timeout
= client_compute_timeout(client
, client
->lease
->t1
, 1);
1209 t2_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 7.0 / 8.0);
1210 client
->lease
->t2
= (client
->lease
->lifetime
* 7) / 8;
1211 if (t2_timeout
<= t1_timeout
) {
1212 /* the computed T2 would be invalid, so discard T1 */
1213 t2_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 0.5);
1214 client
->lease
->t2
= client
->lease
->lifetime
/ 2;
1217 /* fall back to the default timeouts */
1218 t1_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 0.5);
1219 client
->lease
->t1
= client
->lease
->lifetime
/ 2;
1220 t2_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 7.0 / 8.0);
1221 client
->lease
->t2
= (client
->lease
->lifetime
* 7) / 8;
1224 /* arm lifetime timeout */
1225 r
= sd_event_add_time(client
->event
, &client
->timeout_expire
,
1226 clock_boottime_or_monotonic(),
1227 lifetime_timeout
, 10 * USEC_PER_MSEC
,
1228 client_timeout_expire
, client
);
1232 r
= sd_event_source_set_priority(client
->timeout_expire
,
1233 client
->event_priority
);
1237 r
= sd_event_source_set_description(client
->timeout_expire
, "dhcp4-lifetime");
1241 log_dhcp_client(client
, "lease expires in %s",
1242 format_timespan(time_string
, FORMAT_TIMESPAN_MAX
,
1243 lifetime_timeout
- time_now
, 0));
1245 /* don't arm earlier timeouts if this has already expired */
1246 if (lifetime_timeout
<= time_now
)
1249 /* arm T2 timeout */
1250 r
= sd_event_add_time(client
->event
,
1251 &client
->timeout_t2
,
1252 clock_boottime_or_monotonic(),
1255 client_timeout_t2
, client
);
1259 r
= sd_event_source_set_priority(client
->timeout_t2
,
1260 client
->event_priority
);
1264 r
= sd_event_source_set_description(client
->timeout_t2
, "dhcp4-t2-timeout");
1268 log_dhcp_client(client
, "T2 expires in %s",
1269 format_timespan(time_string
, FORMAT_TIMESPAN_MAX
,
1270 t2_timeout
- time_now
, 0));
1272 /* don't arm earlier timeout if this has already expired */
1273 if (t2_timeout
<= time_now
)
1276 /* arm T1 timeout */
1277 r
= sd_event_add_time(client
->event
,
1278 &client
->timeout_t1
,
1279 clock_boottime_or_monotonic(),
1280 t1_timeout
, 10 * USEC_PER_MSEC
,
1281 client_timeout_t1
, client
);
1285 r
= sd_event_source_set_priority(client
->timeout_t1
,
1286 client
->event_priority
);
1290 r
= sd_event_source_set_description(client
->timeout_t1
, "dhcp4-t1-timer");
1294 log_dhcp_client(client
, "T1 expires in %s",
1295 format_timespan(time_string
, FORMAT_TIMESPAN_MAX
,
1296 t1_timeout
- time_now
, 0));
1301 static int client_handle_message(sd_dhcp_client
*client
, DHCPMessage
*message
,
1303 DHCP_CLIENT_DONT_DESTROY(client
);
1304 int r
= 0, notify_event
= 0;
1307 assert(client
->event
);
1310 switch (client
->state
) {
1311 case DHCP_STATE_SELECTING
:
1313 r
= client_handle_offer(client
, message
, len
);
1316 client
->timeout_resend
=
1317 sd_event_source_unref(client
->timeout_resend
);
1319 client
->state
= DHCP_STATE_REQUESTING
;
1320 client
->attempt
= 1;
1322 r
= sd_event_add_time(client
->event
,
1323 &client
->timeout_resend
,
1324 clock_boottime_or_monotonic(),
1326 client_timeout_resend
, client
);
1330 r
= sd_event_source_set_priority(client
->timeout_resend
,
1331 client
->event_priority
);
1335 r
= sd_event_source_set_description(client
->timeout_resend
, "dhcp4-resend-timer");
1338 } else if (r
== -ENOMSG
)
1339 /* invalid message, let's ignore it */
1344 case DHCP_STATE_REBOOTING
:
1345 case DHCP_STATE_REQUESTING
:
1346 case DHCP_STATE_RENEWING
:
1347 case DHCP_STATE_REBINDING
:
1349 r
= client_handle_ack(client
, message
, len
);
1351 client
->timeout_resend
=
1352 sd_event_source_unref(client
->timeout_resend
);
1353 client
->receive_message
=
1354 sd_event_source_unref(client
->receive_message
);
1355 client
->fd
= asynchronous_close(client
->fd
);
1357 if (IN_SET(client
->state
, DHCP_STATE_REQUESTING
,
1358 DHCP_STATE_REBOOTING
))
1359 notify_event
= DHCP_EVENT_IP_ACQUIRE
;
1360 else if (r
!= DHCP_EVENT_IP_ACQUIRE
)
1363 client
->state
= DHCP_STATE_BOUND
;
1364 client
->attempt
= 1;
1366 client
->last_addr
= client
->lease
->address
;
1368 r
= client_set_lease_timeouts(client
);
1372 r
= dhcp_network_bind_udp_socket(client
->lease
->address
,
1375 log_dhcp_client(client
, "could not bind UDP socket");
1381 client_initialize_io_events(client
, client_receive_message_udp
);
1384 client_notify(client
, notify_event
);
1385 if (client
->state
== DHCP_STATE_STOPPED
)
1389 } else if (r
== -EADDRNOTAVAIL
) {
1390 /* got a NAK, let's restart the client */
1391 client
->timeout_resend
=
1392 sd_event_source_unref(client
->timeout_resend
);
1394 r
= client_initialize(client
);
1398 r
= client_start(client
);
1402 log_dhcp_client(client
, "REBOOTED");
1405 } else if (r
== -ENOMSG
)
1406 /* invalid message, let's ignore it */
1411 case DHCP_STATE_BOUND
:
1412 r
= client_handle_forcerenew(client
, message
, len
);
1414 r
= client_timeout_t1(NULL
, 0, client
);
1417 } else if (r
== -ENOMSG
)
1418 /* invalid message, let's ignore it */
1423 case DHCP_STATE_INIT
:
1424 case DHCP_STATE_INIT_REBOOT
:
1428 case DHCP_STATE_STOPPED
:
1435 client_stop(client
, r
);
1440 static int client_receive_message_udp(sd_event_source
*s
, int fd
,
1441 uint32_t revents
, void *userdata
) {
1442 sd_dhcp_client
*client
= userdata
;
1443 _cleanup_free_ DHCPMessage
*message
= NULL
;
1444 int buflen
= 0, len
, r
;
1445 const struct ether_addr zero_mac
= { { 0, 0, 0, 0, 0, 0 } };
1446 const struct ether_addr
*expected_chaddr
= NULL
;
1447 uint8_t expected_hlen
= 0;
1452 r
= ioctl(fd
, FIONREAD
, &buflen
);
1457 /* this can't be right */
1460 message
= malloc0(buflen
);
1464 len
= read(fd
, message
, buflen
);
1466 log_dhcp_client(client
, "could not receive message from UDP "
1469 } else if ((size_t)len
< sizeof(DHCPMessage
)) {
1470 log_dhcp_client(client
, "too small to be a DHCP message: ignoring");
1474 if (be32toh(message
->magic
) != DHCP_MAGIC_COOKIE
) {
1475 log_dhcp_client(client
, "not a DHCP message: ignoring");
1479 if (message
->op
!= BOOTREPLY
) {
1480 log_dhcp_client(client
, "not a BOOTREPLY message: ignoring");
1484 if (message
->htype
!= client
->arp_type
) {
1485 log_dhcp_client(client
, "packet type does not match client type");
1489 if (client
->arp_type
== ARPHRD_ETHER
) {
1490 expected_hlen
= ETH_ALEN
;
1491 expected_chaddr
= (const struct ether_addr
*) &client
->mac_addr
;
1493 /* Non-ethernet links expect zero chaddr */
1495 expected_chaddr
= &zero_mac
;
1498 if (message
->hlen
!= expected_hlen
) {
1499 log_dhcp_client(client
, "unexpected packet hlen %d", message
->hlen
);
1503 if (memcmp(&message
->chaddr
[0], expected_chaddr
, ETH_ALEN
)) {
1504 log_dhcp_client(client
, "received chaddr does not match "
1505 "expected: ignoring");
1509 if (client
->state
!= DHCP_STATE_BOUND
&&
1510 be32toh(message
->xid
) != client
->xid
) {
1511 /* in BOUND state, we may receive FORCERENEW with xid set by server,
1512 so ignore the xid in this case */
1513 log_dhcp_client(client
, "received xid (%u) does not match "
1514 "expected (%u): ignoring",
1515 be32toh(message
->xid
), client
->xid
);
1519 return client_handle_message(client
, message
, len
);
1522 static int client_receive_message_raw(sd_event_source
*s
, int fd
,
1523 uint32_t revents
, void *userdata
) {
1524 sd_dhcp_client
*client
= userdata
;
1525 _cleanup_free_ DHCPPacket
*packet
= NULL
;
1526 uint8_t cmsgbuf
[CMSG_LEN(sizeof(struct tpacket_auxdata
))];
1527 struct iovec iov
= {};
1528 struct msghdr msg
= {
1531 .msg_control
= cmsgbuf
,
1532 .msg_controllen
= sizeof(cmsgbuf
),
1534 struct cmsghdr
*cmsg
;
1535 bool checksum
= true;
1536 int buflen
= 0, len
, r
;
1541 r
= ioctl(fd
, FIONREAD
, &buflen
);
1546 /* this can't be right */
1549 packet
= malloc0(buflen
);
1553 iov
.iov_base
= packet
;
1554 iov
.iov_len
= buflen
;
1556 len
= recvmsg(fd
, &msg
, 0);
1558 log_dhcp_client(client
, "could not receive message from raw "
1561 } else if ((size_t)len
< sizeof(DHCPPacket
))
1564 for (cmsg
= CMSG_FIRSTHDR(&msg
); cmsg
; cmsg
= CMSG_NXTHDR(&msg
, cmsg
)) {
1565 if (cmsg
->cmsg_level
== SOL_PACKET
&&
1566 cmsg
->cmsg_type
== PACKET_AUXDATA
&&
1567 cmsg
->cmsg_len
== CMSG_LEN(sizeof(struct tpacket_auxdata
))) {
1568 struct tpacket_auxdata
*aux
= (struct tpacket_auxdata
*)CMSG_DATA(cmsg
);
1570 checksum
= !(aux
->tp_status
& TP_STATUS_CSUMNOTREADY
);
1575 r
= dhcp_packet_verify_headers(packet
, len
, checksum
);
1579 len
-= DHCP_IP_UDP_SIZE
;
1581 return client_handle_message(client
, &packet
->dhcp
, len
);
1584 int sd_dhcp_client_start(sd_dhcp_client
*client
) {
1587 assert_return(client
, -EINVAL
);
1589 r
= client_initialize(client
);
1593 if (client
->last_addr
)
1594 client
->state
= DHCP_STATE_INIT_REBOOT
;
1596 r
= client_start(client
);
1598 log_dhcp_client(client
, "STARTED on ifindex %u", client
->index
);
1603 int sd_dhcp_client_stop(sd_dhcp_client
*client
) {
1604 DHCP_CLIENT_DONT_DESTROY(client
);
1606 assert_return(client
, -EINVAL
);
1608 client_stop(client
, DHCP_EVENT_STOP
);
1609 client
->state
= DHCP_STATE_STOPPED
;
1614 int sd_dhcp_client_attach_event(sd_dhcp_client
*client
, sd_event
*event
,
1618 assert_return(client
, -EINVAL
);
1619 assert_return(!client
->event
, -EBUSY
);
1622 client
->event
= sd_event_ref(event
);
1624 r
= sd_event_default(&client
->event
);
1629 client
->event_priority
= priority
;
1634 int sd_dhcp_client_detach_event(sd_dhcp_client
*client
) {
1635 assert_return(client
, -EINVAL
);
1637 client
->event
= sd_event_unref(client
->event
);
1642 sd_event
*sd_dhcp_client_get_event(sd_dhcp_client
*client
) {
1646 return client
->event
;
1649 sd_dhcp_client
*sd_dhcp_client_ref(sd_dhcp_client
*client
) {
1651 assert_se(REFCNT_INC(client
->n_ref
) >= 2);
1656 sd_dhcp_client
*sd_dhcp_client_unref(sd_dhcp_client
*client
) {
1657 if (client
&& REFCNT_DEC(client
->n_ref
) <= 0) {
1658 log_dhcp_client(client
, "FREE");
1660 client_initialize(client
);
1662 client
->receive_message
=
1663 sd_event_source_unref(client
->receive_message
);
1665 sd_dhcp_client_detach_event(client
);
1667 sd_dhcp_lease_unref(client
->lease
);
1669 free(client
->req_opts
);
1670 free(client
->hostname
);
1671 free(client
->vendor_class_identifier
);
1678 int sd_dhcp_client_new(sd_dhcp_client
**ret
) {
1679 _cleanup_dhcp_client_unref_ sd_dhcp_client
*client
= NULL
;
1681 assert_return(ret
, -EINVAL
);
1683 client
= new0(sd_dhcp_client
, 1);
1687 client
->n_ref
= REFCNT_INIT
;
1688 client
->state
= DHCP_STATE_INIT
;
1691 client
->attempt
= 1;
1692 client
->mtu
= DHCP_DEFAULT_MIN_SIZE
;
1694 client
->req_opts_size
= ELEMENTSOF(default_req_opts
);
1696 client
->req_opts
= memdup(default_req_opts
, client
->req_opts_size
);
1697 if (!client
->req_opts
)