Skip to content
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
11 changes: 10 additions & 1 deletion sys/net/gnrc/sock/gnrc_sock.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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;
Expand Down
29 changes: 28 additions & 1 deletion sys/net/gnrc/sock/include/gnrc_sock_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
13 changes: 12 additions & 1 deletion sys/net/gnrc/sock/ip/gnrc_sock_ip.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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;
}
Expand All @@ -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;
Expand Down
14 changes: 13 additions & 1 deletion sys/net/gnrc/sock/udp/gnrc_sock_udp.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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;
}
Expand All @@ -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;
Expand Down
6 changes: 6 additions & 0 deletions tests/gnrc_sock_ip/Makefile
Original file line number Diff line number Diff line change
@@ -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
Expand Down
28 changes: 28 additions & 0 deletions tests/gnrc_sock_ip/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 };
Expand Down Expand Up @@ -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());
Expand Down
6 changes: 6 additions & 0 deletions tests/gnrc_sock_udp/Makefile
Original file line number Diff line number Diff line change
@@ -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
Expand Down
31 changes: 31 additions & 0 deletions tests/gnrc_sock_udp/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 };
Expand Down Expand Up @@ -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());
Expand Down