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,
|
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;
|
gnrc_pktsnip_t *pkt, *netif;
|
||||||
msg_t msg;
|
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);
|
assert(ipv6_hdr != NULL);
|
||||||
memcpy(&remote->addr, &ipv6_hdr->src, sizeof(ipv6_addr_t));
|
memcpy(&remote->addr, &ipv6_hdr->src, sizeof(ipv6_addr_t));
|
||||||
remote->family = AF_INET6;
|
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);
|
netif = gnrc_pktsnip_search_type(pkt, GNRC_NETTYPE_NETIF);
|
||||||
if (netif == NULL) {
|
if (netif == NULL) {
|
||||||
remote->netif = SOCK_ADDR_ANY_NETIF;
|
remote->netif = SOCK_ADDR_ANY_NETIF;
|
||||||
|
|||||||
@ -55,6 +55,33 @@ extern "C" {
|
|||||||
*/
|
*/
|
||||||
#define GNRC_SOCK_DYN_PORTRANGE_ERR (0)
|
#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
|
* @brief Internal helper functions for GNRC
|
||||||
* @internal
|
* @internal
|
||||||
@ -116,7 +143,7 @@ void gnrc_sock_create(gnrc_sock_reg_t *reg, gnrc_nettype_t type, uint32_t demux_
|
|||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
ssize_t gnrc_sock_recv(gnrc_sock_reg_t *reg, gnrc_pktsnip_t **pkt, uint32_t timeout,
|
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
|
* @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;
|
gnrc_pktsnip_t *pkt;
|
||||||
sock_ip_ep_t tmp;
|
sock_ip_ep_t tmp;
|
||||||
int res;
|
int res;
|
||||||
|
gnrc_sock_recv_aux_t _aux = { 0 };
|
||||||
|
|
||||||
assert((sock != NULL) && (data != NULL) && (buf_ctx != NULL));
|
assert((sock != NULL) && (data != NULL) && (buf_ctx != NULL));
|
||||||
if (*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;
|
return -EADDRNOTAVAIL;
|
||||||
}
|
}
|
||||||
tmp.family = sock->local.family;
|
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) {
|
if (res < 0) {
|
||||||
return res;
|
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);
|
gnrc_pktbuf_release(pkt);
|
||||||
return -EPROTO;
|
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;
|
*data = pkt->data;
|
||||||
*buf_ctx = pkt;
|
*buf_ctx = pkt;
|
||||||
res = (int)pkt->size;
|
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;
|
udp_hdr_t *hdr;
|
||||||
sock_ip_ep_t tmp;
|
sock_ip_ep_t tmp;
|
||||||
int res;
|
int res;
|
||||||
|
gnrc_sock_recv_aux_t _aux = { 0 };
|
||||||
|
|
||||||
assert((sock != NULL) && (data != NULL) && (buf_ctx != NULL));
|
assert((sock != NULL) && (data != NULL) && (buf_ctx != NULL));
|
||||||
if (*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;
|
return -EADDRNOTAVAIL;
|
||||||
}
|
}
|
||||||
tmp.family = sock->local.family;
|
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) {
|
if (res < 0) {
|
||||||
return res;
|
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);
|
gnrc_pktbuf_release(pkt);
|
||||||
return -EPROTO;
|
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;
|
*data = pkt->data;
|
||||||
*buf_ctx = pkt;
|
*buf_ctx = pkt;
|
||||||
res = (int)pkt->size;
|
res = (int)pkt->size;
|
||||||
|
|||||||
@ -1,5 +1,11 @@
|
|||||||
include ../Makefile.tests_common
|
include ../Makefile.tests_common
|
||||||
|
|
||||||
|
AUX_LOCAL ?= 1
|
||||||
|
|
||||||
|
ifeq (1, $(AUX_LOCAL))
|
||||||
|
USEMODULE += sock_aux_local
|
||||||
|
endif
|
||||||
|
|
||||||
USEMODULE += sock_ip
|
USEMODULE += sock_ip
|
||||||
USEMODULE += gnrc_ipv6
|
USEMODULE += gnrc_ipv6
|
||||||
USEMODULE += ps
|
USEMODULE += ps
|
||||||
|
|||||||
@ -344,6 +344,33 @@ static void test_sock_ip_recv__non_blocking(void)
|
|||||||
expect(_check_net());
|
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 void test_sock_ip_recv_buf__success(void)
|
||||||
{
|
{
|
||||||
static const ipv6_addr_t src_addr = { .u8 = _TEST_ADDR_REMOTE };
|
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__unsocketed_with_remote());
|
||||||
CALL(test_sock_ip_recv__with_timeout());
|
CALL(test_sock_ip_recv__with_timeout());
|
||||||
CALL(test_sock_ip_recv__non_blocking());
|
CALL(test_sock_ip_recv__non_blocking());
|
||||||
|
CALL(test_sock_ip_recv__aux());
|
||||||
CALL(test_sock_ip_recv_buf__success());
|
CALL(test_sock_ip_recv_buf__success());
|
||||||
_prepare_send_checks();
|
_prepare_send_checks();
|
||||||
CALL(test_sock_ip_send__EAFNOSUPPORT_INET());
|
CALL(test_sock_ip_send__EAFNOSUPPORT_INET());
|
||||||
|
|||||||
@ -1,5 +1,11 @@
|
|||||||
include ../Makefile.tests_common
|
include ../Makefile.tests_common
|
||||||
|
|
||||||
|
AUX_LOCAL ?= 1
|
||||||
|
|
||||||
|
ifeq (1, $(AUX_LOCAL))
|
||||||
|
USEMODULE += sock_aux_local
|
||||||
|
endif
|
||||||
|
|
||||||
USEMODULE += gnrc_sock_check_reuse
|
USEMODULE += gnrc_sock_check_reuse
|
||||||
USEMODULE += sock_udp
|
USEMODULE += sock_udp
|
||||||
USEMODULE += gnrc_ipv6
|
USEMODULE += gnrc_ipv6
|
||||||
|
|||||||
@ -423,6 +423,36 @@ static void test_sock_udp_recv__non_blocking(void)
|
|||||||
expect(_check_net());
|
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 void test_sock_udp_recv_buf__success(void)
|
||||||
{
|
{
|
||||||
static const ipv6_addr_t src_addr = { .u8 = _TEST_ADDR_REMOTE };
|
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__unsocketed_with_remote());
|
||||||
CALL(test_sock_udp_recv__with_timeout());
|
CALL(test_sock_udp_recv__with_timeout());
|
||||||
CALL(test_sock_udp_recv__non_blocking());
|
CALL(test_sock_udp_recv__non_blocking());
|
||||||
|
CALL(test_sock_udp_recv__aux());
|
||||||
CALL(test_sock_udp_recv_buf__success());
|
CALL(test_sock_udp_recv_buf__success());
|
||||||
_prepare_send_checks();
|
_prepare_send_checks();
|
||||||
CALL(test_sock_udp_send__EAFNOSUPPORT());
|
CALL(test_sock_udp_send__EAFNOSUPPORT());
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user