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.
This commit is contained in:
Beniamino Galvani 2019-12-20 09:48:45 +01:00
parent af03b77980
commit f860e929c0
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,