net: Add msg_peek support for udp and tcp

Signed-off-by: wangyingdong <wangyingdong@xiaomi.com>
This commit is contained in:
wangyingdong 2023-05-25 19:52:41 +08:00 committed by Xiang Xiao
parent 79af1cdfe6
commit 57bf3e1fea
2 changed files with 41 additions and 14 deletions

View file

@ -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

View file

@ -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
*/
flags &= ~UDP_NEWDATA;
if (!(pstate->ir_flags & MSG_PEEK))
{
/* Indicate that the data has been consumed */
/* Indicate no data in the buffer */
flags &= ~UDP_NEWDATA;
netdev_iob_release(dev);
/* Indicate no data in the buffer */
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 */