From 77b39c5550499e50d5e9466160ab4ee29c5f3a4e Mon Sep 17 00:00:00 2001 From: Marian Buschsieweke Date: Mon, 27 Jul 2020 21:47:37 +0200 Subject: [PATCH 1/3] pkg/lwip: 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. --- pkg/lwip/contrib/sock/ip/lwip_sock_ip.c | 25 ++++++++++++-- pkg/lwip/contrib/sock/udp/lwip_sock_udp.c | 41 +++++++++++++++-------- pkg/lwip/include/lwipopts.h | 8 +++-- 3 files changed, 56 insertions(+), 18 deletions(-) diff --git a/pkg/lwip/contrib/sock/ip/lwip_sock_ip.c b/pkg/lwip/contrib/sock/ip/lwip_sock_ip.c index bb5a02a7dc..344448851f 100644 --- a/pkg/lwip/contrib/sock/ip/lwip_sock_ip.c +++ b/pkg/lwip/contrib/sock/ip/lwip_sock_ip.c @@ -108,7 +108,7 @@ static uint16_t _ip6_addr_to_netif(const ip6_addr_p_t *_addr) #endif static int _parse_iphdr(struct netbuf *buf, void **data, void **ctx, - sock_ip_ep_t *remote) + sock_ip_ep_t *remote, sock_ip_ep_t *local) { uint8_t *data_ptr = buf->ptr->payload; size_t data_len = buf->ptr->len; @@ -124,6 +124,13 @@ static int _parse_iphdr(struct netbuf *buf, void **data, void **ctx, memcpy(&remote->addr, &iphdr->src, sizeof(ip4_addr_t)); remote->netif = _ip4_addr_to_netif(&iphdr->dest); } + if (local != NULL) { + struct ip_hdr *iphdr = (struct ip_hdr *)data_ptr; + + assert(buf->p->len > sizeof(struct ip_hdr)); + local->family = AF_INET; + memcpy(&local->addr, &iphdr->dest, sizeof(ip4_addr_t)); + } data_ptr += sizeof(struct ip_hdr); data_len -= sizeof(struct ip_hdr); break; @@ -138,6 +145,13 @@ static int _parse_iphdr(struct netbuf *buf, void **data, void **ctx, memcpy(&remote->addr, &iphdr->src, sizeof(ip6_addr_t)); remote->netif = _ip6_addr_to_netif(&iphdr->dest); } + if (local != NULL) { + struct ip6_hdr *iphdr = (struct ip6_hdr *)data_ptr; + + assert(buf->p->len > sizeof(struct ip6_hdr)); + local->family = AF_INET6; + memcpy(&local->addr, &iphdr->dest, sizeof(ip6_addr_t)); + } data_ptr += sizeof(struct ip6_hdr); data_len -= sizeof(struct ip6_hdr); break; @@ -202,7 +216,14 @@ ssize_t sock_ip_recv_buf_aux(sock_ip_t *sock, void **data, void **ctx, if ((res = lwip_sock_recv(sock->base.conn, timeout, &buf)) < 0) { return res; } - res = _parse_iphdr(buf, data, ctx, remote); + sock_ip_ep_t *local = NULL; +#if IS_USED(MODULE_SOCK_AUX_LOCAL) + if (aux != NULL) { + local = &aux->local; + aux->flags &= ~(SOCK_AUX_GET_LOCAL); + } +#endif + res = _parse_iphdr(buf, data, ctx, remote, local); return res; } diff --git a/pkg/lwip/contrib/sock/udp/lwip_sock_udp.c b/pkg/lwip/contrib/sock/udp/lwip_sock_udp.c index e65a810bad..0e126f0ee6 100644 --- a/pkg/lwip/contrib/sock/udp/lwip_sock_udp.c +++ b/pkg/lwip/contrib/sock/udp/lwip_sock_udp.c @@ -23,8 +23,9 @@ #include "lwip/api.h" #include "lwip/opt.h" -#include "lwip/sys.h" #include "lwip/sock_internal.h" +#include "lwip/sys.h" +#include "lwip/udp.h" int sock_udp_create(sock_udp_t *sock, const sock_udp_ep_t *local, const sock_udp_ep_t *remote, uint16_t flags) @@ -121,29 +122,41 @@ ssize_t sock_udp_recv_buf_aux(sock_udp_t *sock, void **data, void **ctx, if ((res = lwip_sock_recv(sock->base.conn, timeout, &buf)) < 0) { return res; } - if (remote != NULL) { + if ((remote != NULL) || + ((aux != NULL) && IS_USED(MODULE_SOCK_AUX_LOCAL) + && IS_ACTIVE(LWIP_NETBUF_RECVINFO))) { /* convert remote */ - size_t addr_len; + size_t addr_len = sizeof(ipv4_addr_t); + int family = AF_INET; if (NETCONNTYPE_ISIPV6(sock->base.conn->type)) { addr_len = sizeof(ipv6_addr_t); - remote->family = AF_INET6; + family = AF_INET6; } - else if (IS_ACTIVE(LWIP_IPV4)) { - addr_len = sizeof(ipv4_addr_t); - remote->family = AF_INET; - } - else { + else if (!IS_ACTIVE(LWIP_IPV4)) { netbuf_delete(buf); return -EPROTO; } + if (remote != NULL) { + remote->family = family; #if LWIP_NETBUF_RECVINFO - remote->netif = lwip_sock_bind_addr_to_netif(&buf->toaddr); + remote->netif = lwip_sock_bind_addr_to_netif(&buf->toaddr); #else - remote->netif = SOCK_ADDR_ANY_NETIF; + remote->netif = SOCK_ADDR_ANY_NETIF; #endif - /* copy address */ - memcpy(&remote->addr, &buf->addr, addr_len); - remote->port = buf->port; + /* copy address */ + memcpy(&remote->addr, &buf->addr, addr_len); + remote->port = buf->port; + } +#if IS_USED(MODULE_SOCK_AUX_LOCAL) + static_assert(IS_ACTIVE(LWIP_NETBUF_RECVINFO), + "sock_aux_local depends on LWIP_NETBUF_RECVINFO"); + if ((aux != NULL) && (aux->flags & SOCK_AUX_GET_LOCAL)) { + aux->flags &= ~(SOCK_AUX_GET_LOCAL); + aux->local.family = family; + memcpy(&aux->local.addr, &buf->toaddr, addr_len); + aux->local.port = sock->base.conn->pcb.udp->local_port; + } +#endif /* MODULE_SOCK_AUX_LOCAL */ } *data = buf->ptr->payload; *ctx = buf; diff --git a/pkg/lwip/include/lwipopts.h b/pkg/lwip/include/lwipopts.h index 0d3554718c..9573866ae2 100644 --- a/pkg/lwip/include/lwipopts.h +++ b/pkg/lwip/include/lwipopts.h @@ -128,11 +128,15 @@ extern "C" { #define LWIP_UDPLITE 0 #endif /* MODULE_LWIP_UDPLITE */ -#if defined(MODULE_LWIP_SOCK) +#if IS_USED(MODULE_LWIP_SOCK) #define LWIP_NETCONN 1 +#if IS_USED(MODULE_SOCK_AUX_LOCAL) +#define LWIP_NETBUF_RECVINFO 1 +#endif /* MODULE_SOCK_AUX_LOCAL */ #else #define LWIP_NETCONN 0 -#endif +#endif /* MODULE_LWIP_SOCK */ + #ifndef TCP_LISTEN_BACKLOG # if defined(MODULE_LWIP_SOCK_TCP) From 1282ab12031b92f7e74a861c76492e3ebc298efe Mon Sep 17 00:00:00 2001 From: Marian Buschsieweke Date: Mon, 27 Jul 2020 21:47:58 +0200 Subject: [PATCH 2/3] tests/lwip_sock_udp: Added test for sock_aux_local --- tests/lwip_sock_udp/Makefile | 5 +++ tests/lwip_sock_udp/main.c | 63 ++++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+) diff --git a/tests/lwip_sock_udp/Makefile b/tests/lwip_sock_udp/Makefile index 399ad0b533..2e95304862 100644 --- a/tests/lwip_sock_udp/Makefile +++ b/tests/lwip_sock_udp/Makefile @@ -1,6 +1,7 @@ include ../Makefile.tests_common LWIP_IPV4 ?= 0 +AUX_LOCAL ?= 1 ifneq (0, $(LWIP_IPV4)) USEMODULE += ipv4_addr @@ -17,6 +18,10 @@ ifneq (0, $(LWIP_IPV6)) USEMODULE += lwip_ipv6_autoconfig endif +ifeq (1, $(AUX_LOCAL)) + USEMODULE += sock_aux_local +endif + USEMODULE += inet_csum USEMODULE += l2util USEMODULE += lwip_netdev diff --git a/tests/lwip_sock_udp/main.c b/tests/lwip_sock_udp/main.c index 86ec985308..8cbb0dda9c 100644 --- a/tests/lwip_sock_udp/main.c +++ b/tests/lwip_sock_udp/main.c @@ -394,6 +394,36 @@ static void test_sock_udp_recv4__non_blocking(void) expect(_check_net()); } +static void test_sock_udp_recv4__aux(void) +{ + static const sock_udp_ep_t local = { .family = AF_INET, + .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_4packet(_TEST_ADDR4_REMOTE, _TEST_ADDR4_LOCAL, _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_INET == result.family); + expect(_TEST_ADDR4_REMOTE == result.addr.ipv4_u32); + expect(_TEST_PORT_REMOTE == result.port); +#if IS_USED(MODULE_SOCK_AUX_LOCAL) + expect(_TEST_NETIF == result.netif); + expect(!(aux.flags & SOCK_AUX_GET_LOCAL)); + expect(aux.local.addr.ipv4_u32 == _TEST_ADDR4_LOCAL); + expect(aux.local.port == _TEST_PORT_LOCAL); + expect(aux.local.family == AF_INET); +#else + expect(aux.flags & SOCK_AUX_GET_LOCAL); +#endif /* MODULE_SOCK_AUX_LOCAL */ + expect(_check_net()); +} + + static void test_sock_udp_recv_buf4__success(void) { static const sock_udp_ep_t local = { .family = AF_INET, @@ -1057,6 +1087,37 @@ static void test_sock_udp_recv6__non_blocking(void) expect(_check_net()); } +static void test_sock_udp_recv6__aux(void) +{ + static const ipv6_addr_t src_addr = { .u8 = _TEST_ADDR6_REMOTE }; + static const ipv6_addr_t dst_addr = { .u8 = _TEST_ADDR6_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_6packet(&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); +#if IS_USED(MODULE_SOCK_AUX_LOCAL) + expect(_TEST_NETIF == result.netif); + expect(!(aux.flags & SOCK_AUX_GET_LOCAL)); + expect(memcmp(&aux.local.addr, &dst_addr, sizeof(dst_addr)) == 0); + expect(aux.local.port == _TEST_PORT_LOCAL); + expect(aux.local.family == AF_INET6); +#else + expect(aux.flags & SOCK_AUX_GET_LOCAL); +#endif /* MODULE_SOCK_AUX_LOCAL */ + expect(_check_net()); +} + static void test_sock_udp_recv_buf6__success(void) { static const ipv6_addr_t src_addr = { .u8 = _TEST_ADDR6_REMOTE }; @@ -1409,6 +1470,7 @@ int main(void) CALL(test_sock_udp_recv4__unsocketed_with_remote()); CALL(test_sock_udp_recv4__with_timeout()); CALL(test_sock_udp_recv4__non_blocking()); + CALL(test_sock_udp_recv4__aux()); CALL(test_sock_udp_recv_buf4__success()); _prepare_send_checks(); CALL(test_sock_udp_send4__EAFNOSUPPORT()); @@ -1457,6 +1519,7 @@ int main(void) CALL(test_sock_udp_recv6__unsocketed_with_remote()); CALL(test_sock_udp_recv6__with_timeout()); CALL(test_sock_udp_recv6__non_blocking()); + CALL(test_sock_udp_recv6__aux()); CALL(test_sock_udp_recv_buf6__success()); _prepare_send_checks(); CALL(test_sock_udp_send6__EAFNOSUPPORT()); From e97ed09c3cf4caaa784367b6ee05f3d36849d771 Mon Sep 17 00:00:00 2001 From: Marian Buschsieweke Date: Mon, 27 Jul 2020 21:48:22 +0200 Subject: [PATCH 3/3] tests/lwip_sock_ip: Added test for sock_aux_local --- tests/lwip_sock_ip/Makefile | 5 ++++ tests/lwip_sock_ip/main.c | 56 +++++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+) diff --git a/tests/lwip_sock_ip/Makefile b/tests/lwip_sock_ip/Makefile index caed6075a9..8df768efab 100644 --- a/tests/lwip_sock_ip/Makefile +++ b/tests/lwip_sock_ip/Makefile @@ -1,6 +1,7 @@ include ../Makefile.tests_common LWIP_IPV4 ?= 0 +AUX_LOCAL ?= 1 ifneq (0, $(LWIP_IPV4)) USEMODULE += ipv4_addr @@ -17,6 +18,10 @@ ifneq (0, $(LWIP_IPV6)) USEMODULE += lwip_ipv6_autoconfig endif +ifeq (1, $(AUX_LOCAL)) + USEMODULE += sock_aux_local +endif + USEMODULE += inet_csum USEMODULE += l2util USEMODULE += lwip_netdev diff --git a/tests/lwip_sock_ip/main.c b/tests/lwip_sock_ip/main.c index 5cf9fcce2d..1887f46743 100644 --- a/tests/lwip_sock_ip/main.c +++ b/tests/lwip_sock_ip/main.c @@ -304,6 +304,32 @@ static void test_sock_ip_recv4__non_blocking(void) expect(_check_net()); } +static void test_sock_ip_recv4__aux(void) +{ + static const sock_ip_ep_t local = { .family = AF_INET }; + 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_4packet(_TEST_ADDR4_REMOTE, _TEST_ADDR4_LOCAL, _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_INET == result.family); + expect(_TEST_ADDR4_REMOTE == result.addr.ipv4_u32); + expect(_TEST_NETIF == result.netif); +#if IS_USED(MODULE_SOCK_AUX_LOCAL) + expect(!(aux.flags & SOCK_AUX_GET_LOCAL)); + expect(aux.local.family == AF_INET ); + expect(aux.local.addr.ipv4_u32 == _TEST_ADDR4_LOCAL ); +#else + expect(aux.flags & SOCK_AUX_GET_LOCAL); +#endif + expect(_check_net()); +} + static void test_sock_ip_recv_buf4__success(void) { static const sock_ip_ep_t local = { .family = AF_INET }; @@ -845,6 +871,34 @@ static void test_sock_ip_recv6__non_blocking(void) expect(_check_net()); } +static void test_sock_ip_recv6__aux(void) +{ + static const ipv6_addr_t src_addr = { .u8 = _TEST_ADDR6_REMOTE }; + static const ipv6_addr_t dst_addr = { .u8 = _TEST_ADDR6_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_6packet(&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 defined(MODULE_SOCK_AUX_LOCAL) + expect(!(aux.flags & SOCK_AUX_GET_LOCAL)); + expect(aux.local.family == AF_INET6 ); + 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_buf6__success(void) { static const ipv6_addr_t src_addr = { .u8 = _TEST_ADDR6_REMOTE }; @@ -1164,6 +1218,7 @@ int main(void) CALL(test_sock_ip_recv4__unsocketed_with_remote()); CALL(test_sock_ip_recv4__with_timeout()); CALL(test_sock_ip_recv4__non_blocking()); + CALL(test_sock_ip_recv4__aux()); CALL(test_sock_ip_recv_buf4__success()); _prepare_send_checks(); CALL(test_sock_ip_send4__EAFNOSUPPORT()); @@ -1209,6 +1264,7 @@ int main(void) CALL(test_sock_ip_recv6__unsocketed_with_remote()); CALL(test_sock_ip_recv6__with_timeout()); CALL(test_sock_ip_recv6__non_blocking()); + CALL(test_sock_ip_recv6__aux()); CALL(test_sock_ip_recv_buf6__success()); _prepare_send_checks(); CALL(test_sock_ip_send6__EAFNOSUPPORT());