This is an automated email from the ASF dual-hosted git repository. xiaoxiang pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
The following commit(s) were added to refs/heads/master by this push: new 57bf3e1fea net: Add msg_peek support for udp and tcp 57bf3e1fea is described below commit 57bf3e1feae599aec41ba25c175e36c85611998e Author: wangyingdong <wangyingd...@xiaomi.com> AuthorDate: Thu May 25 19:52:41 2023 +0800 net: Add msg_peek support for udp and tcp Signed-off-by: wangyingdong <wangyingd...@xiaomi.com> --- net/tcp/tcp_recvfrom.c | 21 +++++++++++++++++---- net/udp/udp_recvfrom.c | 34 ++++++++++++++++++++++++---------- 2 files changed, 41 insertions(+), 14 deletions(-) diff --git a/net/tcp/tcp_recvfrom.c b/net/tcp/tcp_recvfrom.c index c3c3f08cd9..68379418a1 100644 --- a/net/tcp/tcp_recvfrom.c +++ b/net/tcp/tcp_recvfrom.c @@ -57,6 +57,7 @@ struct tcp_recvfrom_s FAR socklen_t *ir_fromlen; /* Number of bytes allocated for address of sender */ ssize_t ir_recvlen; /* The received length */ int ir_result; /* Success:OK, failure:negated errno */ + int ir_flags; /* Flags on received message. */ }; /**************************************************************************** @@ -135,7 +136,8 @@ static size_t tcp_recvfrom_newdata(FAR struct net_driver_s *dev, /* Trim the copied buffers */ - dev->d_iob = iob_trimhead(dev->d_iob, recvlen + offset); + dev->d_iob = iob_trimhead(dev->d_iob, + pstate->ir_flags & MSG_PEEK ? offset : recvlen + offset); ninfo("Received %d bytes (of %d)\n", (int)recvlen, (int)dev->d_len); @@ -143,7 +145,7 @@ static size_t tcp_recvfrom_newdata(FAR struct net_driver_s *dev, tcp_update_recvlen(pstate, recvlen); - return recvlen; + return pstate->ir_flags & MSG_PEEK ? 0: recvlen; } /**************************************************************************** @@ -261,6 +263,15 @@ static inline void tcp_readahead(struct tcp_recvfrom_s *pstate) tcp_update_recvlen(pstate, recvlen); + /* If it is in read-ahead mode, + * exit directly to avoid iob being released + */ + + if (pstate->ir_flags & MSG_PEEK) + { + break; + } + /* If we took all of the data from the I/O buffer chain is empty, then * release it. If there is still data available in the I/O buffer * chain, then just trim the data that we have taken from the @@ -511,7 +522,8 @@ static void tcp_recvfrom_initialize(FAR struct tcp_conn_s *conn, FAR void *buf, size_t len, FAR struct sockaddr *infrom, FAR socklen_t *fromlen, - FAR struct tcp_recvfrom_s *pstate) + FAR struct tcp_recvfrom_s *pstate, + int flags) { /* Initialize the state structure. */ @@ -522,6 +534,7 @@ static void tcp_recvfrom_initialize(FAR struct tcp_conn_s *conn, pstate->ir_buffer = buf; pstate->ir_from = infrom; pstate->ir_fromlen = fromlen; + pstate->ir_flags = flags; /* Set up the start time for the timeout */ @@ -612,7 +625,7 @@ ssize_t psock_tcp_recvfrom(FAR struct socket *psock, FAR struct msghdr *msg, * because we don't want anything to happen until we are ready. */ - tcp_recvfrom_initialize(conn, buf, len, from, fromlen, &state); + tcp_recvfrom_initialize(conn, buf, len, from, fromlen, &state, flags); /* Handle any any TCP data already buffered in a read-ahead buffer. NOTE * that there may be read-ahead data to be retrieved even after the diff --git a/net/udp/udp_recvfrom.c b/net/udp/udp_recvfrom.c index e24690a5ba..e96543ff89 100644 --- a/net/udp/udp_recvfrom.c +++ b/net/udp/udp_recvfrom.c @@ -56,6 +56,7 @@ struct udp_recvfrom_s sem_t ir_sem; /* Semaphore signals recv completion */ ssize_t ir_recvlen; /* The received length */ int ir_result; /* Success:OK, failure:negated errno */ + int ir_flags; /* Flags on received message. */ }; /**************************************************************************** @@ -208,11 +209,14 @@ static inline void udp_readahead(struct udp_recvfrom_s *pstate) * buffer queue. */ - iob_remove_queue(&conn->readahead); + if (!(pstate->ir_flags & MSG_PEEK)) + { + iob_remove_queue(&conn->readahead); - /* And free the I/O buffer chain */ + /* And free the I/O buffer chain */ - iob_free_chain(iob); + iob_free_chain(iob); + } } } @@ -422,13 +426,21 @@ static uint16_t udp_eventhandler(FAR struct net_driver_s *dev, udp_terminate(pstate, OK); - /* Indicate that the data has been consumed */ + /* In read-ahead mode, UDP_NEWDATA and iob need to be reserved + * and let udp_callback to call net_dataevent and put this packet + * into conn->readahead + */ + + if (!(pstate->ir_flags & MSG_PEEK)) + { + /* Indicate that the data has been consumed */ - flags &= ~UDP_NEWDATA; + flags &= ~UDP_NEWDATA; - /* Indicate no data in the buffer */ + /* Indicate no data in the buffer */ - netdev_iob_release(dev); + netdev_iob_release(dev); + } } } @@ -455,14 +467,16 @@ static uint16_t udp_eventhandler(FAR struct net_driver_s *dev, static void udp_recvfrom_initialize(FAR struct udp_conn_s *conn, FAR struct msghdr *msg, - FAR struct udp_recvfrom_s *pstate) + FAR struct udp_recvfrom_s *pstate, + int flags) { /* Initialize the state structure. */ memset(pstate, 0, sizeof(struct udp_recvfrom_s)); nxsem_init(&pstate->ir_sem, 0, 0); /* Doesn't really fail */ - pstate->ir_msg = msg; + pstate->ir_msg = msg; + pstate->ir_flags = flags; /* Set up the start time for the timeout */ @@ -558,7 +572,7 @@ ssize_t psock_udp_recvfrom(FAR struct socket *psock, FAR struct msghdr *msg, */ net_lock(); - udp_recvfrom_initialize(conn, msg, &state); + udp_recvfrom_initialize(conn, msg, &state, flags); /* Copy the read-ahead data from the packet */