summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBeniamino Galvani <bgalvani@redhat.com>2022-10-02 13:06:26 +0200
committerBeniamino Galvani <bgalvani@redhat.com>2022-10-02 13:55:46 +0200
commit0530375039bd775b67069d8040ba96dd1c17374e (patch)
tree80388a591a7a66b3c93a1b936bf0fe73e4a6ef44
parent07e0ab48d194b8bd6663a34887c2e753720ae4d3 (diff)
n-dhcp4: close packet socket after timeoutbg/n-dhcp4-packet-socket
In the DRAINING state we keep the packet socket alive until the next I/O event, after the creation of the UDP socket. The goal is to avoid missing packets when switching to the connected socket. However, in normal conditions the next I/O event happens when the address is renewed and therefore the packet socket stays around unnecessarily for a long time. Introduce a timeout of 10 seconds after which, without other events, the packet socket gets closed.
-rw-r--r--src/n-dhcp4/src/n-dhcp4-c-connection.c15
-rw-r--r--src/n-dhcp4/src/n-dhcp4-private.h1
2 files changed, 15 insertions, 1 deletions
diff --git a/src/n-dhcp4/src/n-dhcp4-c-connection.c b/src/n-dhcp4/src/n-dhcp4-c-connection.c
index 65328286e8..572801add1 100644
--- a/src/n-dhcp4/src/n-dhcp4-c-connection.c
+++ b/src/n-dhcp4/src/n-dhcp4-c-connection.c
@@ -175,6 +175,7 @@ int n_dhcp4_c_connection_listen(NDhcp4CConnection *connection) {
connection->state = N_DHCP4_C_CONNECTION_STATE_PACKET;
connection->fd_packet = fd_packet;
+ connection->ns_drain_timeout = 0;
fd_packet = -1;
return 0;
}
@@ -211,6 +212,7 @@ int n_dhcp4_c_connection_connect(NDhcp4CConnection *connection,
}
connection->state = N_DHCP4_C_CONNECTION_STATE_DRAINING;
+ connection->ns_drain_timeout = n_dhcp4_gettime(CLOCK_BOOTTIME) + UINT64_C(10000000000);
connection->fd_udp = fd_udp;
fd_udp = -1;
connection->client_ip = client->s_addr;
@@ -325,7 +327,7 @@ void n_dhcp4_c_connection_get_timeout(NDhcp4CConnection *connection,
size_t n_send;
if (!connection->request) {
- *timeoutp = 0;
+ *timeoutp = connection->ns_drain_timeout;
return;
}
@@ -369,6 +371,9 @@ void n_dhcp4_c_connection_get_timeout(NDhcp4CConnection *connection,
c_assert(0);
}
+ if (connection->ns_drain_timeout != 0 && connection->ns_drain_timeout < timeout)
+ timeout = connection->ns_drain_timeout;
+
*timeoutp = timeout;
}
@@ -1122,6 +1127,13 @@ int n_dhcp4_c_connection_dispatch_timer(NDhcp4CConnection *connection,
uint64_t timeout;
int r;
+ if (connection->ns_drain_timeout != 0 && connection->ns_drain_timeout < timestamp) {
+ epoll_ctl(connection->fd_epoll, EPOLL_CTL_DEL, connection->fd_packet, NULL);
+ connection->fd_packet = c_close(connection->fd_packet);
+ connection->state = N_DHCP4_C_CONNECTION_STATE_UDP;
+ connection->ns_drain_timeout = 0;
+ }
+
if (!connection->request)
return 0;
@@ -1189,6 +1201,7 @@ int n_dhcp4_c_connection_dispatch_io(NDhcp4CConnection *connection,
c_assert(!r);
connection->fd_packet = c_close(connection->fd_packet);
connection->state = N_DHCP4_C_CONNECTION_STATE_UDP;
+ connection->ns_drain_timeout = 0;
/* fall-through */
case N_DHCP4_C_CONNECTION_STATE_UDP:
diff --git a/src/n-dhcp4/src/n-dhcp4-private.h b/src/n-dhcp4/src/n-dhcp4-private.h
index 6b366884be..8b17a1a25f 100644
--- a/src/n-dhcp4/src/n-dhcp4-private.h
+++ b/src/n-dhcp4/src/n-dhcp4-private.h
@@ -331,6 +331,7 @@ struct NDhcp4CConnection {
NDhcp4Outgoing *request; /* current request */
+ uint64_t ns_drain_timeout; /* timeout for closing packet socket */
uint32_t client_ip; /* client IP address, or 0 */
uint32_t server_ip; /* server IP address, or 0 */
uint16_t mtu; /* client mtu, or 0 */