Skip to content

Commit

Permalink
net: coap: Fix response matching algorithm
Browse files Browse the repository at this point in the history
The algorithm for matching request with response was incorrect, which
could lead to false matches (for example if request had a token, and
piggybacked reply had no token but matching message ID only, that would
still be counted as a match).

This commit fixes it. The request/reply matching is implemented based on
RFC now, with separate conditions for piggybacked/separate responses.

Signed-off-by: Robert Lubos <[email protected]>
  • Loading branch information
rlubos committed Jan 17, 2025
1 parent c7c7837 commit e64b481
Showing 1 changed file with 29 additions and 6 deletions.
35 changes: 29 additions & 6 deletions subsys/net/lib/coap/coap.c
Original file line number Diff line number Diff line change
Expand Up @@ -1808,6 +1808,8 @@ struct coap_reply *coap_response_received(
{
struct coap_reply *r;
uint8_t token[COAP_TOKEN_MAX_LEN];
bool piggybacked = false;
uint8_t type;
uint16_t id;
uint8_t tkl;
size_t i;
Expand All @@ -1817,23 +1819,44 @@ struct coap_reply *coap_response_received(
return NULL;
}

type = coap_header_get_type(response);
id = coap_header_get_id(response);
tkl = coap_header_get_token(response, token);

if (type == COAP_TYPE_ACK || type == COAP_TYPE_RESET) {
piggybacked = true;
}

for (i = 0, r = replies; i < len; i++, r++) {
int age;

if ((r->id == 0U) && (r->tkl == 0U)) {
continue;
}

/* Piggybacked must match id when token is empty */
if ((r->id != id) && (tkl == 0U)) {
continue;
}
if (piggybacked) {
/* In a piggybacked response, the Message ID of the
* Confirmable request and the Acknowledgment MUST
* match, and the tokens of the response and original
* request MUST match.
*/
if ((r->id != id || (r->tkl != tkl))) {
continue;
}

if (tkl > 0 && memcmp(r->token, token, tkl)) {
continue;
if (r->tkl > 0) {
if (memcmp(r->token, token, r->tkl) != 0) {
continue;
}
}
} else {
/* In a separate response, just the tokens of the
* response and original request MUST match.
*/
if ((r->tkl == 0) || (r->tkl != tkl) ||
(memcmp(r->token, token, r->tkl) != 0)) {
continue;
}
}

age = coap_get_option_int(response, COAP_OPTION_OBSERVE);
Expand Down

0 comments on commit e64b481

Please sign in to comment.