-
Notifications
You must be signed in to change notification settings - Fork 2.1k
[WIP] sys/net/sock/udp: Provide access to local IP addr #14402
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Add `sock_udp_recv2()` and `sock_udp_recv_buf2()` that also provide the local address a datagram was received on. This is particularly useful if a socket is bound to multiple addresses or to all local addresses. This can be used to implement virtual hosting.
Parenthesis around numbers boolean defined (e.g. `#define LWIP_IPV6 (1)` rather than `#define LWIP_IPV6 1`) prevents using IS_ACTIVE() / IS_USED() macros. Thus, this commit drops the parenthesis.
Since |
I no PoC and WIP, but whatever the final solution is should also provide similar solutions for the other |
@@ -225,6 +229,13 @@ ssize_t sock_udp_recv_buf(sock_udp_t *sock, void **data, void **buf_ctx, | |||
memcpy(remote, &tmp, sizeof(tmp)); | |||
remote->port = byteorder_ntohs(hdr->src_port); | |||
} | |||
if (local != NULL) { | |||
gnrc_pktsnip_t *ipv6 = gnrc_pktsnip_search_type(pkt, GNRC_NETTYPE_IPV6); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might be worth to extend gnrc_sock_recv()
to also provide the destination. Otherwise, we iterate pkt
unnecessary twice.
I now have a different use case that again needs extension of the SOCK API. This makes me wonder if a more generalized solution would be better. E.g. int sock_udp_recv_aux(sock_udp_t *sock, void *data, size_t max_len,
uint32_t timeout, sock_udp_ep_t *remote,
sock_aux_recv_udp_t *auxiliary_data);
ssize_t sock_udp_send_aux(sock_udp_t *sock, const void *data, size_t len,
const sock_udp_ep_t *remote,
sock_aux_send_udp_t *auxiliary_data); And enum {
SOCK_AUX_FLAG_HAS_LOCAL_ENDPOINT = (1UL << 0),
SOCK_AUX_FLAG_HAS_TIMESTAMP = (1UL << 1),
};
typedef struct {
#ifdef MODULE_SOCK_AUX_LOCAL_ENDPOINT
sock_udp_ep_t local;
#endif /* MODULE_SOCK_AUX_RECEIVED_ENDPOINT */
#ifdef MODULE_SOCK_TIMESTAMP
uint64_t received_at;
#endif /* MODULE_SOCK_TIMESTAMP */
unsigned flags; /**< Bitmask identifying which auxiliary data is present */
} sock_aux_recv_udp_t;
typedef struct {
#ifdef MODULE_SOCK_TIMESTAMP
uint64_t send_at;
#endif /* MODULE_SOCK_TIMESTAMP */
unsigned flags; /**< Bitmask identifying which auxiliary data is present */
} sock_aux_send_udp_t; The use case for the time stamp is btw. time synchronization. By having the correct time a frame was received and send, jitter in the message processing does no longer influence precision of time synchronization. E.g. the low level network driver should already be able to get a pretty accurate time stamp. In addition some hardware (e.g. Ethernet with PTP support) will create the timestamp in hardware, so that even the jitter in the ISR can be avoided. The timestamp for sending is needed in context of PTP in server mode for the Fellow_up message or as client for the Delay_Req message. Those time stamps could be provided outside of the SOCK API e.g. by having |
Closing in favor of #14622 |
Contribution description
Motivation / Background
In some use cases where a socket is bound to multiple IP addresses, it is useful to know on which address a datagram was received. The current sock API makes it hard to retrieve this information:
sock_udp_get_local()
will return whatever IP the interface was bound to; which in the use case of multiple IP addresses often isSOCK_IPV6_EP_ANY
.E.g. lets say we have a RIOT border router connected to the Internet via Ethernet and to an IEEE 802.15.4 network. A CoAP server running additionally on this border router might provide access to its resources without access control, DTLS, OSCORE, ... over IEEE 802.15.4, as Layer 2 security might be considered as sufficient in that scenario. However, for requests received from the Internet, additional security measures seem to be a good idea.
There are likely many other use cases for virtual hosting there.
Proposed solution
Add an
sock_udp_recv2()
function, which in addition tosock_udp_ep_t *remote
also takes ansock_udp_ep_t *local
as optional argument (optional = "passNULL
if you don't care). The existingsock_udp_recv()
is implemented asstatic inline
wrapper on top ofsock_udp_recv2()
, passingNULL
forlocal
. Thus, sock implementations don't need to provide both functions and existing code can keep usingsock_udp_recv()
.A proof of concept implementation was added for GNRC, lwIP, and emb6.
Testing procedure
TBD
Issues/PRs references
None