diff options
-rw-r--r-- | shared/n-dhcp4/src/n-dhcp4-c-connection.c | 16 | ||||
-rw-r--r-- | shared/n-dhcp4/src/n-dhcp4-c-probe.c | 17 |
2 files changed, 30 insertions, 3 deletions
diff --git a/shared/n-dhcp4/src/n-dhcp4-c-connection.c b/shared/n-dhcp4/src/n-dhcp4-c-connection.c index 29dbc27a42..e51a3e3249 100644 --- a/shared/n-dhcp4/src/n-dhcp4-c-connection.c +++ b/shared/n-dhcp4/src/n-dhcp4-c-connection.c @@ -139,7 +139,19 @@ int n_dhcp4_c_connection_listen(NDhcp4CConnection *connection) { _c_cleanup_(c_closep) int fd_packet = -1; int r; - c_assert(connection->state == N_DHCP4_C_CONNECTION_STATE_INIT); + c_assert(connection->state == N_DHCP4_C_CONNECTION_STATE_INIT || + connection->state == N_DHCP4_C_CONNECTION_STATE_DRAINING || + connection->state == N_DHCP4_C_CONNECTION_STATE_UDP); + + if (connection->fd_packet >= 0) { + epoll_ctl(connection->fd_epoll, EPOLL_CTL_DEL, connection->fd_packet, NULL); + connection->fd_packet = c_close(connection->fd_packet); + } + + if (connection->fd_udp >= 0) { + epoll_ctl(connection->fd_epoll, EPOLL_CTL_DEL, connection->fd_udp, NULL); + connection->fd_udp = c_close(connection->fd_udp); + } r = n_dhcp4_c_socket_packet_new(&fd_packet, connection->client_config->ifindex); if (r) @@ -1027,13 +1039,13 @@ static int n_dhcp4_c_connection_send_request(NDhcp4CConnection *connection, case N_DHCP4_C_MESSAGE_SELECT: case N_DHCP4_C_MESSAGE_REBOOT: case N_DHCP4_C_MESSAGE_DECLINE: + case N_DHCP4_C_MESSAGE_REBIND: broadcast = true; r = n_dhcp4_c_connection_packet_broadcast(connection, request); if (r) return r; break; case N_DHCP4_C_MESSAGE_INFORM: - case N_DHCP4_C_MESSAGE_REBIND: broadcast = true; r = n_dhcp4_c_connection_udp_broadcast(connection, request); if (r) diff --git a/shared/n-dhcp4/src/n-dhcp4-c-probe.c b/shared/n-dhcp4/src/n-dhcp4-c-probe.c index 1810df1e8d..4fb7d3892a 100644 --- a/shared/n-dhcp4/src/n-dhcp4-c-probe.c +++ b/shared/n-dhcp4/src/n-dhcp4-c-probe.c @@ -785,6 +785,10 @@ static int n_dhcp4_client_probe_transition_t2(NDhcp4ClientProbe *probe, uint64_t switch (probe->state) { case N_DHCP4_CLIENT_PROBE_STATE_BOUND: case N_DHCP4_CLIENT_PROBE_STATE_RENEWING: + r = n_dhcp4_c_connection_listen(&probe->connection); + if (r) + return r; + r = n_dhcp4_c_connection_rebind_new(&probe->connection, &request); if (r) return r; @@ -907,11 +911,22 @@ static int n_dhcp4_client_probe_transition_ack(NDhcp4ClientProbe *probe, NDhcp4I _c_cleanup_(n_dhcp4_incoming_freep) NDhcp4Incoming *message = message_take; _c_cleanup_(n_dhcp4_client_lease_unrefp) NDhcp4ClientLease *lease = NULL; NDhcp4CEventNode *node; + struct in_addr client = {}; + struct in_addr server = {}; int r; switch (probe->state) { - case N_DHCP4_CLIENT_PROBE_STATE_RENEWING: case N_DHCP4_CLIENT_PROBE_STATE_REBINDING: + n_dhcp4_incoming_get_yiaddr(message, &client); + + r = n_dhcp4_incoming_query_server_identifier(message, &server); + if (r) + return r; + r = n_dhcp4_c_connection_connect(&probe->connection, &client, &server); + if (r) + return r; + /* fall-through */ + case N_DHCP4_CLIENT_PROBE_STATE_RENEWING: r = n_dhcp4_client_probe_raise(probe, &node, |