Skip to content

Commit

Permalink
sys/net/dhcpv6: discard stale replies
Browse files Browse the repository at this point in the history
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
  • Loading branch information
benpicco committed Jun 21, 2020
1 parent a5cf43d commit 2d11604
Showing 1 changed file with 11 additions and 0 deletions.
11 changes: 11 additions & 0 deletions sys/net/application_layer/dhcpv6/client.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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),
Expand Down Expand Up @@ -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) ||
Expand Down

0 comments on commit 2d11604

Please sign in to comment.