net: Add msg_peek support for udp and tcp
Signed-off-by: wangyingdong <wangyingdong@xiaomi.com>
This commit is contained in:
parent
79af1cdfe6
commit
57bf3e1fea
2 changed files with 41 additions and 14 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue