Skip to content

Commit

Permalink
Merge pull request #20949 from maribu/sys/net/nanocoap/fix-coap_build…
Browse files Browse the repository at this point in the history
…_reply_header

sys/net/nanocoap: fix `coap_build_reply_header()`
  • Loading branch information
benpicco authored Nov 5, 2024
2 parents afb16bb + e52659c commit 2734366
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 4 deletions.
14 changes: 14 additions & 0 deletions sys/net/application_layer/nanocoap/nanocoap.c
Original file line number Diff line number Diff line change
Expand Up @@ -558,6 +558,13 @@ ssize_t coap_build_reply_header(coap_pkt_t *pkt, unsigned code,
? COAP_TYPE_ACK
: COAP_TYPE_NON;

if (IS_USED(MODULE_NANOCOAP_TOKEN_EXT)) {
/* Worst case: 2 byte extended token length field.
* See https://www.rfc-editor.org/rfc/rfc8974#name-extended-token-length-tkl-f
*/
hdr_len += 2;
}

if (hdr_len > len) {
return -ENOBUFS;
}
Expand Down Expand Up @@ -585,6 +592,13 @@ ssize_t coap_build_reply_header(coap_pkt_t *pkt, unsigned code,
}
}

if (IS_USED(MODULE_NANOCOAP_TOKEN_EXT)) {
/* we need to update the header length with the actual one, as we may
* have used less bytes for the extended token length fields as our
* worst case assumption */
hdr_len = bufpos - (uint8_t *)buf;
}

if (payload) {
if (ct >= 0) {
bufpos += coap_put_option_ct(bufpos, 0, ct);
Expand Down
49 changes: 45 additions & 4 deletions tests/unittests/tests-nanocoap/tests-nanocoap.c
Original file line number Diff line number Diff line change
Expand Up @@ -1099,15 +1099,35 @@ static void test_nanocoap__token_length_ext_16(void)
uint8_t buf[32];
coap_hdr_t *hdr = (void *)buf;

/* build a request with an overlong token (that mandates the use of
* an 8 bit extended token length field) */
TEST_ASSERT_EQUAL_INT(21, coap_build_hdr(hdr, COAP_TYPE_CON,
(void *)token, strlen(token),
COAP_CODE_204, 23));
COAP_METHOD_DELETE, 23));

/* parse the packet build, and verify it parses back as expected */
coap_pkt_t pkt;
int res = coap_parse(&pkt, buf, 21);

TEST_ASSERT_EQUAL_INT(0, res);
TEST_ASSERT_EQUAL_INT(21, coap_get_total_hdr_len(&pkt));
TEST_ASSERT_EQUAL_INT(204, coap_get_code_decimal(&pkt));
TEST_ASSERT_EQUAL_INT(COAP_METHOD_DELETE, coap_get_code_raw(&pkt));
TEST_ASSERT_EQUAL_INT(23, coap_get_id(&pkt));
TEST_ASSERT_EQUAL_INT(strlen(token), coap_get_token_len(&pkt));
TEST_ASSERT_EQUAL_INT(0, memcmp(coap_get_token(&pkt), token, strlen(token)));
TEST_ASSERT_EQUAL_INT(0, pkt.payload_len);
TEST_ASSERT_EQUAL_INT(13, hdr->ver_t_tkl & 0xf);

/* now build the corresponding reply and check that it parses back as
* expected */
uint8_t rbuf[sizeof(buf)];
ssize_t len = coap_build_reply_header(&pkt, COAP_CODE_DELETED, rbuf,
sizeof(rbuf), 0, NULL, NULL);
TEST_ASSERT_EQUAL_INT(21, len);
res = coap_parse(&pkt, rbuf, 21);
TEST_ASSERT_EQUAL_INT(0, res);
TEST_ASSERT_EQUAL_INT(21, coap_get_total_hdr_len(&pkt));
TEST_ASSERT_EQUAL_INT(COAP_CODE_DELETED, coap_get_code_raw(&pkt));
TEST_ASSERT_EQUAL_INT(23, coap_get_id(&pkt));
TEST_ASSERT_EQUAL_INT(strlen(token), coap_get_token_len(&pkt));
TEST_ASSERT_EQUAL_INT(0, memcmp(coap_get_token(&pkt), token, strlen(token)));
Expand All @@ -1128,15 +1148,36 @@ static void test_nanocoap__token_length_ext_269(void)
uint8_t buf[280];
coap_hdr_t *hdr = (void *)buf;

/* build a request with an overlong token (that mandates the use of
* an 16 bit extended token length field) */
TEST_ASSERT_EQUAL_INT(275, coap_build_hdr(hdr, COAP_TYPE_CON,
(void *)token, strlen(token),
COAP_CODE_204, 23));
COAP_METHOD_DELETE, 23));

/* parse the packet build, and verify it parses back as expected */
coap_pkt_t pkt;
int res = coap_parse(&pkt, buf, 275);

TEST_ASSERT_EQUAL_INT(0, res);
TEST_ASSERT_EQUAL_INT(275, coap_get_total_hdr_len(&pkt));
TEST_ASSERT_EQUAL_INT(204, coap_get_code_decimal(&pkt));
TEST_ASSERT_EQUAL_INT(COAP_METHOD_DELETE, coap_get_code_raw(&pkt));
TEST_ASSERT_EQUAL_INT(23, coap_get_id(&pkt));
TEST_ASSERT_EQUAL_INT(strlen(token), coap_get_token_len(&pkt));
TEST_ASSERT_EQUAL_INT(0, memcmp(coap_get_token(&pkt), token, strlen(token)));
TEST_ASSERT_EQUAL_INT(0, pkt.payload_len);
TEST_ASSERT_EQUAL_INT(14, hdr->ver_t_tkl & 0xf);

/* now build the corresponding reply and check that it parses back as
* expected */
uint8_t rbuf[sizeof(buf)];
ssize_t len = coap_build_reply_header(&pkt, COAP_CODE_DELETED, rbuf,
sizeof(rbuf), 0, NULL, NULL);

TEST_ASSERT_EQUAL_INT(275, len);
res = coap_parse(&pkt, rbuf, 275);
TEST_ASSERT_EQUAL_INT(0, res);
TEST_ASSERT_EQUAL_INT(275, coap_get_total_hdr_len(&pkt));
TEST_ASSERT_EQUAL_INT(COAP_CODE_DELETED, coap_get_code_raw(&pkt));
TEST_ASSERT_EQUAL_INT(23, coap_get_id(&pkt));
TEST_ASSERT_EQUAL_INT(strlen(token), coap_get_token_len(&pkt));
TEST_ASSERT_EQUAL_INT(0, memcmp(coap_get_token(&pkt), token, strlen(token)));
Expand Down

0 comments on commit 2734366

Please sign in to comment.