Commit f13602b4 authored by Juliusz Chroboczek's avatar Juliusz Chroboczek

Split last PC into unicast and multicast values.

It has been reported that some WiFi networks delay multicast
packets by up to 200ms, which breaks the PC check.  Split
the receiver's state into two last PC values, one for multicast
and one for unicast.  This is safe as the destination address
is covered by the MAC.
parent 420a7087
babel 1.12.1 (unreleased)
* Implement separate PC values for unicast and multicast, which avoids
dropping packets protected by MAC when WiFi powersave is active.
Thanks to Daniel Gröber.
5 May 2022: babeld-1.12 5 May 2022: babeld-1.12
* Implement v4-via-v6 routing (RFC 9229), which allows a router with * Implement v4-via-v6 routing (RFC 9229), which allows a router with
......
...@@ -551,7 +551,8 @@ preparse_packet(const unsigned char *from, struct interface *ifp, ...@@ -551,7 +551,8 @@ preparse_packet(const unsigned char *from, struct interface *ifp,
} else if(challenge_success) { } else if(challenge_success) {
neigh->index_len = index_len; neigh->index_len = index_len;
memcpy(neigh->index, index, index_len); memcpy(neigh->index, index, index_len);
memcpy(neigh->pc, pc, 4); memcpy(neigh->pc_m, pc, 4);
memcpy(neigh->pc_u, pc, 4);
accept_packet = 1; accept_packet = 1;
} else { } else {
neigh = neigh != NULL ? neigh : find_neighbour(from, ifp); neigh = neigh != NULL ? neigh : find_neighbour(from, ifp);
...@@ -563,14 +564,21 @@ preparse_packet(const unsigned char *from, struct interface *ifp, ...@@ -563,14 +564,21 @@ preparse_packet(const unsigned char *from, struct interface *ifp,
rc = send_challenge_request(neigh); rc = send_challenge_request(neigh);
if(rc < -1) if(rc < -1)
fputs("Could not send challenge request.\n", stderr); fputs("Could not send challenge request.\n", stderr);
} else if(memcmp(pc, neigh->pc, 4) <= 0) { } else {
unsigned char *last_pc;
if(IN6_IS_ADDR_MULTICAST(to))
last_pc = neigh->pc_m;
else
last_pc = neigh->pc_u;
if(memcmp(pc, last_pc, 4) <= 0) {
debugf("Out of order PC.\n"); debugf("Out of order PC.\n");
nonce = NULL; nonce = NULL;
} else { } else {
memcpy(neigh->pc, pc, 4); memcpy(last_pc, pc, 4);
accept_packet = 1; accept_packet = 1;
} }
} }
}
if(nonce != NULL) { /* a challenge request was received */ if(nonce != NULL) { /* a challenge request was received */
neigh = neigh != NULL ? neigh : find_neighbour(from, ifp); neigh = neigh != NULL ? neigh : find_neighbour(from, ifp);
...@@ -645,7 +653,7 @@ parse_packet(const unsigned char *from, struct interface *ifp, ...@@ -645,7 +653,7 @@ parse_packet(const unsigned char *from, struct interface *ifp,
} else { } else {
neigh = preparse_packet(from, ifp, packet, bodylen, to); neigh = preparse_packet(from, ifp, packet, bodylen, to);
if(neigh == NULL) { if(neigh == NULL) {
debugf("Received packet with wrong PC.\n"); debugf("PC check failed.\n");
return; return;
} }
} }
......
...@@ -47,7 +47,7 @@ struct neighbour { ...@@ -47,7 +47,7 @@ struct neighbour {
struct timeval echo_receive_time; struct timeval echo_receive_time;
unsigned int rtt; unsigned int rtt;
struct timeval rtt_time; struct timeval rtt_time;
unsigned char pc[4]; unsigned char pc_u[4], pc_m[4];
int index_len; /* This is -1 when index is undefined */ int index_len; /* This is -1 when index is undefined */
unsigned char index[32]; unsigned char index[32];
unsigned char nonce[NONCE_LEN]; unsigned char nonce[NONCE_LEN];
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment