Networking: Allow receipt of empty UDP packets. From Max Neklyudov
This commit is contained in:
parent
e0238df359
commit
7d04104485
|
@ -10797,10 +10797,11 @@
|
|||
* arch/arm/src/samv7: Add the framework for an SPI slave drvier. This
|
||||
driver has a lot of missing logic on initial commit (2015-08-09).
|
||||
* arch/arm/src/samv7: Basic, no-DMA SPI slave driver is in place
|
||||
(2015-080=-10).
|
||||
(2015-08-10).
|
||||
* fs/vfs/epoll.c and include/sys/epoll.h: Add a very simple epoll layer
|
||||
just around poll calls. To satisfy build app requirements. From Anton
|
||||
D. Kachalov.
|
||||
D. Kachalov (2015-08-10).
|
||||
* drivers/mtd/ramtron.c: Update to include supportf for newer
|
||||
RAMTRON parts. From David Sidrane.
|
||||
|
||||
RAMTRON parts. From David Sidrane (2015-08-10).
|
||||
* Networking: Allow receipt of empty UDP packets. From Max Neklyudov
|
||||
(2015-08-11).
|
||||
|
|
|
@ -101,6 +101,12 @@ int iob_copyout(FAR uint8_t *dest, FAR const struct iob_s *iob,
|
|||
{
|
||||
offset -= iob->io_len;
|
||||
iob = iob->io_flink;
|
||||
if (iob == NULL)
|
||||
{
|
||||
/* We have no requested data in iob chain */
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Then loop until all of the I/O data is copied to the user buffer */
|
||||
|
|
|
@ -101,7 +101,7 @@ struct recvfrom_s
|
|||
uint8_t *rf_buffer; /* Pointer to receive buffer */
|
||||
FAR struct sockaddr *rf_from; /* Address of sender */
|
||||
FAR socklen_t *rf_fromlen; /* Number of bytes allocated for address of sender */
|
||||
size_t rf_recvlen; /* The received length */
|
||||
ssize_t rf_recvlen; /* The received length */
|
||||
int rf_result; /* Success:OK, failure:negated errno */
|
||||
};
|
||||
#endif /* CONFIG_NET_UDP || CONFIG_NET_TCP */
|
||||
|
@ -404,8 +404,9 @@ static inline void recvfrom_udpreadahead(struct recvfrom_s *pstate)
|
|||
* buffer.
|
||||
*/
|
||||
|
||||
if ((iob = iob_peek_queue(&conn->readahead)) != NULL &&
|
||||
pstate->rf_buflen > 0)
|
||||
pstate->rf_recvlen = -1;
|
||||
|
||||
if ((iob = iob_peek_queue(&conn->readahead)) != NULL)
|
||||
{
|
||||
FAR struct iob_s *tmp;
|
||||
uint8_t src_addr_size;
|
||||
|
@ -445,16 +446,23 @@ static inline void recvfrom_udpreadahead(struct recvfrom_s *pstate)
|
|||
}
|
||||
}
|
||||
|
||||
recvlen = iob_copyout(pstate->rf_buffer, iob, pstate->rf_buflen,
|
||||
src_addr_size + sizeof(uint8_t));
|
||||
if (pstate->rf_buflen > 0)
|
||||
{
|
||||
recvlen = iob_copyout(pstate->rf_buffer, iob, pstate->rf_buflen,
|
||||
src_addr_size + sizeof(uint8_t));
|
||||
|
||||
nllvdbg("Received %d bytes (of %d)\n", recvlen, iob->io_pktlen);
|
||||
nllvdbg("Received %d bytes (of %d)\n", recvlen, iob->io_pktlen);
|
||||
|
||||
/* Update the accumulated size of the data read */
|
||||
/* Update the accumulated size of the data read */
|
||||
|
||||
pstate->rf_recvlen += recvlen;
|
||||
pstate->rf_buffer += recvlen;
|
||||
pstate->rf_buflen -= recvlen;
|
||||
pstate->rf_recvlen = recvlen;
|
||||
pstate->rf_buffer += recvlen;
|
||||
pstate->rf_buflen -= recvlen;
|
||||
}
|
||||
else
|
||||
{
|
||||
pstate->rf_recvlen = 0;
|
||||
}
|
||||
|
||||
out:
|
||||
/* Remove the I/O buffer chain from the head of the read-ahead
|
||||
|
@ -1482,7 +1490,7 @@ static ssize_t udp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
|
|||
* something was received (already in 'ret'); EAGAIN if not.
|
||||
*/
|
||||
|
||||
if (ret <= 0)
|
||||
if (ret < 0)
|
||||
{
|
||||
/* Nothing was received */
|
||||
|
||||
|
|
|
@ -200,19 +200,23 @@ static uint16_t udp_datahandler(FAR struct net_driver_s *dev, FAR struct udp_con
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* Copy the new appdata into the I/O buffer chain */
|
||||
|
||||
ret = iob_trycopyin(iob, buffer, buflen, src_addr_size + sizeof(uint8_t),
|
||||
true);
|
||||
if (ret < 0)
|
||||
if (buflen > 0)
|
||||
{
|
||||
/* On a failure, iob_trycopyin return a negated error value but does
|
||||
* not free any I/O buffers.
|
||||
*/
|
||||
/* Copy the new appdata into the I/O buffer chain */
|
||||
|
||||
nlldbg("ERROR: Failed to add data to the I/O buffer chain: %d\n", ret);
|
||||
(void)iob_free_chain(iob);
|
||||
return 0;
|
||||
ret = iob_trycopyin(iob, buffer, buflen,
|
||||
src_addr_size + sizeof(uint8_t), true);
|
||||
if (ret < 0)
|
||||
{
|
||||
/* On a failure, iob_trycopyin return a negated error value but
|
||||
* does not free any I/O buffers.
|
||||
*/
|
||||
|
||||
nlldbg("ERROR: Failed to add data to the I/O buffer chain: %d\n",
|
||||
ret);
|
||||
(void)iob_free_chain(iob);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Add the new I/O buffer chain to the tail of the read-ahead queue */
|
||||
|
@ -243,6 +247,11 @@ net_dataevent(FAR struct net_driver_s *dev, FAR struct udp_conn_s *conn,
|
|||
uint16_t flags)
|
||||
{
|
||||
uint16_t ret;
|
||||
#ifdef CONFIG_NET_UDP_READAHEAD
|
||||
uint8_t *buffer = dev->d_appdata;
|
||||
int buflen = dev->d_len;
|
||||
uint16_t recvlen;
|
||||
#endif
|
||||
|
||||
ret = (flags & ~UDP_NEWDATA);
|
||||
|
||||
|
@ -250,35 +259,26 @@ net_dataevent(FAR struct net_driver_s *dev, FAR struct udp_conn_s *conn,
|
|||
* can have zero-length with UDP_NEWDATA set just to cause an ACK).
|
||||
*/
|
||||
|
||||
if (dev->d_len > 0)
|
||||
{
|
||||
nllvdbg("No receive on connection\n");
|
||||
|
||||
#ifdef CONFIG_NET_UDP_READAHEAD
|
||||
uint8_t *buffer = dev->d_appdata;
|
||||
int buflen = dev->d_len;
|
||||
uint16_t recvlen;
|
||||
/* Save as the packet data as in the read-ahead buffer. NOTE that
|
||||
* partial packets will not be buffered.
|
||||
*/
|
||||
|
||||
recvlen = udp_datahandler(dev, conn, buffer, buflen);
|
||||
if (recvlen < buflen)
|
||||
#endif
|
||||
|
||||
nllvdbg("No receive on connection\n");
|
||||
|
||||
#ifdef CONFIG_NET_UDP_READAHEAD
|
||||
/* Save as the packet data as in the read-ahead buffer. NOTE that
|
||||
* partial packets will not be buffered.
|
||||
{
|
||||
/* There is no handler to receive new data and there are no free
|
||||
* read-ahead buffers to retain the data -- drop the packet.
|
||||
*/
|
||||
|
||||
recvlen = udp_datahandler(dev, conn, buffer, buflen);
|
||||
if (recvlen < buflen)
|
||||
#endif
|
||||
{
|
||||
/* There is no handler to receive new data and there are no free
|
||||
* read-ahead buffers to retain the data -- drop the packet.
|
||||
*/
|
||||
nllvdbg("Dropped %d bytes\n", dev->d_len);
|
||||
|
||||
nllvdbg("Dropped %d bytes\n", dev->d_len);
|
||||
|
||||
#ifdef CONFIG_NET_STATISTICS
|
||||
g_netstats.udp.drop++;
|
||||
#ifdef CONFIG_NET_STATISTICS
|
||||
g_netstats.udp.drop++;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/* In any event, the new data has now been handled */
|
||||
|
|
Loading…
Reference in New Issue