From 2b92e9ec598e86cead5beb9c950849c29ec28c34 Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Mon, 7 Nov 2022 16:57:33 +0100 Subject: [PATCH] gnrc_sock_udp: accept response from any address if remote is multicast --- sys/include/net/sock.h | 3 ++- sys/net/gnrc/sock/udp/gnrc_sock_udp.c | 28 ++++++++++++++++----------- 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/sys/include/net/sock.h b/sys/include/net/sock.h index 3487f4e1da..4acf9f36a2 100644 --- a/sys/include/net/sock.h +++ b/sys/include/net/sock.h @@ -143,7 +143,8 @@ extern "C" { * @anchor net_sock_flags * @{ */ -#define SOCK_FLAGS_REUSE_EP (0x0001) /**< allow to reuse end point on bind */ +#define SOCK_FLAGS_REUSE_EP (0x0001) /**< allow to reuse end point on bind */ +#define SOCK_FLAGS_CONNECT_REMOTE (0x0002) /**< restrict responses to remote address */ /** @} */ /** diff --git a/sys/net/gnrc/sock/udp/gnrc_sock_udp.c b/sys/net/gnrc/sock/udp/gnrc_sock_udp.c index b30a250258..d3b86c2ded 100644 --- a/sys/net/gnrc/sock/udp/gnrc_sock_udp.c +++ b/sys/net/gnrc/sock/udp/gnrc_sock_udp.c @@ -136,6 +136,12 @@ int sock_udp_create(sock_udp_t *sock, const sock_udp_ep_t *local, } gnrc_ep_set((sock_ip_ep_t *)&sock->remote, (sock_ip_ep_t *)remote, sizeof(sock_udp_ep_t)); + + /* only accept responses from the set remote */ + if (!ipv6_addr_is_multicast((ipv6_addr_t *)&remote->addr) && + !ipv6_addr_is_unspecified((ipv6_addr_t *)&remote->addr)) { + flags |= SOCK_FLAGS_CONNECT_REMOTE; + } } if (local != NULL) { /* listen only with local given */ @@ -200,22 +206,22 @@ ssize_t sock_udp_recv_aux(sock_udp_t *sock, void *data, size_t max_len, return (nobufs) ? -ENOBUFS : ((res < 0) ? res : ret); } -static bool _remote_mismatch(const sock_udp_t *sock, const udp_hdr_t *hdr, const sock_ip_ep_t *remote) +static bool _remote_accept(const sock_udp_t *sock, const udp_hdr_t *hdr, + const sock_ip_ep_t *remote) { + if ((sock->flags & SOCK_FLAGS_CONNECT_REMOTE) == 0) { + /* socket is not bound to a remote */ + return true; + } + if (sock->remote.family == AF_UNSPEC) { /* socket accepts any remote */ - return false; + return true; } if (sock->remote.port != byteorder_ntohs(hdr->src_port)) { DEBUG("gnrc_sock_udp: port mismatch (%u != %u)\n", sock->remote.port, byteorder_ntohs(hdr->src_port)); - return true; - } - - /* We only have IPv6 for now, so just comparing the whole end point should suffice */ - if (memcmp(&sock->remote.addr, &ipv6_addr_unspecified, sizeof(ipv6_addr_t)) == 0) { - /* socket accepts any remote address */ return false; } @@ -225,10 +231,10 @@ static bool _remote_mismatch(const sock_udp_t *sock, const udp_hdr_t *hdr, const 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 true; + return false; } - return false; + return true; } ssize_t sock_udp_recv_buf_aux(sock_udp_t *sock, void **data, void **buf_ctx, @@ -280,7 +286,7 @@ ssize_t sock_udp_recv_buf_aux(sock_udp_t *sock, void **data, void **buf_ctx, memcpy(remote, &tmp, sizeof(tmp)); remote->port = byteorder_ntohs(hdr->src_port); } - if (_remote_mismatch(sock, hdr, &tmp)) { + if (!_remote_accept(sock, hdr, &tmp)) { gnrc_pktbuf_release(pkt); return -EPROTO; }