n-dhcp4: use packet socket in rebinding state

After t1, the client tries to renew the lease by contacting via the
udp socket the server specified in the server-id option. If this
fails, after t2 it tries to contact any server using broadcast. For
this to work, the packet socket must be used.

(cherry picked from commit f860e929c0)
This commit is contained in:
Beniamino Galvani 2019-12-20 09:48:45 +01:00
parent 965219a4cd
commit 6017d78734
2 changed files with 30 additions and 3 deletions

View file

@ -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)

View file

@ -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,