chiark / gitweb /
sd-dhcp-client: only verify UDP messages
[elogind.git] / src / libsystemd-network / sd-dhcp-client.c
1 /***
2   This file is part of systemd.
3
4   Copyright (C) 2013 Intel Corporation. All rights reserved.
5
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.
10
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.
15
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/>.
18 ***/
19
20 #include <stdlib.h>
21 #include <errno.h>
22 #include <string.h>
23 #include <stdio.h>
24 #include <net/ethernet.h>
25 #include <net/if_arp.h>
26 #include <netinet/ether.h>
27 #include <sys/param.h>
28 #include <sys/ioctl.h>
29
30 #include "util.h"
31 #include "list.h"
32 #include "refcnt.h"
33 #include "async.h"
34
35 #include "dhcp-protocol.h"
36 #include "dhcp-internal.h"
37 #include "dhcp-lease-internal.h"
38 #include "sd-dhcp-client.h"
39
40 struct sd_dhcp_client {
41         RefCount n_ref;
42
43         DHCPState state;
44         sd_event *event;
45         int event_priority;
46         sd_event_source *timeout_resend;
47         int index;
48         int fd;
49         union sockaddr_union link;
50         sd_event_source *receive_message;
51         bool request_broadcast;
52         uint8_t *req_opts;
53         size_t req_opts_allocated;
54         size_t req_opts_size;
55         be32_t last_addr;
56         struct {
57                 uint8_t type;
58                 struct ether_addr mac_addr;
59         } _packed_ client_id;
60         char *hostname;
61         char *vendor_class_identifier;
62         uint32_t xid;
63         usec_t start_time;
64         uint16_t secs;
65         unsigned int attempt;
66         usec_t request_sent;
67         sd_event_source *timeout_t1;
68         sd_event_source *timeout_t2;
69         sd_event_source *timeout_expire;
70         sd_dhcp_client_cb_t cb;
71         void *userdata;
72         sd_dhcp_lease *lease;
73 };
74
75 static const uint8_t default_req_opts[] = {
76         DHCP_OPTION_SUBNET_MASK,
77         DHCP_OPTION_ROUTER,
78         DHCP_OPTION_HOST_NAME,
79         DHCP_OPTION_DOMAIN_NAME,
80         DHCP_OPTION_DOMAIN_NAME_SERVER,
81         DHCP_OPTION_NTP_SERVER,
82 };
83
84 static int client_receive_message_raw(sd_event_source *s, int fd,
85                                       uint32_t revents, void *userdata);
86 static int client_receive_message_udp(sd_event_source *s, int fd,
87                                       uint32_t revents, void *userdata);
88 static void client_stop(sd_dhcp_client *client, int error);
89
90 int sd_dhcp_client_set_callback(sd_dhcp_client *client, sd_dhcp_client_cb_t cb,
91                                 void *userdata) {
92         assert_return(client, -EINVAL);
93
94         client->cb = cb;
95         client->userdata = userdata;
96
97         return 0;
98 }
99
100 int sd_dhcp_client_set_request_broadcast(sd_dhcp_client *client, int broadcast) {
101         assert_return(client, -EINVAL);
102
103         client->request_broadcast = !!broadcast;
104
105         return 0;
106 }
107
108 int sd_dhcp_client_set_request_option(sd_dhcp_client *client, uint8_t option) {
109         size_t i;
110
111         assert_return(client, -EINVAL);
112         assert_return (IN_SET(client->state, DHCP_STATE_INIT,
113                               DHCP_STATE_STOPPED), -EBUSY);
114
115         switch(option) {
116         case DHCP_OPTION_PAD:
117         case DHCP_OPTION_OVERLOAD:
118         case DHCP_OPTION_MESSAGE_TYPE:
119         case DHCP_OPTION_PARAMETER_REQUEST_LIST:
120         case DHCP_OPTION_END:
121                 return -EINVAL;
122
123         default:
124                 break;
125         }
126
127         for (i = 0; i < client->req_opts_size; i++)
128                 if (client->req_opts[i] == option)
129                         return -EEXIST;
130
131         if (!GREEDY_REALLOC(client->req_opts, client->req_opts_allocated,
132                             client->req_opts_size + 1))
133                 return -ENOMEM;
134
135         client->req_opts[client->req_opts_size++] = option;
136
137         return 0;
138 }
139
140 int sd_dhcp_client_set_request_address(sd_dhcp_client *client,
141                                        const struct in_addr *last_addr) {
142         assert_return(client, -EINVAL);
143         assert_return (IN_SET(client->state, DHCP_STATE_INIT,
144                               DHCP_STATE_STOPPED), -EBUSY);
145
146         if (last_addr)
147                 client->last_addr = last_addr->s_addr;
148         else
149                 client->last_addr = INADDR_ANY;
150
151         return 0;
152 }
153
154 int sd_dhcp_client_set_index(sd_dhcp_client *client, int interface_index) {
155         assert_return(client, -EINVAL);
156         assert_return (IN_SET(client->state, DHCP_STATE_INIT,
157                               DHCP_STATE_STOPPED), -EBUSY);
158         assert_return(interface_index > 0, -EINVAL);
159
160         client->index = interface_index;
161
162         return 0;
163 }
164
165 int sd_dhcp_client_set_mac(sd_dhcp_client *client,
166                            const struct ether_addr *addr) {
167         DHCP_CLIENT_DONT_DESTROY(client);
168         bool need_restart = false;
169
170         assert_return(client, -EINVAL);
171         assert_return(addr, -EINVAL);
172
173         if (memcmp(&client->client_id.mac_addr, addr, ETH_ALEN) == 0)
174                 return 0;
175
176         if (!IN_SET(client->state, DHCP_STATE_INIT, DHCP_STATE_STOPPED)) {
177                 log_dhcp_client(client, "Changing MAC address on running DHCP "
178                                 "client, restarting");
179                 need_restart = true;
180                 client_stop(client, DHCP_EVENT_STOP);
181         }
182
183         memcpy(&client->client_id.mac_addr, addr, ETH_ALEN);
184         client->client_id.type = 0x01;
185
186         if (need_restart && client->state != DHCP_STATE_STOPPED)
187                 sd_dhcp_client_start(client);
188
189         return 0;
190 }
191
192 int sd_dhcp_client_set_hostname(sd_dhcp_client *client,
193                                 const char *hostname) {
194         char *new_hostname = NULL;
195
196         assert_return(client, -EINVAL);
197
198         if (streq_ptr(client->hostname, hostname))
199                 return 0;
200
201         if (hostname) {
202                 new_hostname = strdup(hostname);
203                 if (!new_hostname)
204                         return -ENOMEM;
205         }
206
207         free(client->hostname);
208         client->hostname = new_hostname;
209
210         return 0;
211 }
212
213 int sd_dhcp_client_set_vendor_class_identifier(sd_dhcp_client *client,
214                                                const char *vci) {
215         char *new_vci = NULL;
216
217         assert_return(client, -EINVAL);
218
219         new_vci = strdup(vci);
220         if (!new_vci)
221                 return -ENOMEM;
222
223         free(client->vendor_class_identifier);
224
225         client->vendor_class_identifier = new_vci;
226
227         return 0;
228 }
229
230 int sd_dhcp_client_get_lease(sd_dhcp_client *client, sd_dhcp_lease **ret) {
231         assert_return(client, -EINVAL);
232         assert_return(ret, -EINVAL);
233
234         if (client->state != DHCP_STATE_BOUND &&
235             client->state != DHCP_STATE_RENEWING &&
236             client->state != DHCP_STATE_REBINDING)
237                 return -EADDRNOTAVAIL;
238
239         *ret = sd_dhcp_lease_ref(client->lease);
240
241         return 0;
242 }
243
244 static void client_notify(sd_dhcp_client *client, int event) {
245         if (client->cb)
246                 client->cb(client, event, client->userdata);
247 }
248
249 static int client_initialize(sd_dhcp_client *client) {
250         assert_return(client, -EINVAL);
251
252         client->receive_message =
253                 sd_event_source_unref(client->receive_message);
254
255         client->fd = asynchronous_close(client->fd);
256
257         client->timeout_resend = sd_event_source_unref(client->timeout_resend);
258
259         client->timeout_t1 = sd_event_source_unref(client->timeout_t1);
260         client->timeout_t2 = sd_event_source_unref(client->timeout_t2);
261         client->timeout_expire = sd_event_source_unref(client->timeout_expire);
262
263         client->attempt = 1;
264
265         client->state = DHCP_STATE_INIT;
266         client->xid = 0;
267
268         if (client->lease)
269                 client->lease = sd_dhcp_lease_unref(client->lease);
270
271         return 0;
272 }
273
274 static void client_stop(sd_dhcp_client *client, int error) {
275         assert(client);
276
277         if (error < 0)
278                 log_dhcp_client(client, "STOPPED: %s", strerror(-error));
279         else {
280                 switch(error) {
281                 case DHCP_EVENT_STOP:
282                         log_dhcp_client(client, "STOPPED");
283                         break;
284                 case DHCP_EVENT_NO_LEASE:
285                         log_dhcp_client(client, "STOPPED: No lease");
286                         break;
287                 default:
288                         log_dhcp_client(client, "STOPPED: Unknown reason");
289                         break;
290                 }
291         }
292
293         client_notify(client, error);
294
295         client_initialize(client);
296 }
297
298 static int client_message_init(sd_dhcp_client *client, DHCPPacket **ret,
299                                uint8_t type, size_t *_optlen, size_t *_optoffset) {
300         _cleanup_free_ DHCPPacket *packet;
301         size_t optlen, optoffset, size;
302         be16_t max_size;
303         int r;
304
305         assert(client);
306         assert(client->secs);
307         assert(ret);
308         assert(_optlen);
309         assert(_optoffset);
310         assert(type == DHCP_DISCOVER || type == DHCP_REQUEST);
311
312         optlen = DHCP_MIN_OPTIONS_SIZE;
313         size = sizeof(DHCPPacket) + optlen;
314
315         packet = malloc0(size);
316         if (!packet)
317                 return -ENOMEM;
318
319         r = dhcp_message_init(&packet->dhcp, BOOTREQUEST, client->xid, type,
320                               optlen, &optoffset);
321         if (r < 0)
322                 return r;
323
324         /* Although 'secs' field is a SHOULD in RFC 2131, certain DHCP servers
325            refuse to issue an DHCP lease if 'secs' is set to zero */
326         packet->dhcp.secs = htobe16(client->secs);
327
328         /* RFC2132 section 4.1
329            A client that cannot receive unicast IP datagrams until its protocol
330            software has been configured with an IP address SHOULD set the
331            BROADCAST bit in the 'flags' field to 1 in any DHCPDISCOVER or
332            DHCPREQUEST messages that client sends.  The BROADCAST bit will
333            provide a hint to the DHCP server and BOOTP relay agent to broadcast
334            any messages to the client on the client's subnet.
335
336            Note: some interfaces needs this to be enabled, but some networks
337            needs this to be disabled as broadcasts are filteretd, so this
338            needs to be configurable */
339         if (client->request_broadcast)
340                 packet->dhcp.flags = htobe16(0x8000);
341
342         /* RFC2132 section 4.1.1:
343            The client MUST include its hardware address in the â€™chaddr’ field, if
344            necessary for delivery of DHCP reply messages.
345          */
346         memcpy(&packet->dhcp.chaddr, &client->client_id.mac_addr, ETH_ALEN);
347
348         /* Some DHCP servers will refuse to issue an DHCP lease if the Client
349            Identifier option is not set */
350         r = dhcp_option_append(&packet->dhcp, optlen, &optoffset, 0,
351                                DHCP_OPTION_CLIENT_IDENTIFIER,
352                                sizeof(client->client_id), &client->client_id);
353         if (r < 0)
354                 return r;
355
356
357         /* RFC2131 section 3.5:
358            in its initial DHCPDISCOVER or DHCPREQUEST message, a
359            client may provide the server with a list of specific
360            parameters the client is interested in. If the client
361            includes a list of parameters in a DHCPDISCOVER message,
362            it MUST include that list in any subsequent DHCPREQUEST
363            messages.
364          */
365         r = dhcp_option_append(&packet->dhcp, optlen, &optoffset, 0,
366                                DHCP_OPTION_PARAMETER_REQUEST_LIST,
367                                client->req_opts_size, client->req_opts);
368         if (r < 0)
369                 return r;
370
371         /* RFC2131 section 3.5:
372            The client SHOULD include the â€™maximum DHCP message size’ option to
373            let the server know how large the server may make its DHCP messages.
374
375            Note (from ConnMan): Some DHCP servers will send bigger DHCP packets
376            than the defined default size unless the Maximum Messge Size option
377            is explicitely set
378          */
379         max_size = htobe16(size);
380         r = dhcp_option_append(&packet->dhcp, optlen, &optoffset, 0,
381                                DHCP_OPTION_MAXIMUM_MESSAGE_SIZE,
382                                2, &max_size);
383         if (r < 0)
384                 return r;
385
386         *_optlen = optlen;
387         *_optoffset = optoffset;
388         *ret = packet;
389         packet = NULL;
390
391         return 0;
392 }
393
394 static int dhcp_client_send_raw(sd_dhcp_client *client, DHCPPacket *packet,
395                                 size_t len) {
396         dhcp_packet_append_ip_headers(packet, INADDR_ANY, DHCP_PORT_CLIENT,
397                                       INADDR_BROADCAST, DHCP_PORT_SERVER, len);
398
399         return dhcp_network_send_raw_socket(client->fd, &client->link,
400                                             packet, len);
401 }
402
403 static int client_send_discover(sd_dhcp_client *client) {
404         _cleanup_free_ DHCPPacket *discover = NULL;
405         size_t optoffset, optlen;
406         usec_t time_now;
407         int r;
408
409         assert(client);
410         assert(client->state == DHCP_STATE_INIT ||
411                client->state == DHCP_STATE_SELECTING);
412
413         /* See RFC2131 section 4.4.1 */
414
415         r = sd_event_now(client->event, clock_boottime_or_monotonic(), &time_now);
416         if (r < 0)
417                 return r;
418         assert(time_now >= client->start_time);
419
420         /* seconds between sending first and last DISCOVER
421          * must always be strictly positive to deal with broken servers */
422         client->secs = ((time_now - client->start_time) / USEC_PER_SEC) ? : 1;
423
424         r = client_message_init(client, &discover, DHCP_DISCOVER,
425                                 &optlen, &optoffset);
426         if (r < 0)
427                 return r;
428
429         /* the client may suggest values for the network address
430            and lease time in the DHCPDISCOVER message. The client may include
431            the â€™requested IP address’ option to suggest that a particular IP
432            address be assigned, and may include the â€™IP address lease time’
433            option to suggest the lease time it would like.
434          */
435         if (client->last_addr != INADDR_ANY) {
436                 r = dhcp_option_append(&discover->dhcp, optlen, &optoffset, 0,
437                                        DHCP_OPTION_REQUESTED_IP_ADDRESS,
438                                        4, &client->last_addr);
439                 if (r < 0)
440                         return r;
441         }
442
443         /* it is unclear from RFC 2131 if client should send hostname in
444            DHCPDISCOVER but dhclient does and so we do as well
445         */
446         if (client->hostname) {
447                 r = dhcp_option_append(&discover->dhcp, optlen, &optoffset, 0,
448                                        DHCP_OPTION_HOST_NAME,
449                                        strlen(client->hostname), client->hostname);
450                 if (r < 0)
451                         return r;
452         }
453
454         if (client->vendor_class_identifier) {
455                 r = dhcp_option_append(&discover->dhcp, optlen, &optoffset, 0,
456                                        DHCP_OPTION_VENDOR_CLASS_IDENTIFIER,
457                                        strlen(client->vendor_class_identifier),
458                                        client->vendor_class_identifier);
459                 if (r < 0)
460                         return r;
461         }
462
463         r = dhcp_option_append(&discover->dhcp, optlen, &optoffset, 0,
464                                DHCP_OPTION_END, 0, NULL);
465         if (r < 0)
466                 return r;
467
468         /* We currently ignore:
469            The client SHOULD wait a random time between one and ten seconds to
470            desynchronize the use of DHCP at startup.
471          */
472         r = dhcp_client_send_raw(client, discover, sizeof(DHCPPacket) + optoffset);
473         if (r < 0)
474                 return r;
475
476         log_dhcp_client(client, "DISCOVER");
477
478         return 0;
479 }
480
481 static int client_send_request(sd_dhcp_client *client) {
482         _cleanup_free_ DHCPPacket *request = NULL;
483         size_t optoffset, optlen;
484         int r;
485
486         r = client_message_init(client, &request, DHCP_REQUEST,
487                                 &optlen, &optoffset);
488         if (r < 0)
489                 return r;
490
491         switch (client->state) {
492         /* See RFC2131 section 4.3.2 (note that there is a typo in the RFC,
493            SELECTING should be REQUESTING)
494          */
495
496         case DHCP_STATE_REQUESTING:
497                 /* Client inserts the address of the selected server in â€™server
498                    identifier’, â€™ciaddr’ MUST be zero, â€™requested IP address’ MUST be
499                    filled in with the yiaddr value from the chosen DHCPOFFER.
500                  */
501
502                 r = dhcp_option_append(&request->dhcp, optlen, &optoffset, 0,
503                                        DHCP_OPTION_SERVER_IDENTIFIER,
504                                        4, &client->lease->server_address);
505                 if (r < 0)
506                         return r;
507
508                 r = dhcp_option_append(&request->dhcp, optlen, &optoffset, 0,
509                                        DHCP_OPTION_REQUESTED_IP_ADDRESS,
510                                        4, &client->lease->address);
511                 if (r < 0)
512                         return r;
513
514                 break;
515
516         case DHCP_STATE_INIT_REBOOT:
517                 /* â€™server identifier’ MUST NOT be filled in, â€™requested IP address’
518                    option MUST be filled in with client’s notion of its previously
519                    assigned address. â€™ciaddr’ MUST be zero.
520                  */
521                 r = dhcp_option_append(&request->dhcp, optlen, &optoffset, 0,
522                                        DHCP_OPTION_REQUESTED_IP_ADDRESS,
523                                        4, &client->last_addr);
524                 if (r < 0)
525                         return r;
526                 break;
527
528         case DHCP_STATE_RENEWING:
529                 /* â€™server identifier’ MUST NOT be filled in, â€™requested IP address’
530                    option MUST NOT be filled in, â€™ciaddr’ MUST be filled in with
531                    client’s IP address.
532                 */
533
534                 /* fall through */
535         case DHCP_STATE_REBINDING:
536                 /* â€™server identifier’ MUST NOT be filled in, â€™requested IP address’
537                    option MUST NOT be filled in, â€™ciaddr’ MUST be filled in with
538                    client’s IP address.
539
540                    This message MUST be broadcast to the 0xffffffff IP broadcast address.
541                  */
542                 request->dhcp.ciaddr = client->lease->address;
543
544                 break;
545
546         case DHCP_STATE_INIT:
547         case DHCP_STATE_SELECTING:
548         case DHCP_STATE_REBOOTING:
549         case DHCP_STATE_BOUND:
550         case DHCP_STATE_STOPPED:
551                 return -EINVAL;
552         }
553
554         if (client->hostname) {
555                 r = dhcp_option_append(&request->dhcp, optlen, &optoffset, 0,
556                                        DHCP_OPTION_HOST_NAME,
557                                        strlen(client->hostname), client->hostname);
558                 if (r < 0)
559                         return r;
560         }
561
562         r = dhcp_option_append(&request->dhcp, optlen, &optoffset, 0,
563                                DHCP_OPTION_END, 0, NULL);
564         if (r < 0)
565                 return r;
566
567         if (client->state == DHCP_STATE_RENEWING) {
568                 r = dhcp_network_send_udp_socket(client->fd,
569                                                  client->lease->server_address,
570                                                  DHCP_PORT_SERVER,
571                                                  &request->dhcp,
572                                                  sizeof(DHCPMessage) + optoffset);
573         } else {
574                 r = dhcp_client_send_raw(client, request, sizeof(DHCPPacket) + optoffset);
575         }
576         if (r < 0)
577                 return r;
578
579         switch (client->state) {
580         case DHCP_STATE_REQUESTING:
581                 log_dhcp_client(client, "REQUEST (requesting)");
582                 break;
583         case DHCP_STATE_INIT_REBOOT:
584                 log_dhcp_client(client, "REQUEST (init-reboot)");
585                 break;
586         case DHCP_STATE_RENEWING:
587                 log_dhcp_client(client, "REQUEST (renewing)");
588                 break;
589         case DHCP_STATE_REBINDING:
590                 log_dhcp_client(client, "REQUEST (rebinding)");
591                 break;
592         default:
593                 log_dhcp_client(client, "REQUEST (invalid)");
594                 break;
595         }
596
597         return 0;
598 }
599
600 static int client_start(sd_dhcp_client *client);
601
602 static int client_timeout_resend(sd_event_source *s, uint64_t usec,
603                                  void *userdata) {
604         sd_dhcp_client *client = userdata;
605         DHCP_CLIENT_DONT_DESTROY(client);
606         usec_t next_timeout = 0;
607         uint64_t time_now;
608         uint32_t time_left;
609         int r;
610
611         assert(s);
612         assert(client);
613         assert(client->event);
614
615         r = sd_event_now(client->event, clock_boottime_or_monotonic(), &time_now);
616         if (r < 0)
617                 goto error;
618
619         switch (client->state) {
620         case DHCP_STATE_RENEWING:
621
622                 time_left = (client->lease->t2 - client->lease->t1) / 2;
623                 if (time_left < 60)
624                         time_left = 60;
625
626                 next_timeout = time_now + time_left * USEC_PER_SEC;
627
628                 break;
629
630         case DHCP_STATE_REBINDING:
631
632                 time_left = (client->lease->lifetime - client->lease->t2) / 2;
633                 if (time_left < 60)
634                         time_left = 60;
635
636                 next_timeout = time_now + time_left * USEC_PER_SEC;
637                 break;
638
639         case DHCP_STATE_REBOOTING:
640                 /* start over as we did not receive a timely ack or nak */
641                 r = client_initialize(client);
642                 if (r < 0)
643                         goto error;
644
645                 r = client_start(client);
646                 if (r < 0)
647                         goto error;
648                 else {
649                         log_dhcp_client(client, "REBOOTED");
650                         return 0;
651                 }
652
653         case DHCP_STATE_INIT:
654         case DHCP_STATE_INIT_REBOOT:
655         case DHCP_STATE_SELECTING:
656         case DHCP_STATE_REQUESTING:
657         case DHCP_STATE_BOUND:
658
659                 if (client->attempt < 64)
660                         client->attempt *= 2;
661
662                 next_timeout = time_now + (client->attempt - 1) * USEC_PER_SEC;
663
664                 break;
665
666         case DHCP_STATE_STOPPED:
667                 r = -EINVAL;
668                 goto error;
669         }
670
671         next_timeout += (random_u32() & 0x1fffff);
672
673         client->timeout_resend = sd_event_source_unref(client->timeout_resend);
674
675         r = sd_event_add_time(client->event,
676                               &client->timeout_resend,
677                               clock_boottime_or_monotonic(),
678                               next_timeout, 10 * USEC_PER_MSEC,
679                               client_timeout_resend, client);
680         if (r < 0)
681                 goto error;
682
683         r = sd_event_source_set_priority(client->timeout_resend,
684                                          client->event_priority);
685         if (r < 0)
686                 goto error;
687
688         switch (client->state) {
689         case DHCP_STATE_INIT:
690                 r = client_send_discover(client);
691                 if (r >= 0) {
692                         client->state = DHCP_STATE_SELECTING;
693                         client->attempt = 1;
694                 } else {
695                         if (client->attempt >= 64)
696                                 goto error;
697                 }
698
699                 break;
700
701         case DHCP_STATE_SELECTING:
702                 r = client_send_discover(client);
703                 if (r < 0 && client->attempt >= 64)
704                         goto error;
705
706                 break;
707
708         case DHCP_STATE_INIT_REBOOT:
709         case DHCP_STATE_REQUESTING:
710         case DHCP_STATE_RENEWING:
711         case DHCP_STATE_REBINDING:
712                 r = client_send_request(client);
713                 if (r < 0 && client->attempt >= 64)
714                          goto error;
715
716                 if (client->state == DHCP_STATE_INIT_REBOOT)
717                         client->state = DHCP_STATE_REBOOTING;
718
719                 client->request_sent = time_now;
720
721                 break;
722
723         case DHCP_STATE_REBOOTING:
724         case DHCP_STATE_BOUND:
725
726                 break;
727
728         case DHCP_STATE_STOPPED:
729                 r = -EINVAL;
730                 goto error;
731         }
732
733         return 0;
734
735 error:
736         client_stop(client, r);
737
738         /* Errors were dealt with when stopping the client, don't spill
739            errors into the event loop handler */
740         return 0;
741 }
742
743 static int client_initialize_events(sd_dhcp_client *client,
744                                     sd_event_io_handler_t io_callback) {
745         int r;
746
747         assert(client);
748         assert(client->event);
749
750         r = sd_event_add_io(client->event, &client->receive_message,
751                             client->fd, EPOLLIN, io_callback,
752                             client);
753         if (r < 0)
754                 goto error;
755
756         r = sd_event_source_set_priority(client->receive_message,
757                                          client->event_priority);
758         if (r < 0)
759                 goto error;
760
761         client->timeout_resend = sd_event_source_unref(client->timeout_resend);
762
763         r = sd_event_add_time(client->event,
764                               &client->timeout_resend,
765                               clock_boottime_or_monotonic(),
766                               0, 0,
767                               client_timeout_resend, client);
768         if (r < 0)
769                 goto error;
770
771         r = sd_event_source_set_priority(client->timeout_resend,
772                                          client->event_priority);
773
774 error:
775         if (r < 0)
776                 client_stop(client, r);
777
778         return 0;
779
780 }
781
782 static int client_start(sd_dhcp_client *client) {
783         int r;
784
785         assert_return(client, -EINVAL);
786         assert_return(client->event, -EINVAL);
787         assert_return(client->index > 0, -EINVAL);
788         assert_return(client->fd < 0, -EBUSY);
789         assert_return(client->xid == 0, -EINVAL);
790         assert_return(client->state == DHCP_STATE_INIT ||
791                       client->state == DHCP_STATE_INIT_REBOOT, -EBUSY);
792
793         client->xid = random_u32();
794
795         r = dhcp_network_bind_raw_socket(client->index, &client->link, client->xid, client->client_id.mac_addr);
796         if (r < 0) {
797                 client_stop(client, r);
798                 return r;
799         }
800         client->fd = r;
801
802         if (client->state == DHCP_STATE_INIT) {
803                 client->start_time = now(clock_boottime_or_monotonic());
804                 client->secs = 0;
805         }
806
807         return client_initialize_events(client, client_receive_message_raw);
808 }
809
810 static int client_timeout_expire(sd_event_source *s, uint64_t usec,
811                                  void *userdata) {
812         sd_dhcp_client *client = userdata;
813         DHCP_CLIENT_DONT_DESTROY(client);
814
815         log_dhcp_client(client, "EXPIRED");
816
817         client_notify(client, DHCP_EVENT_EXPIRED);
818
819         /* lease was lost, start over if not freed or stopped in callback */
820         if (client->state != DHCP_STATE_STOPPED) {
821                 client_initialize(client);
822                 client_start(client);
823         }
824
825         return 0;
826 }
827
828 static int client_timeout_t2(sd_event_source *s, uint64_t usec, void *userdata) {
829         sd_dhcp_client *client = userdata;
830         DHCP_CLIENT_DONT_DESTROY(client);
831         int r;
832
833         client->receive_message = sd_event_source_unref(client->receive_message);
834         client->fd = asynchronous_close(client->fd);
835
836         client->state = DHCP_STATE_REBINDING;
837         client->attempt = 1;
838
839         r = dhcp_network_bind_raw_socket(client->index, &client->link, client->xid, client->client_id.mac_addr);
840         if (r < 0) {
841                 client_stop(client, r);
842                 return 0;
843         }
844         client->fd = r;
845
846         return client_initialize_events(client, client_receive_message_raw);
847 }
848
849 static int client_timeout_t1(sd_event_source *s, uint64_t usec,
850                              void *userdata) {
851         sd_dhcp_client *client = userdata;
852         DHCP_CLIENT_DONT_DESTROY(client);
853         int r;
854
855         client->state = DHCP_STATE_RENEWING;
856         client->attempt = 1;
857
858         r = dhcp_network_bind_udp_socket(client->lease->address,
859                                          DHCP_PORT_CLIENT);
860         if (r < 0) {
861                 log_dhcp_client(client, "could not bind UDP socket");
862                 return 0;
863         }
864
865         client->fd = r;
866
867         return client_initialize_events(client, client_receive_message_udp);
868 }
869
870 static int client_handle_offer(sd_dhcp_client *client, DHCPMessage *offer,
871                                size_t len) {
872         _cleanup_dhcp_lease_unref_ sd_dhcp_lease *lease = NULL;
873         int r;
874
875         r = dhcp_lease_new(&lease);
876         if (r < 0)
877                 return r;
878
879         r = dhcp_option_parse(offer, len, dhcp_lease_parse_options, lease);
880         if (r != DHCP_OFFER) {
881                 log_dhcp_client(client, "receieved message was not an OFFER, ignoring");
882                 return -ENOMSG;
883         }
884
885         lease->next_server = offer->siaddr;
886
887         lease->address = offer->yiaddr;
888
889         if (lease->address == INADDR_ANY ||
890             lease->server_address == INADDR_ANY ||
891             lease->lifetime == 0) {
892                 log_dhcp_client(client, "receieved lease lacks address, server "
893                                 "address or lease lifetime, ignoring");
894                 return -ENOMSG;
895         }
896
897         if (lease->subnet_mask == INADDR_ANY) {
898                 r = dhcp_lease_set_default_subnet_mask(lease);
899                 if (r < 0) {
900                         log_dhcp_client(client, "receieved lease lacks subnet "
901                                         "mask, and a fallback one can not be "
902                                         "generated, ignoring");
903                         return -ENOMSG;
904                 }
905         }
906
907         sd_dhcp_lease_unref(client->lease);
908         client->lease = lease;
909         lease = NULL;
910
911         log_dhcp_client(client, "OFFER");
912
913         return 0;
914 }
915
916 static int client_handle_ack(sd_dhcp_client *client, DHCPMessage *ack,
917                              size_t len) {
918         _cleanup_dhcp_lease_unref_ sd_dhcp_lease *lease = NULL;
919         int r;
920
921         r = dhcp_lease_new(&lease);
922         if (r < 0)
923                 return r;
924
925         r = dhcp_option_parse(ack, len, dhcp_lease_parse_options, lease);
926         if (r == DHCP_NAK) {
927                 log_dhcp_client(client, "NAK");
928                 return DHCP_EVENT_NO_LEASE;
929         }
930
931         if (r != DHCP_ACK) {
932                 log_dhcp_client(client, "receieved message was not an ACK, ignoring");
933                 return -ENOMSG;
934         }
935
936         lease->next_server = ack->siaddr;
937
938         lease->address = ack->yiaddr;
939
940         if (lease->address == INADDR_ANY ||
941             lease->server_address == INADDR_ANY ||
942             lease->lifetime == 0) {
943                 log_dhcp_client(client, "receieved lease lacks address, server "
944                                 "address or lease lifetime, ignoring");
945                 return -ENOMSG;
946         }
947
948         if (lease->subnet_mask == INADDR_ANY) {
949                 r = dhcp_lease_set_default_subnet_mask(lease);
950                 if (r < 0) {
951                         log_dhcp_client(client, "receieved lease lacks subnet "
952                                         "mask, and a fallback one can not be "
953                                         "generated, ignoring");
954                         return -ENOMSG;
955                 }
956         }
957
958         r = DHCP_EVENT_IP_ACQUIRE;
959         if (client->lease) {
960                 if (client->lease->address != lease->address ||
961                     client->lease->subnet_mask != lease->subnet_mask ||
962                     client->lease->router != lease->router) {
963                         r = DHCP_EVENT_IP_CHANGE;
964                 } else
965                         r = DHCP_EVENT_RENEW;
966
967                 client->lease = sd_dhcp_lease_unref(client->lease);
968         }
969
970         client->lease = lease;
971         lease = NULL;
972
973         log_dhcp_client(client, "ACK");
974
975         return r;
976 }
977
978 static uint64_t client_compute_timeout(sd_dhcp_client *client,
979                                        uint32_t lifetime, double factor) {
980         assert(client);
981         assert(client->request_sent);
982         assert(lifetime);
983
984         return client->request_sent + ((lifetime - 3) * USEC_PER_SEC * factor) +
985                 + (random_u32() & 0x1fffff);
986 }
987
988 static int client_set_lease_timeouts(sd_dhcp_client *client) {
989         usec_t time_now;
990         uint64_t lifetime_timeout;
991         uint64_t t2_timeout;
992         uint64_t t1_timeout;
993         char time_string[FORMAT_TIMESPAN_MAX];
994         int r;
995
996         assert(client);
997         assert(client->event);
998         assert(client->lease);
999         assert(client->lease->lifetime);
1000
1001         client->timeout_t1 = sd_event_source_unref(client->timeout_t1);
1002         client->timeout_t2 = sd_event_source_unref(client->timeout_t2);
1003         client->timeout_expire = sd_event_source_unref(client->timeout_expire);
1004
1005         /* don't set timers for infinite leases */
1006         if (client->lease->lifetime == 0xffffffff)
1007                 return 0;
1008
1009         r = sd_event_now(client->event, clock_boottime_or_monotonic(), &time_now);
1010         if (r < 0)
1011                 return r;
1012         assert(client->request_sent <= time_now);
1013
1014         /* convert the various timeouts from relative (secs) to absolute (usecs) */
1015         lifetime_timeout = client_compute_timeout(client, client->lease->lifetime, 1);
1016         if (client->lease->t1 && client->lease->t2) {
1017                 /* both T1 and T2 are given */
1018                 if (client->lease->t1 < client->lease->t2 &&
1019                     client->lease->t2 < client->lease->lifetime) {
1020                         /* they are both valid */
1021                         t2_timeout = client_compute_timeout(client, client->lease->t2, 1);
1022                         t1_timeout = client_compute_timeout(client, client->lease->t1, 1);
1023                 } else {
1024                         /* discard both */
1025                         t2_timeout = client_compute_timeout(client, client->lease->lifetime, 7.0 / 8.0);
1026                         client->lease->t2 = (client->lease->lifetime * 7) / 8;
1027                         t1_timeout = client_compute_timeout(client, client->lease->lifetime, 0.5);
1028                         client->lease->t1 = client->lease->lifetime / 2;
1029                 }
1030         } else if (client->lease->t2 && client->lease->t2 < client->lease->lifetime) {
1031                 /* only T2 is given, and it is valid */
1032                 t2_timeout = client_compute_timeout(client, client->lease->t2, 1);
1033                 t1_timeout = client_compute_timeout(client, client->lease->lifetime, 0.5);
1034                 client->lease->t1 = client->lease->lifetime / 2;
1035                 if (t2_timeout <= t1_timeout) {
1036                         /* the computed T1 would be invalid, so discard T2 */
1037                         t2_timeout = client_compute_timeout(client, client->lease->lifetime, 7.0 / 8.0);
1038                         client->lease->t2 = (client->lease->lifetime * 7) / 8;
1039                 }
1040         } else if (client->lease->t1 && client->lease->t1 < client->lease->lifetime) {
1041                 /* only T1 is given, and it is valid */
1042                 t1_timeout = client_compute_timeout(client, client->lease->t1, 1);
1043                 t2_timeout = client_compute_timeout(client, client->lease->lifetime, 7.0 / 8.0);
1044                 client->lease->t2 = (client->lease->lifetime * 7) / 8;
1045                 if (t2_timeout <= t1_timeout) {
1046                         /* the computed T2 would be invalid, so discard T1 */
1047                         t2_timeout = client_compute_timeout(client, client->lease->lifetime, 0.5);
1048                         client->lease->t2 = client->lease->lifetime / 2;
1049                 }
1050         } else {
1051                 /* fall back to the default timeouts */
1052                 t1_timeout = client_compute_timeout(client, client->lease->lifetime, 0.5);
1053                 client->lease->t1 = client->lease->lifetime / 2;
1054                 t2_timeout = client_compute_timeout(client, client->lease->lifetime, 7.0 / 8.0);
1055                 client->lease->t2 = (client->lease->lifetime * 7) / 8;
1056         }
1057
1058         /* arm lifetime timeout */
1059         r = sd_event_add_time(client->event, &client->timeout_expire,
1060                               clock_boottime_or_monotonic(),
1061                               lifetime_timeout, 10 * USEC_PER_MSEC,
1062                               client_timeout_expire, client);
1063         if (r < 0)
1064                 return r;
1065
1066         r = sd_event_source_set_priority(client->timeout_expire,
1067                                          client->event_priority);
1068         if (r < 0)
1069                 return r;
1070
1071         log_dhcp_client(client, "lease expires in %s",
1072                         format_timespan(time_string, FORMAT_TIMESPAN_MAX,
1073                         lifetime_timeout - time_now, 0));
1074
1075         /* don't arm earlier timeouts if this has already expired */
1076         if (lifetime_timeout <= time_now)
1077                 return 0;
1078
1079         /* arm T2 timeout */
1080         r = sd_event_add_time(client->event,
1081                               &client->timeout_t2,
1082                               clock_boottime_or_monotonic(),
1083                               t2_timeout,
1084                               10 * USEC_PER_MSEC,
1085                               client_timeout_t2, client);
1086         if (r < 0)
1087                 return r;
1088
1089         r = sd_event_source_set_priority(client->timeout_t2,
1090                                          client->event_priority);
1091         if (r < 0)
1092                 return r;
1093
1094         log_dhcp_client(client, "T2 expires in %s",
1095                         format_timespan(time_string, FORMAT_TIMESPAN_MAX,
1096                         t2_timeout - time_now, 0));
1097
1098         /* don't arm earlier timeout if this has already expired */
1099         if (t2_timeout <= time_now)
1100                 return 0;
1101
1102         /* arm T1 timeout */
1103         r = sd_event_add_time(client->event,
1104                               &client->timeout_t1,
1105                               clock_boottime_or_monotonic(),
1106                               t1_timeout, 10 * USEC_PER_MSEC,
1107                               client_timeout_t1, client);
1108         if (r < 0)
1109                 return r;
1110
1111         r = sd_event_source_set_priority(client->timeout_t1,
1112                                          client->event_priority);
1113         if (r < 0)
1114                 return r;
1115
1116         log_dhcp_client(client, "T1 expires in %s",
1117                         format_timespan(time_string, FORMAT_TIMESPAN_MAX,
1118                         t1_timeout - time_now, 0));
1119
1120         return 0;
1121 }
1122
1123 static int client_handle_message(sd_dhcp_client *client, DHCPMessage *message,
1124                                  int len) {
1125         DHCP_CLIENT_DONT_DESTROY(client);
1126         int r = 0, notify_event = 0;
1127
1128         assert(client);
1129         assert(client->event);
1130         assert(message);
1131
1132         switch (client->state) {
1133         case DHCP_STATE_SELECTING:
1134
1135                 r = client_handle_offer(client, message, len);
1136                 if (r >= 0) {
1137
1138                         client->timeout_resend =
1139                                 sd_event_source_unref(client->timeout_resend);
1140
1141                         client->state = DHCP_STATE_REQUESTING;
1142                         client->attempt = 1;
1143
1144                         r = sd_event_add_time(client->event,
1145                                               &client->timeout_resend,
1146                                               clock_boottime_or_monotonic(),
1147                                               0, 0,
1148                                               client_timeout_resend, client);
1149                         if (r < 0)
1150                                 goto error;
1151
1152                         r = sd_event_source_set_priority(client->timeout_resend,
1153                                                          client->event_priority);
1154                         if (r < 0)
1155                                 goto error;
1156                 } else if (r == -ENOMSG)
1157                         /* invalid message, let's ignore it */
1158                         return 0;
1159
1160                 break;
1161
1162         case DHCP_STATE_REBOOTING:
1163         case DHCP_STATE_REQUESTING:
1164         case DHCP_STATE_RENEWING:
1165         case DHCP_STATE_REBINDING:
1166
1167                 r = client_handle_ack(client, message, len);
1168                 if (r == DHCP_EVENT_NO_LEASE) {
1169
1170                         client->timeout_resend =
1171                                 sd_event_source_unref(client->timeout_resend);
1172
1173                         if (client->state == DHCP_STATE_REBOOTING) {
1174                                 r = client_initialize(client);
1175                                 if (r < 0)
1176                                         goto error;
1177
1178                                 r = client_start(client);
1179                                 if (r < 0)
1180                                         goto error;
1181
1182                                 log_dhcp_client(client, "REBOOTED");
1183                         }
1184
1185                         goto error;
1186                 } else if (r >= 0) {
1187                         client->timeout_resend =
1188                                 sd_event_source_unref(client->timeout_resend);
1189
1190                         if (IN_SET(client->state, DHCP_STATE_REQUESTING,
1191                                    DHCP_STATE_REBOOTING))
1192                                 notify_event = DHCP_EVENT_IP_ACQUIRE;
1193                         else if (r != DHCP_EVENT_IP_ACQUIRE)
1194                                 notify_event = r;
1195
1196                         client->state = DHCP_STATE_BOUND;
1197                         client->attempt = 1;
1198
1199                         client->last_addr = client->lease->address;
1200
1201                         r = client_set_lease_timeouts(client);
1202                         if (r < 0)
1203                                 goto error;
1204
1205                         if (notify_event) {
1206                                 client_notify(client, notify_event);
1207                                 if (client->state == DHCP_STATE_STOPPED)
1208                                         return 0;
1209                         }
1210
1211                         client->receive_message =
1212                                 sd_event_source_unref(client->receive_message);
1213                         client->fd = asynchronous_close(client->fd);
1214                 } else if (r == -ENOMSG)
1215                         /* invalid message, let's ignore it */
1216                         return 0;
1217
1218                 break;
1219
1220         case DHCP_STATE_INIT:
1221         case DHCP_STATE_INIT_REBOOT:
1222         case DHCP_STATE_BOUND:
1223
1224                 break;
1225
1226         case DHCP_STATE_STOPPED:
1227                 r = -EINVAL;
1228                 goto error;
1229         }
1230
1231 error:
1232         if (r < 0 || r == DHCP_EVENT_NO_LEASE)
1233                 client_stop(client, r);
1234
1235         return r;
1236 }
1237
1238 static int client_receive_message_udp(sd_event_source *s, int fd,
1239                                       uint32_t revents, void *userdata) {
1240         sd_dhcp_client *client = userdata;
1241         _cleanup_free_ DHCPMessage *message = NULL;
1242         int buflen = 0, len, r;
1243
1244         assert(s);
1245         assert(client);
1246
1247         r = ioctl(fd, FIONREAD, &buflen);
1248         if (r < 0)
1249                 return r;
1250
1251         if (buflen < 0)
1252                 /* this can't be right */
1253                 return -EIO;
1254
1255         message = malloc0(buflen);
1256         if (!message)
1257                 return -ENOMEM;
1258
1259         len = read(fd, message, buflen);
1260         if (len < 0) {
1261                 log_dhcp_client(client, "could not receive message from UDP "
1262                                 "socket: %m");
1263                 return 0;
1264         } else if ((size_t)len < sizeof(DHCPMessage)) {
1265                 log_dhcp_client(client, "too small to be a DHCP message: ignoring");
1266                 return 0;
1267         }
1268
1269         if (be32toh(message->magic) != DHCP_MAGIC_COOKIE) {
1270                 log_dhcp_client(client, "not a DHCP message: ignoring");
1271                 return 0;
1272         }
1273
1274         if (message->op != BOOTREPLY) {
1275                 log_dhcp_client(client, "not a BOOTREPLY message: ignoring");
1276                 return 0;
1277         }
1278
1279         if (be32toh(message->xid) != client->xid) {
1280                 log_dhcp_client(client, "received xid (%u) does not match "
1281                                 "expected (%u): ignoring",
1282                                 be32toh(message->xid), client->xid);
1283                 return 0;
1284         }
1285
1286         if (message->htype != ARPHRD_ETHER || message->hlen != ETHER_ADDR_LEN) {
1287                 log_dhcp_client(client, "not an ethernet packet");
1288                 return 0;
1289         }
1290
1291         if (memcmp(&message->chaddr[0], &client->client_id.mac_addr,
1292                    ETH_ALEN)) {
1293                 log_dhcp_client(client, "received chaddr does not match "
1294                                 "expected: ignoring");
1295                 return 0;
1296         }
1297
1298         return client_handle_message(client, message, len);
1299 }
1300
1301 static int client_receive_message_raw(sd_event_source *s, int fd,
1302                                       uint32_t revents, void *userdata) {
1303         sd_dhcp_client *client = userdata;
1304         _cleanup_free_ DHCPPacket *packet = NULL;
1305         uint8_t cmsgbuf[CMSG_LEN(sizeof(struct tpacket_auxdata))];
1306         struct iovec iov = {};
1307         struct msghdr msg = {
1308                 .msg_iov = &iov,
1309                 .msg_iovlen = 1,
1310                 .msg_control = cmsgbuf,
1311                 .msg_controllen = sizeof(cmsgbuf),
1312         };
1313         struct cmsghdr *cmsg;
1314         bool checksum = true;
1315         int buflen = 0, len, r;
1316
1317         assert(s);
1318         assert(client);
1319
1320         r = ioctl(fd, FIONREAD, &buflen);
1321         if (r < 0)
1322                 return r;
1323
1324         if (buflen < 0)
1325                 /* this can't be right */
1326                 return -EIO;
1327
1328         packet = malloc0(buflen);
1329         if (!packet)
1330                 return -ENOMEM;
1331
1332         iov.iov_base = packet;
1333         iov.iov_len = buflen;
1334
1335         len = recvmsg(fd, &msg, 0);
1336         if (len < 0) {
1337                 log_dhcp_client(client, "could not receive message from raw "
1338                                 "socket: %m");
1339                 return 0;
1340         } else if ((size_t)len < sizeof(DHCPPacket))
1341                 return 0;
1342
1343         for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
1344                 if (cmsg->cmsg_level == SOL_PACKET &&
1345                     cmsg->cmsg_type == PACKET_AUXDATA &&
1346                     cmsg->cmsg_len == CMSG_LEN(sizeof(struct tpacket_auxdata))) {
1347                         struct tpacket_auxdata *aux = (struct tpacket_auxdata*)CMSG_DATA(cmsg);
1348
1349                         checksum = !(aux->tp_status & TP_STATUS_CSUMNOTREADY);
1350                         break;
1351                 }
1352         }
1353
1354         r = dhcp_packet_verify_headers(packet, len, checksum);
1355         if (r < 0)
1356                 return 0;
1357
1358         len -= DHCP_IP_UDP_SIZE;
1359
1360         return client_handle_message(client, &packet->dhcp, len);
1361 }
1362
1363 int sd_dhcp_client_start(sd_dhcp_client *client) {
1364         int r;
1365
1366         assert_return(client, -EINVAL);
1367
1368         r = client_initialize(client);
1369         if (r < 0)
1370                 return r;
1371
1372         if (client->last_addr)
1373                 client->state = DHCP_STATE_INIT_REBOOT;
1374
1375         r = client_start(client);
1376         if (r >= 0)
1377                 log_dhcp_client(client, "STARTED on ifindex %u with address %s",
1378                                 client->index,
1379                                 ether_ntoa(&client->client_id.mac_addr));
1380
1381         return r;
1382 }
1383
1384 int sd_dhcp_client_stop(sd_dhcp_client *client) {
1385         DHCP_CLIENT_DONT_DESTROY(client);
1386
1387         assert_return(client, -EINVAL);
1388
1389         client_stop(client, DHCP_EVENT_STOP);
1390         client->state = DHCP_STATE_STOPPED;
1391
1392         return 0;
1393 }
1394
1395 int sd_dhcp_client_attach_event(sd_dhcp_client *client, sd_event *event,
1396                                 int priority) {
1397         int r;
1398
1399         assert_return(client, -EINVAL);
1400         assert_return(!client->event, -EBUSY);
1401
1402         if (event)
1403                 client->event = sd_event_ref(event);
1404         else {
1405                 r = sd_event_default(&client->event);
1406                 if (r < 0)
1407                         return 0;
1408         }
1409
1410         client->event_priority = priority;
1411
1412         return 0;
1413 }
1414
1415 int sd_dhcp_client_detach_event(sd_dhcp_client *client) {
1416         assert_return(client, -EINVAL);
1417
1418         client->event = sd_event_unref(client->event);
1419
1420         return 0;
1421 }
1422
1423 sd_event *sd_dhcp_client_get_event(sd_dhcp_client *client) {
1424         if (!client)
1425                 return NULL;
1426
1427         return client->event;
1428 }
1429
1430 sd_dhcp_client *sd_dhcp_client_ref(sd_dhcp_client *client) {
1431         if (client)
1432                 assert_se(REFCNT_INC(client->n_ref) >= 2);
1433
1434         return client;
1435 }
1436
1437 sd_dhcp_client *sd_dhcp_client_unref(sd_dhcp_client *client) {
1438         if (client && REFCNT_DEC(client->n_ref) <= 0) {
1439                 log_dhcp_client(client, "FREE");
1440
1441                 client_initialize(client);
1442
1443                 client->receive_message =
1444                         sd_event_source_unref(client->receive_message);
1445
1446                 sd_dhcp_client_detach_event(client);
1447
1448                 sd_dhcp_lease_unref(client->lease);
1449
1450                 free(client->req_opts);
1451                 free(client->hostname);
1452                 free(client->vendor_class_identifier);
1453                 free(client);
1454         }
1455
1456         return NULL;
1457 }
1458
1459 int sd_dhcp_client_new(sd_dhcp_client **ret) {
1460         _cleanup_dhcp_client_unref_ sd_dhcp_client *client = NULL;
1461
1462         assert_return(ret, -EINVAL);
1463
1464         client = new0(sd_dhcp_client, 1);
1465         if (!client)
1466                 return -ENOMEM;
1467
1468         client->n_ref = REFCNT_INIT;
1469         client->state = DHCP_STATE_INIT;
1470         client->index = -1;
1471         client->fd = -1;
1472         client->attempt = 1;
1473
1474         client->req_opts_size = ELEMENTSOF(default_req_opts);
1475
1476         client->req_opts = memdup(default_req_opts, client->req_opts_size);
1477         if (!client->req_opts)
1478                 return -ENOMEM;
1479
1480         *ret = client;
1481         client = NULL;
1482
1483         return 0;
1484 }