Merge pull request #14704 from maribu/sock-aux-gnrc
net/gnrc/sock: Implement sock_aux_local
This commit is contained in:
commit
ba89d8641e
@ -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;
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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());
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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());
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user