1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2025-01-18 12:52:44 +01:00

sys/net/dhcpv6: discard stale replies

The DHCPv6 server might send reponses multiple times.
The DHCPv6 client will only handle the first response, if additional
responses are comming in they are left in the RX queue.

That results in the client always reading the response of a previous
transaction on any subsequent transactions.
In this case the client will try again, creating a new transaction - that
will again only read the previous response.

To fix this, discard previous responses by flushing the RX queue before
sending a new message to the DHCPv6 server.

fixes #13834
This commit is contained in:
Benjamin Valentin 2020-04-08 12:30:58 +02:00
parent a5cf43da09
commit 2d1160426d

View File

@ -369,6 +369,15 @@ static bool _check_sid_opt(dhcpv6_opt_duid_t *sid)
(memcmp(sid->duid, server.duid.u8, server.duid_len) == 0));
}
/* discard stale messages in the receive buffer */
static void _flush_stale_replies(sock_udp_t *sock)
{
int res;
while ((res = sock_udp_recv(sock, recv_buf, sizeof(recv_buf), 0, NULL)) >= 0) {
DEBUG("DHCPv6 client: discarding %d stale bytes\n", res);
}
}
static int _preparse_advertise(uint8_t *adv, size_t len, uint8_t **buf)
{
dhcpv6_opt_duid_t *cid = NULL, *sid = NULL;
@ -696,6 +705,7 @@ static void _solicit_servers(event_t *event)
ARRAY_SIZE(oro_opts));
msg_len += _add_ia_pd_from_config(&send_buf[msg_len]);
DEBUG("DHCPv6 client: send SOLICIT\n");
_flush_stale_replies(&sock);
res = sock_udp_send(&sock, send_buf, msg_len, &remote);
assert(res > 0); /* something went terribly wrong */
while (((res = sock_udp_recv(&sock, recv_buf, sizeof(recv_buf),
@ -802,6 +812,7 @@ static void _request_renew_rebind(uint8_t type)
msg_len += _compose_oro_opt((dhcpv6_opt_oro_t *)&send_buf[msg_len], oro_opts,
ARRAY_SIZE(oro_opts));
msg_len += _add_ia_pd_from_config(&send_buf[msg_len]);
_flush_stale_replies(&sock);
while (sock_udp_send(&sock, send_buf, msg_len, &remote) <= 0) {}
while (((res = sock_udp_recv(&sock, recv_buf, sizeof(recv_buf),
retrans_timeout, NULL)) <= 0) ||