Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gnrc, nanocoap: add optional work-arounds for buggy CoAP servers #20564

Merged
merged 2 commits into from
Apr 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions sys/include/net/nanocoap_sock.h
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,18 @@ extern "C" {
#define CONFIG_NANOCOAP_SERVER_STACK_SIZE THREAD_STACKSIZE_DEFAULT
#endif

/**
* @brief Include a random token with block-wise transfers.
*
* This is a workaround for buggy CoPA implementations (e.g. go-coap) that expect
* to identify block-wise transfers based on the token.
*
* See https://github.com/plgd-dev/go-coap/issues/512
*/
#ifndef CONFIG_NANOCOAP_SOCK_BLOCK_TOKEN
#define CONFIG_NANOCOAP_SOCK_BLOCK_TOKEN (0)
#endif

/**
* @brief NanoCoAP socket types
*/
Expand Down
19 changes: 18 additions & 1 deletion sys/net/application_layer/nanocoap/sock.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@
coap_blockwise_cb_t callback;
void *arg;
bool more;
#if CONFIG_NANOCOAP_SOCK_BLOCK_TOKEN
uint8_t token[4];
#endif
} _block_ctx_t;

int nanocoap_sock_dtls_connect(nanocoap_sock_t *sock, sock_udp_ep_t *local,
Expand Down Expand Up @@ -190,7 +193,7 @@

/* random timeout, deadline for receive retries */
uint32_t timeout = random_uint32_range((uint32_t)CONFIG_COAP_ACK_TIMEOUT_MS * US_PER_MS,
(uint32_t)CONFIG_COAP_ACK_TIMEOUT_MS * CONFIG_COAP_RANDOM_FACTOR_1000);

Check warning on line 196 in sys/net/application_layer/nanocoap/sock.c

View workflow job for this annotation

GitHub Actions / static-tests

line is longer than 100 characters
uint32_t deadline = _deadline_from_interval(timeout);

/* check if we expect a reply */
Expand Down Expand Up @@ -601,7 +604,17 @@
};
uint16_t lastonum = 0;

buf += coap_build_hdr(pkt.hdr, COAP_TYPE_CON, NULL, 0, COAP_METHOD_GET,
void *token = NULL;
size_t token_len = 0;

#if CONFIG_NANOCOAP_SOCK_BLOCK_TOKEN
/* HACK: go-coap always expects a token */
/* see https://github.com/plgd-dev/go-coap/issues/512 */
token = ctx->token;
token_len = sizeof(ctx->token);
#endif

buf += coap_build_hdr(pkt.hdr, COAP_TYPE_CON, token, token_len, COAP_METHOD_GET,
nanocoap_sock_next_msg_id(sock));
buf += coap_opt_put_uri_pathquery(buf, &lastonum, path);
buf += coap_opt_put_uint(buf, lastonum, COAP_OPT_BLOCK2, (num << 4) | blksize);
Expand Down Expand Up @@ -674,6 +687,10 @@
.more = true,
};

#if CONFIG_NANOCOAP_SOCK_BLOCK_TOKEN
random_bytes(ctx.token, sizeof(ctx.token));
#endif

unsigned num = 0;
while (ctx.more) {
DEBUG("nanocoap: fetching block %u\n", num);
Expand Down
8 changes: 8 additions & 0 deletions sys/net/gnrc/sock/include/gnrc_sock_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,14 @@ extern "C" {
*/
#define GNRC_SOCK_DYN_PORTRANGE_ERR (0)

/**
* @brief Check if remote address of a UDP packet matches the address the socket
* is bound to.
*/
#ifndef CONFIG_GNRC_SOCK_UDP_CHECK_REMOTE_ADDR
#define CONFIG_GNRC_SOCK_UDP_CHECK_REMOTE_ADDR (1)
#endif

/**
* @brief Structure to retrieve auxiliary data from @ref gnrc_sock_recv
*
Expand Down
4 changes: 3 additions & 1 deletion sys/net/gnrc/sock/udp/gnrc_sock_udp.c
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,9 @@ static bool _accept_remote(const sock_udp_t *sock, const udp_hdr_t *hdr,
ipv6_addr_to_str(addr_str, (ipv6_addr_t *)&sock->remote.addr, sizeof(addr_str)));
DEBUG(", source (%s) does not match\n",
ipv6_addr_to_str(addr_str, (ipv6_addr_t *)&remote->addr, sizeof(addr_str)));
return false;
if (CONFIG_GNRC_SOCK_UDP_CHECK_REMOTE_ADDR) {
return false;
}
}

return true;
Expand Down
Loading