Lines Matching defs:client

29 #include "sd-dhcp-client.h"
122 static void client_stop(sd_dhcp_client *client, int error);
124 int sd_dhcp_client_set_callback(sd_dhcp_client *client, sd_dhcp_client_cb_t cb,
126 assert_return(client, -EINVAL);
128 client->cb = cb;
129 client->userdata = userdata;
134 int sd_dhcp_client_set_request_broadcast(sd_dhcp_client *client, int broadcast) {
135 assert_return(client, -EINVAL);
137 client->request_broadcast = !!broadcast;
142 int sd_dhcp_client_set_request_option(sd_dhcp_client *client, uint8_t option) {
145 assert_return(client, -EINVAL);
146 assert_return (IN_SET(client->state, DHCP_STATE_INIT,
161 for (i = 0; i < client->req_opts_size; i++)
162 if (client->req_opts[i] == option)
165 if (!GREEDY_REALLOC(client->req_opts, client->req_opts_allocated,
166 client->req_opts_size + 1))
169 client->req_opts[client->req_opts_size++] = option;
174 int sd_dhcp_client_set_request_address(sd_dhcp_client *client,
176 assert_return(client, -EINVAL);
177 assert_return (IN_SET(client->state, DHCP_STATE_INIT,
181 client->last_addr = last_addr->s_addr;
183 client->last_addr = INADDR_ANY;
188 int sd_dhcp_client_set_index(sd_dhcp_client *client, int interface_index) {
189 assert_return(client, -EINVAL);
190 assert_return (IN_SET(client->state, DHCP_STATE_INIT,
194 client->index = interface_index;
199 int sd_dhcp_client_set_mac(sd_dhcp_client *client, const uint8_t *addr,
201 DHCP_CLIENT_DONT_DESTROY(client);
204 assert_return(client, -EINVAL);
216 if (client->mac_addr_len == addr_len &&
217 memcmp(&client->mac_addr, addr, addr_len) == 0)
220 if (!IN_SET(client->state, DHCP_STATE_INIT, DHCP_STATE_STOPPED)) {
221 log_dhcp_client(client, "Changing MAC address on running DHCP "
222 "client, restarting");
224 client_stop(client, SD_DHCP_CLIENT_EVENT_STOP);
227 memcpy(&client->mac_addr, addr, addr_len);
228 client->mac_addr_len = addr_len;
229 client->arp_type = arp_type;
231 if (need_restart && client->state != DHCP_STATE_STOPPED)
232 sd_dhcp_client_start(client);
237 int sd_dhcp_client_get_client_id(sd_dhcp_client *client, uint8_t *type,
240 assert_return(client, -EINVAL);
248 if (client->client_id_len) {
249 *type = client->client_id.type;
250 *data = client->client_id.raw.data;
251 *data_len = client->client_id_len - sizeof(client->client_id.type);
257 int sd_dhcp_client_set_client_id(sd_dhcp_client *client, uint8_t type,
259 DHCP_CLIENT_DONT_DESTROY(client);
262 assert_return(client, -EINVAL);
279 if (client->client_id_len == data_len + sizeof(client->client_id.type) &&
280 client->client_id.type == type &&
281 memcmp(&client->client_id.raw.data, data, data_len) == 0)
284 if (!IN_SET(client->state, DHCP_STATE_INIT, DHCP_STATE_STOPPED)) {
285 log_dhcp_client(client, "Changing client ID on running DHCP "
286 "client, restarting");
288 client_stop(client, SD_DHCP_CLIENT_EVENT_STOP);
291 client->client_id.type = type;
292 memcpy(&client->client_id.raw.data, data, data_len);
293 client->client_id_len = data_len + sizeof (client->client_id.type);
295 if (need_restart && client->state != DHCP_STATE_STOPPED)
296 sd_dhcp_client_start(client);
301 int sd_dhcp_client_set_hostname(sd_dhcp_client *client,
305 assert_return(client, -EINVAL);
310 if (streq_ptr(client->hostname, hostname))
319 free(client->hostname);
320 client->hostname = new_hostname;
325 int sd_dhcp_client_set_vendor_class_identifier(sd_dhcp_client *client,
329 assert_return(client, -EINVAL);
335 free(client->vendor_class_identifier);
337 client->vendor_class_identifier = new_vci;
342 int sd_dhcp_client_set_mtu(sd_dhcp_client *client, uint32_t mtu) {
343 assert_return(client, -EINVAL);
346 client->mtu = mtu;
351 int sd_dhcp_client_get_lease(sd_dhcp_client *client, sd_dhcp_lease **ret) {
352 assert_return(client, -EINVAL);
355 if (client->state != DHCP_STATE_BOUND &&
356 client->state != DHCP_STATE_RENEWING &&
357 client->state != DHCP_STATE_REBINDING)
360 *ret = client->lease;
365 static void client_notify(sd_dhcp_client *client, int event) {
366 if (client->cb)
367 client->cb(client, event, client->userdata);
370 static int client_initialize(sd_dhcp_client *client) {
371 assert_return(client, -EINVAL);
373 client->receive_message =
374 sd_event_source_unref(client->receive_message);
376 client->fd = asynchronous_close(client->fd);
378 client->timeout_resend = sd_event_source_unref(client->timeout_resend);
380 client->timeout_t1 = sd_event_source_unref(client->timeout_t1);
381 client->timeout_t2 = sd_event_source_unref(client->timeout_t2);
382 client->timeout_expire = sd_event_source_unref(client->timeout_expire);
384 client->attempt = 1;
386 client->state = DHCP_STATE_INIT;
387 client->xid = 0;
389 client->lease = sd_dhcp_lease_unref(client->lease);
394 static void client_stop(sd_dhcp_client *client, int error) {
395 assert(client);
398 log_dhcp_client(client, "STOPPED: %s", strerror(-error));
400 log_dhcp_client(client, "STOPPED");
402 log_dhcp_client(client, "STOPPED: Unknown event");
404 client_notify(client, error);
406 client_initialize(client);
409 static int client_message_init(sd_dhcp_client *client, DHCPPacket **ret,
418 assert(client);
419 assert(client->start_time);
432 r = dhcp_message_init(&packet->dhcp, BOOTREQUEST, client->xid, type,
433 client->arp_type, optlen, &optoffset);
439 r = sd_event_now(client->event, clock_boottime_or_monotonic(), &time_now);
442 assert(time_now >= client->start_time);
446 secs = ((time_now - client->start_time) / USEC_PER_SEC) ? : 1;
450 A client that cannot receive unicast IP datagrams until its protocol
453 DHCPREQUEST messages that client sends. The BROADCAST bit will
455 any messages to the client on the client's subnet.
460 if (client->request_broadcast || client->arp_type != ARPHRD_ETHER)
464 The client MUST include its hardware address in the ’chaddr’ field, if
466 interfaces will leave 'chaddr' empty and use the client identifier
469 if (client->arp_type == ARPHRD_ETHER)
470 memcpy(&packet->dhcp.chaddr, &client->mac_addr, ETH_ALEN);
472 /* If no client identifier exists, construct an RFC 4361-compliant one */
473 if (client->client_id_len == 0) {
476 client->client_id.type = 255;
478 r = dhcp_identifier_set_iaid(client->index, client->mac_addr, client->mac_addr_len, &client->client_id.ns.iaid);
482 r = dhcp_identifier_set_duid_en(&client->client_id.ns.duid, &duid_len);
486 client->client_id_len = sizeof(client->client_id.type) + sizeof(client->client_id.ns.iaid) + duid_len;
491 if (client->client_id_len) {
494 client->client_id_len,
495 &client->client_id);
502 client may provide the server with a list of specific
503 parameters the client is interested in. If the client
510 client->req_opts_size, client->req_opts);
515 The client SHOULD include the ’maximum DHCP message size’ option to
527 Maximum DHCP Message Size [4] option if the DHCP client's TCP/IP
529 client SHOULD set the value of this option to at least the MTU of the
530 interface that the client is configuring. The client MAY set the
537 r = dhcp_option_append(&packet->dhcp, client->mtu, &optoffset, 0,
569 static int dhcp_client_send_raw(sd_dhcp_client *client, DHCPPacket *packet,
574 return dhcp_network_send_raw_socket(client->fd, &client->link,
578 static int client_send_discover(sd_dhcp_client *client) {
583 assert(client);
584 assert(client->state == DHCP_STATE_INIT ||
585 client->state == DHCP_STATE_SELECTING);
587 r = client_message_init(client, &discover, DHCP_DISCOVER,
592 /* the client may suggest values for the network address
593 and lease time in the DHCPDISCOVER message. The client may include
598 if (client->last_addr != INADDR_ANY) {
601 4, &client->last_addr);
606 if (client->hostname) {
611 if (dns_name_is_single_label(client->hostname)) {
612 /* it is unclear from RFC 2131 if client should send hostname in
617 strlen(client->hostname), client->hostname);
620 client->hostname);
625 if (client->vendor_class_identifier) {
628 strlen(client->vendor_class_identifier),
629 client->vendor_class_identifier);
640 The client SHOULD wait a random time between one and ten seconds to
643 r = dhcp_client_send_raw(client, discover, sizeof(DHCPPacket) + optoffset);
647 log_dhcp_client(client, "DISCOVER");
652 static int client_send_request(sd_dhcp_client *client) {
657 r = client_message_init(client, &request, DHCP_REQUEST,
662 switch (client->state) {
675 4, &client->lease->server_address);
681 4, &client->lease->address);
689 option MUST be filled in with client’s notion of its previously
694 4, &client->last_addr);
702 client’s IP address.
709 client’s IP address.
713 request->dhcp.ciaddr = client->lease->address;
725 if (client->hostname) {
726 if (dns_name_is_single_label(client->hostname))
729 strlen(client->hostname), client->hostname);
732 client->hostname);
742 if (client->state == DHCP_STATE_RENEWING) {
743 r = dhcp_network_send_udp_socket(client->fd,
744 client->lease->server_address,
749 r = dhcp_client_send_raw(client, request, sizeof(DHCPPacket) + optoffset);
754 switch (client->state) {
756 log_dhcp_client(client, "REQUEST (requesting)");
759 log_dhcp_client(client, "REQUEST (init-reboot)");
762 log_dhcp_client(client, "REQUEST (renewing)");
765 log_dhcp_client(client, "REQUEST (rebinding)");
768 log_dhcp_client(client, "REQUEST (invalid)");
775 static int client_start(sd_dhcp_client *client);
779 sd_dhcp_client *client = userdata;
780 DHCP_CLIENT_DONT_DESTROY(client);
787 assert(client);
788 assert(client->event);
790 r = sd_event_now(client->event, clock_boottime_or_monotonic(), &time_now);
794 switch (client->state) {
797 time_left = (client->lease->t2 - client->lease->t1) / 2;
807 time_left = (client->lease->lifetime - client->lease->t2) / 2;
816 r = client_initialize(client);
820 r = client_start(client);
824 log_dhcp_client(client, "REBOOTED");
834 if (client->attempt < 64)
835 client->attempt *= 2;
837 next_timeout = time_now + (client->attempt - 1) * USEC_PER_SEC;
848 client->timeout_resend = sd_event_source_unref(client->timeout_resend);
850 r = sd_event_add_time(client->event,
851 &client->timeout_resend,
854 client_timeout_resend, client);
858 r = sd_event_source_set_priority(client->timeout_resend,
859 client->event_priority);
863 r = sd_event_source_set_description(client->timeout_resend, "dhcp4-resend-timer");
867 switch (client->state) {
869 r = client_send_discover(client);
871 client->state = DHCP_STATE_SELECTING;
872 client->attempt = 1;
874 if (client->attempt >= 64)
881 r = client_send_discover(client);
882 if (r < 0 && client->attempt >= 64)
891 r = client_send_request(client);
892 if (r < 0 && client->attempt >= 64)
895 if (client->state == DHCP_STATE_INIT_REBOOT)
896 client->state = DHCP_STATE_REBOOTING;
898 client->request_sent = time_now;
915 client_stop(client, r);
917 /* Errors were dealt with when stopping the client, don't spill
922 static int client_initialize_io_events(sd_dhcp_client *client,
926 assert(client);
927 assert(client->event);
929 r = sd_event_add_io(client->event, &client->receive_message,
930 client->fd, EPOLLIN, io_callback,
931 client);
935 r = sd_event_source_set_priority(client->receive_message,
936 client->event_priority);
940 r = sd_event_source_set_description(client->receive_message, "dhcp4-receive-message");
946 client_stop(client, r);
951 static int client_initialize_time_events(sd_dhcp_client *client) {
955 assert(client);
956 assert(client->event);
958 client->timeout_resend = sd_event_source_unref(client->timeout_resend);
960 if (client->start_delay) {
961 sd_event_now(client->event, clock_boottime_or_monotonic(), &usec);
962 usec += client->start_delay;
965 r = sd_event_add_time(client->event,
966 &client->timeout_resend,
969 client_timeout_resend, client);
973 r = sd_event_source_set_priority(client->timeout_resend,
974 client->event_priority);
978 r = sd_event_source_set_description(client->timeout_resend, "dhcp4-resend-timer");
984 client_stop(client, r);
990 static int client_initialize_events(sd_dhcp_client *client,
992 client_initialize_io_events(client, io_callback);
993 client_initialize_time_events(client);
998 static int client_start_delayed(sd_dhcp_client *client) {
1001 assert_return(client, -EINVAL);
1002 assert_return(client->event, -EINVAL);
1003 assert_return(client->index > 0, -EINVAL);
1004 assert_return(client->fd < 0, -EBUSY);
1005 assert_return(client->xid == 0, -EINVAL);
1006 assert_return(client->state == DHCP_STATE_INIT ||
1007 client->state == DHCP_STATE_INIT_REBOOT, -EBUSY);
1009 client->xid = random_u32();
1011 r = dhcp_network_bind_raw_socket(client->index, &client->link,
1012 client->xid, client->mac_addr,
1013 client->mac_addr_len, client->arp_type);
1015 client_stop(client, r);
1018 client->fd = r;
1020 if (client->state == DHCP_STATE_INIT || client->state == DHCP_STATE_INIT_REBOOT)
1021 client->start_time = now(clock_boottime_or_monotonic());
1023 return client_initialize_events(client, client_receive_message_raw);
1026 static int client_start(sd_dhcp_client *client) {
1027 client->start_delay = 0;
1028 return client_start_delayed(client);
1033 sd_dhcp_client *client = userdata;
1034 DHCP_CLIENT_DONT_DESTROY(client);
1036 log_dhcp_client(client, "EXPIRED");
1038 client_notify(client, SD_DHCP_CLIENT_EVENT_EXPIRED);
1041 if (client->state != DHCP_STATE_STOPPED) {
1042 client_initialize(client);
1043 client_start(client);
1050 sd_dhcp_client *client = userdata;
1051 DHCP_CLIENT_DONT_DESTROY(client);
1054 client->receive_message = sd_event_source_unref(client->receive_message);
1055 client->fd = asynchronous_close(client->fd);
1057 client->state = DHCP_STATE_REBINDING;
1058 client->attempt = 1;
1060 r = dhcp_network_bind_raw_socket(client->index, &client->link,
1061 client->xid, client->mac_addr,
1062 client->mac_addr_len, client->arp_type);
1064 client_stop(client, r);
1067 client->fd = r;
1069 return client_initialize_events(client, client_receive_message_raw);
1074 sd_dhcp_client *client = userdata;
1075 DHCP_CLIENT_DONT_DESTROY(client);
1077 client->state = DHCP_STATE_RENEWING;
1078 client->attempt = 1;
1080 return client_initialize_time_events(client);
1083 static int client_handle_offer(sd_dhcp_client *client, DHCPMessage *offer,
1092 if (client->client_id_len) {
1094 (uint8_t *) &client->client_id,
1095 client->client_id_len);
1102 log_dhcp_client(client, "received message was not an OFFER, ignoring");
1112 log_dhcp_client(client, "received lease lacks address, server address or lease lifetime, ignoring");
1119 log_dhcp_client(client, "received lease lacks subnet "
1126 sd_dhcp_lease_unref(client->lease);
1127 client->lease = lease;
1130 log_dhcp_client(client, "OFFER");
1135 static int client_handle_forcerenew(sd_dhcp_client *client, DHCPMessage *force,
1143 log_dhcp_client(client, "FORCERENEW");
1148 static int client_handle_ack(sd_dhcp_client *client, DHCPMessage *ack,
1158 if (client->client_id_len) {
1160 (uint8_t *) &client->client_id,
1161 client->client_id_len);
1168 log_dhcp_client(client, "NAK: %s", strna(error_message));
1173 log_dhcp_client(client, "received message was not an ACK, ignoring");
1184 log_dhcp_client(client, "received lease lacks address, server "
1192 log_dhcp_client(client, "received lease lacks subnet "
1200 if (client->lease) {
1201 if (client->lease->address != lease->address ||
1202 client->lease->subnet_mask != lease->subnet_mask ||
1203 client->lease->router != lease->router) {
1208 client->lease = sd_dhcp_lease_unref(client->lease);
1211 client->lease = lease;
1214 log_dhcp_client(client, "ACK");
1219 static uint64_t client_compute_timeout(sd_dhcp_client *client, uint32_t lifetime, double factor) {
1220 assert(client);
1221 assert(client->request_sent);
1229 return client->request_sent + (lifetime * USEC_PER_SEC * factor) +
1233 static int client_set_lease_timeouts(sd_dhcp_client *client) {
1241 assert(client);
1242 assert(client->event);
1243 assert(client->lease);
1244 assert(client->lease->lifetime);
1246 client->timeout_t1 = sd_event_source_unref(client->timeout_t1);
1247 client->timeout_t2 = sd_event_source_unref(client->timeout_t2);
1248 client->timeout_expire = sd_event_source_unref(client->timeout_expire);
1251 if (client->lease->lifetime == 0xffffffff)
1254 r = sd_event_now(client->event, clock_boottime_or_monotonic(), &time_now);
1257 assert(client->request_sent <= time_now);
1260 lifetime_timeout = client_compute_timeout(client, client->lease->lifetime, 1);
1261 if (client->lease->t1 > 0 && client->lease->t2 > 0) {
1263 if (client->lease->t1 < client->lease->t2 &&
1264 client->lease->t2 < client->lease->lifetime) {
1266 t2_timeout = client_compute_timeout(client, client->lease->t2, 1);
1267 t1_timeout = client_compute_timeout(client, client->lease->t1, 1);
1270 t2_timeout = client_compute_timeout(client, client->lease->lifetime, 7.0 / 8.0);
1271 client->lease->t2 = (client->lease->lifetime * 7) / 8;
1272 t1_timeout = client_compute_timeout(client, client->lease->lifetime, 0.5);
1273 client->lease->t1 = client->lease->lifetime / 2;
1275 } else if (client->lease->t2 > 0 && client->lease->t2 < client->lease->lifetime) {
1277 t2_timeout = client_compute_timeout(client, client->lease->t2, 1);
1278 t1_timeout = client_compute_timeout(client, client->lease->lifetime, 0.5);
1279 client->lease->t1 = client->lease->lifetime / 2;
1282 t2_timeout = client_compute_timeout(client, client->lease->lifetime, 7.0 / 8.0);
1283 client->lease->t2 = (client->lease->lifetime * 7) / 8;
1285 } else if (client->lease->t1 > 0 && client->lease->t1 < client->lease->lifetime) {
1287 t1_timeout = client_compute_timeout(client, client->lease->t1, 1);
1288 t2_timeout = client_compute_timeout(client, client->lease->lifetime, 7.0 / 8.0);
1289 client->lease->t2 = (client->lease->lifetime * 7) / 8;
1292 t2_timeout = client_compute_timeout(client, client->lease->lifetime, 0.5);
1293 client->lease->t2 = client->lease->lifetime / 2;
1297 t1_timeout = client_compute_timeout(client, client->lease->lifetime, 0.5);
1298 client->lease->t1 = client->lease->lifetime / 2;
1299 t2_timeout = client_compute_timeout(client, client->lease->lifetime, 7.0 / 8.0);
1300 client->lease->t2 = (client->lease->lifetime * 7) / 8;
1304 r = sd_event_add_time(client->event, &client->timeout_expire,
1307 client_timeout_expire, client);
1311 r = sd_event_source_set_priority(client->timeout_expire,
1312 client->event_priority);
1316 r = sd_event_source_set_description(client->timeout_expire, "dhcp4-lifetime");
1320 log_dhcp_client(client, "lease expires in %s",
1328 r = sd_event_add_time(client->event,
1329 &client->timeout_t2,
1333 client_timeout_t2, client);
1337 r = sd_event_source_set_priority(client->timeout_t2,
1338 client->event_priority);
1342 r = sd_event_source_set_description(client->timeout_t2, "dhcp4-t2-timeout");
1346 log_dhcp_client(client, "T2 expires in %s",
1354 r = sd_event_add_time(client->event,
1355 &client->timeout_t1,
1358 client_timeout_t1, client);
1362 r = sd_event_source_set_priority(client->timeout_t1,
1363 client->event_priority);
1367 r = sd_event_source_set_description(client->timeout_t1, "dhcp4-t1-timer");
1371 log_dhcp_client(client, "T1 expires in %s",
1377 static int client_handle_message(sd_dhcp_client *client, DHCPMessage *message,
1379 DHCP_CLIENT_DONT_DESTROY(client);
1383 assert(client);
1384 assert(client->event);
1387 switch (client->state) {
1390 r = client_handle_offer(client, message, len);
1393 client->timeout_resend =
1394 sd_event_source_unref(client->timeout_resend);
1396 client->state = DHCP_STATE_REQUESTING;
1397 client->attempt = 1;
1399 r = sd_event_add_time(client->event,
1400 &client->timeout_resend,
1403 client_timeout_resend, client);
1407 r = sd_event_source_set_priority(client->timeout_resend,
1408 client->event_priority);
1412 r = sd_event_source_set_description(client->timeout_resend, "dhcp4-resend-timer");
1426 r = client_handle_ack(client, message, len);
1428 client->start_delay = 0;
1429 client->timeout_resend =
1430 sd_event_source_unref(client->timeout_resend);
1431 client->receive_message =
1432 sd_event_source_unref(client->receive_message);
1433 client->fd = asynchronous_close(client->fd);
1435 if (IN_SET(client->state, DHCP_STATE_REQUESTING,
1441 client->state = DHCP_STATE_BOUND;
1442 client->attempt = 1;
1444 client->last_addr = client->lease->address;
1446 r = client_set_lease_timeouts(client);
1448 log_dhcp_client(client, "could not set lease timeouts");
1452 r = dhcp_network_bind_udp_socket(client->lease->address,
1455 log_dhcp_client(client, "could not bind UDP socket");
1459 client->fd = r;
1461 client_initialize_io_events(client, client_receive_message_udp);
1464 client_notify(client, notify_event);
1465 if (client->state == DHCP_STATE_STOPPED)
1470 /* got a NAK, let's restart the client */
1471 client->timeout_resend =
1472 sd_event_source_unref(client->timeout_resend);
1474 r = client_initialize(client);
1478 r = client_start_delayed(client);
1482 log_dhcp_client(client, "REBOOT in %s", format_timespan(time_string, FORMAT_TIMESPAN_MAX,
1483 client->start_delay, USEC_PER_SEC));
1485 client->start_delay = CLAMP(client->start_delay * 2,
1496 r = client_handle_forcerenew(client, message, len);
1498 r = client_timeout_t1(NULL, 0, client);
1519 client_stop(client, r);
1526 sd_dhcp_client *client = userdata;
1534 assert(client);
1552 log_dhcp_client(client, "Could not receive message from UDP socket: %m");
1555 log_dhcp_client(client, "Too small to be a DHCP message: ignoring");
1560 log_dhcp_client(client, "Not a DHCP message: ignoring");
1565 log_dhcp_client(client, "Not a BOOTREPLY message: ignoring");
1569 if (message->htype != client->arp_type) {
1570 log_dhcp_client(client, "Packet type does not match client type");
1574 if (client->arp_type == ARPHRD_ETHER) {
1576 expected_chaddr = (const struct ether_addr *) &client->mac_addr;
1584 log_dhcp_client(client, "Unexpected packet hlen %d", message->hlen);
1589 log_dhcp_client(client, "Received chaddr does not match expected: ignoring");
1593 if (client->state != DHCP_STATE_BOUND &&
1594 be32toh(message->xid) != client->xid) {
1597 log_dhcp_client(client, "Received xid (%u) does not match expected (%u): ignoring",
1598 be32toh(message->xid), client->xid);
1602 return client_handle_message(client, message, len);
1607 sd_dhcp_client *client = userdata;
1622 assert(client);
1643 log_dhcp_client(client, "Could not receive message from raw socket: %m");
1666 return client_handle_message(client, &packet->dhcp, len);
1669 int sd_dhcp_client_start(sd_dhcp_client *client) {
1672 assert_return(client, -EINVAL);
1674 r = client_initialize(client);
1678 if (client->last_addr)
1679 client->state = DHCP_STATE_INIT_REBOOT;
1681 r = client_start(client);
1683 log_dhcp_client(client, "STARTED on ifindex %i", client->index);
1688 int sd_dhcp_client_stop(sd_dhcp_client *client) {
1689 DHCP_CLIENT_DONT_DESTROY(client);
1691 assert_return(client, -EINVAL);
1693 client_stop(client, SD_DHCP_CLIENT_EVENT_STOP);
1694 client->state = DHCP_STATE_STOPPED;
1699 int sd_dhcp_client_attach_event(sd_dhcp_client *client, sd_event *event,
1703 assert_return(client, -EINVAL);
1704 assert_return(!client->event, -EBUSY);
1707 client->event = sd_event_ref(event);
1709 r = sd_event_default(&client->event);
1714 client->event_priority = priority;
1719 int sd_dhcp_client_detach_event(sd_dhcp_client *client) {
1720 assert_return(client, -EINVAL);
1722 client->event = sd_event_unref(client->event);
1727 sd_event *sd_dhcp_client_get_event(sd_dhcp_client *client) {
1728 if (!client)
1731 return client->event;
1734 sd_dhcp_client *sd_dhcp_client_ref(sd_dhcp_client *client) {
1736 if (!client)
1739 assert(client->n_ref >= 1);
1740 client->n_ref++;
1742 return client;
1745 sd_dhcp_client *sd_dhcp_client_unref(sd_dhcp_client *client) {
1747 if (!client)
1750 assert(client->n_ref >= 1);
1751 client->n_ref--;
1753 if (client->n_ref > 0)
1756 log_dhcp_client(client, "FREE");
1758 client_initialize(client);
1760 client->receive_message = sd_event_source_unref(client->receive_message);
1762 sd_dhcp_client_detach_event(client);
1764 sd_dhcp_lease_unref(client->lease);
1766 free(client->req_opts);
1767 free(client->hostname);
1768 free(client->vendor_class_identifier);
1769 free(client);
1775 _cleanup_(sd_dhcp_client_unrefp) sd_dhcp_client *client = NULL;
1779 client = new0(sd_dhcp_client, 1);
1780 if (!client)
1783 client->n_ref = 1;
1784 client->state = DHCP_STATE_INIT;
1785 client->index = -1;
1786 client->fd = -1;
1787 client->attempt = 1;
1788 client->mtu = DHCP_DEFAULT_MIN_SIZE;
1790 client->req_opts_size = ELEMENTSOF(default_req_opts);
1792 client->req_opts = memdup(default_req_opts, client->req_opts_size);
1793 if (!client->req_opts)
1796 *ret = client;
1797 client = NULL;