aboutsummaryrefslogtreecommitdiff
path: root/src/sp/transport/udp/udp.c
diff options
context:
space:
mode:
authorGarrett D'Amore <garrett@damore.org>2024-12-29 16:30:31 -0800
committerGarrett D'Amore <garrett@damore.org>2024-12-29 17:36:46 -0800
commitaabe3ed301081aacce11408749c26b6baae3faaa (patch)
treec7e72e15c94221d0326204513fb666e6a7bd45a1 /src/sp/transport/udp/udp.c
parent60ff324b1e6e5124dbbfefec732940512ed40f87 (diff)
downloadnng-aabe3ed301081aacce11408749c26b6baae3faaa.tar.gz
nng-aabe3ed301081aacce11408749c26b6baae3faaa.tar.bz2
nng-aabe3ed301081aacce11408749c26b6baae3faaa.zip
udp: use a bounce buffer if we lack sendmsg or recvmsg
This includes checks to determine if those functions are present, and a test case to verify that scatter gather with UDP works.
Diffstat (limited to 'src/sp/transport/udp/udp.c')
-rw-r--r--src/sp/transport/udp/udp.c28
1 files changed, 16 insertions, 12 deletions
diff --git a/src/sp/transport/udp/udp.c b/src/sp/transport/udp/udp.c
index fee142e3..45260a1b 100644
--- a/src/sp/transport/udp/udp.c
+++ b/src/sp/transport/udp/udp.c
@@ -214,7 +214,7 @@ struct udp_ep {
nni_list connaios; // aios from accept waiting for a client peer
nni_list connpipes; // pipes waiting to be connected
nng_duration refresh; // refresh interval for connections in seconds
- udp_sp_msg rx_msg; // contains the received message header
+ udp_sp_msg *rx_msg; // contains the received message header
uint16_t rcvmax; // max payload, trimmed to uint16_t
uint16_t copymax;
udp_txring tx_ring;
@@ -385,14 +385,20 @@ udp_pipe_schedule(udp_pipe *p)
static void
udp_start_rx(udp_ep *ep)
{
- nni_iov iov[2];
+ nni_iov iov;
+
+ // We use this trick to collect the message header so that we can
+ // do the entire message in a single iov, which avoids the need to
+ // scatter/gather (which can be problematic for platforms that cannot
+ // do scatter/gather due to missing recvmsg.)
+ (void) nni_msg_insert(ep->rx_payload, NULL, sizeof(udp_sp_msg));
+ iov.iov_buf = nni_msg_body(ep->rx_payload);
+ iov.iov_len = nni_msg_len(ep->rx_payload);
+ ep->rx_msg = nni_msg_body(ep->rx_payload);
+ nni_msg_trim(ep->rx_payload, sizeof(udp_sp_msg));
- iov[0].iov_buf = &ep->rx_msg;
- iov[0].iov_len = sizeof(ep->rx_msg);
- iov[1].iov_buf = nni_msg_body(ep->rx_payload);
- iov[1].iov_len = nni_msg_len(ep->rx_payload);
nni_aio_set_input(&ep->rx_aio, 0, &ep->rx_sa);
- nni_aio_set_iov(&ep->rx_aio, 2, iov);
+ nni_aio_set_iov(&ep->rx_aio, 1, &iov);
nni_udp_recv(ep->udp, &ep->rx_aio);
}
@@ -678,8 +684,7 @@ udp_recv_data(udp_ep *ep, udp_sp_data *dreq, size_t len, nng_sockaddr *sa)
nni_stat_inc(&ep->st_rcv_nocopy, 1);
// Message size larger than copy break, do zero copy
msg = ep->rx_payload;
- if (nng_msg_alloc(&ep->rx_payload,
- ep->rcvmax + sizeof(ep->rx_msg)) != 0) {
+ if (nng_msg_alloc(&ep->rx_payload, ep->rcvmax) != 0) {
ep->rx_payload = msg; // make sure we put it back
if (p->npipe != NULL) {
nni_pipe_bump_error(p->npipe, NNG_ENOMEM);
@@ -892,7 +897,7 @@ udp_rx_cb(void *arg)
}
// Received message will be in the ep rx header.
- hdr = &ep->rx_msg;
+ hdr = ep->rx_msg;
sa = &ep->rx_sa;
n = nng_aio_count(aio);
@@ -1281,8 +1286,7 @@ udp_ep_init(
ep->refresh = NNG_UDP_REFRESH; // one minute by default
ep->rcvmax = NNG_UDP_RECVMAX;
ep->copymax = NNG_UDP_COPYMAX;
- if ((rv = nni_msg_alloc(&ep->rx_payload,
- ep->rcvmax + sizeof(ep->rx_msg)) != 0)) {
+ if ((rv = nni_msg_alloc(&ep->rx_payload, ep->rcvmax) != 0)) {
NNI_FREE_STRUCTS(ep->tx_ring.descs, NNG_UDP_TXQUEUE_LEN);
return (rv);
}