mirror of
https://github.com/apache/nuttx.git
synced 2026-05-28 03:45:50 +08:00
Networking: Allow receipt of empty UDP packets. From Max Neklyudov
This commit is contained in:
committed by
Gregory Nutt
parent
e0238df359
commit
7d04104485
@@ -10797,10 +10797,11 @@
|
|||||||
* arch/arm/src/samv7: Add the framework for an SPI slave drvier. This
|
* 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).
|
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
|
* 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
|
* 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
|
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
|
* 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;
|
offset -= iob->io_len;
|
||||||
iob = iob->io_flink;
|
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 */
|
/* Then loop until all of the I/O data is copied to the user buffer */
|
||||||
|
|||||||
+19
-11
@@ -101,7 +101,7 @@ struct recvfrom_s
|
|||||||
uint8_t *rf_buffer; /* Pointer to receive buffer */
|
uint8_t *rf_buffer; /* Pointer to receive buffer */
|
||||||
FAR struct sockaddr *rf_from; /* Address of sender */
|
FAR struct sockaddr *rf_from; /* Address of sender */
|
||||||
FAR socklen_t *rf_fromlen; /* Number of bytes allocated for 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 */
|
int rf_result; /* Success:OK, failure:negated errno */
|
||||||
};
|
};
|
||||||
#endif /* CONFIG_NET_UDP || CONFIG_NET_TCP */
|
#endif /* CONFIG_NET_UDP || CONFIG_NET_TCP */
|
||||||
@@ -404,8 +404,9 @@ static inline void recvfrom_udpreadahead(struct recvfrom_s *pstate)
|
|||||||
* buffer.
|
* buffer.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if ((iob = iob_peek_queue(&conn->readahead)) != NULL &&
|
pstate->rf_recvlen = -1;
|
||||||
pstate->rf_buflen > 0)
|
|
||||||
|
if ((iob = iob_peek_queue(&conn->readahead)) != NULL)
|
||||||
{
|
{
|
||||||
FAR struct iob_s *tmp;
|
FAR struct iob_s *tmp;
|
||||||
uint8_t src_addr_size;
|
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,
|
if (pstate->rf_buflen > 0)
|
||||||
src_addr_size + sizeof(uint8_t));
|
{
|
||||||
|
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_recvlen = recvlen;
|
||||||
pstate->rf_buffer += recvlen;
|
pstate->rf_buffer += recvlen;
|
||||||
pstate->rf_buflen -= recvlen;
|
pstate->rf_buflen -= recvlen;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pstate->rf_recvlen = 0;
|
||||||
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
/* Remove the I/O buffer chain from the head of the read-ahead
|
/* 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.
|
* something was received (already in 'ret'); EAGAIN if not.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (ret <= 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
/* Nothing was received */
|
/* Nothing was received */
|
||||||
|
|
||||||
|
|||||||
+34
-34
@@ -200,19 +200,23 @@ static uint16_t udp_datahandler(FAR struct net_driver_s *dev, FAR struct udp_con
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Copy the new appdata into the I/O buffer chain */
|
if (buflen > 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
|
/* Copy the new appdata into the I/O buffer chain */
|
||||||
* not free any I/O buffers.
|
|
||||||
*/
|
|
||||||
|
|
||||||
nlldbg("ERROR: Failed to add data to the I/O buffer chain: %d\n", ret);
|
ret = iob_trycopyin(iob, buffer, buflen,
|
||||||
(void)iob_free_chain(iob);
|
src_addr_size + sizeof(uint8_t), true);
|
||||||
return 0;
|
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 */
|
/* 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 flags)
|
||||||
{
|
{
|
||||||
uint16_t ret;
|
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);
|
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).
|
* 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
|
#ifdef CONFIG_NET_UDP_READAHEAD
|
||||||
uint8_t *buffer = dev->d_appdata;
|
/* Save as the packet data as in the read-ahead buffer. NOTE that
|
||||||
int buflen = dev->d_len;
|
* partial packets will not be buffered.
|
||||||
uint16_t recvlen;
|
*/
|
||||||
|
|
||||||
|
recvlen = udp_datahandler(dev, conn, buffer, buflen);
|
||||||
|
if (recvlen < buflen)
|
||||||
#endif
|
#endif
|
||||||
|
{
|
||||||
nllvdbg("No receive on connection\n");
|
/* There is no handler to receive new data and there are no free
|
||||||
|
* read-ahead buffers to retain the data -- drop the packet.
|
||||||
#ifdef CONFIG_NET_UDP_READAHEAD
|
|
||||||
/* 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);
|
nllvdbg("Dropped %d bytes\n", dev->d_len);
|
||||||
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);
|
#ifdef CONFIG_NET_STATISTICS
|
||||||
|
g_netstats.udp.drop++;
|
||||||
#ifdef CONFIG_NET_STATISTICS
|
|
||||||
g_netstats.udp.drop++;
|
|
||||||
#endif
|
#endif
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* In any event, the new data has now been handled */
|
/* In any event, the new data has now been handled */
|
||||||
|
|||||||
Reference in New Issue
Block a user