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