From 1d69f067d121737a008b7a0f49def0d78fba9537 Mon Sep 17 00:00:00 2001 From: Marian Buschsieweke Date: Mon, 27 Jul 2020 16:07:19 +0200 Subject: [PATCH 1/3] sys/net/gnrc: Implement sock_aux_local Provide address the IP packet / UDP datagram was received on in the auxiliary data, if module sock_aux_local is used. --- sys/net/gnrc/sock/gnrc_sock.c | 11 ++++++- .../gnrc/sock/include/gnrc_sock_internal.h | 29 ++++++++++++++++++- sys/net/gnrc/sock/ip/gnrc_sock_ip.c | 13 ++++++++- sys/net/gnrc/sock/udp/gnrc_sock_udp.c | 14 ++++++++- 4 files changed, 63 insertions(+), 4 deletions(-) diff --git a/sys/net/gnrc/sock/gnrc_sock.c b/sys/net/gnrc/sock/gnrc_sock.c index f19d5cb2b3..1b7e15886e 100644 --- a/sys/net/gnrc/sock/gnrc_sock.c +++ b/sys/net/gnrc/sock/gnrc_sock.c @@ -89,8 +89,11 @@ void gnrc_sock_create(gnrc_sock_reg_t *reg, gnrc_nettype_t type, uint32_t demux_ } ssize_t gnrc_sock_recv(gnrc_sock_reg_t *reg, gnrc_pktsnip_t **pkt_out, - uint32_t timeout, sock_ip_ep_t *remote) + uint32_t timeout, sock_ip_ep_t *remote, + gnrc_sock_recv_aux_t aux) { + /* only used when some sock_aux_% module is used */ + (void)aux; gnrc_pktsnip_t *pkt, *netif; msg_t msg; @@ -150,6 +153,12 @@ ssize_t gnrc_sock_recv(gnrc_sock_reg_t *reg, gnrc_pktsnip_t **pkt_out, assert(ipv6_hdr != NULL); memcpy(&remote->addr, &ipv6_hdr->src, sizeof(ipv6_addr_t)); remote->family = AF_INET6; +#if IS_USED(MODULE_SOCK_AUX_LOCAL) + if (aux.local != NULL) { + memcpy(&aux.local->addr, &ipv6_hdr->dst, sizeof(ipv6_addr_t)); + aux.local->family = AF_INET6; + } +#endif /* MODULE_SOCK_AUX_LOCAL */ netif = gnrc_pktsnip_search_type(pkt, GNRC_NETTYPE_NETIF); if (netif == NULL) { remote->netif = SOCK_ADDR_ANY_NETIF; diff --git a/sys/net/gnrc/sock/include/gnrc_sock_internal.h b/sys/net/gnrc/sock/include/gnrc_sock_internal.h index a91a94ce25..df38e233de 100644 --- a/sys/net/gnrc/sock/include/gnrc_sock_internal.h +++ b/sys/net/gnrc/sock/include/gnrc_sock_internal.h @@ -55,6 +55,33 @@ extern "C" { */ #define GNRC_SOCK_DYN_PORTRANGE_ERR (0) +/** + * @brief Structure to retrieve auxiliary data from @ref gnrc_sock_recv + * + * @details The members of this function depend on the modules used + * @internal + */ +typedef struct { +#if IS_USED(MODULE_SOCK_AUX_LOCAL) || DOXYGEN + /** + * @brief local IP address PDU was received on + * + * This member is only present if module `sock_aux_local` is used. + */ + sock_ip_ep_t *local; +#endif +#if !IS_USED(MODULE_SOCK_AUX_LOCAL) || DOXYGEN + /** + * @brief Workaround in case no `sock_aux_%` module is used + * + * Empty structures are only allowed with a GNU extension. For portability, + * this member is present if and only if this structure would be otherwise + * empty. + */ + uint8_t this_struct_is_not_empty; +#endif +} gnrc_sock_recv_aux_t; + /** * @brief Internal helper functions for GNRC * @internal @@ -116,7 +143,7 @@ void gnrc_sock_create(gnrc_sock_reg_t *reg, gnrc_nettype_t type, uint32_t demux_ * @internal */ ssize_t gnrc_sock_recv(gnrc_sock_reg_t *reg, gnrc_pktsnip_t **pkt, uint32_t timeout, - sock_ip_ep_t *remote); + sock_ip_ep_t *remote, gnrc_sock_recv_aux_t aux); /** * @brief Send a packet internally diff --git a/sys/net/gnrc/sock/ip/gnrc_sock_ip.c b/sys/net/gnrc/sock/ip/gnrc_sock_ip.c index 461966a013..e10a19021b 100644 --- a/sys/net/gnrc/sock/ip/gnrc_sock_ip.c +++ b/sys/net/gnrc/sock/ip/gnrc_sock_ip.c @@ -117,6 +117,7 @@ ssize_t sock_ip_recv_buf_aux(sock_ip_t *sock, void **data, void **buf_ctx, gnrc_pktsnip_t *pkt; sock_ip_ep_t tmp; int res; + gnrc_sock_recv_aux_t _aux = { 0 }; assert((sock != NULL) && (data != NULL) && (buf_ctx != NULL)); if (*buf_ctx != NULL) { @@ -129,7 +130,12 @@ ssize_t sock_ip_recv_buf_aux(sock_ip_t *sock, void **data, void **buf_ctx, return -EADDRNOTAVAIL; } tmp.family = sock->local.family; - res = gnrc_sock_recv((gnrc_sock_reg_t *)sock, &pkt, timeout, &tmp); +#if IS_USED(MODULE_SOCK_AUX_LOCAL) + if ((aux != NULL) && (aux->flags & SOCK_AUX_GET_LOCAL)) { + _aux.local = &aux->local; + } +#endif + res = gnrc_sock_recv((gnrc_sock_reg_t *)sock, &pkt, timeout, &tmp, _aux); if (res < 0) { return res; } @@ -146,6 +152,11 @@ ssize_t sock_ip_recv_buf_aux(sock_ip_t *sock, void **data, void **buf_ctx, gnrc_pktbuf_release(pkt); return -EPROTO; } +#if IS_USED(MODULE_SOCK_AUX_LOCAL) + if ((aux != NULL) && (aux->flags & SOCK_AUX_GET_LOCAL)) { + aux->flags &= ~(SOCK_AUX_GET_LOCAL); + } +#endif *data = pkt->data; *buf_ctx = pkt; res = (int)pkt->size; diff --git a/sys/net/gnrc/sock/udp/gnrc_sock_udp.c b/sys/net/gnrc/sock/udp/gnrc_sock_udp.c index 8c5b1d9b50..fd81ec83d2 100644 --- a/sys/net/gnrc/sock/udp/gnrc_sock_udp.c +++ b/sys/net/gnrc/sock/udp/gnrc_sock_udp.c @@ -206,6 +206,7 @@ ssize_t sock_udp_recv_buf_aux(sock_udp_t *sock, void **data, void **buf_ctx, udp_hdr_t *hdr; sock_ip_ep_t tmp; int res; + gnrc_sock_recv_aux_t _aux = { 0 }; assert((sock != NULL) && (data != NULL) && (buf_ctx != NULL)); if (*buf_ctx != NULL) { @@ -218,7 +219,12 @@ ssize_t sock_udp_recv_buf_aux(sock_udp_t *sock, void **data, void **buf_ctx, return -EADDRNOTAVAIL; } tmp.family = sock->local.family; - res = gnrc_sock_recv((gnrc_sock_reg_t *)sock, &pkt, timeout, &tmp); +#if IS_USED(MODULE_SOCK_AUX_LOCAL) + if ((aux != NULL) && (aux->flags & SOCK_AUX_GET_LOCAL)) { + _aux.local = (sock_ip_ep_t *)&aux->local; + } +#endif + res = gnrc_sock_recv((gnrc_sock_reg_t *)sock, &pkt, timeout, &tmp, _aux); if (res < 0) { return res; } @@ -240,6 +246,12 @@ ssize_t sock_udp_recv_buf_aux(sock_udp_t *sock, void **data, void **buf_ctx, gnrc_pktbuf_release(pkt); return -EPROTO; } +#if IS_USED(MODULE_SOCK_AUX_LOCAL) + if ((aux != NULL) && (aux->flags & SOCK_AUX_GET_LOCAL)) { + aux->flags &= ~SOCK_AUX_GET_LOCAL; + aux->local.port = sock->local.port; + } +#endif *data = pkt->data; *buf_ctx = pkt; res = (int)pkt->size; From f97c190117d45a7cb75fa99c3ae61fd17e397d90 Mon Sep 17 00:00:00 2001 From: Marian Buschsieweke Date: Mon, 27 Jul 2020 16:21:25 +0200 Subject: [PATCH 2/3] tests/gnrc_sock_udp: Added test for sock_aux_local --- tests/gnrc_sock_udp/Makefile | 6 ++++++ tests/gnrc_sock_udp/main.c | 31 +++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/tests/gnrc_sock_udp/Makefile b/tests/gnrc_sock_udp/Makefile index 08e7f4dabf..4dbc8d4065 100644 --- a/tests/gnrc_sock_udp/Makefile +++ b/tests/gnrc_sock_udp/Makefile @@ -1,5 +1,11 @@ include ../Makefile.tests_common +AUX_LOCAL ?= 1 + +ifeq (1, $(AUX_LOCAL)) + USEMODULE += sock_aux_local +endif + USEMODULE += gnrc_sock_check_reuse USEMODULE += sock_udp USEMODULE += gnrc_ipv6 diff --git a/tests/gnrc_sock_udp/main.c b/tests/gnrc_sock_udp/main.c index d211cada5b..ae8bf75d9e 100644 --- a/tests/gnrc_sock_udp/main.c +++ b/tests/gnrc_sock_udp/main.c @@ -423,6 +423,36 @@ static void test_sock_udp_recv__non_blocking(void) expect(_check_net()); } +static void test_sock_udp_recv__aux(void) +{ + static const ipv6_addr_t src_addr = { .u8 = _TEST_ADDR_REMOTE }; + static const ipv6_addr_t dst_addr = { .u8 = _TEST_ADDR_LOCAL }; + static const sock_udp_ep_t local = { .family = AF_INET6, + .port = _TEST_PORT_LOCAL }; + sock_udp_ep_t result; + sock_udp_aux_rx_t aux = { .flags = SOCK_AUX_GET_LOCAL }; + + expect(0 == sock_udp_create(&_sock, &local, NULL, SOCK_FLAGS_REUSE_EP)); + expect(_inject_packet(&src_addr, &dst_addr, _TEST_PORT_REMOTE, + _TEST_PORT_LOCAL, "ABCD", sizeof("ABCD"), + _TEST_NETIF)); + expect(sizeof("ABCD") == sock_udp_recv_aux(&_sock, _test_buffer, + sizeof(_test_buffer), 0, + &result, &aux)); + expect(AF_INET6 == result.family); + expect(memcmp(&result.addr, &src_addr, sizeof(result.addr)) == 0); + expect(_TEST_PORT_REMOTE == result.port); + expect(_TEST_NETIF == result.netif); +#if IS_USED(MODULE_SOCK_AUX_LOCAL) + expect(!(aux.flags & SOCK_AUX_GET_LOCAL)); + expect(memcmp(&aux.local.addr, &dst_addr, sizeof(dst_addr)) == 0); + expect(_TEST_PORT_LOCAL == aux.local.port); +#else + expect(aux.flags & SOCK_AUX_GET_LOCAL); +#endif + expect(_check_net()); +} + static void test_sock_udp_recv_buf__success(void) { static const ipv6_addr_t src_addr = { .u8 = _TEST_ADDR_REMOTE }; @@ -751,6 +781,7 @@ int main(void) CALL(test_sock_udp_recv__unsocketed_with_remote()); CALL(test_sock_udp_recv__with_timeout()); CALL(test_sock_udp_recv__non_blocking()); + CALL(test_sock_udp_recv__aux()); CALL(test_sock_udp_recv_buf__success()); _prepare_send_checks(); CALL(test_sock_udp_send__EAFNOSUPPORT()); From 3e1417c75dc19f9984975eed24484b3ac6b169e5 Mon Sep 17 00:00:00 2001 From: Marian Buschsieweke Date: Mon, 27 Jul 2020 16:43:10 +0200 Subject: [PATCH 3/3] tests/gnrc_sock_ip: Added test for sock_aux_local --- tests/gnrc_sock_ip/Makefile | 6 ++++++ tests/gnrc_sock_ip/main.c | 28 ++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/tests/gnrc_sock_ip/Makefile b/tests/gnrc_sock_ip/Makefile index 6c9b963267..968ea0fdd3 100644 --- a/tests/gnrc_sock_ip/Makefile +++ b/tests/gnrc_sock_ip/Makefile @@ -1,5 +1,11 @@ include ../Makefile.tests_common +AUX_LOCAL ?= 1 + +ifeq (1, $(AUX_LOCAL)) + USEMODULE += sock_aux_local +endif + USEMODULE += sock_ip USEMODULE += gnrc_ipv6 USEMODULE += ps diff --git a/tests/gnrc_sock_ip/main.c b/tests/gnrc_sock_ip/main.c index baab17bdcd..a37365a423 100644 --- a/tests/gnrc_sock_ip/main.c +++ b/tests/gnrc_sock_ip/main.c @@ -344,6 +344,33 @@ static void test_sock_ip_recv__non_blocking(void) expect(_check_net()); } +static void test_sock_ip_recv__aux(void) +{ + static const ipv6_addr_t src_addr = { .u8 = _TEST_ADDR_REMOTE }; + static const ipv6_addr_t dst_addr = { .u8 = _TEST_ADDR_LOCAL }; + static const sock_ip_ep_t local = { .family = AF_INET6 }; + sock_ip_ep_t result; + sock_ip_aux_rx_t aux = { .flags = SOCK_AUX_GET_LOCAL }; + + expect(0 == sock_ip_create(&_sock, &local, NULL, _TEST_PROTO, + SOCK_FLAGS_REUSE_EP)); + expect(_inject_packet(&src_addr, &dst_addr, _TEST_PROTO, "ABCD", + sizeof("ABCD"), _TEST_NETIF)); + expect(sizeof("ABCD") == sock_ip_recv_aux(&_sock, _test_buffer, + sizeof(_test_buffer), 0, &result, + &aux)); + expect(AF_INET6 == result.family); + expect(memcmp(&result.addr, &src_addr, sizeof(result.addr)) == 0); + expect(_TEST_NETIF == result.netif); +#if IS_USED(MODULE_SOCK_AUX_LOCAL) + expect(!(aux.flags & SOCK_AUX_GET_LOCAL)); + expect(memcmp(&aux.local.addr, &dst_addr, sizeof(dst_addr)) == 0); +#else + expect(aux.flags & SOCK_AUX_GET_LOCAL); +#endif + expect(_check_net()); +} + static void test_sock_ip_recv_buf__success(void) { static const ipv6_addr_t src_addr = { .u8 = _TEST_ADDR_REMOTE }; @@ -650,6 +677,7 @@ int main(void) CALL(test_sock_ip_recv__unsocketed_with_remote()); CALL(test_sock_ip_recv__with_timeout()); CALL(test_sock_ip_recv__non_blocking()); + CALL(test_sock_ip_recv__aux()); CALL(test_sock_ip_recv_buf__success()); _prepare_send_checks(); CALL(test_sock_ip_send__EAFNOSUPPORT_INET());