From 0fb153daca690e5616bfc404417518ab11043976 Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Wed, 10 Apr 2024 12:25:49 +0200 Subject: [PATCH 1/2] gnrc_sock/udp: add option to disable remote address check If a server has e.g. multiple global IPv6 addresses, it might respond with a different address that the one it received the request on. This is against the CoAP spec, but that doesn't stop existing implementations from doing it. --- sys/net/gnrc/sock/include/gnrc_sock_internal.h | 8 ++++++++ sys/net/gnrc/sock/udp/gnrc_sock_udp.c | 4 +++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/sys/net/gnrc/sock/include/gnrc_sock_internal.h b/sys/net/gnrc/sock/include/gnrc_sock_internal.h index 897351f3b2fa..ea0a13e17566 100644 --- a/sys/net/gnrc/sock/include/gnrc_sock_internal.h +++ b/sys/net/gnrc/sock/include/gnrc_sock_internal.h @@ -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 * diff --git a/sys/net/gnrc/sock/udp/gnrc_sock_udp.c b/sys/net/gnrc/sock/udp/gnrc_sock_udp.c index 2d8f4a6abe15..23d62eb16612 100644 --- a/sys/net/gnrc/sock/udp/gnrc_sock_udp.c +++ b/sys/net/gnrc/sock/udp/gnrc_sock_udp.c @@ -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; From 13fd806f4f56262c07f1fed39a17af0cd099e7fc Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Wed, 10 Apr 2024 12:36:53 +0200 Subject: [PATCH 2/2] nanocoap_sock: add option to include token for block-wise --- sys/include/net/nanocoap_sock.h | 12 ++++++++++++ sys/net/application_layer/nanocoap/sock.c | 19 ++++++++++++++++++- 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/sys/include/net/nanocoap_sock.h b/sys/include/net/nanocoap_sock.h index 55b6881c04bb..e079df79cc5c 100644 --- a/sys/include/net/nanocoap_sock.h +++ b/sys/include/net/nanocoap_sock.h @@ -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 */ diff --git a/sys/net/application_layer/nanocoap/sock.c b/sys/net/application_layer/nanocoap/sock.c index eb82c7bef174..1802ad26cdcf 100644 --- a/sys/net/application_layer/nanocoap/sock.c +++ b/sys/net/application_layer/nanocoap/sock.c @@ -60,6 +60,9 @@ typedef struct { 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, @@ -601,7 +604,17 @@ static int _fetch_block(nanocoap_sock_t *sock, uint8_t *buf, size_t len, }; 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); @@ -674,6 +687,10 @@ int nanocoap_sock_get_blockwise(nanocoap_sock_t *sock, const char *path, .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);