chiark / gitweb /
sd-dhcp-client: make sure timers fire immediately
[elogind.git] / src / libsystemd-network / sd-dhcp-client.c
index 07b27d5..5374db7 100644 (file)
@@ -185,7 +185,7 @@ static int client_stop(sd_dhcp_client *client, int error) {
                 sd_event_source_unref(client->receive_message);
 
         if (client->fd >= 0)
-                close(client->fd);
+                close_nointr_nofail(client->fd);
         client->fd = -1;
 
         client->timeout_resend = sd_event_source_unref(client->timeout_resend);
@@ -264,6 +264,15 @@ static int client_message_init(sd_dhcp_client *client, DHCPMessage *message,
         return 0;
 }
 
+static int dhcp_client_send_raw(sd_dhcp_client *client, DHCPPacket *packet,
+                                size_t len) {
+        dhcp_packet_append_ip_headers(packet, INADDR_ANY, DHCP_PORT_CLIENT,
+                                      INADDR_BROADCAST, DHCP_PORT_SERVER, len);
+
+        return dhcp_network_send_raw_socket(client->fd, &client->link,
+                                            packet, len);
+}
+
 static int client_send_discover(sd_dhcp_client *client, uint16_t secs) {
         int err = 0;
         _cleanup_free_ DHCPPacket *discover;
@@ -295,14 +304,13 @@ static int client_send_discover(sd_dhcp_client *client, uint16_t secs) {
         if (err < 0)
                 return err;
 
-        dhcp_packet_append_ip_headers(discover, len);
-
-        err = dhcp_network_send_raw_socket(client->fd, &client->link,
-                                           discover, len);
+        err = dhcp_client_send_raw(client, discover, len);
+        if (err < 0)
+                return err;
 
         log_dhcp_client(client, "DISCOVER");
 
-        return err;
+        return 0;
 }
 
 static int client_send_request(sd_dhcp_client *client, uint16_t secs) {
@@ -348,15 +356,14 @@ static int client_send_request(sd_dhcp_client *client, uint16_t secs) {
                                                    &request->dhcp,
                                                    len - DHCP_IP_UDP_SIZE);
         } else {
-                dhcp_packet_append_ip_headers(request, len);
-
-                err = dhcp_network_send_raw_socket(client->fd, &client->link,
-                                                   request, len);
+                err = dhcp_client_send_raw(client, request, len);
         }
+        if (err < 0)
+                return err;
 
         log_dhcp_client(client, "REQUEST");
 
-        return err;
+        return 0;
 }
 
 static uint16_t client_update_secs(sd_dhcp_client *client, usec_t time_now)
@@ -370,13 +377,18 @@ static int client_timeout_resend(sd_event_source *s, uint64_t usec,
                                  void *userdata) {
         sd_dhcp_client *client = userdata;
         usec_t next_timeout = 0;
+        uint64_t time_now;
         uint32_t time_left;
-        int r = 0;
+        int r;
 
         assert(s);
         assert(client);
         assert(client->event);
 
+        r = sd_event_get_now_monotonic(client->event, &time_now);
+        if (r < 0)
+                goto error;
+
         switch (client->state) {
         case DHCP_STATE_RENEWING:
 
@@ -384,7 +396,7 @@ static int client_timeout_resend(sd_event_source *s, uint64_t usec,
                 if (time_left < 60)
                         time_left = 60;
 
-                next_timeout = usec + time_left * USEC_PER_SEC;
+                next_timeout = time_now + time_left * USEC_PER_SEC;
 
                 break;
 
@@ -394,7 +406,7 @@ static int client_timeout_resend(sd_event_source *s, uint64_t usec,
                 if (time_left < 60)
                         time_left = 60;
 
-                next_timeout = usec + time_left * USEC_PER_SEC;
+                next_timeout = time_now + time_left * USEC_PER_SEC;
                 break;
 
         case DHCP_STATE_INIT:
@@ -407,7 +419,7 @@ static int client_timeout_resend(sd_event_source *s, uint64_t usec,
                 if (client->attempt < 64)
                         client->attempt *= 2;
 
-                next_timeout = usec + (client->attempt - 1) * USEC_PER_SEC;
+                next_timeout = time_now + (client->attempt - 1) * USEC_PER_SEC;
 
                 break;
         }
@@ -432,7 +444,7 @@ static int client_timeout_resend(sd_event_source *s, uint64_t usec,
         switch (client->state) {
         case DHCP_STATE_INIT:
 
-                client_update_secs(client, usec);
+                client_update_secs(client, time_now);
 
                 r = client_send_discover(client, client->secs);
                 if (r >= 0) {
@@ -446,7 +458,7 @@ static int client_timeout_resend(sd_event_source *s, uint64_t usec,
                 break;
 
         case DHCP_STATE_SELECTING:
-                client_update_secs(client, usec);
+                client_update_secs(client, time_now);
 
                 r = client_send_discover(client, client->secs);
                 if (r < 0 && client->attempt >= 64)
@@ -461,7 +473,7 @@ static int client_timeout_resend(sd_event_source *s, uint64_t usec,
                 if (r < 0 && client->attempt >= 64)
                          goto error;
 
-                client->request_sent = usec;
+                client->request_sent = time_now;
 
                 break;
 
@@ -483,8 +495,7 @@ error:
 }
 
 static int client_initialize_events(sd_dhcp_client *client,
-                                    sd_event_io_handler_t io_callback,
-                                    usec_t usec) {
+                                    sd_event_io_handler_t io_callback) {
         int r;
 
         assert(client);
@@ -504,8 +515,7 @@ static int client_initialize_events(sd_dhcp_client *client,
         client->timeout_resend = sd_event_source_unref(client->timeout_resend);
 
         r = sd_event_add_monotonic(client->event,
-                                   &client->timeout_resend,
-                                   usec, 0,
+                                   &client->timeout_resend, 0, 0,
                                    client_timeout_resend, client);
         if (r < 0)
                 goto error;
@@ -539,7 +549,7 @@ static int client_timeout_t2(sd_event_source *s, uint64_t usec, void *userdata)
         if (client->fd >= 0) {
                 client->receive_message =
                         sd_event_source_unref(client->receive_message);
-                close(client->fd);
+                close_nointr_nofail(client->fd);
                 client->fd = -1;
         }
 
@@ -556,8 +566,7 @@ static int client_timeout_t2(sd_event_source *s, uint64_t usec, void *userdata)
 
         log_dhcp_client(client, "TIMEOUT T2");
 
-        return client_initialize_events(client, client_receive_message_raw,
-                                        usec);
+        return client_initialize_events(client, client_receive_message_raw);
 }
 
 static int client_timeout_t1(sd_event_source *s, uint64_t usec,
@@ -580,7 +589,7 @@ static int client_timeout_t1(sd_event_source *s, uint64_t usec,
 
         log_dhcp_client(client, "TIMEOUT T1");
 
-        return client_initialize_events(client, client_receive_message_udp, usec);
+        return client_initialize_events(client, client_receive_message_udp);
 }
 
 static int client_handle_offer(sd_dhcp_client *client, DHCPMessage *offer,
@@ -689,10 +698,10 @@ static int client_set_lease_timeouts(sd_dhcp_client *client, uint64_t usec) {
                 return -EINVAL;
 
         r = sd_event_add_monotonic(client->event,
-                                     &client->timeout_t1,
-                                     next_timeout,
-                                     10 * USEC_PER_MSEC,
-                                     client_timeout_t1, client);
+                                   &client->timeout_t1,
+                                   next_timeout,
+                                   10 * USEC_PER_MSEC,
+                                   client_timeout_t1, client);
         if (r < 0)
                 return r;
 
@@ -716,10 +725,10 @@ static int client_set_lease_timeouts(sd_dhcp_client *client, uint64_t usec) {
                 return -EINVAL;
 
         r = sd_event_add_monotonic(client->event,
-                                     &client->timeout_t2,
-                                     next_timeout,
-                                     10 * USEC_PER_MSEC,
-                                     client_timeout_t2, client);
+                                   &client->timeout_t2,
+                                   next_timeout,
+                                   10 * USEC_PER_MSEC,
+                                   client_timeout_t2, client);
         if (r < 0)
                 return r;
 
@@ -734,9 +743,9 @@ static int client_set_lease_timeouts(sd_dhcp_client *client, uint64_t usec) {
                 return -EINVAL;
 
         r = sd_event_add_monotonic(client->event,
-                                     &client->timeout_expire, next_timeout,
-                                     10 * USEC_PER_MSEC,
-                                     client_timeout_expire, client);
+                                   &client->timeout_expire, next_timeout,
+                                   10 * USEC_PER_MSEC,
+                                   client_timeout_expire, client);
         if (r < 0)
                 return r;
 
@@ -794,9 +803,8 @@ static int client_handle_message(sd_dhcp_client *client, DHCPMessage *message,
                         client->attempt = 1;
 
                         r = sd_event_add_monotonic(client->event,
-                                                   &client->timeout_resend,
-                                                   time_now, 0,
-                                                   client_timeout_resend,
+                                                   &client->timeout_resend, 0,
+                                                   0, client_timeout_resend,
                                                    client);
                         if (r < 0)
                                 goto error;
@@ -841,7 +849,7 @@ static int client_handle_message(sd_dhcp_client *client, DHCPMessage *message,
 
                         client->receive_message =
                                 sd_event_source_unref(client->receive_message);
-                        close(client->fd);
+                        close_nointr_nofail(client->fd);
                         client->fd = -1;
                 }
 
@@ -980,8 +988,7 @@ int sd_dhcp_client_start(sd_dhcp_client *client) {
 
         log_dhcp_client(client, "STARTED");
 
-        return client_initialize_events(client, client_receive_message_raw,
-                                        client->start_time);
+        return client_initialize_events(client, client_receive_message_raw);
 }
 
 int sd_dhcp_client_stop(sd_dhcp_client *client) {