From efa9e7bffdcc01701ec8790f4315266f1b8d7042 Mon Sep 17 00:00:00 2001 From: Xiang Xiao Date: Sat, 11 Jan 2020 11:56:03 +0800 Subject: [PATCH 1/3] Make the read ahead buffer unselectable Here is the email loop talk about why it is better to remove the option: https://groups.google.com/forum/#!topic/nuttx/AaNkS7oU6R0 Change-Id: Ib66c037752149ad4b2787ef447f966c77aa12aad Signed-off-by: Xiang Xiao --- Documentation/NuttxPortingGuide.html | 4 +- Documentation/NuttxUserGuide.html | 2 - boards/arm/kinetis/freedom-k64f/README.txt | 2 - boards/arm/kinetis/freedom-k66f/README.txt | 2 - boards/arm/kinetis/twr-k64f120m/README.txt | 2 - boards/arm/sam34/sam4e-ek/README.txt | 1 - boards/arm/sama5/sama5d3-xplained/README.txt | 1 - .../sama5d3-xplained/configs/bridge/defconfig | 1 - boards/arm/sama5/sama5d3x-ek/README.txt | 1 - boards/arm/sama5/sama5d4-ek/README.txt | 1 - .../sama5/sama5d4-ek/configs/bridge/defconfig | 1 - boards/arm/samv7/same70-xplained/README.txt | 1 - boards/arm/samv7/samv71-xult/README.txt | 1 - .../arm/stm32/cloudctrl/configs/nsh/defconfig | 1 - .../olimex-stm32-p207/configs/nsh/defconfig | 1 - .../arm/stm32/viewtool-stm32f107/README.txt | 2 - boards/arm/tiva/dk-tm4c129x/README.txt | 2 - .../tiva/dk-tm4c129x/configs/ipv6/defconfig | 1 - .../tiva/lm3s6432-s2e/configs/nsh/defconfig | 1 - fs/procfs/fs_procfsiobinfo.c | 4 +- graphics/vnc/server/Kconfig | 1 - graphics/vnc/server/vnc_server.h | 4 - include/nuttx/mm/iob.h | 4 +- include/nuttx/net/netconfig.h | 14 -- mm/iob/Kconfig | 8 +- net/Kconfig | 2 + net/inet/inet_recvfrom.c | 130 +++--------------- net/inet/inet_sockif.c | 16 --- net/tcp/Kconfig | 35 +---- net/tcp/tcp.h | 6 +- net/tcp/tcp_callback.c | 6 - net/tcp/tcp_conn.c | 6 - net/tcp/tcp_netpoll.c | 6 - net/tcp/tcp_notifier.c | 6 - net/tcp/tcp_recvwindow.c | 8 +- net/udp/Kconfig | 8 +- net/udp/udp.h | 9 +- net/udp/udp_callback.c | 6 - net/udp/udp_conn.c | 2 - net/udp/udp_netpoll.c | 2 - net/udp/udp_notifier.c | 6 - 41 files changed, 35 insertions(+), 282 deletions(-) diff --git a/Documentation/NuttxPortingGuide.html b/Documentation/NuttxPortingGuide.html index 5e5b932bbd43a..c51d9cbd14fb3 100644 --- a/Documentation/NuttxPortingGuide.html +++ b/Documentation/NuttxPortingGuide.html @@ -4600,7 +4600,7 @@

4.14.1 Configuration Options

CONFIG_IOB_NBUFFERS
Number of pre-allocated I/O buffers. Each packet is represented by a series of small I/O buffers in a chain. This setting determines the number of preallocated I/O buffers available for packet data. - The default value is setup for network support. The default is 8 buffers if neither TCP read-ahead or TCP write buffering is enabled (neither CONFIG_NET_TCP_WRITE_BUFFERS nor CONFIG_NET_TCP_READAHEAD), 24 if only write buffering is enabled, and 36 if both read-ahead and write buffering are enabled. + The default value is setup for network support. The default is 8 buffers if neither TCP/UDP or write buffering is enabled (neither CONFIG_NET_TCP_WRITE_BUFFERS nor CONFIG_NET_TCP), 24 if only TCP/UDP is enabled, and 36 if both TCP/UDP and write buffering are enabled.
CONFIG_IOB_BUFSIZE
Payload size of one I/O buffer. Each packet is represented by a series of small I/O buffers in a chain. This setting determines the data payload each preallocated I/O buffer. The default value is 196 bytes. @@ -4610,7 +4610,7 @@

4.14.1 Configuration Options

These generic I/O buffer chain containers are not currently used by any logic in NuttX. That is because their other other specialized I/O buffer chain containers that also carry a payload of usage specific information. - The default value is zero if nether TCP nor UDP read-ahead buffering is enabled (i.e., neither CONFIG_NET_TCP_READAHEAD && !CONFIG_NET_UDP_READAHEAD or eight if either is enabled. + The default value is zero if nether TCP nor UDP is enabled (i.e., neither CONFIG_NET_TCP && !CONFIG_NET_UDP or eight if either is enabled.
CONFIG_IOB_THROTTLE
I/O buffer throttle value. TCP write buffering and read-ahead buffer use the same pool of free I/O buffers. In order to prevent uncontrolled incoming TCP packets from hogging all of the available, pre-allocated I/O buffers, a throttling value is required. This throttle value assures that I/O buffers will be denied to the read-ahead logic before TCP writes are halted. diff --git a/Documentation/NuttxUserGuide.html b/Documentation/NuttxUserGuide.html index 064977d75f247..67c50120736c7 100644 --- a/Documentation/NuttxUserGuide.html +++ b/Documentation/NuttxUserGuide.html @@ -8639,8 +8639,6 @@
2.10.2.4.1 poll
  • CONFIG_NET Defined for general network support
  • CONFIG_NET_TCP Defined for TCP/IP support
  • -
  • CONFIG_NET_TCP_READAHEAD Define to enable read-ahead buffering
  • -
  • CONFIG_NET_NTCP_READAHEAD_BUFFERS Defined to be greater than zero

In order to for select to work with incoming connections, you must also select: diff --git a/boards/arm/kinetis/freedom-k64f/README.txt b/boards/arm/kinetis/freedom-k64f/README.txt index 49b208191a88b..5ef51abe08dff 100644 --- a/boards/arm/kinetis/freedom-k64f/README.txt +++ b/boards/arm/kinetis/freedom-k64f/README.txt @@ -200,11 +200,9 @@ Networking Support CONFIG_NET_ARP_IPIN=y : Enable ARP address harvesting CONFIG_NET_ARP_SEND=y : Send ARP request before sending data CONFIG_NET_TCP=y : Enable TCP/IP networking - CONFIG_NET_TCP_READAHEAD=y : Support TCP read-ahead CONFIG_NET_TCP_WRITE_BUFFERS=y : Support TCP write-buffering CONFIG_NET_TCPBACKLOG=y : Support TCP/IP backlog CONFIG_NET_MAX_LISTENPORTS=20 : - CONFIG_NET_TCP_READAHEAD_BUFSIZE=536 Read-ahead buffer size CONFIG_NET_UDP=y : Enable UDP networking CONFIG_NET_BROADCAST=y : Needed for DNS name resolution CONFIG_NET_ICMP=y : Enable ICMP networking diff --git a/boards/arm/kinetis/freedom-k66f/README.txt b/boards/arm/kinetis/freedom-k66f/README.txt index 7c5cc5bb75378..1d2db56f785b9 100644 --- a/boards/arm/kinetis/freedom-k66f/README.txt +++ b/boards/arm/kinetis/freedom-k66f/README.txt @@ -203,11 +203,9 @@ Networking Support CONFIG_NET_ARP_IPIN=y : Enable ARP address harvesting CONFIG_NET_ARP_SEND=y : Send ARP request before sending data CONFIG_NET_TCP=y : Enable TCP/IP networking - CONFIG_NET_TCP_READAHEAD=y : Support TCP read-ahead CONFIG_NET_TCP_WRITE_BUFFERS=y : Support TCP write-buffering CONFIG_NET_TCPBACKLOG=y : Support TCP/IP backlog CONFIG_NET_MAX_LISTENPORTS=20 : - CONFIG_NET_TCP_READAHEAD_BUFSIZE=536 Read-ahead buffer size CONFIG_NET_UDP=y : Enable UDP networking CONFIG_NET_BROADCAST=y : Needed for DNS name resolution CONFIG_NET_ICMP=y : Enable ICMP networking diff --git a/boards/arm/kinetis/twr-k64f120m/README.txt b/boards/arm/kinetis/twr-k64f120m/README.txt index 5898395e116d5..a0221b9ec1b27 100644 --- a/boards/arm/kinetis/twr-k64f120m/README.txt +++ b/boards/arm/kinetis/twr-k64f120m/README.txt @@ -178,11 +178,9 @@ Networking Support CONFIG_NET_ARP_IPIN=y : Enable ARP address harvesting CONFIG_NET_ARP_SEND=y : Send ARP request before sending data CONFIG_NET_TCP=y : Enable TCP/IP networking - CONFIG_NET_TCP_READAHEAD=y : Support TCP read-ahead CONFIG_NET_TCP_WRITE_BUFFERS=y : Support TCP write-buffering CONFIG_NET_TCPBACKLOG=y : Support TCP/IP backlog CONFIG_NET_MAX_LISTENPORTS=20 : - CONFIG_NET_TCP_READAHEAD_BUFSIZE=536 Read-ahead buffer size CONFIG_NET_UDP=y : Enable UDP networking CONFIG_NET_BROADCAST=y : Needed for DNS name resolution CONFIG_NET_ICMP=y : Enable ICMP networking diff --git a/boards/arm/sam34/sam4e-ek/README.txt b/boards/arm/sam34/sam4e-ek/README.txt index c78b42fef23c9..404237b0a0741 100644 --- a/boards/arm/sam34/sam4e-ek/README.txt +++ b/boards/arm/sam34/sam4e-ek/README.txt @@ -226,7 +226,6 @@ Networking Support CONFIG_NET_ETH_PKTSIZE=562 : Maximum packet size 1518 is more standard CONFIG_NET_TCP=y : Enable TCP/IP networking CONFIG_NET_TCPBACKLOG=y : Support TCP/IP backlog - CONFIG_NET_TCP_READAHEAD_BUFSIZE=536 Read-ahead buffer size CONFIG_NET_UDP=y : Enable UDP networking CONFIG_NET_BROADCAST=y : Needed for DNS name resolution CONFIG_NET_ICMP=y : Enable ICMP networking diff --git a/boards/arm/sama5/sama5d3-xplained/README.txt b/boards/arm/sama5/sama5d3-xplained/README.txt index 1273b4aec84bc..a2611b202a759 100644 --- a/boards/arm/sama5/sama5d3-xplained/README.txt +++ b/boards/arm/sama5/sama5d3-xplained/README.txt @@ -843,7 +843,6 @@ Networking CONFIG_NET_ETH_PKTSIZE=562 : Maximum packet size 1518 is more standard CONFIG_NET_TCP=y : Enable TCP/IP networking CONFIG_NET_TCPBACKLOG=y : Support TCP/IP backlog - CONFIG_NET_TCP_READAHEAD_BUFSIZE=562 : Read-ahead buffer size CONFIG_NET_UDP=y : Enable UDP networking CONFIG_NET_ICMP=y : Enable ICMP networking CONFIG_NET_ICMP_SOCKET=y : Needed for NSH ping command diff --git a/boards/arm/sama5/sama5d3-xplained/configs/bridge/defconfig b/boards/arm/sama5/sama5d3-xplained/configs/bridge/defconfig index f0116cd3b787b..f0dfc939fabeb 100644 --- a/boards/arm/sama5/sama5d3-xplained/configs/bridge/defconfig +++ b/boards/arm/sama5/sama5d3-xplained/configs/bridge/defconfig @@ -5,7 +5,6 @@ # You can then do "make savedefconfig" to generate a new defconfig file that includes your # modifications. # -# CONFIG_NET_UDP_READAHEAD is not set # CONFIG_SAMA5_ISRAM_HEAP is not set # CONFIG_SAMA5_UART0 is not set CONFIG_ARCH="arm" diff --git a/boards/arm/sama5/sama5d3x-ek/README.txt b/boards/arm/sama5/sama5d3x-ek/README.txt index 4ebddbebfde21..b67e2fa18902f 100644 --- a/boards/arm/sama5/sama5d3x-ek/README.txt +++ b/boards/arm/sama5/sama5d3x-ek/README.txt @@ -983,7 +983,6 @@ Networking CONFIG_NET_ETH_PKTSIZE=562 : Maximum packet size 1518 is more standard CONFIG_NET_TCP=y : Enable TCP/IP networking CONFIG_NET_TCPBACKLOG=y : Support TCP/IP backlog - CONFIG_NET_TCP_READAHEAD_BUFSIZE=562 : Read-ahead buffer size CONFIG_NET_UDP=y : Enable UDP networking CONFIG_NET_ICMP=y : Enable ICMP networking CONFIG_NET_ICMP_SOCKET=y : Needed for NSH ping command diff --git a/boards/arm/sama5/sama5d4-ek/README.txt b/boards/arm/sama5/sama5d4-ek/README.txt index 2ac52073af03c..00569981cea2f 100644 --- a/boards/arm/sama5/sama5d4-ek/README.txt +++ b/boards/arm/sama5/sama5d4-ek/README.txt @@ -1344,7 +1344,6 @@ Networking CONFIG_NET_ARP_IPIN=y : IP address harvesting (optional) CONFIG_NET_TCP=y : Enable TCP/IP networking CONFIG_NET_TCPBACKLOG=y : Support TCP/IP backlog - CONFIG_NET_TCP_READAHEAD=y : Enable TCP read-ahead buffering CONFIG_NET_TCP_WRITE_BUFFERS=y : Enable TCP write buffering CONFIG_NET_UDP=y : Enable UDP networking CONFIG_NET_BROADCAST=y : Support UDP broadcast packets diff --git a/boards/arm/sama5/sama5d4-ek/configs/bridge/defconfig b/boards/arm/sama5/sama5d4-ek/configs/bridge/defconfig index c31d0c713e41e..0fddd31111aaf 100644 --- a/boards/arm/sama5/sama5d4-ek/configs/bridge/defconfig +++ b/boards/arm/sama5/sama5d4-ek/configs/bridge/defconfig @@ -5,7 +5,6 @@ # You can then do "make savedefconfig" to generate a new defconfig file that includes your # modifications. # -# CONFIG_NET_UDP_READAHEAD is not set # CONFIG_SAMA5_ISRAM_HEAP is not set # CONFIG_SAMA5_UART0 is not set CONFIG_ARCH="arm" diff --git a/boards/arm/samv7/same70-xplained/README.txt b/boards/arm/samv7/same70-xplained/README.txt index 2a952b4b43f02..5530291556455 100644 --- a/boards/arm/samv7/same70-xplained/README.txt +++ b/boards/arm/samv7/same70-xplained/README.txt @@ -395,7 +395,6 @@ Selecting the GMAC peripheral CONFIG_NET_ARP_SEND=y : Use ARP to get peer address before sending CONFIG_NET_TCP=y : Enable TCP/IP networking CONFIG_NET_TCPBACKLOG=y : Support TCP/IP backlog - CONFIG_NET_TCP_READAHEAD=y : Enable TCP read-ahead buffering CONFIG_NET_TCP_WRITE_BUFFERS=y : Enable TCP write buffering CONFIG_NET_UDP=y : Enable UDP networking CONFIG_NET_BROADCAST=y : Support UDP broadcast packets diff --git a/boards/arm/samv7/samv71-xult/README.txt b/boards/arm/samv7/samv71-xult/README.txt index 68125b60bcfa6..8b09a6df06c80 100644 --- a/boards/arm/samv7/samv71-xult/README.txt +++ b/boards/arm/samv7/samv71-xult/README.txt @@ -711,7 +711,6 @@ Selecting the GMAC peripheral CONFIG_NET_ARP_SEND=y : Use ARP to get peer address before sending CONFIG_NET_TCP=y : Enable TCP/IP networking CONFIG_NET_TCPBACKLOG=y : Support TCP/IP backlog - CONFIG_NET_TCP_READAHEAD=y : Enable TCP read-ahead buffering CONFIG_NET_TCP_WRITE_BUFFERS=y : Enable TCP write buffering CONFIG_NET_UDP=y : Enable UDP networking CONFIG_NET_BROADCAST=y : Support UDP broadcast packets diff --git a/boards/arm/stm32/cloudctrl/configs/nsh/defconfig b/boards/arm/stm32/cloudctrl/configs/nsh/defconfig index 822fbdced8d9b..48fabb27541db 100644 --- a/boards/arm/stm32/cloudctrl/configs/nsh/defconfig +++ b/boards/arm/stm32/cloudctrl/configs/nsh/defconfig @@ -5,7 +5,6 @@ # You can then do "make savedefconfig" to generate a new defconfig file that includes your # modifications. # -# CONFIG_NET_UDP_READAHEAD is not set # CONFIG_NSH_DISABLE_IFCONFIG is not set # CONFIG_NSH_DISABLE_PS is not set # CONFIG_SPI_CALLBACK is not set diff --git a/boards/arm/stm32/olimex-stm32-p207/configs/nsh/defconfig b/boards/arm/stm32/olimex-stm32-p207/configs/nsh/defconfig index 52c54cc3b63f2..0199fe6c45e31 100644 --- a/boards/arm/stm32/olimex-stm32-p207/configs/nsh/defconfig +++ b/boards/arm/stm32/olimex-stm32-p207/configs/nsh/defconfig @@ -5,7 +5,6 @@ # You can then do "make savedefconfig" to generate a new defconfig file that includes your # modifications. # -# CONFIG_NET_UDP_READAHEAD is not set # CONFIG_NSH_DISABLE_IFCONFIG is not set # CONFIG_NSH_DISABLE_PS is not set CONFIG_ADC=y diff --git a/boards/arm/stm32/viewtool-stm32f107/README.txt b/boards/arm/stm32/viewtool-stm32f107/README.txt index 2f38ea7e35360..e1f5bdaec6319 100644 --- a/boards/arm/stm32/viewtool-stm32f107/README.txt +++ b/boards/arm/stm32/viewtool-stm32f107/README.txt @@ -374,8 +374,6 @@ ViewTool DP83848 Ethernet Module CONFIG_NET_SOCKOPTS=y CONFIG_NET_ETH_PKTSIZE=650 : Maximum packet size - CONFIG_NET_TCP_READAHEAD=y : Enable read-ahead buffering - CONFIG_NET_TCP_READAHEAD_BUFSIZE=650 CONFIG_NET_TCP=y : TCP support CONFIG_NET_NTCP_READAHEAD_BUFFERS=8 diff --git a/boards/arm/tiva/dk-tm4c129x/README.txt b/boards/arm/tiva/dk-tm4c129x/README.txt index f1784565026e0..a167b414f3ccf 100644 --- a/boards/arm/tiva/dk-tm4c129x/README.txt +++ b/boards/arm/tiva/dk-tm4c129x/README.txt @@ -232,11 +232,9 @@ Networking Support CONFIG_NET_ARP_IPIN=y : Enable ARP address harvesting CONFIG_NET_ARP_SEND=y : Send ARP request before sending data CONFIG_NET_TCP=y : Enable TCP/IP networking - CONFIG_NET_TCP_READAHEAD=y : Support TCP read-ahead CONFIG_NET_TCP_WRITE_BUFFERS=y : Support TCP write-buffering CONFIG_NET_TCPBACKLOG=y : Support TCP/IP backlog CONFIG_NET_MAX_LISTENPORTS=20 : - CONFIG_NET_TCP_READAHEAD_BUFSIZE=536 Read-ahead buffer size CONFIG_NET_UDP=y : Enable UDP networking CONFIG_NET_BROADCAST=y : Needed for DNS name resolution CONFIG_NET_ICMP=y : Enable ICMP networking diff --git a/boards/arm/tiva/dk-tm4c129x/configs/ipv6/defconfig b/boards/arm/tiva/dk-tm4c129x/configs/ipv6/defconfig index 1a2c6d087c3d4..50e031e7e4bc7 100644 --- a/boards/arm/tiva/dk-tm4c129x/configs/ipv6/defconfig +++ b/boards/arm/tiva/dk-tm4c129x/configs/ipv6/defconfig @@ -7,7 +7,6 @@ # # CONFIG_ARCH_FPU is not set # CONFIG_NET_IPv4 is not set -# CONFIG_NET_UDP_READAHEAD is not set # CONFIG_NSH_DISABLE_IFCONFIG is not set # CONFIG_NSH_DISABLE_PS is not set CONFIG_ARCH="arm" diff --git a/boards/arm/tiva/lm3s6432-s2e/configs/nsh/defconfig b/boards/arm/tiva/lm3s6432-s2e/configs/nsh/defconfig index e1d18e276b214..f7fd6e4a18e70 100644 --- a/boards/arm/tiva/lm3s6432-s2e/configs/nsh/defconfig +++ b/boards/arm/tiva/lm3s6432-s2e/configs/nsh/defconfig @@ -5,7 +5,6 @@ # You can then do "make savedefconfig" to generate a new defconfig file that includes your # modifications. # -# CONFIG_NET_UDP_READAHEAD is not set # CONFIG_NSH_DISABLE_IFCONFIG is not set # CONFIG_NSH_DISABLE_PS is not set CONFIG_ARCH="arm" diff --git a/fs/procfs/fs_procfsiobinfo.c b/fs/procfs/fs_procfsiobinfo.c index 1ddfb8e66d96c..44e7486a08073 100644 --- a/fs/procfs/fs_procfsiobinfo.c +++ b/fs/procfs/fs_procfsiobinfo.c @@ -136,13 +136,13 @@ static FAR const char *g_iob_user_names[] = #ifdef CONFIG_NET_BLUETOOTH "bluetooth_sock", #endif -#ifdef CONFIG_NET_UDP_READAHEAD +#if defined(CONFIG_NET_UDP) && !defined(NET_UDP_NO_STACK) "udp_readahead", #endif #ifdef CONFIG_NET_UDP_WRITE_BUFFERS "udp_writebuffer", #endif -#ifdef CONFIG_NET_TCP_READAHEAD +#if defined(CONFIG_NET_TCP) && !defined(NET_TCP_NO_STACK) "tcp_readahead", #endif #ifdef CONFIG_NET_TCP_WRITE_BUFFERS diff --git a/graphics/vnc/server/Kconfig b/graphics/vnc/server/Kconfig index cf7fca29b329d..c0158a3623890 100644 --- a/graphics/vnc/server/Kconfig +++ b/graphics/vnc/server/Kconfig @@ -7,7 +7,6 @@ menuconfig VNCSERVER bool "VNC server" default n depends on NET_TCP && !NX_LCDDRIVER - select NET_TCP_READAHEAD select NX_UPDATE ---help--- Enable support for a VNC Remote Frame Buffer (RFB) server. diff --git a/graphics/vnc/server/vnc_server.h b/graphics/vnc/server/vnc_server.h index 04f41c28e8883..6bfc686d69126 100644 --- a/graphics/vnc/server/vnc_server.h +++ b/graphics/vnc/server/vnc_server.h @@ -60,10 +60,6 @@ /* Configuration */ -#ifndef CONFIG_NET_TCP_READAHEAD -# error CONFIG_NET_TCP_READAHEAD must be set to use VNC -#endif - #ifndef CONFIG_NX_UPDATE # error CONFIG_NX_UPDATE must be set to use VNC #endif diff --git a/include/nuttx/mm/iob.h b/include/nuttx/mm/iob.h index ab2ee37a66879..43cceea918d34 100644 --- a/include/nuttx/mm/iob.h +++ b/include/nuttx/mm/iob.h @@ -187,13 +187,13 @@ enum iob_user_e #ifdef CONFIG_NET_BLUETOOTH IOBUSER_NET_SOCK_BLUETOOTH, #endif -#ifdef CONFIG_NET_UDP_READAHEAD +#if defined(CONFIG_NET_UDP) && !defined(NET_UDP_NO_STACK) IOBUSER_NET_UDP_READAHEAD, #endif #ifdef CONFIG_NET_UDP_WRITE_BUFFERS IOBUSER_NET_UDP_WRITEBUFFER, #endif -#ifdef CONFIG_NET_TCP_READAHEAD +#if defined(CONFIG_NET_TCP) && !defined(NET_TCP_NO_STACK) IOBUSER_NET_TCP_READAHEAD, #endif #ifdef CONFIG_NET_TCP_WRITE_BUFFERS diff --git a/include/nuttx/net/netconfig.h b/include/nuttx/net/netconfig.h index 69c713cba9ba6..780290f8a9552 100644 --- a/include/nuttx/net/netconfig.h +++ b/include/nuttx/net/netconfig.h @@ -587,20 +587,6 @@ # endif #endif -/* General configuration options */ - -/* Delay after receive to catch a following packet. No delay should be - * required if TCP/IP read-ahead buffering is enabled. - */ - -#ifndef CONFIG_NET_TCP_RECVDELAY -# ifdef CONFIG_NET_TCP_READAHEAD -# define CONFIG_NET_TCP_RECVDELAY 0 -# else -# define CONFIG_NET_TCP_RECVDELAY 5 -# endif -#endif - /**************************************************************************** * Public Type Definitions ****************************************************************************/ diff --git a/mm/iob/Kconfig b/mm/iob/Kconfig index b7f72cd441028..95a43767c5bc8 100644 --- a/mm/iob/Kconfig +++ b/mm/iob/Kconfig @@ -16,8 +16,8 @@ if MM_IOB config IOB_NBUFFERS int "Number of pre-allocated I/O buffers" - default 24 if (NET_WRITE_BUFFERS && !NET_READAHEAD) || (!NET_WRITE_BUFFERS && NET_READAHEAD) - default 36 if NET_WRITE_BUFFERS && NET_READAHEAD + default 36 if NET_WRITE_BUFFERS + default 24 if !NET_WRITE_BUFFERS && NET_READAHEAD default 8 if !NET_WRITE_BUFFERS && !NET_READAHEAD ---help--- Each packet is represented by a series of small I/O buffers in a @@ -34,8 +34,8 @@ config IOB_BUFSIZE config IOB_NCHAINS int "Number of pre-allocated I/O buffer chain heads" - default 0 if !NET_READAHEAD && !NET_UDP_READAHEAD - default IOB_NBUFFERS if NET_READAHEAD || NET_UDP_READAHEAD + default 0 if !NET_READAHEAD + default IOB_NBUFFERS if NET_READAHEAD ---help--- These tiny nodes are used as "containers" to support queueing of I/O buffer chains. This will limit the number of I/O transactions diff --git a/net/Kconfig b/net/Kconfig index d10088697f921..4c8d0dcec6dd1 100644 --- a/net/Kconfig +++ b/net/Kconfig @@ -14,10 +14,12 @@ config ARCH_HAVE_PHY config NET_WRITE_BUFFERS bool default n + select MM_IOB config NET_READAHEAD bool default n + select MM_IOB config NET_MCASTGROUP bool diff --git a/net/inet/inet_recvfrom.c b/net/inet/inet_recvfrom.c index e4edc5cd0d13c..458fab24b2c46 100644 --- a/net/inet/inet_recvfrom.c +++ b/net/inet/inet_recvfrom.c @@ -223,7 +223,6 @@ static inline void inet_tcp_newdata(FAR struct net_driver_s *dev, if (recvlen < dev->d_len) { -#ifdef CONFIG_NET_TCP_READAHEAD FAR struct tcp_conn_s *conn = (FAR struct tcp_conn_s *)pstate->ir_sock->s_conn; FAR uint8_t *buffer = (FAR uint8_t *)dev->d_appdata + recvlen; uint16_t buflen = dev->d_len - recvlen; @@ -251,9 +250,6 @@ static inline void inet_tcp_newdata(FAR struct net_driver_s *dev, { nerr("ERROR: packet data not saved (%d bytes)\n", buflen - nsaved); } -#endif -#else - nerr("ERROR: packet data lost (%d bytes)\n", dev->d_len - recvlen); #endif } @@ -312,7 +308,7 @@ static inline void inet_udp_newdata(FAR struct net_driver_s *dev, * ****************************************************************************/ -#if defined(NET_TCP_HAVE_STACK) && defined(CONFIG_NET_TCP_READAHEAD) +#ifdef NET_TCP_HAVE_STACK static inline void inet_tcp_readahead(struct inet_recvfrom_s *pstate) { FAR struct tcp_conn_s *conn = (FAR struct tcp_conn_s *)pstate->ir_sock->s_conn; @@ -373,9 +369,9 @@ static inline void inet_tcp_readahead(struct inet_recvfrom_s *pstate) } } } -#endif /* NET_TCP_HAVE_STACK && CONFIG_NET_TCP_READAHEAD */ +#endif /* NET_TCP_HAVE_STACK */ -#if defined(NET_UDP_HAVE_STACK) && defined(CONFIG_NET_UDP_READAHEAD) +#ifdef NET_UDP_HAVE_STACK static inline void inet_udp_readahead(struct inet_recvfrom_s *pstate) { @@ -501,26 +497,6 @@ static int inet_recvfrom_timeout(struct inet_recvfrom_s *pstate) timeo = psock->s_rcvtimeo; } - /* Use a fixed, configurable delay under the following circumstances: - * - * 1) This delay function has been enabled with CONFIG_NET_TCP_RECVDELAY > 0 - * 2) Some data has already been received from the socket. Since this can - * only be true for a TCP/IP socket, this logic applies only to TCP/IP - * sockets. And either - * 3) There is no configured receive timeout, or - * 4) The configured receive timeout is greater than than the delay - */ - -#if CONFIG_NET_TCP_RECVDELAY > 0 - if ((timeo == 0 || timeo > CONFIG_NET_TCP_RECVDELAY) && - pstate->ir_recvlen > 0) - { - /* Use the configured timeout */ - - timeo = CONFIG_NET_TCP_RECVDELAY; - } -#endif - /* Is there an effective timeout? */ if (timeo) @@ -675,28 +651,14 @@ static uint16_t inet_tcp_eventhandler(FAR struct net_driver_s *dev, flags = (flags & ~TCP_NEWDATA) | TCP_SNDACK; - /* Check for transfer complete. We will consider the transfer - * complete in own of two different ways, depending on the setting - * of CONFIG_NET_TCP_RECVDELAY. - * - * 1) If CONFIG_NET_TCP_RECVDELAY == 0 then we will consider the - * TCP/IP transfer complete as soon as any data has been received. - * This is safe because if any additional data is received, it - * will be retained in the TCP/IP read-ahead buffer until the - * next receive is performed. - * 2) CONFIG_NET_TCP_RECVDELAY > 0 may be set to wait a little - * bit to determine if more data will be received. You might - * do this if read-ahead buffering is disabled and we want to - * minimize the loss of back-to-back packets. In this case, - * the transfer is complete when either a) the entire user buffer - * is full or 2) when the receive timeout occurs (below). + /* Check for transfer complete. We will consider the + * TCP/IP transfer complete as soon as any data has been received. + * This is safe because if any additional data is received, it + * will be retained in the TCP/IP read-ahead buffer until the + * next receive is performed. */ -#if CONFIG_NET_TCP_RECVDELAY > 0 - if (pstate->ir_buflen == 0) -#else if (pstate->ir_recvlen > 0) -#endif { ninfo("TCP resume\n"); @@ -765,23 +727,7 @@ static uint16_t inet_tcp_eventhandler(FAR struct net_driver_s *dev, } else { - /* If no data has been received, then return ENOTCONN. - * Otherwise, let this return success. The failure will - * be reported the next time that recv[from]() is called. - */ - -#if CONFIG_NET_TCP_RECVDELAY > 0 - if (pstate->ir_recvlen > 0) - { - pstate->ir_result = 0; - } - else - { - pstate->ir_result = -ENOTCONN; - } -#else pstate->ir_result = -ENOTCONN; -#endif } /* Wake up the waiting thread */ @@ -806,19 +752,9 @@ static uint16_t inet_tcp_eventhandler(FAR struct net_driver_s *dev, pstate->ir_cb->priv = NULL; pstate->ir_cb->event = NULL; - /* Report an error only if no data has been received. (If - * CONFIG_NET_TCP_RECVDELAY then ir_recvlen should always be - * less than or equal to zero). - */ - -#if CONFIG_NET_TCP_RECVDELAY > 0 - if (pstate->ir_recvlen <= 0) -#endif - { - /* Report the timeout error */ + /* Report the timeout error */ - pstate->ir_result = -EAGAIN; - } + pstate->ir_result = -EAGAIN; /* Wake up the waiting thread, returning either the error -EAGAIN * that signals the timeout event or the data received up to @@ -1207,7 +1143,6 @@ static ssize_t inet_udp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t net_lock(); inet_recvfrom_initialize(psock, buf, len, from, fromlen, &state); -#ifdef CONFIG_NET_UDP_READAHEAD /* Copy the read-ahead data from the packet */ inet_udp_readahead(&state); @@ -1220,15 +1155,6 @@ static ssize_t inet_udp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t ret = state.ir_recvlen; -#else - /* Otherwise, the default return value of zero is used (only for the case - * where len == state.ir_buflen is zero). - */ - - ret = 0; -#endif - -#ifdef CONFIG_NET_UDP_READAHEAD /* Handle non-blocking UDP sockets */ if (_SS_ISNONBLOCK(psock->s_flags)) @@ -1253,7 +1179,6 @@ static ssize_t inet_udp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t */ else if (state.ir_recvlen <= 0) -#endif { /* Get the device that will handle the packet transfers. This may be * NULL if the UDP socket is bound to INADDR_ANY. In that case, no @@ -1336,7 +1261,6 @@ static ssize_t inet_tcp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t * socket has been disconnected. */ -#ifdef CONFIG_NET_TCP_READAHEAD inet_tcp_readahead(&state); /* The default return value is the number of bytes that we just copied @@ -1347,14 +1271,6 @@ static ssize_t inet_tcp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t ret = state.ir_recvlen; -#else - /* Otherwise, the default return value of zero is used (only for the case - * where len == state.ir_buflen is zero). - */ - - ret = 0; -#endif - /* Verify that the SOCK_STREAM has been and still is connected */ if (!_SS_ISCONNECTED(psock->s_flags)) @@ -1370,11 +1286,7 @@ static ssize_t inet_tcp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t * end-of-file indication. */ -#ifdef CONFIG_NET_TCP_READAHEAD if (ret <= 0 && !_SS_ISCLOSED(psock->s_flags)) -#else - if (!_SS_ISCLOSED(psock->s_flags)) -#endif { /* Nothing was previously received from the readahead buffers. * The SOCK_STREAM must be (re-)connected in order to receive any @@ -1391,9 +1303,7 @@ static ssize_t inet_tcp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t * if no data was obtained from the read-ahead buffers. */ - else -#ifdef CONFIG_NET_TCP_READAHEAD - if (_SS_ISNONBLOCK(psock->s_flags)) + else if (_SS_ISNONBLOCK(psock->s_flags)) { /* Return the number of bytes read from the read-ahead buffer if * something was received (already in 'ret'); EAGAIN if not. @@ -1413,27 +1323,19 @@ static ssize_t inet_tcp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t */ else -#endif /* We get here when we we decide that we need to setup the wait for incoming * TCP/IP data. Just a few more conditions to check: * * 1) Make sure thet there is buffer space to receive additional data - * (state.ir_buflen > 0). This could be zero, for example, if read-ahead - * buffering was enabled and we filled the user buffer with data from - * the read-ahead buffers. And - * 2) if read-ahead buffering is enabled (CONFIG_NET_TCP_READAHEAD) - * and delay logic is disabled (CONFIG_NET_TCP_RECVDELAY == 0), then we - * not want to wait if we already obtained some data from the read-ahead - * buffer. In that case, return now with what we have (don't want for more - * because there may be no timeout). + * (state.ir_buflen > 0). This could be zero, for example, we filled + * the user buffer with data from the read-ahead buffers. And + * 2) then we not want to wait if we already obtained some data from the + * read-ahead buffer. In that case, return now with what we have (don't + * want for more because there may be no timeout). */ -#if CONFIG_NET_TCP_RECVDELAY == 0 && defined(CONFIG_NET_TCP_READAHEAD) if (state.ir_recvlen == 0 && state.ir_buflen > 0) -#else - if (state.ir_buflen > 0) -#endif { FAR struct tcp_conn_s *conn = (FAR struct tcp_conn_s *)psock->s_conn; diff --git a/net/inet/inet_sockif.c b/net/inet/inet_sockif.c index 2f03075672d0a..ff856eea54d5b 100644 --- a/net/inet/inet_sockif.c +++ b/net/inet/inet_sockif.c @@ -287,28 +287,12 @@ static sockcaps_t inet_sockcaps(FAR struct socket *psock) { #ifdef NET_TCP_HAVE_STACK case SOCK_STREAM: - /* REVISIT: Non-blocking recv() depends on CONFIG_NET_TCP_READAHEAD, - * but non-blocking send() depends on CONFIG_NET_TCP_WRITE_BUFFERS. - */ - -#ifdef CONFIG_NET_TCP_READAHEAD return SOCKCAP_NONBLOCKING; -#else - return 0; -#endif #endif #ifdef NET_UDP_HAVE_STACK case SOCK_DGRAM: - /* REVISIT: Non-blocking recvfrom() depends on CONFIG_NET_UDP_READAHEAD, - * but non-blocking sendto() depends on CONFIG_NET_UDP_WRITE_BUFFERS. - */ - -#ifdef CONFIG_NET_UDP_READAHEAD return SOCKCAP_NONBLOCKING; -#else - return 0; -#endif #endif default: diff --git a/net/tcp/Kconfig b/net/tcp/Kconfig index 9319c62bc968a..325f7b79446ff 100644 --- a/net/tcp/Kconfig +++ b/net/tcp/Kconfig @@ -8,6 +8,7 @@ menu "TCP/IP Networking" config NET_TCP bool "TCP/IP Networking" default n + select NET_READAHEAD if !NET_TCP_NO_STACK ---help--- Enable or disable TCP networking support. @@ -90,30 +91,10 @@ config NET_TCP_NOTIFIER purpose notifier, but was developed specifically to support poll() logic where the poll must wait for these events. -config NET_TCP_READAHEAD - bool "Enable TCP/IP read-ahead buffering" - default y - select NET_READAHEAD - select MM_IOB - ---help--- - Read-ahead buffers allows buffering of TCP/IP packets when there is no - receive in place to catch the TCP packet. In that case, the packet - will be retained in the NuttX read-ahead buffers. - - You might want to disable TCP/IP read-ahead buffering on a highly - memory constrained system that does not have any TCP/IP packet rate - issues. But, if disabled, there will probably be more packet - retransmissions or even packet loss. - - Make sure that you check the setting in the I/O Buffering menu. - These settings are critical to the reasonable operation of read- - ahead buffering. - config NET_TCP_WRITE_BUFFERS bool "Enable TCP/IP write buffering" default n select NET_WRITE_BUFFERS - select MM_IOB ---help--- Write buffers allows buffering of ongoing TCP/IP packets, providing for higher performance, streamed output. @@ -157,20 +138,6 @@ config NET_TCP_WRBUFFER_DUMP endif # NET_TCP_WRITE_BUFFERS -config NET_TCP_RECVDELAY - int "TCP Rx delay" - default 0 - ---help--- - If NET_TCP_READAHEAD_BUFFERS is undefined, then there will be no buffering - of TCP/IP packets: Any TCP/IP packet received will be ACKed, but its contents - will be dropped in the bit-bucket. - - One low-performance option is delay for a short period of time after a - TCP/IP packet is received to see if another comes right behind it. Then - the packet data from both can be combined. This option only makes since - if performance is not an issue and you need to handle short bursts of - small, back-to-back packets. The delay is in units of deciseconds. - config NET_TCPBACKLOG bool "TCP/IP backlog support" default n diff --git a/net/tcp/tcp.h b/net/tcp/tcp.h index 5430bc4730bd3..5253018974e69 100644 --- a/net/tcp/tcp.h +++ b/net/tcp/tcp.h @@ -208,7 +208,6 @@ struct tcp_conn_s FAR struct net_driver_s *dev; -#ifdef CONFIG_NET_TCP_READAHEAD /* Read-ahead buffering. * * readahead - A singly linked list of type struct iob_qentry_s @@ -216,7 +215,6 @@ struct tcp_conn_s */ struct iob_queue_s readahead; /* Read-ahead buffering */ -#endif #ifdef CONFIG_NET_TCP_WRITE_BUFFERS /* Write buffering @@ -1109,10 +1107,8 @@ uint16_t tcp_callback(FAR struct net_driver_s *dev, * ****************************************************************************/ -#ifdef CONFIG_NET_TCP_READAHEAD uint16_t tcp_datahandler(FAR struct tcp_conn_s *conn, FAR uint8_t *buffer, uint16_t nbytes); -#endif /**************************************************************************** * Name: tcp_backlogcreate @@ -1708,7 +1704,7 @@ int tcp_notifier_teardown(int key); * ****************************************************************************/ -#if defined(CONFIG_NET_TCP_READAHEAD) && defined(CONFIG_NET_TCP_NOTIFIER) +#ifdef CONFIG_NET_TCP_NOTIFIER void tcp_readahead_signal(FAR struct tcp_conn_s *conn); #endif diff --git a/net/tcp/tcp_callback.c b/net/tcp/tcp_callback.c index 73f49f1d3e1ea..ba2d4d7cb4df1 100644 --- a/net/tcp/tcp_callback.c +++ b/net/tcp/tcp_callback.c @@ -89,22 +89,18 @@ tcp_data_event(FAR struct net_driver_s *dev, FAR struct tcp_conn_s *conn, if (dev->d_len > 0) { -#ifdef CONFIG_NET_TCP_READAHEAD uint8_t *buffer = dev->d_appdata; int buflen = dev->d_len; uint16_t recvlen; -#endif ninfo("No listener on connection\n"); -#ifdef CONFIG_NET_TCP_READAHEAD /* Save as the packet data as in the read-ahead buffer. NOTE that * partial packets will not be buffered. */ recvlen = tcp_datahandler(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. @@ -241,7 +237,6 @@ uint16_t tcp_callback(FAR struct net_driver_s *dev, * ****************************************************************************/ -#ifdef CONFIG_NET_TCP_READAHEAD uint16_t tcp_datahandler(FAR struct tcp_conn_s *conn, FAR uint8_t *buffer, uint16_t buflen) { @@ -298,6 +293,5 @@ uint16_t tcp_datahandler(FAR struct tcp_conn_s *conn, FAR uint8_t *buffer, ninfo("Buffered %d bytes\n", buflen); return buflen; } -#endif /* CONFIG_NET_TCP_READAHEAD */ #endif /* NET_TCP_HAVE_STACK */ diff --git a/net/tcp/tcp_conn.c b/net/tcp/tcp_conn.c index 1f3465c62b759..180094e51c35e 100644 --- a/net/tcp/tcp_conn.c +++ b/net/tcp/tcp_conn.c @@ -775,11 +775,9 @@ void tcp_free(FAR struct tcp_conn_s *conn) dq_rem(&conn->node, &g_active_tcp_connections); } -#ifdef CONFIG_NET_TCP_READAHEAD /* Release any read-ahead buffers attached to the connection */ iob_free_queue(&conn->readahead, IOBUSER_NET_TCP_READAHEAD); -#endif #ifdef CONFIG_NET_TCP_WRITE_BUFFERS /* Release any write buffers attached to the connection */ @@ -1020,11 +1018,9 @@ FAR struct tcp_conn_s *tcp_alloc_accept(FAR struct net_driver_s *dev, memcpy(conn->rcvseq, tcp->seqno, 4); -#ifdef CONFIG_NET_TCP_READAHEAD /* Initialize the list of TCP read-ahead buffers */ IOB_QINIT(&conn->readahead); -#endif #ifdef CONFIG_NET_TCP_WRITE_BUFFERS /* Initialize the write buffer lists */ @@ -1257,11 +1253,9 @@ int tcp_connect(FAR struct tcp_conn_s *conn, FAR const struct sockaddr *addr) conn->sndseq_max = 0; #endif -#ifdef CONFIG_NET_TCP_READAHEAD /* Initialize the list of TCP read-ahead buffers */ IOB_QINIT(&conn->readahead); -#endif #ifdef CONFIG_NET_TCP_WRITE_BUFFERS /* Initialize the TCP write buffer lists */ diff --git a/net/tcp/tcp_netpoll.c b/net/tcp/tcp_netpoll.c index e883c97ab4b4c..dca5ca38cbeb3 100644 --- a/net/tcp/tcp_netpoll.c +++ b/net/tcp/tcp_netpoll.c @@ -302,15 +302,9 @@ int tcp_pollsetup(FAR struct socket *psock, FAR struct pollfd *fds) fds->priv = (FAR void *)info; -#ifdef CONFIG_NET_TCP_READAHEAD /* Check for read data or backlogged connection availability now */ if (!IOB_QEMPTY(&conn->readahead) || tcp_backlogavailable(conn)) -#else - /* Check for backlogged connection now */ - - if (tcp_backlogavailable(conn)) -#endif { /* Normal data may be read without blocking. */ diff --git a/net/tcp/tcp_notifier.c b/net/tcp/tcp_notifier.c index 23673cfef536d..acd6404854c59 100644 --- a/net/tcp/tcp_notifier.c +++ b/net/tcp/tcp_notifier.c @@ -85,7 +85,6 @@ int tcp_readahead_notifier_setup(worker_t worker, FAR struct tcp_conn_s *conn, FAR void *arg) { -#ifdef CONFIG_NET_TCP_READAHEAD struct work_notifier_s info; DEBUGASSERT(worker != NULL); @@ -108,9 +107,6 @@ int tcp_readahead_notifier_setup(worker_t worker, info.worker = worker; return work_notifier_setup(&info); -#else - return 0; -#endif } /**************************************************************************** @@ -269,14 +265,12 @@ int tcp_notifier_teardown(int key) * ****************************************************************************/ -#ifdef CONFIG_NET_TCP_READAHEAD void tcp_readahead_signal(FAR struct tcp_conn_s *conn) { /* This is just a simple wrapper around work_notifier_signal(). */ return work_notifier_signal(WORK_TCP_READAHEAD, conn); } -#endif /**************************************************************************** * Name: tcp_writebuffer_signal diff --git a/net/tcp/tcp_recvwindow.c b/net/tcp/tcp_recvwindow.c index 694b965682b17..c6b2dea4e2161 100644 --- a/net/tcp/tcp_recvwindow.c +++ b/net/tcp/tcp_recvwindow.c @@ -75,10 +75,8 @@ uint16_t tcp_get_recvwindow(FAR struct net_driver_s *dev) uint16_t iplen; uint16_t mss; uint16_t recvwndo; -#ifdef CONFIG_NET_TCP_READAHEAD - int niob_avail; - int nqentry_avail; -#endif + int niob_avail; + int nqentry_avail; #ifdef CONFIG_NET_IPv6 #ifdef CONFIG_NET_IPv4 @@ -106,7 +104,6 @@ uint16_t tcp_get_recvwindow(FAR struct net_driver_s *dev) mss = dev->d_pktsize - (NET_LL_HDRLEN(dev) + iplen + TCP_HDRLEN); -#ifdef CONFIG_NET_TCP_READAHEAD /* Update the TCP received window based on read-ahead I/O buffer * and IOB chain availability. At least one queue entry is required. * If one queue entry is available, then the amount of read-ahead @@ -168,7 +165,6 @@ uint16_t tcp_get_recvwindow(FAR struct net_driver_s *dev) recvwndo = (uint16_t)rwnd; } else /* nqentry_avail == 0 || niob_avail == 0 */ -#endif { /* No IOB chains or noIOBs are available. The only buffering * available is within the packet buffer itself. We can buffer no diff --git a/net/udp/Kconfig b/net/udp/Kconfig index 095d86af754a8..24e05366b59b4 100644 --- a/net/udp/Kconfig +++ b/net/udp/Kconfig @@ -8,6 +8,7 @@ menu "UDP Networking" config NET_UDP bool "UDP Networking" default n + select NET_READAHEAD if !NET_UDP_NO_STACK depends on NET ---help--- Enable or disable UDP networking support. @@ -59,17 +60,10 @@ config NET_UDP_NPOLLWAITERS int "Number of UDP poll waiters" default 1 -config NET_UDP_READAHEAD - bool "Enable UDP/IP read-ahead buffering" - default y - select NET_READAHEAD - select MM_IOB - config NET_UDP_WRITE_BUFFERS bool "Enable UDP/IP write buffering" default n select NET_WRITE_BUFFERS - select MM_IOB ---help--- Write buffers allows buffering of ongoing UDP/IP packets, providing for higher performance, streamed output. diff --git a/net/udp/udp.h b/net/udp/udp.h index d63b1f75358c0..c2aa4ded3da6b 100644 --- a/net/udp/udp.h +++ b/net/udp/udp.h @@ -48,10 +48,7 @@ #include #include - -#ifdef CONFIG_NET_UDP_READAHEAD -# include -#endif +#include #ifdef CONFIG_NET_UDP_NOTIFIER # include @@ -143,7 +140,6 @@ struct udp_conn_s * Unbound: 0, Bound: 1-MAX_IFINDEX */ #endif -#ifdef CONFIG_NET_UDP_READAHEAD /* Read-ahead buffering. * * readahead - A singly linked list of type struct iob_qentry_s @@ -151,7 +147,6 @@ struct udp_conn_s */ struct iob_queue_s readahead; /* Read-ahead buffering */ -#endif #ifdef CONFIG_NET_UDP_WRITE_BUFFERS /* Write buffering @@ -814,7 +809,7 @@ int udp_notifier_teardown(int key); * ****************************************************************************/ -#if defined(CONFIG_NET_UDP_READAHEAD) && defined(CONFIG_NET_UDP_NOTIFIER) +#ifdef CONFIG_NET_UDP_NOTIFIER void udp_readahead_signal(FAR struct udp_conn_s *conn); #endif diff --git a/net/udp/udp_callback.c b/net/udp/udp_callback.c index 8b882a69d16f5..6d8cb35a40174 100644 --- a/net/udp/udp_callback.c +++ b/net/udp/udp_callback.c @@ -75,7 +75,6 @@ * ****************************************************************************/ -#ifdef CONFIG_NET_UDP_READAHEAD static uint16_t udp_datahandler(FAR struct net_driver_s *dev, FAR struct udp_conn_s *conn, FAR uint8_t *buffer, uint16_t buflen) @@ -245,7 +244,6 @@ static uint16_t udp_datahandler(FAR struct net_driver_s *dev, ninfo("Buffered %d bytes\n", buflen); return buflen; } -#endif /* CONFIG_NET_UDP_READAHEAD */ /**************************************************************************** * Name: net_dataevent @@ -260,11 +258,9 @@ 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); @@ -274,14 +270,12 @@ net_dataevent(FAR struct net_driver_s *dev, FAR struct udp_conn_s *conn, ninfo("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. */ 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. diff --git a/net/udp/udp_conn.c b/net/udp/udp_conn.c index 83e1fd7f35275..45e0f7d6f133d 100644 --- a/net/udp/udp_conn.c +++ b/net/udp/udp_conn.c @@ -617,11 +617,9 @@ void udp_free(FAR struct udp_conn_s *conn) dq_rem(&conn->node, &g_active_udp_connections); -#ifdef CONFIG_NET_UDP_READAHEAD /* Release any read-ahead buffers attached to the connection */ iob_free_queue(&conn->readahead, IOBUSER_NET_UDP_READAHEAD); -#endif #ifdef CONFIG_NET_UDP_WRITE_BUFFERS /* Release any write buffers attached to the connection */ diff --git a/net/udp/udp_netpoll.c b/net/udp/udp_netpoll.c index c351ea55a6157..076edf5a6d2b2 100644 --- a/net/udp/udp_netpoll.c +++ b/net/udp/udp_netpoll.c @@ -281,7 +281,6 @@ int udp_pollsetup(FAR struct socket *psock, FAR struct pollfd *fds) fds->priv = (FAR void *)info; -#ifdef CONFIG_NET_UDP_READAHEAD /* Check for read data availability now */ if (!IOB_QEMPTY(&conn->readahead)) @@ -290,7 +289,6 @@ int udp_pollsetup(FAR struct socket *psock, FAR struct pollfd *fds) fds->revents |= (POLLRDNORM & fds->events); } -#endif if (psock_udp_cansend(psock) >= 0) { diff --git a/net/udp/udp_notifier.c b/net/udp/udp_notifier.c index e2c909a2fc4bf..37a57f5d670e1 100644 --- a/net/udp/udp_notifier.c +++ b/net/udp/udp_notifier.c @@ -83,7 +83,6 @@ int udp_readahead_notifier_setup(worker_t worker, FAR struct udp_conn_s *conn, FAR void *arg) { -#ifdef CONFIG_NET_UDP_READAHEAD struct work_notifier_s info; DEBUGASSERT(worker != NULL); @@ -106,9 +105,6 @@ int udp_readahead_notifier_setup(worker_t worker, info.worker = worker; return work_notifier_setup(&info); -#else - return 0; -#endif } /**************************************************************************** @@ -215,14 +211,12 @@ int udp_notifier_teardown(int key) * ****************************************************************************/ -#ifdef CONFIG_NET_UDP_READAHEAD void udp_readahead_signal(FAR struct udp_conn_s *conn) { /* This is just a simple wrapper around work_notifier_signal(). */ return work_notifier_signal(WORK_UDP_READAHEAD, conn); } -#endif /**************************************************************************** * Name: udp_writebuffer_signal From d4031679479d0bb607e9c103cece387289202959 Mon Sep 17 00:00:00 2001 From: Xiang Xiao Date: Sat, 4 Jan 2020 18:37:46 +0800 Subject: [PATCH 2/3] network: simplify the timeout process logic 1.Consolidate absolute to relative timeout conversion into one place(_net_timedwait) 2.Drive the wait timeout logic by net_timedwait instead of devif_timer This patch help us remove devif_timer(period tick) to save the power in the future. Change-Id: I534748a5d767ca6da8a7843c3c2f993ed9ea77d4 Signed-off-by: Xiang Xiao --- include/nuttx/net/neighbor.h | 1 + include/nuttx/net/net.h | 10 +- net/arp/arp.h | 3 +- net/arp/arp_notify.c | 28 +----- net/arp/arp_send.c | 21 +--- net/bluetooth/bluetooth_recvfrom.c | 1 - net/bluetooth/bluetooth_sendto.c | 1 - net/devif/devif.h | 1 - net/icmp/icmp_recvfrom.c | 67 ++----------- net/icmp/icmp_sendto.c | 106 +++++--------------- net/icmpv6/icmpv6.h | 7 +- net/icmpv6/icmpv6_autoconfig.c | 21 +--- net/icmpv6/icmpv6_neighbor.c | 21 +--- net/icmpv6/icmpv6_notify.c | 32 +----- net/icmpv6/icmpv6_recvfrom.c | 67 ++----------- net/icmpv6/icmpv6_rnotify.c | 32 +----- net/icmpv6/icmpv6_sendto.c | 108 +++++---------------- net/ieee802154/ieee802154_recvfrom.c | 1 - net/ieee802154/ieee802154_sendto.c | 1 - net/inet/inet.h | 6 +- net/inet/inet_close.c | 62 +++--------- net/inet/inet_recvfrom.c | 134 ++------------------------ net/inet/inet_txdrain.c | 9 +- net/neighbor/neighbor.h | 1 - net/neighbor/neighbor_globals.c | 1 - net/pkt/pkt_recvfrom.c | 1 - net/pkt/pkt_send.c | 1 - net/sixlowpan/sixlowpan_internal.h | 2 +- net/sixlowpan/sixlowpan_reassbuf.c | 3 +- net/sixlowpan/sixlowpan_send.c | 68 ++----------- net/sixlowpan/sixlowpan_tcpsend.c | 91 +++-------------- net/sixlowpan/sixlowpan_udpsend.c | 9 +- net/socket/socket.h | 8 ++ net/tcp/tcp.h | 9 +- net/tcp/tcp_conn.c | 1 - net/tcp/tcp_getsockopt.c | 1 - net/tcp/tcp_input.c | 1 - net/tcp/tcp_send_buffered.c | 1 - net/tcp/tcp_send_unbuffered.c | 87 +++-------------- net/tcp/tcp_sendfile.c | 100 ++++--------------- net/tcp/tcp_setsockopt.c | 2 - net/tcp/tcp_txdrain.c | 8 +- net/tcp/tcp_wrbuffer.c | 2 +- net/udp/udp.h | 13 +-- net/udp/udp_psock_sendto_buffered.c | 68 ------------- net/udp/udp_psock_sendto_unbuffered.c | 87 +++-------------- net/udp/udp_setsockopt.c | 2 - net/udp/udp_txdrain.c | 8 +- net/udp/udp_wrbuffer.c | 2 +- net/usrsock/usrsock_accept.c | 26 +---- net/usrsock/usrsock_dev.c | 13 +-- net/usrsock/usrsock_recvfrom.c | 26 +---- net/usrsock/usrsock_sendto.c | 26 +---- net/utils/net_lock.c | 41 +++++--- 54 files changed, 242 insertions(+), 1207 deletions(-) diff --git a/include/nuttx/net/neighbor.h b/include/nuttx/net/neighbor.h index 0d0382110b8b9..57bb527eac163 100644 --- a/include/nuttx/net/neighbor.h +++ b/include/nuttx/net/neighbor.h @@ -50,6 +50,7 @@ #include #include +#include #include #include diff --git a/include/nuttx/net/net.h b/include/nuttx/net/net.h index 1efa774e62d24..5924ecbf45bc5 100644 --- a/include/nuttx/net/net.h +++ b/include/nuttx/net/net.h @@ -370,7 +370,7 @@ void net_unlock(void); * * Input Parameters: * sem - A reference to the semaphore to be taken. - * abstime - The absolute time to wait until a timeout is declared. + * timeout - The relative time to wait until a timeout is declared. * * Returned Value: * Zero (OK) is returned on success; a negated errno value is returned on @@ -378,8 +378,7 @@ void net_unlock(void); * ****************************************************************************/ -struct timespec; -int net_timedwait(sem_t *sem, FAR const struct timespec *abstime); +int net_timedwait(sem_t *sem, unsigned int timeout); /**************************************************************************** * Name: net_lockedwait @@ -412,7 +411,7 @@ int net_lockedwait(sem_t *sem); * * Input Parameters: * sem - A reference to the semaphore to be taken. - * abstime - The absolute time to wait until a timeout is declared. + * timeout - The relative time to wait until a timeout is declared. * * Returned Value: * Zero (OK) is returned on success; a negated errno value is returned on @@ -420,8 +419,7 @@ int net_lockedwait(sem_t *sem); * ****************************************************************************/ -int net_timedwait_uninterruptible(sem_t *sem, - FAR const struct timespec *abstime); +int net_timedwait_uninterruptible(sem_t *sem, unsigned int timeout); /**************************************************************************** * Name: net_lockedwait_uninterruptible diff --git a/net/arp/arp.h b/net/arp/arp.h index b1eaad4e1909e..3214b36b0ecaf 100644 --- a/net/arp/arp.h +++ b/net/arp/arp.h @@ -292,8 +292,7 @@ int arp_wait_cancel(FAR struct arp_notify_s *notify); ****************************************************************************/ #ifdef CONFIG_NET_ARP_SEND -struct timespec; -int arp_wait(FAR struct arp_notify_s *notify, FAR struct timespec *timeout); +int arp_wait(FAR struct arp_notify_s *notify, unsigned int timeout); #else # define arp_wait(n,t) (0) #endif diff --git a/net/arp/arp_notify.c b/net/arp/arp_notify.c index 628ced4d2c1a8..4176b9c6f94c7 100644 --- a/net/arp/arp_notify.c +++ b/net/arp/arp_notify.c @@ -39,7 +39,6 @@ #include -#include #include #include #include @@ -168,30 +167,13 @@ int arp_wait_cancel(FAR struct arp_notify_s *notify) * ****************************************************************************/ -int arp_wait(FAR struct arp_notify_s *notify, FAR struct timespec *timeout) +int arp_wait(FAR struct arp_notify_s *notify, unsigned int timeout) { - struct timespec abstime; - irqstate_t flags; int ret; - /* And wait for the ARP response (or a timeout). Interrupts will be re- - * enabled while we wait. - */ - - flags = enter_critical_section(); - DEBUGVERIFY(clock_gettime(CLOCK_REALTIME, &abstime)); + /* And wait for the ARP response (or a timeout). */ - abstime.tv_sec += timeout->tv_sec; - abstime.tv_nsec += timeout->tv_nsec; - if (abstime.tv_nsec >= 1000000000) - { - abstime.tv_sec++; - abstime.tv_nsec -= 1000000000; - } - - /* Wait to get either the correct response or a timeout. */ - - net_timedwait_uninterruptible(¬ify->nt_sem, &abstime); + net_timedwait_uninterruptible(¬ify->nt_sem, timeout); /* Then get the real result of the transfer */ @@ -202,10 +184,6 @@ int arp_wait(FAR struct arp_notify_s *notify, FAR struct timespec *timeout) */ arp_wait_cancel(notify); - - /* Re-enable interrupts and return the result of the wait */ - - leave_critical_section(flags); return ret; } diff --git a/net/arp/arp_send.c b/net/arp/arp_send.c index 7339c2761610b..83717204720ed 100644 --- a/net/arp/arp_send.c +++ b/net/arp/arp_send.c @@ -42,7 +42,6 @@ #include #include #include -#include #include #include @@ -61,15 +60,6 @@ #ifdef CONFIG_NET_ARP_SEND -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -#define CONFIG_ARP_SEND_DELAYSEC \ - (CONFIG_ARP_SEND_DELAYMSEC / 1000) -#define CONFIG_ARP_SEND_DELAYNSEC \ - ((CONFIG_ARP_SEND_DELAYMSEC - 1000*CONFIG_ARP_SEND_DELAYSEC) * 1000000) - /**************************************************************************** * Private Functions ****************************************************************************/ @@ -202,7 +192,6 @@ int arp_send(in_addr_t ipaddr) { FAR struct net_driver_s *dev; struct arp_notify_s notify; - struct timespec delay; struct arp_send_s state; int ret; @@ -323,11 +312,6 @@ int arp_send(in_addr_t ipaddr) * sending the ARP request if it is not. */ - /* The optimal delay would be the worst case round trip time. */ - - delay.tv_sec = CONFIG_ARP_SEND_DELAYSEC; - delay.tv_nsec = CONFIG_ARP_SEND_DELAYNSEC; - ret = -ETIMEDOUT; /* Assume a timeout failure */ while (state.snd_retries < CONFIG_ARP_SEND_MAXTRIES) @@ -386,7 +370,7 @@ int arp_send(in_addr_t ipaddr) /* Now wait for response to the ARP response to be received. */ - ret = arp_wait(¬ify, &delay); + ret = arp_wait(¬ify, CONFIG_ARP_SEND_DELAYMSEC); /* arp_wait will return OK if and only if the matching ARP response * is received. Otherwise, it will return -ETIMEDOUT. @@ -399,10 +383,9 @@ int arp_send(in_addr_t ipaddr) break; } - /* Increment the retry count and double the delay time */ + /* Increment the retry count */ state.snd_retries++; - clock_timespec_add(&delay, &delay, &delay); nerr("ERROR: arp_wait failed: %d\n", ret); } diff --git a/net/bluetooth/bluetooth_recvfrom.c b/net/bluetooth/bluetooth_recvfrom.c index 60964680fed39..bacd04b884b80 100644 --- a/net/bluetooth/bluetooth_recvfrom.c +++ b/net/bluetooth/bluetooth_recvfrom.c @@ -50,7 +50,6 @@ #include #include -#include #include #include #include diff --git a/net/bluetooth/bluetooth_sendto.c b/net/bluetooth/bluetooth_sendto.c index 931e26809caa7..6f939e268c079 100644 --- a/net/bluetooth/bluetooth_sendto.c +++ b/net/bluetooth/bluetooth_sendto.c @@ -52,7 +52,6 @@ #include #include -#include #include #include #include diff --git a/net/devif/devif.h b/net/devif/devif.h index f3aef4e4dce44..cbe1a005cb4c3 100644 --- a/net/devif/devif.h +++ b/net/devif/devif.h @@ -51,7 +51,6 @@ #include #include -#include #include /**************************************************************************** diff --git a/net/icmp/icmp_recvfrom.c b/net/icmp/icmp_recvfrom.c index 8ef86d12304c6..1a8fc0718d5b5 100644 --- a/net/icmp/icmp_recvfrom.c +++ b/net/icmp/icmp_recvfrom.c @@ -71,7 +71,6 @@ struct icmp_recvfrom_s FAR struct devif_callback_s *recv_cb; /* Reference to callback instance */ FAR struct socket *recv_sock; /* IPPROTO_ICMP socket structure */ sem_t recv_sem; /* Use to manage the wait for the response */ - clock_t recv_time; /* Start time for determining timeouts */ in_addr_t recv_from; /* The peer we received the request from */ FAR uint8_t *recv_buf; /* Location to return the response */ uint16_t recv_buflen; /* Size of the response */ @@ -83,46 +82,6 @@ struct icmp_recvfrom_s * Private Functions ****************************************************************************/ -/**************************************************************************** - * Name: recvfrom_timeout - * - * Description: - * Check for send timeout. - * - * Input Parameters: - * pstate - Reference to instance ot recvfrom state structure - * - * Returned Value: - * true: timeout false: no timeout - * - * Assumptions: - * The network is locked - * - ****************************************************************************/ - -#ifdef CONFIG_NET_SOCKOPTS -static inline int recvfrom_timeout(FAR struct icmp_recvfrom_s *pstate) -{ - FAR struct socket *psock; - - /* Check for a timeout configured via setsockopts(SO_SNDTIMEO). - * If none... we will let the send wait forever. - */ - - psock = pstate->recv_sock; - if (psock != NULL && psock->s_rcvtimeo != 0) - { - /* Check if the configured timeout has elapsed */ - - return net_timeo(pstate->recv_time, psock->s_rcvtimeo); - } - - /* No timeout */ - - return false; -} -#endif /* CONFIG_NET_SOCKOPTS */ - /**************************************************************************** * Name: recvfrom_eventhandler * @@ -239,17 +198,6 @@ static uint16_t recvfrom_eventhandler(FAR struct net_driver_s *dev, goto end_wait; } -#ifdef CONFIG_NET_SOCKOPTS - /* Check if the selected timeout has elapsed */ - - if (recvfrom_timeout(pstate)) - { - nerr("ERROR: recvfrom() timeout\n"); - pstate->recv_result = -ETIMEDOUT; - goto end_wait; - } -#endif - /* Continue waiting */ } @@ -477,9 +425,6 @@ ssize_t icmp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len, state.recv_buf = buf; /* Location to return the response */ state.recv_buflen = len; /* Size of the response */ - net_lock(); - state.recv_time = clock_systimer(); - /* Get the device that was used to send the ICMP request. */ dev = conn->dev; @@ -490,6 +435,8 @@ ssize_t icmp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len, goto errout; } + net_lock(); + /* Set up the callback */ state.recv_cb = icmp_callback_alloc(dev, conn); @@ -498,14 +445,16 @@ ssize_t icmp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len, state.recv_cb->flags = (ICMP_NEWDATA | NETDEV_DOWN); state.recv_cb->priv = (FAR void *)&state; state.recv_cb->event = recvfrom_eventhandler; - state.recv_result = -EINTR; /* Assume sem-wait interrupted by signal */ /* Wait for either the response to be received or for timeout to - * occur. net_lockedwait will also terminate if a signal is received. + * occur. net_timedwait will also terminate if a signal is received. */ - ninfo("Start time: 0x%08x\n", state.recv_time); - net_lockedwait(&state.recv_sem); + ret = net_timedwait(&state.recv_sem, _SO_TIMEOUT(psock->s_rcvtimeo)); + if (ret < 0) + { + state.recv_result = ret; + } icmp_callback_free(dev, conn, state.recv_cb); } diff --git a/net/icmp/icmp_sendto.c b/net/icmp/icmp_sendto.c index c50acf2ca1a3d..b88fcaf14cd36 100644 --- a/net/icmp/icmp_sendto.c +++ b/net/icmp/icmp_sendto.c @@ -87,9 +87,7 @@ struct icmp_sendto_s { FAR struct devif_callback_s *snd_cb; /* Reference to callback instance */ - FAR struct socket *snd_sock; /* IPPROTO_ICMP socket structure */ sem_t snd_sem; /* Use to manage the wait for send complete */ - clock_t snd_time; /* Start time for determining timeouts */ in_addr_t snd_toaddr; /* The peer to send the request to */ FAR const uint8_t *snd_buf; /* ICMP header + data payload */ uint16_t snd_buflen; /* Size of the ICMP header + data payload */ @@ -100,46 +98,6 @@ struct icmp_sendto_s * Private Functions ****************************************************************************/ -/**************************************************************************** - * Name: sendto_timeout - * - * Description: - * Check for send timeout. - * - * Input Parameters: - * pstate - Reference to instance ot sendto state structure - * - * Returned Value: - * true: timeout false: no timeout - * - * Assumptions: - * The network is locked - * - ****************************************************************************/ - -#ifdef CONFIG_NET_SOCKOPTS -static inline int sendto_timeout(FAR struct icmp_sendto_s *pstate) -{ - FAR struct socket *psock; - - /* Check for a timeout configured via setsockopts(SO_SNDTIMEO). - * If none... we will let the send wait forever. - */ - - psock = pstate->snd_sock; - if (psock != NULL && psock->s_sndtimeo != 0) - { - /* Check if the configured timeout has elapsed */ - - return net_timeo(pstate->snd_time, psock->s_sndtimeo); - } - - /* No timeout */ - - return false; -} -#endif /* CONFIG_NET_SOCKOPTS */ - /**************************************************************************** * Name: sendto_request * @@ -289,41 +247,6 @@ static uint16_t sendto_eventhandler(FAR struct net_driver_s *dev, goto end_wait; } -#ifdef CONFIG_NET_SOCKOPTS - /* Check if the selected timeout has elapsed */ - - if (sendto_timeout(pstate)) - { - int failcode; - - /* Check if this device is on the same network as the destination - * device. - */ - - if (!net_ipv4addr_maskcmp(pstate->snd_toaddr, dev->d_ipaddr, - dev->d_netmask)) - { - /* Destination address was not on the local network served by - * this device. If a timeout occurs, then the most likely - * reason is that the destination address is not reachable. - */ - - nerr("ERROR: Not reachable\n"); - failcode = -ENETUNREACH; - } - else - { - nerr("ERROR: sendto() timeout\n"); - failcode = -ETIMEDOUT; - } - - /* Report the failure */ - - pstate->snd_result = failcode; - goto end_wait; - } -#endif - /* Continue waiting */ } @@ -445,14 +368,12 @@ ssize_t icmp_sendto(FAR struct socket *psock, FAR const void *buf, size_t len, nxsem_init(&state.snd_sem, 0, 0); nxsem_setprotocol(&state.snd_sem, SEM_PRIO_NONE); - state.snd_sock = psock; /* The IPPROTO_ICMP socket instance */ state.snd_result = -ENOMEM; /* Assume allocation failure */ state.snd_toaddr = inaddr->sin_addr.s_addr; /* Address of the peer to send the request */ state.snd_buf = buf; /* ICMP header + data payload */ state.snd_buflen = len; /* Size of the ICMP header + data payload */ net_lock(); - state.snd_time = clock_systimer(); /* Set up the callback */ @@ -462,7 +383,6 @@ ssize_t icmp_sendto(FAR struct socket *psock, FAR const void *buf, size_t len, state.snd_cb->flags = (ICMP_POLL | NETDEV_DOWN); state.snd_cb->priv = (FAR void *)&state; state.snd_cb->event = sendto_eventhandler; - state.snd_result = -EINTR; /* Assume sem-wait interrupted by signal */ /* Setup to receive ICMP ECHO replies */ @@ -479,11 +399,31 @@ ssize_t icmp_sendto(FAR struct socket *psock, FAR const void *buf, size_t len, netdev_txnotify_dev(dev); /* Wait for either the send to complete or for timeout to occur. - * net_lockedwait will also terminate if a signal is received. + * net_timedwait will also terminate if a signal is received. */ - ninfo("Start time: 0x%08x\n", state.snd_time); - net_lockedwait(&state.snd_sem); + ret = net_timedwait(&state.snd_sem, _SO_TIMEOUT(psock->s_sndtimeo)); + if (ret < 0) + { + if (ret == -ETIMEDOUT) + { + /* Check if this device is on the same network as the destination + * device. + */ + + if (!net_ipv4addr_maskcmp(state.snd_toaddr, dev->d_ipaddr, + dev->d_netmask)) + { + /* Destination address was not on the local network served by + * this device. If a timeout occurs, then the most likely + * reason is that the destination address is not reachable. + */ + + ret = -ENETUNREACH; + } + } + state.snd_result = ret; + } icmp_callback_free(dev, conn, state.snd_cb); } diff --git a/net/icmpv6/icmpv6.h b/net/icmpv6/icmpv6.h index f5f2ab5fcec3c..f9db0e0432cf3 100644 --- a/net/icmpv6/icmpv6.h +++ b/net/icmpv6/icmpv6.h @@ -71,7 +71,6 @@ * Public Type Definitions ****************************************************************************/ -struct timespec; /* Forward reference */ struct net_driver_s; /* Forward reference */ struct socket; /* Forward reference */ struct sockaddr; /* Forward reference */ @@ -399,8 +398,7 @@ int icmpv6_wait_cancel(FAR struct icmpv6_notify_s *notify); ****************************************************************************/ #ifdef CONFIG_NET_ICMPv6_NEIGHBOR -int icmpv6_wait(FAR struct icmpv6_notify_s *notify, - FAR struct timespec *timeout); +int icmpv6_wait(FAR struct icmpv6_notify_s *notify, unsigned int timeout); #else # define icmpv6_wait(n,t) (0) #endif @@ -503,8 +501,7 @@ int icmpv6_rwait_cancel(FAR struct icmpv6_rnotify_s *notify); ****************************************************************************/ #ifdef CONFIG_NET_ICMPv6_AUTOCONF -int icmpv6_rwait(FAR struct icmpv6_rnotify_s *notify, - FAR struct timespec *timeout); +int icmpv6_rwait(FAR struct icmpv6_rnotify_s *notify, unsigned int timeout); #else # define icmpv6_rwait(n,t) (0) #endif diff --git a/net/icmpv6/icmpv6_autoconfig.c b/net/icmpv6/icmpv6_autoconfig.c index 6edd23fbeeef7..68271a4cb4d07 100644 --- a/net/icmpv6/icmpv6_autoconfig.c +++ b/net/icmpv6/icmpv6_autoconfig.c @@ -41,7 +41,6 @@ #include #include -#include #include #include @@ -58,15 +57,6 @@ #ifdef CONFIG_NET_ICMPv6_AUTOCONF -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -#define CONFIG_ICMPv6_AUTOCONF_DELAYSEC \ - (CONFIG_ICMPv6_AUTOCONF_DELAYMSEC / 1000) -#define CONFIG_ICMPv6_AUTOCONF_DELAYNSEC \ - ((CONFIG_ICMPv6_AUTOCONF_DELAYMSEC - 1000*CONFIG_ICMPv6_AUTOCONF_DELAYSEC) * 1000000) - /**************************************************************************** * Private Types ****************************************************************************/ @@ -293,7 +283,6 @@ static int icmpv6_send_message(FAR struct net_driver_s *dev, bool advertise) int icmpv6_autoconfig(FAR struct net_driver_s *dev) { struct icmpv6_rnotify_s notify; - struct timespec delay; net_ipv6addr_t lladdr; int retries; int ret; @@ -374,11 +363,6 @@ int icmpv6_autoconfig(FAR struct net_driver_s *dev) net_ipv6addr_copy(dev->d_ipv6addr, lladdr); - /* The optimal delay would be the worst case round trip time. */ - - delay.tv_sec = CONFIG_ICMPv6_AUTOCONF_DELAYSEC; - delay.tv_nsec = CONFIG_ICMPv6_AUTOCONF_DELAYNSEC; - /* 4. Router Contact: The node next attempts to contact a local router for * more information on continuing the configuration. This is done either * by listening for Router Advertisement messages sent periodically by @@ -405,7 +389,7 @@ int icmpv6_autoconfig(FAR struct net_driver_s *dev) /* Wait to receive the Router Advertisement message */ - ret = icmpv6_rwait(¬ify, &delay); + ret = icmpv6_rwait(¬ify, CONFIG_ICMPv6_AUTOCONF_DELAYMSEC); if (ret != -ETIMEDOUT) { /* ETIMEDOUT is the only expected failure. We will retry on that @@ -415,9 +399,6 @@ int icmpv6_autoconfig(FAR struct net_driver_s *dev) break; } - /* Double the delay time for the next loop */ - - clock_timespec_add(&delay, &delay, &delay); ninfo("Timed out... retrying %d\n", retries + 1); } diff --git a/net/icmpv6/icmpv6_neighbor.c b/net/icmpv6/icmpv6_neighbor.c index 8de2dbc575409..359fa1d8cca22 100644 --- a/net/icmpv6/icmpv6_neighbor.c +++ b/net/icmpv6/icmpv6_neighbor.c @@ -42,7 +42,6 @@ #include #include #include -#include #include #include @@ -63,15 +62,6 @@ #ifdef CONFIG_NET_ICMPv6_NEIGHBOR -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -#define CONFIG_ICMPv6_NEIGHBOR_DELAYSEC \ - (CONFIG_ICMPv6_NEIGHBOR_DELAYMSEC / 1000) -#define CONFIG_ICMPv6_NEIGHBOR_DELAYNSEC \ - ((CONFIG_ICMPv6_NEIGHBOR_DELAYMSEC - 1000*CONFIG_ICMPv6_NEIGHBOR_DELAYSEC) * 1000000) - /**************************************************************************** * Private Types ****************************************************************************/ @@ -199,7 +189,6 @@ int icmpv6_neighbor(const net_ipv6addr_t ipaddr) { FAR struct net_driver_s *dev; struct icmpv6_notify_s notify; - struct timespec delay; struct icmpv6_neighbor_s state; net_ipv6addr_t lookup; int ret; @@ -295,11 +284,6 @@ int icmpv6_neighbor(const net_ipv6addr_t ipaddr) * re-sending the Neighbor Solicitation if it is not. */ - /* The optimal delay would be the worst case round trip time. */ - - delay.tv_sec = CONFIG_ICMPv6_NEIGHBOR_DELAYSEC; - delay.tv_nsec = CONFIG_ICMPv6_NEIGHBOR_DELAYNSEC; - ret = -ETIMEDOUT; /* Assume a timeout failure */ while (state.snd_retries < CONFIG_ICMPv6_NEIGHBOR_MAXTRIES) @@ -348,7 +332,7 @@ int icmpv6_neighbor(const net_ipv6addr_t ipaddr) /* Now wait for response to the Neighbor Advertisement to be received. */ - ret = icmpv6_wait(¬ify, &delay); + ret = icmpv6_wait(¬ify, CONFIG_ICMPv6_NEIGHBOR_DELAYMSEC); /* icmpv6_wait will return OK if and only if the matching Neighbor * Advertisement is received. Otherwise, it will return -ETIMEDOUT. @@ -359,9 +343,8 @@ int icmpv6_neighbor(const net_ipv6addr_t ipaddr) break; } - /* Increment the retry count and double the delay time */ + /* Increment the retry count */ - clock_timespec_add(&delay, &delay, &delay); state.snd_retries++; } diff --git a/net/icmpv6/icmpv6_notify.c b/net/icmpv6/icmpv6_notify.c index 5c514f89eaee0..f883a35906843 100644 --- a/net/icmpv6/icmpv6_notify.c +++ b/net/icmpv6/icmpv6_notify.c @@ -40,7 +40,6 @@ #include #include -#include #include #include #include @@ -182,44 +181,23 @@ int icmpv6_wait_cancel(FAR struct icmpv6_notify_s *notify) * ****************************************************************************/ -int icmpv6_wait(FAR struct icmpv6_notify_s *notify, - FAR struct timespec *timeout) +int icmpv6_wait(FAR struct icmpv6_notify_s *notify, unsigned int timeout) { - struct timespec abstime; - irqstate_t flags; int ret; - /* And wait for the Neighbor Advertisement (or a timeout). Interrupts will - * be re-enabled while we wait. - */ + /* And wait for the Neighbor Advertisement (or a timeout). */ - flags = enter_critical_section(); - DEBUGVERIFY(clock_gettime(CLOCK_REALTIME, &abstime)); - - abstime.tv_sec += timeout->tv_sec; - abstime.tv_nsec += timeout->tv_nsec; - if (abstime.tv_nsec >= 1000000000) + ret = net_timedwait(¬ify->nt_sem, timeout); + if (ret >= 0) { - abstime.tv_sec++; - abstime.tv_nsec -= 1000000000; + ret = notify->nt_result; } - /* REVISIT: If net_timedwait() is awakened with signal, we will return - * the wrong error code. - */ - - net_timedwait(¬ify->nt_sem, &abstime); - ret = notify->nt_result; - /* Remove our wait structure from the list (we may no longer be at the * head of the list). */ icmpv6_wait_cancel(notify); - - /* Re-enable interrupts and return the result of the wait */ - - leave_critical_section(flags); return ret; } diff --git a/net/icmpv6/icmpv6_recvfrom.c b/net/icmpv6/icmpv6_recvfrom.c index db2d43594840b..ce54aadbe68f8 100644 --- a/net/icmpv6/icmpv6_recvfrom.c +++ b/net/icmpv6/icmpv6_recvfrom.c @@ -74,7 +74,6 @@ struct icmpv6_recvfrom_s FAR struct devif_callback_s *recv_cb; /* Reference to callback instance */ FAR struct socket *recv_sock; /* IPPROTO_ICMP6 socket structure */ sem_t recv_sem; /* Use to manage the wait for the response */ - clock_t recv_time; /* Start time for determining timeouts */ struct in6_addr recv_from; /* The peer we received the request from */ FAR uint8_t *recv_buf; /* Location to return the response */ uint16_t recv_buflen; /* Size of the response */ @@ -86,46 +85,6 @@ struct icmpv6_recvfrom_s * Private Functions ****************************************************************************/ -/**************************************************************************** - * Name: recvfrom_timeout - * - * Description: - * Check for send timeout. - * - * Input Parameters: - * pstate - Reference to instance ot recvfrom state structure - * - * Returned Value: - * true: timeout false: no timeout - * - * Assumptions: - * The network is locked - * - ****************************************************************************/ - -#ifdef CONFIG_NET_SOCKOPTS -static inline int recvfrom_timeout(FAR struct icmpv6_recvfrom_s *pstate) -{ - FAR struct socket *psock; - - /* Check for a timeout configured via setsockopts(SO_SNDTIMEO). - * If none... we will let the send wait forever. - */ - - psock = pstate->recv_sock; - if (psock != NULL && psock->s_rcvtimeo != 0) - { - /* Check if the configured timeout has elapsed */ - - return net_timeo(pstate->recv_time, psock->s_rcvtimeo); - } - - /* No timeout */ - - return false; -} -#endif /* CONFIG_NET_SOCKOPTS */ - /**************************************************************************** * Name: recvfrom_eventhandler * @@ -246,17 +205,6 @@ static uint16_t recvfrom_eventhandler(FAR struct net_driver_s *dev, goto end_wait; } -#ifdef CONFIG_NET_SOCKOPTS - /* Check if the selected timeout has elapsed */ - - if (recvfrom_timeout(pstate)) - { - nerr("ERROR: recvfrom() timeout\n"); - pstate->recv_result = -ETIMEDOUT; - goto end_wait; - } -#endif - /* Continue waiting */ } @@ -484,9 +432,6 @@ ssize_t icmpv6_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len, state.recv_buf = buf; /* Location to return the response */ state.recv_buflen = len; /* Size of the response */ - net_lock(); - state.recv_time = clock_systimer(); - /* Get the device that was used to send the ICMPv6 request. */ dev = conn->dev; @@ -497,6 +442,8 @@ ssize_t icmpv6_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len, goto errout; } + net_lock(); + /* Set up the callback */ state.recv_cb = icmpv6_callback_alloc(dev, conn); @@ -505,17 +452,19 @@ ssize_t icmpv6_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len, state.recv_cb->flags = (ICMPv6_NEWDATA | NETDEV_DOWN); state.recv_cb->priv = (FAR void *)&state; state.recv_cb->event = recvfrom_eventhandler; - state.recv_result = -EINTR; /* Assume sem-wait interrupted by signal */ /* Wait for either the response to be received or for timeout to - * occur. (1) net_lockedwait will also terminate if a signal is + * occur. (1) net_timedwait will also terminate if a signal is * received, (2) interrupts may be disabled! They will be re-enabled * while the task sleeps and automatically re-enabled when the task * restarts. */ - ninfo("Start time: 0x%08x\n", state.recv_time); - net_lockedwait(&state.recv_sem); + ret = net_timedwait(&state.recv_sem, _SO_TIMEOUT(psock->s_rcvtimeo)); + if (ret < 0) + { + state.recv_result = ret; + } icmpv6_callback_free(dev, conn, state.recv_cb); } diff --git a/net/icmpv6/icmpv6_rnotify.c b/net/icmpv6/icmpv6_rnotify.c index 38de50ea1fc61..d6ff6fa910e4f 100644 --- a/net/icmpv6/icmpv6_rnotify.c +++ b/net/icmpv6/icmpv6_rnotify.c @@ -40,7 +40,6 @@ #include #include -#include #include #include #include @@ -266,46 +265,25 @@ int icmpv6_rwait_cancel(FAR struct icmpv6_rnotify_s *notify) * ****************************************************************************/ -int icmpv6_rwait(FAR struct icmpv6_rnotify_s *notify, - FAR struct timespec *timeout) +int icmpv6_rwait(FAR struct icmpv6_rnotify_s *notify, unsigned int timeout) { - struct timespec abstime; - irqstate_t flags; int ret; ninfo("Waiting...\n"); - /* And wait for the Neighbor Advertisement (or a timeout). Interrupts will - * be re-enabled while we wait. - */ + /* And wait for the Neighbor Advertisement (or a timeout). */ - flags = enter_critical_section(); - DEBUGVERIFY(clock_gettime(CLOCK_REALTIME, &abstime)); - - abstime.tv_sec += timeout->tv_sec; - abstime.tv_nsec += timeout->tv_nsec; - if (abstime.tv_nsec >= 1000000000) + ret = net_timedwait(¬ify->rn_sem, timeout); + if (ret >= 0) { - abstime.tv_sec++; - abstime.tv_nsec -= 1000000000; + ret = notify->rn_result; } - /* REVISIT: If net_timedwait() is awakened with signal, we will return - * the wrong error code. - */ - - net_timedwait(¬ify->rn_sem, &abstime); - ret = notify->rn_result; - /* Remove our wait structure from the list (we may no longer be at the * head of the list). */ icmpv6_rwait_cancel(notify); - - /* Re-enable interrupts and return the result of the wait */ - - leave_critical_section(flags); return ret; } diff --git a/net/icmpv6/icmpv6_sendto.c b/net/icmpv6/icmpv6_sendto.c index 353268a4ab8f9..944865117dde2 100644 --- a/net/icmpv6/icmpv6_sendto.c +++ b/net/icmpv6/icmpv6_sendto.c @@ -86,9 +86,7 @@ struct icmpv6_sendto_s { FAR struct devif_callback_s *snd_cb; /* Reference to callback instance */ - FAR struct socket *snd_sock; /* IPPROTO_ICMP6 socket structure */ sem_t snd_sem; /* Use to manage the wait for send complete */ - clock_t snd_time; /* Start time for determining timeouts */ struct in6_addr snd_toaddr; /* The peer to send the request to */ FAR const uint8_t *snd_buf; /* ICMPv6 header + data payload */ uint16_t snd_buflen; /* Size of the ICMPv6 header + data payload */ @@ -99,46 +97,6 @@ struct icmpv6_sendto_s * Private Functions ****************************************************************************/ -/**************************************************************************** - * Name: sendto_timeout - * - * Description: - * Check for send timeout. - * - * Input Parameters: - * pstate - Reference to instance ot sendto state structure - * - * Returned Value: - * true: timeout false: no timeout - * - * Assumptions: - * The network is locked - * - ****************************************************************************/ - -#ifdef CONFIG_NET_SOCKOPTS -static inline int sendto_timeout(FAR struct icmpv6_sendto_s *pstate) -{ - FAR struct socket *psock; - - /* Check for a timeout configured via setsockopts(SO_SNDTIMEO). - * If none... we will let the send wait forever. - */ - - psock = pstate->snd_sock; - if (psock != NULL && psock->s_sndtimeo != 0) - { - /* Check if the configured timeout has elapsed */ - - return net_timeo(pstate->snd_time, psock->s_sndtimeo); - } - - /* No timeout */ - - return false; -} -#endif /* CONFIG_NET_SOCKOPTS */ - /**************************************************************************** * Name: sendto_request * @@ -279,41 +237,6 @@ static uint16_t sendto_eventhandler(FAR struct net_driver_s *dev, goto end_wait; } -#ifdef CONFIG_NET_SOCKOPTS - /* Check if the selected timeout has elapsed */ - - if (sendto_timeout(pstate)) - { - int failcode; - - /* Check if this device is on the same network as the destination - * device. - */ - - if (!net_ipv6addr_maskcmp(pstate->snd_toaddr.s6_addr16, - dev->d_ipv6addr, dev->d_ipv6netmask)) - { - /* Destination address was not on the local network served by this - * device. If a timeout occurs, then the most likely reason is - * that the destination address is not reachable. - */ - - nerr("ERROR: Not reachable\n"); - failcode = -ENETUNREACH; - } - else - { - nerr("ERROR: sendto() timeout\n"); - failcode = -ETIMEDOUT; - } - - /* Report the failure */ - - pstate->snd_result = failcode; - goto end_wait; - } -#endif - /* Continue waiting */ } @@ -436,7 +359,6 @@ ssize_t icmpv6_sendto(FAR struct socket *psock, FAR const void *buf, size_t len, nxsem_init(&state.snd_sem, 0, 0); nxsem_setprotocol(&state.snd_sem, SEM_PRIO_NONE); - state.snd_sock = psock; /* The IPPROTO_ICMP6 socket instance */ state.snd_result = -ENOMEM; /* Assume allocation failure */ state.snd_buf = buf; /* ICMPv6 header + data payload */ state.snd_buflen = len; /* Size of the ICMPv6 header+data payload */ @@ -445,7 +367,6 @@ ssize_t icmpv6_sendto(FAR struct socket *psock, FAR const void *buf, size_t len, inaddr->sin6_addr.s6_addr16); net_lock(); - state.snd_time = clock_systimer(); /* Set up the callback */ @@ -455,7 +376,6 @@ ssize_t icmpv6_sendto(FAR struct socket *psock, FAR const void *buf, size_t len, state.snd_cb->flags = (ICMPv6_POLL | NETDEV_DOWN); state.snd_cb->priv = (FAR void *)&state; state.snd_cb->event = sendto_eventhandler; - state.snd_result = -EINTR; /* Assume sem-wait interrupted by signal */ /* Setup to receive ICMPv6 ECHO replies */ @@ -465,18 +385,38 @@ ssize_t icmpv6_sendto(FAR struct socket *psock, FAR const void *buf, size_t len, conn->nreqs = 1; } - conn->dev = dev; + conn->dev = dev; /* Notify the device driver of the availability of TX data */ netdev_txnotify_dev(dev); /* Wait for either the send to complete or for timeout to occur. - * net_lockedwait will also terminate if a signal is received. + * net_timedwait will also terminate if a signal is received. */ - ninfo("Start time: 0x%08x\n", state.snd_time); - net_lockedwait(&state.snd_sem); + ret = net_timedwait(&state.snd_sem, _SO_TIMEOUT(psock->s_sndtimeo)); + if (ret < 0) + { + if (ret == -ETIMEDOUT) + { + /* Check if this device is on the same network as the destination + * device. + */ + + if (!net_ipv6addr_maskcmp(state.snd_toaddr.s6_addr16, + dev->d_ipv6addr, dev->d_ipv6netmask)) + { + /* Destination address was not on the local network served by + * this device. If a timeout occurs, then the most likely + * reason is that the destination address is not reachable. + */ + + ret = -ENETUNREACH; + } + } + state.snd_result = ret; + } icmpv6_callback_free(dev, conn, state.snd_cb); } diff --git a/net/ieee802154/ieee802154_recvfrom.c b/net/ieee802154/ieee802154_recvfrom.c index ee35d890b83b3..501f6498209c4 100644 --- a/net/ieee802154/ieee802154_recvfrom.c +++ b/net/ieee802154/ieee802154_recvfrom.c @@ -49,7 +49,6 @@ #include -#include #include #include #include diff --git a/net/ieee802154/ieee802154_sendto.c b/net/ieee802154/ieee802154_sendto.c index b2f28cfa135e1..6ef9a313c719d 100644 --- a/net/ieee802154/ieee802154_sendto.c +++ b/net/ieee802154/ieee802154_sendto.c @@ -51,7 +51,6 @@ #include -#include #include #include #include diff --git a/net/inet/inet.h b/net/inet/inet.h index 54adbde77476a..eef1f369866c2 100644 --- a/net/inet/inet.h +++ b/net/inet/inet.h @@ -301,7 +301,7 @@ int inet_close(FAR struct socket *psock); * * Parameters: * psock - Pointer to the socket structure instance - * abstime - The absolute time when the timeout will occur + * timeout - The relative time when the timeout will occur * * Returned Value: * Zero (OK) is returned on success; a negated error value is returned on @@ -309,9 +309,7 @@ int inet_close(FAR struct socket *psock); * ****************************************************************************/ -struct timespec; -int inet_txdrain(FAR struct socket *psock, - FAR const struct timespec *abstime); +int inet_txdrain(FAR struct socket *psock, unsigned int timeout); #undef EXTERN #if defined(__cplusplus) diff --git a/net/inet/inet_close.c b/net/inet/inet_close.c index 632483b2ed082..0cd5d6cf6d598 100644 --- a/net/inet/inet_close.c +++ b/net/inet/inet_close.c @@ -221,10 +221,6 @@ static inline int tcp_close_disconnect(FAR struct socket *psock) { struct tcp_close_s state; FAR struct tcp_conn_s *conn; -#ifdef CONFIG_NET_SOLINGER - struct timespec abstime; - bool linger; -#endif int ret = OK; /* Interrupts are disabled here to avoid race conditions */ @@ -247,31 +243,18 @@ static inline int tcp_close_disconnect(FAR struct socket *psock) * state of the option and linger interval. */ - linger = _SO_GETOPT(psock->s_options, SO_LINGER); - if (linger) + if (_SO_GETOPT(psock->s_options, SO_LINGER)) { - /* Get the current time */ + /* Wait until for the buffered TX data to be sent. */ - ret = clock_gettime(CLOCK_REALTIME, &abstime); - if (ret >= 0) + ret = tcp_txdrain(psock, _SO_TIMEOUT(psock->s_linger)); + if (ret < 0) { - /* NOTE: s_linger's unit is deciseconds so we don't need to update - * abstime.tv_nsec here. + /* tcp_txdrain may fail, but that won't stop us from closing + * the socket. */ - abstime.tv_sec += psock->s_linger / DSEC_PER_SEC; - - /* Wait until abstime for the buffered TX data to be sent. */ - - ret = tcp_txdrain(psock, &abstime); - if (ret < 0) - { - /* tcp_txdrain may fail, but that won't stop us from closing - * the socket. - */ - - nerr("ERROR: tcp_txdrain() failed: %d\n", ret); - } + nerr("ERROR: tcp_txdrain() failed: %d\n", ret); } } #endif @@ -376,10 +359,6 @@ static inline int tcp_close_disconnect(FAR struct socket *psock) static inline int udp_close(FAR struct socket *psock) { FAR struct udp_conn_s *conn; -#ifdef CONFIG_NET_SOLINGER - struct timespec abstime; - bool linger; -#endif /* Interrupts are disabled here to avoid race conditions */ @@ -401,33 +380,20 @@ static inline int udp_close(FAR struct socket *psock) * state of the option and linger interval. */ - linger = _SO_GETOPT(psock->s_options, SO_LINGER); - if (linger) + if (_SO_GETOPT(psock->s_options, SO_LINGER)) { int ret; - /* Get the current time */ + /* Wait until for the buffered TX data to be sent. */ - ret = clock_gettime(CLOCK_REALTIME, &abstime); - if (ret >= 0) + ret = udp_txdrain(psock, _SO_TIMEOUT(psock->s_linger)); + if (ret < 0) { - /* NOTE: s_linger's unit is deciseconds so we don't need to update - * abstime.tv_nsec here. + /* udp_txdrain may fail, but that won't stop us from closing + * the socket. */ - abstime.tv_sec += psock->s_linger / DSEC_PER_SEC; - - /* Wait until abstime for the buffered TX data to be sent. */ - - ret = udp_txdrain(psock, &abstime); - if (ret < 0) - { - /* udp_txdrain may fail, but that won't stop us from closing - * the socket. - */ - - nerr("ERROR: udp_txdrain() failed: %d\n", ret); - } + nerr("ERROR: udp_txdrain() failed: %d\n", ret); } } #endif diff --git a/net/inet/inet_recvfrom.c b/net/inet/inet_recvfrom.c index 458fab24b2c46..b217cca0f66e4 100644 --- a/net/inet/inet_recvfrom.c +++ b/net/inet/inet_recvfrom.c @@ -51,7 +51,6 @@ #include -#include #include #include #include @@ -92,9 +91,6 @@ struct inet_recvfrom_s { FAR struct socket *ir_sock; /* The parent socket structure */ -#ifdef CONFIG_NET_SOCKOPTS - clock_t ir_starttime; /* rcv start time for determining timeout */ -#endif FAR struct devif_callback_s *ir_cb; /* Reference to callback instance */ sem_t ir_sem; /* Semaphore signals recv completion */ size_t ir_buflen; /* Length of receive buffer */ @@ -335,7 +331,7 @@ static inline void inet_tcp_readahead(struct inet_recvfrom_s *pstate) inet_update_recvlen(pstate, recvlen); - /* If we took all of the ata from the I/O buffer chain is empty, then + /* 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 * beginning of the I/O buffer chain. @@ -459,60 +455,6 @@ static inline void inet_udp_readahead(struct inet_recvfrom_s *pstate) } #endif -/**************************************************************************** - * Name: inet_recvfrom_timeout - * - * Description: - * Check for recvfrom timeout. - * - * Input Parameters: - * pstate recvfrom state structure - * - * Returned Value: - * TRUE:timeout FALSE:no timeout - * - * Assumptions: - * The network is locked. - * - ****************************************************************************/ - -#if defined(NET_UDP_HAVE_STACK) || defined(NET_TCP_HAVE_STACK) -#ifdef CONFIG_NET_SOCKOPTS -static int inet_recvfrom_timeout(struct inet_recvfrom_s *pstate) -{ - FAR struct socket *psock = 0; - socktimeo_t timeo = 0; - - /* Check for a timeout configured via setsockopts(SO_RCVTIMEO). If none... - * we well let the read hang forever (except for the special case below). - */ - - /* Get the socket reference from the private data */ - - psock = pstate->ir_sock; - if (psock) - { - /* Recover the timeout value (zero if no timeout) */ - - timeo = psock->s_rcvtimeo; - } - - /* Is there an effective timeout? */ - - if (timeo) - { - /* Yes.. Check if the timeout has elapsed */ - - return net_timeo(pstate->ir_starttime, timeo); - } - - /* No timeout -- hang forever waiting for data. */ - - return FALSE; -} -#endif /* CONFIG_NET_SOCKOPTS */ -#endif /* NET_UDP_HAVE_STACK || NET_TCP_HAVE_STACK */ - /**************************************************************************** * Name: inet_tcp_sender * @@ -676,14 +618,6 @@ static uint16_t inet_tcp_eventhandler(FAR struct net_driver_s *dev, nxsem_post(&pstate->ir_sem); } - -#ifdef CONFIG_NET_SOCKOPTS - /* Reset the timeout. We will want a short timeout to terminate - * the TCP receive. - */ - - pstate->ir_starttime = clock_systimer(); -#endif } /* Check for a loss of connection. @@ -734,36 +668,6 @@ static uint16_t inet_tcp_eventhandler(FAR struct net_driver_s *dev, nxsem_post(&pstate->ir_sem); } - -#ifdef CONFIG_NET_SOCKOPTS - /* No data has been received -- this is some other event... probably a - * poll -- check for a timeout. - */ - - else if (inet_recvfrom_timeout(pstate)) - { - /* Yes.. the timeout has elapsed... do not allow any further - * callbacks - */ - - ninfo("TCP timeout\n"); - - pstate->ir_cb->flags = 0; - pstate->ir_cb->priv = NULL; - pstate->ir_cb->event = NULL; - - /* Report the timeout error */ - - pstate->ir_result = -EAGAIN; - - /* Wake up the waiting thread, returning either the error -EAGAIN - * that signals the timeout event or the data received up to - * the point that the timeout occurred (no error). - */ - - nxsem_post(&pstate->ir_sem); - } -#endif /* CONFIG_NET_SOCKOPTS */ } return flags; @@ -977,25 +881,6 @@ static uint16_t inet_udp_eventhandler(FAR struct net_driver_s *dev, flags &= ~UDP_NEWDATA; } - -#ifdef CONFIG_NET_SOCKOPTS - /* No data has been received -- this is some other event... probably a - * poll -- check for a timeout. - */ - - else if (inet_recvfrom_timeout(pstate)) - { - /* Yes.. the timeout has elapsed... do not allow any further - * callbacks - */ - - nerr("ERROR: UDP timeout\n"); - - /* Terminate the transfer with an -EAGAIN error */ - - inet_udp_terminate(pstate, -EAGAIN); - } -#endif /* CONFIG_NET_SOCKOPTS */ } return flags; @@ -1046,9 +931,6 @@ static void inet_recvfrom_initialize(FAR struct socket *psock, FAR void *buf, /* Set up the start time for the timeout */ pstate->ir_sock = psock; -#ifdef CONFIG_NET_SOCKOPTS - pstate->ir_starttime = clock_systimer(); -#endif } /* The only un-initialization that has to be performed is destroying the @@ -1066,7 +948,7 @@ static void inet_recvfrom_initialize(FAR struct socket *psock, FAR void *buf, * Evaluate the result of the recv operations * * Input Parameters: - * result The result of the net_lockedwait operation (may indicate EINTR) + * result The result of the net_timedwait operation (may indicate EINTR) * pstate A pointer to the state structure to be initialized * * Returned Value: @@ -1092,8 +974,8 @@ static ssize_t inet_recvfrom_result(int result, struct inet_recvfrom_s *pstate) return pstate->ir_result; } - /* If net_lockedwait failed, then we were probably reawakened by a signal. In - * this case, net_lockedwait will have returned negated errno appropriately. + /* If net_timedwait failed, then we were probably reawakened by a signal. In + * this case, net_timedwait will have returned negated errno appropriately. */ if (result < 0) @@ -1199,11 +1081,11 @@ static ssize_t inet_udp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t state.ir_cb->event = inet_udp_eventhandler; /* Wait for either the receive to complete or for an error/timeout - * to occur. net_lockedwait will also terminate if a signal is + * to occur. net_timedwait will also terminate if a signal is * received. */ - ret = net_lockedwait(&state. ir_sem); + ret = net_timedwait(&state. ir_sem, _SO_TIMEOUT(psock->s_rcvtimeo)); /* Make sure that no further events are processed */ @@ -1349,11 +1231,11 @@ static ssize_t inet_tcp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t state.ir_cb->event = inet_tcp_eventhandler; /* Wait for either the receive to complete or for an error/timeout - * to occur. net_lockedwait will also terminate if a signal isi + * to occur. net_timedwait will also terminate if a signal isi * received. */ - ret = net_lockedwait(&state.ir_sem); + ret = net_timedwait(&state.ir_sem, _SO_TIMEOUT(psock->s_rcvtimeo)); /* Make sure that no further events are processed */ diff --git a/net/inet/inet_txdrain.c b/net/inet/inet_txdrain.c index ca3fc37d9b926..f1d0cade7a232 100644 --- a/net/inet/inet_txdrain.c +++ b/net/inet/inet_txdrain.c @@ -64,7 +64,7 @@ * * Parameters: * psock - Pointer to the socket structure instance - * abstime - The absolute time when the timeout will occur + * timeout - The relative time when the timeout will occur * * Returned Value: * Zero (OK) is returned on success; a negated error value is returned on @@ -72,8 +72,7 @@ * ****************************************************************************/ -int inet_txdrain(FAR struct socket *psock, - FAR const struct timespec *abstime) +int inet_txdrain(FAR struct socket *psock, unsigned int timeout) { int ret = OK; @@ -86,7 +85,7 @@ int inet_txdrain(FAR struct socket *psock, #if defined(NET_TCP_HAVE_STACK) case SOCK_STREAM: { - ret = tcp_txdrain(psock, abstime); + ret = tcp_txdrain(psock, timeout); } break; #endif @@ -94,7 +93,7 @@ int inet_txdrain(FAR struct socket *psock, #if defined(NET_UDP_HAVE_STACK) case SOCK_DGRAM: { - ret = udp_txdrain(psock, abstime); + ret = udp_txdrain(psock, timeout); } break; #endif diff --git a/net/neighbor/neighbor.h b/net/neighbor/neighbor.h index 64c30fc2f44fd..508837feab0ef 100644 --- a/net/neighbor/neighbor.h +++ b/net/neighbor/neighbor.h @@ -49,7 +49,6 @@ #include -#include #include #include #include diff --git a/net/neighbor/neighbor_globals.c b/net/neighbor/neighbor_globals.c index e8c0587806475..175cbc63f5f50 100644 --- a/net/neighbor/neighbor_globals.c +++ b/net/neighbor/neighbor_globals.c @@ -42,7 +42,6 @@ ****************************************************************************/ #include -#include #include "neighbor/neighbor.h" diff --git a/net/pkt/pkt_recvfrom.c b/net/pkt/pkt_recvfrom.c index 70f99de3e68c2..5c8912ca73ad3 100644 --- a/net/pkt/pkt_recvfrom.c +++ b/net/pkt/pkt_recvfrom.c @@ -51,7 +51,6 @@ #include -#include #include #include #include diff --git a/net/pkt/pkt_send.c b/net/pkt/pkt_send.c index 71e3436bcce2c..571886f923d08 100644 --- a/net/pkt/pkt_send.c +++ b/net/pkt/pkt_send.c @@ -51,7 +51,6 @@ #include -#include #include #include #include diff --git a/net/sixlowpan/sixlowpan_internal.h b/net/sixlowpan/sixlowpan_internal.h index d97b4707ce2c3..5305291864465 100644 --- a/net/sixlowpan/sixlowpan_internal.h +++ b/net/sixlowpan/sixlowpan_internal.h @@ -267,7 +267,7 @@ struct iob_s; /* Forward reference */ * buf - Data to send * len - Length of data to send * destmac - The IEEE802.15.4 MAC address of the destination - * timeout - Send timeout in deciseconds + * timeout - Send timeout in milliseconds * * Returned Value: * Ok is returned on success; Othewise a negated errno value is returned. diff --git a/net/sixlowpan/sixlowpan_reassbuf.c b/net/sixlowpan/sixlowpan_reassbuf.c index a2a9936e6f56e..4e124e0fe36f4 100644 --- a/net/sixlowpan/sixlowpan_reassbuf.c +++ b/net/sixlowpan/sixlowpan_reassbuf.c @@ -46,7 +46,6 @@ #include #include -#include #include #include @@ -162,7 +161,7 @@ static void sixlowpan_reass_expire(void) /* If the reassembly has expired, then free the reassembly buffer */ - if (elapsed > NET_6LOWPAN_TIMEOUT) + if (elapsed >= NET_6LOWPAN_TIMEOUT) { nwarn("WARNING: Reassembly timed out\n"); sixlowpan_reass_free(reass); diff --git a/net/sixlowpan/sixlowpan_send.c b/net/sixlowpan/sixlowpan_send.c index 13b76495da026..930f809509df1 100644 --- a/net/sixlowpan/sixlowpan_send.c +++ b/net/sixlowpan/sixlowpan_send.c @@ -44,7 +44,6 @@ #include #include -#include #include #include #include @@ -81,8 +80,6 @@ struct sixlowpan_send_s FAR struct devif_callback_s *s_cb; /* Reference to callback instance */ sem_t s_waitsem; /* Supports waiting for driver events */ int s_result; /* The result of the transfer */ - uint16_t s_timeout; /* Send timeout in deciseconds */ - clock_t s_time; /* Last send time for determining timeout */ FAR const struct ipv6_hdr_s *s_ipv6hdr; /* IPv6 header, followed by UDP or ICMP header. */ FAR const struct netdev_varaddr_s *s_destmac; /* Destination MAC address */ FAR const void *s_buf; /* Data to send */ @@ -93,47 +90,6 @@ struct sixlowpan_send_s * Private Functions ****************************************************************************/ -/**************************************************************************** - * Name: send_timeout - * - * Description: - * Check for send timeout. - * - * Input Parameters: - * sinfo - Send state structure reference - * - * Returned Value: - * TRUE:timeout FALSE:no timeout - * - * Assumptions: - * The network is locked - * - ****************************************************************************/ - -static inline bool send_timeout(FAR struct sixlowpan_send_s *sinfo) -{ - /* Check for a timeout. Zero means none and, in that case, we will let - * the send wait forever. - */ - - if (sinfo->s_timeout != 0) - { - /* Check if the configured timeout has elapsed */ - - clock_t timeo_ticks = DSEC2TICK(sinfo->s_timeout); - clock_t elapsed = clock_systimer() - sinfo->s_time; - - if (elapsed >= timeo_ticks) - { - return true; - } - } - - /* No timeout */ - - return false; -} - /**************************************************************************** * Name: send_eventhandler * @@ -203,18 +159,6 @@ static uint16_t send_eventhandler(FAR struct net_driver_s *dev, goto end_wait; } - /* Check for a timeout. */ - - if (send_timeout(sinfo)) - { - /* Yes.. report the timeout */ - - nwarn("WARNING: SEND timeout\n"); - sinfo->s_result = -ETIMEDOUT; - neighbor_notreachable(dev); - goto end_wait; - } - /* Continue waiting */ return flags; @@ -257,7 +201,7 @@ static uint16_t send_eventhandler(FAR struct net_driver_s *dev, * buf - Data to send * len - Length of data to send * destmac - The IEEE802.15.4 MAC address of the destination - * timeout - Send timeout in deciseconds + * timeout - Send timeout in milliseconds * * Returned Value: * Ok is returned on success; Othewise a negated errno value is returned. @@ -286,8 +230,6 @@ int sixlowpan_send(FAR struct net_driver_s *dev, nxsem_setprotocol(&sinfo.s_waitsem, SEM_PRIO_NONE); sinfo.s_result = -EBUSY; - sinfo.s_timeout = timeout; - sinfo.s_time = clock_systimer(); sinfo.s_ipv6hdr = ipv6hdr; sinfo.s_destmac = destmac; sinfo.s_buf = buf; @@ -318,14 +260,18 @@ int sixlowpan_send(FAR struct net_driver_s *dev, netdev_txnotify_dev(dev); /* Wait for the send to complete or an error to occur. - * net_lockedwait will also terminate if a signal is received. + * net_timedwait will also terminate if a signal is received. */ ninfo("Wait for send complete\n"); - ret = net_lockedwait(&sinfo.s_waitsem); + ret = net_timedwait(&sinfo.s_waitsem, timeout); if (ret < 0) { + if (ret == -ETIMEDOUT) + { + neighbor_notreachable(dev); + } sinfo.s_result = ret; } diff --git a/net/sixlowpan/sixlowpan_tcpsend.c b/net/sixlowpan/sixlowpan_tcpsend.c index 3b695cdcdc093..dc7b51cfad074 100644 --- a/net/sixlowpan/sixlowpan_tcpsend.c +++ b/net/sixlowpan/sixlowpan_tcpsend.c @@ -94,8 +94,6 @@ struct sixlowpan_send_s FAR struct devif_callback_s *s_cb; /* Reference to callback instance */ sem_t s_waitsem; /* Supports waiting for driver events */ int s_result; /* The result of the transfer */ - uint16_t s_timeout; /* Send timeout in deciseconds */ - clock_t s_time; /* Last send time for determining timeout */ FAR const struct netdev_varaddr_s *s_destmac; /* Destination MAC address */ FAR const uint8_t *s_buf; /* Data to send */ size_t s_buflen; /* Length of data in buf */ @@ -287,47 +285,6 @@ static int sixlowpan_tcp_header(FAR struct tcp_conn_s *conn, return OK; } -/**************************************************************************** - * Name: send_timeout - * - * Description: - * Check for send timeout. - * - * Input Parameters: - * sinfo - Send state structure reference - * - * Returned Value: - * TRUE:timeout FALSE:no timeout - * - * Assumptions: - * The network is locked - * - ****************************************************************************/ - -static inline bool send_timeout(FAR struct sixlowpan_send_s *sinfo) -{ - /* Check for a timeout. Zero means none and, in that case, we will let - * the send wait forever. - */ - - if (sinfo->s_timeout != 0) - { - /* Check if the configured timeout has elapsed */ - - clock_t timeo_ticks = DSEC2TICK(sinfo->s_timeout); - clock_t elapsed = clock_systimer() - sinfo->s_time; - - if (elapsed >= timeo_ticks) - { - return true; - } - } - - /* No timeout */ - - return false; -} - /**************************************************************************** * Name: tcp_send_eventhandler * @@ -398,12 +355,6 @@ static uint16_t tcp_send_eventhandler(FAR struct net_driver_s *dev, { FAR struct tcp_hdr_s *tcp = TCPBUF(dev); -#ifdef CONFIG_NET_SOCKOPTS - /* Update the timeout */ - - sinfo->s_time = clock_systimer(); -#endif - /* The current acknowledgement number number is the (relative) offset * of the of the next byte needed by the receiver. The s_isn is the * offset of the first byte to send to the receiver. The difference @@ -583,21 +534,6 @@ static uint16_t tcp_send_eventhandler(FAR struct net_driver_s *dev, } } -#ifdef CONFIG_NET_SOCKOPTS - /* All data has been sent and we are just waiting for ACK or re-transmit - * indications to complete the send. Check for a timeout. - */ - - if (send_timeout(sinfo)) - { - /* Yes.. report the timeout */ - - nwarn("WARNING: SEND timeout\n"); - sinfo->s_sent = -ETIMEDOUT; - goto end_wait; - } -#endif /* CONFIG_NET_SOCKOPTS */ - /* Continue waiting */ return flags; @@ -640,7 +576,7 @@ static uint16_t tcp_send_eventhandler(FAR struct net_driver_s *dev, * buf - Data to send * len - Length of data to send * destmac - The IEEE802.15.4 MAC address of the destination - * timeout - Send timeout in deciseconds + * timeout - Send timeout in milliseconds * * Returned Value: * Ok is returned on success; Othewise a negated errno value is returned. @@ -689,8 +625,6 @@ static int sixlowpan_send_packet(FAR struct socket *psock, sinfo.s_sock = psock; sinfo.s_result = -EBUSY; - sinfo.s_timeout = timeout; - sinfo.s_time = clock_systimer(); sinfo.s_destmac = destmac; sinfo.s_buf = buf; sinfo.s_buflen = len; @@ -717,12 +651,22 @@ static int sixlowpan_send_packet(FAR struct socket *psock, netdev_txnotify_dev(dev); /* Wait for the send to complete or an error to occur. - * net_lockedwait will also terminate if a signal is received. + * net_timedwait will also terminate if a signal is received. */ ninfo("Wait for send complete\n"); - ret = net_lockedwait(&sinfo.s_waitsem); + for (; ; ) + { + uint32_t acked = sinfo.s_acked; + + ret = net_timedwait(&sinfo.s_waitsem, timeout); + if (ret != -ETIMEDOUT || acked == sinfo.s_acked) + { + break; /* Timeout without any progress */ + } + } + if (ret < 0) { sinfo.s_result = ret; @@ -773,7 +717,6 @@ ssize_t psock_6lowpan_tcp_send(FAR struct socket *psock, FAR const void *buf, FAR struct tcp_conn_s *conn; FAR struct net_driver_s *dev; struct netdev_varaddr_s destmac; - uint16_t timeout; int ret; ninfo("buflen %lu\n", (unsigned long)buflen); @@ -859,14 +802,8 @@ ssize_t psock_6lowpan_tcp_send(FAR struct socket *psock, FAR const void *buf, * packet buffer. */ -#ifdef CONFIG_NET_SOCKOPTS - timeout = psock->s_sndtimeo; -#else - timeout = 0; -#endif - ret = sixlowpan_send_packet(psock, dev, conn, buf, buflen, &destmac, - timeout); + _SO_TIMEOUT(psock->s_sndtimeo)); if (ret < 0) { nerr("ERROR: sixlowpan_send_packet() failed: %d\n", ret); diff --git a/net/sixlowpan/sixlowpan_udpsend.c b/net/sixlowpan/sixlowpan_udpsend.c index 1d111a2cd9303..bcbe482f64603 100644 --- a/net/sixlowpan/sixlowpan_udpsend.c +++ b/net/sixlowpan/sixlowpan_udpsend.c @@ -167,7 +167,6 @@ ssize_t psock_6lowpan_udp_sendto(FAR struct socket *psock, struct ipv6udp_hdr_s ipv6udp; struct netdev_varaddr_s destmac; uint16_t iplen; - uint16_t timeout; int ret; ninfo("buflen %lu\n", (unsigned long)buflen); @@ -306,15 +305,9 @@ ssize_t psock_6lowpan_udp_sendto(FAR struct socket *psock, * packet. */ -#ifdef CONFIG_NET_SOCKOPTS - timeout = psock->s_sndtimeo; -#else - timeout = 0; -#endif - ret = sixlowpan_send(dev, &conn->list, (FAR const struct ipv6_hdr_s *)&ipv6udp, - buf, buflen, &destmac, timeout); + buf, buflen, &destmac, _SO_TIMEOUT(psock->s_sndtimeo)); if (ret < 0) { nerr("ERROR: sixlowpan_send() failed: %d\n", ret); diff --git a/net/socket/socket.h b/net/socket/socket.h index 4359c1cc76b2f..a2452f2e6e956 100644 --- a/net/socket/socket.h +++ b/net/socket/socket.h @@ -121,6 +121,14 @@ #define _SO_GETVALID(o) (((unsigned int)(o)) <= _SO_MAXOPT) #define _SO_SETVALID(o) ((((unsigned int)(o)) <= _SO_MAXOPT) && !_SO_GETONLY(o)) +/* Macros to convert timeout value */ + +#ifdef CONFIG_NET_SOCKOPTS +#define _SO_TIMEOUT(t) ((t) ? (t) * MSEC_PER_DSEC : UINT_MAX) +#else +#define _SO_TIMEOUT(t) (UINT_MAX) +#endif /* CONFIG_NET_SOCKOPTS */ + /* Macro to set socket errors */ #ifdef CONFIG_NET_SOCKOPTS diff --git a/net/tcp/tcp.h b/net/tcp/tcp.h index 5253018974e69..af62daba4e86c 100644 --- a/net/tcp/tcp.h +++ b/net/tcp/tcp.h @@ -1455,7 +1455,6 @@ void tcp_wrbuffer_initialize(void); #ifdef CONFIG_NET_TCP_WRITE_BUFFERS struct tcp_wrbuffer_s; - FAR struct tcp_wrbuffer_s *tcp_wrbuffer_alloc(void); /**************************************************************************** @@ -1760,7 +1759,7 @@ void tcp_disconnect_signal(FAR struct tcp_conn_s *conn); * * Input Parameters: * psock - An instance of the internal socket structure. - * abstime - The absolute time when the timeout will occur + * timeout - The relative time when the timeout will occur * * Returned Value: * Zero (OK) is returned on success; a negated errno value is returned @@ -1769,11 +1768,9 @@ void tcp_disconnect_signal(FAR struct tcp_conn_s *conn); ****************************************************************************/ #if defined(CONFIG_NET_TCP_WRITE_BUFFERS) && defined(CONFIG_NET_TCP_NOTIFIER) -struct timespec; -int tcp_txdrain(FAR struct socket *psock, - FAR const struct timespec *abstime); +int tcp_txdrain(FAR struct socket *psock, unsigned int timeout); #else -# define tcp_txdrain(conn, abstime) (0) +# define tcp_txdrain(conn, timeout) (0) #endif #undef EXTERN diff --git a/net/tcp/tcp_conn.c b/net/tcp/tcp_conn.c index 180094e51c35e..2c22246af9f58 100644 --- a/net/tcp/tcp_conn.c +++ b/net/tcp/tcp_conn.c @@ -54,7 +54,6 @@ #include -#include #include #include #include diff --git a/net/tcp/tcp_getsockopt.c b/net/tcp/tcp_getsockopt.c index c07a488873e33..ee4963aa03b0a 100644 --- a/net/tcp/tcp_getsockopt.c +++ b/net/tcp/tcp_getsockopt.c @@ -39,7 +39,6 @@ #include -#include #include #include #include diff --git a/net/tcp/tcp_input.c b/net/tcp/tcp_input.c index db718be9df04f..7acf298cc5d38 100644 --- a/net/tcp/tcp_input.c +++ b/net/tcp/tcp_input.c @@ -51,7 +51,6 @@ #include #include -#include #include #include #include diff --git a/net/tcp/tcp_send_buffered.c b/net/tcp/tcp_send_buffered.c index 262d10a471871..76d4af2a9cb74 100644 --- a/net/tcp/tcp_send_buffered.c +++ b/net/tcp/tcp_send_buffered.c @@ -62,7 +62,6 @@ #include #include -#include #include #include #include diff --git a/net/tcp/tcp_send_unbuffered.c b/net/tcp/tcp_send_unbuffered.c index 1a778212144a3..1d9b502835221 100644 --- a/net/tcp/tcp_send_unbuffered.c +++ b/net/tcp/tcp_send_unbuffered.c @@ -54,7 +54,6 @@ #include -#include #include #include #include @@ -108,9 +107,6 @@ struct send_s ssize_t snd_sent; /* The number of bytes sent */ uint32_t snd_isn; /* Initial sequence number */ uint32_t snd_acked; /* The number of bytes acked */ -#ifdef CONFIG_NET_SOCKOPTS - clock_t snd_time; /* Last send time for determining timeout */ -#endif #if defined(CONFIG_NET_TCP_SPLIT) bool snd_odd; /* True: Odd packet in pair transaction */ #endif @@ -120,46 +116,6 @@ struct send_s * Private Functions ****************************************************************************/ -/**************************************************************************** - * Name: send_timeout - * - * Description: - * Check for send timeout. - * - * Input Parameters: - * pstate send state structure - * - * Returned Value: - * TRUE:timeout FALSE:no timeout - * - * Assumptions: - * The network is locked. - * - ****************************************************************************/ - -#ifdef CONFIG_NET_SOCKOPTS -static inline int send_timeout(FAR struct send_s *pstate) -{ - FAR struct socket *psock; - - /* Check for a timeout configured via setsockopts(SO_SNDTIMEO). - * If none... we will let the send wait forever. - */ - - psock = pstate->snd_sock; - if (psock && psock->s_sndtimeo != 0) - { - /* Check if the configured timeout has elapsed */ - - return net_timeo(pstate->snd_time, psock->s_sndtimeo); - } - - /* No timeout */ - - return FALSE; -} -#endif /* CONFIG_NET_SOCKOPTS */ - /**************************************************************************** * Name: tcpsend_ipselect * @@ -251,12 +207,6 @@ static uint16_t tcpsend_eventhandler(FAR struct net_driver_s *dev, { FAR struct tcp_hdr_s *tcp; - /* Update the timeout */ - -#ifdef CONFIG_NET_SOCKOPTS - pstate->snd_time = clock_systimer(); -#endif - /* Get the offset address of the TCP header */ #ifdef CONFIG_NET_IPv4 @@ -503,21 +453,6 @@ static uint16_t tcpsend_eventhandler(FAR struct net_driver_s *dev, } } -#ifdef CONFIG_NET_SOCKOPTS - /* All data has been sent and we are just waiting for ACK or re-transmit - * indications to complete the send. Check for a timeout. - */ - - if (send_timeout(pstate)) - { - /* Yes.. report the timeout */ - - nwarn("WARNING: SEND timeout\n"); - pstate->snd_sent = -ETIMEDOUT; - goto end_wait; - } -#endif /* CONFIG_NET_SOCKOPTS */ - /* Continue waiting */ return flags; @@ -734,6 +669,7 @@ ssize_t psock_tcp_send(FAR struct socket *psock, { /* Allocate resources to receive a callback */ + ret = -ENOMEM; /* Assume allocation failure */ state.snd_cb = tcp_callback_alloc(conn); if (state.snd_cb) { @@ -747,11 +683,6 @@ ssize_t psock_tcp_send(FAR struct socket *psock, conn->tx_unacked = 0; - /* Set the initial time for calculating timeouts */ - -#ifdef CONFIG_NET_SOCKOPTS - state.snd_time = clock_systimer(); -#endif /* Set up the callback in the connection */ state.snd_cb->flags = (TCP_ACKDATA | TCP_REXMIT | TCP_POLL | @@ -767,7 +698,17 @@ ssize_t psock_tcp_send(FAR struct socket *psock, * net_lockedwait will also terminate if a signal is received. */ - ret = net_lockedwait(&state.snd_sem); + for (; ; ) + { + uint32_t acked = state.snd_acked; + + ret = net_timedwait(&state.snd_sem, + _SO_TIMEOUT(psock->s_sndtimeo)); + if (ret != -ETIMEOUT || acked == state.snd_acked) + { + break; /* Timeout without any progress */ + } + } /* Make sure that no further events are processed */ @@ -788,8 +729,8 @@ ssize_t psock_tcp_send(FAR struct socket *psock, goto errout; } - /* If net_lockedwait failed, then we were probably reawakened by a signal. - * In this case, net_lockedwait will have returned negated errno + /* If net_timedwait failed, then we were probably reawakened by a signal. + * In this case, net_timedwait will have returned negated errno * appropriately. */ diff --git a/net/tcp/tcp_sendfile.c b/net/tcp/tcp_sendfile.c index c7fcaed41b5a9..d5cbba0b1f1d6 100644 --- a/net/tcp/tcp_sendfile.c +++ b/net/tcp/tcp_sendfile.c @@ -55,7 +55,6 @@ #include #include -#include #include #include #include @@ -105,55 +104,12 @@ struct sendfile_s ssize_t snd_sent; /* The number of bytes sent */ uint32_t snd_isn; /* Initial sequence number */ uint32_t snd_acked; /* The number of bytes acked */ -#ifdef CONFIG_NET_SOCKOPTS - clock_t snd_time; /* Last send time for determining timeout */ -#endif }; /**************************************************************************** * Private Functions ****************************************************************************/ -/**************************************************************************** - * Name: sendfile_timeout - * - * Description: - * Check for send timeout. - * - * Input Parameters: - * pstate - send state structure - * - * Returned Value: - * TRUE:timeout FALSE:no timeout - * - * Assumptions: - * The network is locked - * - ****************************************************************************/ - -#ifdef CONFIG_NET_SOCKOPTS -static inline int sendfile_timeout(FAR struct sendfile_s *pstate) -{ - FAR struct socket *psock = 0; - - /* Check for a timeout configured via setsockopts(SO_SNDTIMEO). - * If none... we well let the send wait forever. - */ - - psock = pstate->snd_sock; - if (psock && psock->s_sndtimeo != 0) - { - /* Check if the configured timeout has elapsed */ - - return net_timeo(pstate->snd_time, psock->s_sndtimeo); - } - - /* No timeout */ - - return FALSE; -} -#endif /* CONFIG_NET_SOCKOPTS */ - static uint16_t ack_eventhandler(FAR struct net_driver_s *dev, FAR void *pvconn, FAR void *pvpriv, uint16_t flags) @@ -166,12 +122,6 @@ static uint16_t ack_eventhandler(FAR struct net_driver_s *dev, { FAR struct tcp_hdr_s *tcp; -#ifdef CONFIG_NET_SOCKOPTS - /* Update the timeout */ - - pstate->snd_time = clock_systimer(); -#endif - /* Get the offset address of the TCP header */ #ifdef CONFIG_NET_IPv6 @@ -179,7 +129,7 @@ static uint16_t ack_eventhandler(FAR struct net_driver_s *dev, if (IFF_IS_IPv6(dev->d_flags)) #endif { - DEBUGASSERT(pstate->snd_sock == PF_INET6); + DEBUGASSERT(pstate->snd_sock->s_domain == PF_INET6); tcp = TCPIPv6BUF; } #endif /* CONFIG_NET_IPv6 */ @@ -189,7 +139,7 @@ static uint16_t ack_eventhandler(FAR struct net_driver_s *dev, else #endif { - DEBUGASSERT(pstate->snd_sock == PF_INET); + DEBUGASSERT(pstate->snd_sock->s_domain == PF_INET); tcp = TCPIPv4BUF; } #endif /* CONFIG_NET_IPv4 */ @@ -401,21 +351,6 @@ static uint16_t sendfile_eventhandler(FAR struct net_driver_s *dev, } } -#ifdef CONFIG_NET_SOCKOPTS - /* All data has been send and we are just waiting for ACK or re-transmit - * indications to complete the send. Check for a timeout. - */ - - if (sendfile_timeout(pstate)) - { - /* Yes.. report the timeout */ - - nwarn("WARNING: SEND timeout\n"); - pstate->snd_sent = -ETIMEDOUT; - goto end_wait; - } -#endif /* CONFIG_NET_SOCKOPTS */ - if (pstate->snd_sent >= pstate->snd_flen && pstate->snd_acked < pstate->snd_flen) { @@ -612,12 +547,6 @@ ssize_t tcp_sendfile(FAR struct socket *psock, FAR struct file *infile, conn->tx_unacked = 0; -#ifdef CONFIG_NET_SOCKOPTS - /* Set the initial time for calculating timeouts */ - - state.snd_time = clock_systimer(); -#endif - /* Set up the ACK callback in the connection */ state.snd_ackcb->flags = (TCP_ACKDATA | TCP_REXMIT | TCP_DISCONN_EVENTS); @@ -626,18 +555,25 @@ ssize_t tcp_sendfile(FAR struct socket *psock, FAR struct file *infile, /* Perform the TCP send operation */ - do - { - state.snd_datacb->flags = TCP_POLL; - state.snd_datacb->priv = (FAR void *)&state; - state.snd_datacb->event = sendfile_eventhandler; + state.snd_datacb->flags = TCP_POLL; + state.snd_datacb->priv = (FAR void *)&state; + state.snd_datacb->event = sendfile_eventhandler; - /* Notify the device driver of the availability of TX data */ + /* Notify the device driver of the availability of TX data */ - sendfile_txnotify(psock, conn); - net_lockedwait(&state.snd_sem); + sendfile_txnotify(psock, conn); + + for (; ; ) + { + uint32_t acked = state.snd_acked; + + ret = net_timedwait_uninterruptible(&state.snd_sem, + _SO_TIMEOUT(psock->s_sndtimeo)); + if (ret != -ETIMEDOUT || acked == state.snd_acked) + { + break; /* Timeout without any progress */ + } } - while (state.snd_sent >= 0 && state.snd_acked < state.snd_flen); tcp_callback_free(conn, state.snd_ackcb); diff --git a/net/tcp/tcp_setsockopt.c b/net/tcp/tcp_setsockopt.c index 369c6d47a6bab..e6760eaec956f 100644 --- a/net/tcp/tcp_setsockopt.c +++ b/net/tcp/tcp_setsockopt.c @@ -39,7 +39,6 @@ #include -#include #include #include #include @@ -47,7 +46,6 @@ #include -#include #include #include diff --git a/net/tcp/tcp_txdrain.c b/net/tcp/tcp_txdrain.c index dfd9d14fd9e8b..3c90470c50d56 100644 --- a/net/tcp/tcp_txdrain.c +++ b/net/tcp/tcp_txdrain.c @@ -42,7 +42,6 @@ #include #include #include -#include #include #include @@ -91,7 +90,7 @@ static void txdrain_worker(FAR void *arg) * * Input Parameters: * psock - An instance of the internal socket structure. - * abstime - The absolute time when the timeout will occur + * timeout - The relative time when the timeout will occur * * Returned Value: * Zero (OK) is returned on success; a negated errno value is returned @@ -99,8 +98,7 @@ static void txdrain_worker(FAR void *arg) * ****************************************************************************/ -int tcp_txdrain(FAR struct socket *psock, - FAR const struct timespec *abstime) +int tcp_txdrain(FAR struct socket *psock, unsigned int timeout) { FAR struct tcp_conn_s *conn; sem_t waitsem; @@ -159,7 +157,7 @@ int tcp_txdrain(FAR struct socket *psock, * wait for it to drain or be be disconnected. */ - ret = net_timedwait_uninterruptible(&waitsem, abstime); + ret = net_timedwait_uninterruptible(&waitsem, timeout); /* Tear down the disconnect notifier */ diff --git a/net/tcp/tcp_wrbuffer.c b/net/tcp/tcp_wrbuffer.c index 44dcad2612287..cd7c6062d7830 100644 --- a/net/tcp/tcp_wrbuffer.c +++ b/net/tcp/tcp_wrbuffer.c @@ -150,7 +150,7 @@ FAR struct tcp_wrbuffer_s *tcp_wrbuffer_alloc(void) * buffer */ - while (net_lockedwait(&g_wrbuffer.sem) < 0); + net_lockedwait_uninterruptible(&g_wrbuffer.sem); /* Now, we are guaranteed to have a write buffer structure reserved * for us in the free list. diff --git a/net/udp/udp.h b/net/udp/udp.h index c2aa4ded3da6b..76033fd21de7e 100644 --- a/net/udp/udp.h +++ b/net/udp/udp.h @@ -46,7 +46,6 @@ #include #include -#include #include #include @@ -175,9 +174,6 @@ struct udp_wrbuffer_s { sq_entry_t wb_node; /* Supports a singly linked list */ struct sockaddr_storage wb_dest; /* Destination address */ -#ifdef CONFIG_NET_SOCKOPTS - clock_t wb_start; /* Start time for timeout calculation */ -#endif struct iob_s *wb_iob; /* Head of the I/O buffer chain */ }; #endif @@ -451,7 +447,6 @@ void udp_wrbuffer_initialize(void); #ifdef CONFIG_NET_UDP_WRITE_BUFFERS struct udp_wrbuffer_s; - FAR struct udp_wrbuffer_s *udp_wrbuffer_alloc(void); #endif /* CONFIG_NET_UDP_WRITE_BUFFERS */ @@ -846,7 +841,7 @@ void udp_writebuffer_signal(FAR struct udp_conn_s *conn); * * Input Parameters: * psock - An instance of the internal socket structure. - * abstime - The absolute time when the timeout will occur + * timeout - The relative time when the timeout will occur * * Returned Value: * Zero (OK) is returned on success; a negated errno value is returned @@ -855,11 +850,9 @@ void udp_writebuffer_signal(FAR struct udp_conn_s *conn); ****************************************************************************/ #if defined(CONFIG_NET_UDP_WRITE_BUFFERS) && defined(CONFIG_NET_UDP_NOTIFIER) -struct timespec; -int udp_txdrain(FAR struct socket *psock, - FAR const struct timespec *abstime); +int udp_txdrain(FAR struct socket *psock, unsigned int timeout); #else -# define udp_txdrain(conn, abstime) (0) +# define udp_txdrain(conn, timeout) (0) #endif #undef EXTERN diff --git a/net/udp/udp_psock_sendto_buffered.c b/net/udp/udp_psock_sendto_buffered.c index 047355d4959a6..0dcf89275962a 100644 --- a/net/udp/udp_psock_sendto_buffered.c +++ b/net/udp/udp_psock_sendto_buffered.c @@ -61,7 +61,6 @@ #include #include -#include #include #include #include @@ -110,10 +109,6 @@ static inline void sendto_ipselect(FAR struct net_driver_s *dev, FAR struct udp_conn_s *conn); #endif -#ifdef CONFIG_NET_SOCKOPTS -static inline int sendto_timeout(FAR struct socket *psock, - FAR struct udp_conn_s *conn); -#endif static int sendto_next_transfer(FAR struct socket *psock, FAR struct udp_conn_s *conn); static uint16_t sendto_eventhandler(FAR struct net_driver_s *dev, @@ -234,52 +229,6 @@ static inline void sendto_ipselect(FAR struct net_driver_s *dev, } #endif -/**************************************************************************** - * Name: sendto_timeout - * - * Description: - * Check for send timeout. - * - * Input Parameters: - * pstate - sendto state structure - * - * Returned Value: - * TRUE:timeout FALSE:no timeout - * - * Assumptions: - * The network is locked - * - ****************************************************************************/ - -#ifdef CONFIG_NET_SOCKOPTS -static inline int sendto_timeout(FAR struct socket *psock, - FAR struct udp_conn_s *conn) -{ - FAR struct udp_wrbuffer_s *wrb; - - /* Peek at the head of the write queue (without altering the write queue). */ - - wrb = (FAR struct udp_wrbuffer_s *)sq_peek(&conn->write_q); - if (wrb != NULL) - { - /* Check for a timeout configured via setsockopts(SO_SNDTIMEO). - * If none... we well let the send wait forever. - */ - - if (psock->s_sndtimeo != 0) - { - /* Check if the configured timeout has elapsed */ - - return net_timeo(wrb->wb_start, psock->s_sndtimeo); - } - } - - /* No timeout */ - - return FALSE; -} -#endif /* CONFIG_NET_SOCKOPTS */ - /**************************************************************************** * Name: sendto_next_transfer * @@ -514,19 +463,6 @@ static uint16_t sendto_eventhandler(FAR struct net_driver_s *dev, flags &= ~UDP_POLL; } -#ifdef CONFIG_NET_SOCKOPTS - /* We cannot send the data now. Check for a timeout. */ - - else if (sendto_timeout(psock, conn)) - { - /* Free the write buffer at the head of the queue and attempt to setup - * the next transfer. - */ - - sendto_writebuffer_release(psock, conn); - } -#endif /* CONFIG_NET_SOCKOPTS */ - /* Continue waiting */ return flags; @@ -766,10 +702,6 @@ ssize_t psock_udp_sendto(FAR struct socket *psock, FAR const void *buf, memcpy(&wrb->wb_dest, to, tolen); } -#ifdef CONFIG_NET_SOCKOPTS - wrb->wb_start = clock_systimer(); -#endif - /* Copy the user data into the write buffer. We cannot wait for * buffer space if the socket was opened non-blocking. */ diff --git a/net/udp/udp_psock_sendto_unbuffered.c b/net/udp/udp_psock_sendto_unbuffered.c index dede3409759ec..3ced869d34a18 100644 --- a/net/udp/udp_psock_sendto_unbuffered.c +++ b/net/udp/udp_psock_sendto_unbuffered.c @@ -78,14 +78,11 @@ struct sendto_s { -#if defined(CONFIG_NET_SOCKOPTS) || defined(NEED_IPDOMAIN_SUPPORT) +#ifdef NEED_IPDOMAIN_SUPPORT FAR struct socket *st_sock; /* Points to the parent socket structure */ #endif FAR struct devif_callback_s *st_cb; /* Reference to callback instance */ FAR struct net_driver_s *st_dev; /* Driver that will perform the transmission */ -#ifdef CONFIG_NET_SOCKOPTS - clock_t st_time; /* Last send time for determining timeout */ -#endif sem_t st_sem; /* Semaphore signals sendto completion */ uint16_t st_buflen; /* Length of send buffer (error if <0) */ const char *st_buffer; /* Pointer to send buffer */ @@ -96,46 +93,6 @@ struct sendto_s * Private Functions ****************************************************************************/ -/**************************************************************************** - * Name: sendto_timeout - * - * Description: - * Check for send timeout. - * - * Input Parameters: - * pstate - sendto state structure - * - * Returned Value: - * TRUE:timeout FALSE:no timeout - * - * Assumptions: - * The network is locked - * - ****************************************************************************/ - -#ifdef CONFIG_NET_SOCKOPTS -static inline int sendto_timeout(FAR struct sendto_s *pstate) -{ - FAR struct socket *psock; - - /* Check for a timeout configured via setsockopts(SO_SNDTIMEO). - * If none... we well let the send wait forever. - */ - - psock = pstate->st_sock; - if (psock && psock->s_sndtimeo != 0) - { - /* Check if the configured timeout has elapsed */ - - return net_timeo(pstate->st_time, psock->s_sndtimeo); - } - - /* No timeout */ - - return FALSE; -} -#endif /* CONFIG_NET_SOCKOPTS */ - /**************************************************************************** * Name: sendto_ipselect * @@ -246,25 +203,10 @@ static uint16_t sendto_eventhandler(FAR struct net_driver_s *dev, else if (dev->d_sndlen > 0 || (flags & UDP_NEWDATA) != 0) { /* Another thread has beat us sending data or the buffer is busy, - * Check for a timeout. If not timed out, wait for the next - * polling cycle and check again. + * wait for the next polling cycle and check again. */ -#ifdef CONFIG_NET_SOCKOPTS - if (sendto_timeout(pstate)) - { - /* Yes.. report the timeout */ - - nwarn("WARNING: SEND timeout\n"); - pstate->st_sndlen = -ETIMEDOUT; - } - else -#endif /* CONFIG_NET_SOCKOPTS */ - { - /* No timeout. Just wait for the next polling cycle */ - - return flags; - } + return flags; } /* It looks like we are good to send the data */ @@ -477,7 +419,7 @@ ssize_t psock_udp_sendto(FAR struct socket *psock, FAR const void *buf, state.st_buflen = len; state.st_buffer = buf; -#if defined(CONFIG_NET_SOCKOPTS) || defined(NEED_IPDOMAIN_SUPPORT) +#ifdef NEED_IPDOMAIN_SUPPORT /* Save the reference to the socket structure if it will be needed for * asynchronous processing. */ @@ -485,12 +427,6 @@ ssize_t psock_udp_sendto(FAR struct socket *psock, FAR const void *buf, state.st_sock = psock; #endif -#ifdef CONFIG_NET_SOCKOPTS - /* Set the initial time for calculating timeouts */ - - state.st_time = clock_systimer(); -#endif - /* Check if the socket is connected */ if (!_SS_ISCONNECTED(psock->s_flags)) @@ -530,6 +466,7 @@ ssize_t psock_udp_sendto(FAR struct socket *psock, FAR const void *buf, /* Set up the callback in the connection */ + ret = -ENOMEM; /* Assume allocation failure */ state.st_cb = udp_callback_alloc(state.st_dev, conn); if (state.st_cb) { @@ -542,21 +479,23 @@ ssize_t psock_udp_sendto(FAR struct socket *psock, FAR const void *buf, netdev_txnotify_dev(state.st_dev); /* Wait for either the receive to complete or for an error/timeout to - * occur. NOTES: net_lockedwait will also terminate if a signal + * occur. NOTES: net_timedwait will also terminate if a signal * is received. */ - net_lockedwait(&state.st_sem); + ret = net_timedwait(&state.st_sem, _SO_TIMEOUT(psock->s_sndtimeo)); + if (ret >= 0) + { + /* The result of the sendto operation is the number of bytes transferred */ + + ret = state.st_sndlen; + } /* Make sure that no further events are processed */ udp_callback_free(state.st_dev, conn, state.st_cb); } - /* The result of the sendto operation is the number of bytes transferred */ - - ret = state.st_sndlen; - errout_with_lock: /* Release the semaphore */ diff --git a/net/udp/udp_setsockopt.c b/net/udp/udp_setsockopt.c index 2a68172094dc4..8877f6192b3aa 100644 --- a/net/udp/udp_setsockopt.c +++ b/net/udp/udp_setsockopt.c @@ -39,7 +39,6 @@ #include -#include #include #include #include @@ -47,7 +46,6 @@ #include -#include #include #include diff --git a/net/udp/udp_txdrain.c b/net/udp/udp_txdrain.c index c8b9ace05b1a1..162935b305679 100644 --- a/net/udp/udp_txdrain.c +++ b/net/udp/udp_txdrain.c @@ -42,7 +42,6 @@ #include #include #include -#include #include #include @@ -91,7 +90,7 @@ static void txdrain_worker(FAR void *arg) * * Input Parameters: * psock - An instance of the internal socket structure. - * abstime - The absolute time when the timeout will occur + * timeout - The relative time when the timeout will occur * * Returned Value: * Zero (OK) is returned on success; a negated errno value is returned @@ -99,8 +98,7 @@ static void txdrain_worker(FAR void *arg) * ****************************************************************************/ -int udp_txdrain(FAR struct socket *psock, - FAR const struct timespec *abstime) +int udp_txdrain(FAR struct socket *psock, unsigned int timeout) { FAR struct udp_conn_s *conn; sem_t waitsem; @@ -126,7 +124,7 @@ int udp_txdrain(FAR struct socket *psock, /* There is pending write data.. wait for it to drain. */ - ret = net_timedwait_uninterruptible(&waitsem, abstime); + ret = net_timedwait_uninterruptible(&waitsem, timeout); /* Tear down the notifier (in case we timed out or were canceled) */ diff --git a/net/udp/udp_wrbuffer.c b/net/udp/udp_wrbuffer.c index 9248c3afcd298..3738fd5368462 100644 --- a/net/udp/udp_wrbuffer.c +++ b/net/udp/udp_wrbuffer.c @@ -147,7 +147,7 @@ FAR struct udp_wrbuffer_s *udp_wrbuffer_alloc(void) * buffer */ - while (net_lockedwait(&g_wrbuffer.sem) < 0); + net_lockedwait_uninterruptible(&g_wrbuffer.sem); /* Now, we are guaranteed to have a write buffer structure reserved * for us in the free list. diff --git a/net/usrsock/usrsock_accept.c b/net/usrsock/usrsock_accept.c index edb20ede826d0..707ae8a3e0aae 100644 --- a/net/usrsock/usrsock_accept.c +++ b/net/usrsock/usrsock_accept.c @@ -240,10 +240,6 @@ int usrsock_accept(FAR struct socket *psock, FAR struct sockaddr *addr, socklen_t inaddrlen = 0; socklen_t outaddrlen = 0; int ret; -#ifdef CONFIG_NET_SOCKOPTS - struct timespec abstime; -#endif - struct timespec *ptimeo = NULL; DEBUGASSERT(conn); @@ -307,25 +303,6 @@ int usrsock_accept(FAR struct socket *psock, FAR struct sockaddr *addr, goto errout_unlock; } -#ifdef CONFIG_NET_SOCKOPTS - if (psock->s_rcvtimeo != 0) - { - DEBUGVERIFY(clock_gettime(CLOCK_REALTIME, &abstime)); - - /* Prepare timeout value for accept. */ - - abstime.tv_sec += psock->s_rcvtimeo / DSEC_PER_SEC; - abstime.tv_nsec += (psock->s_rcvtimeo % DSEC_PER_SEC) * NSEC_PER_DSEC; - if (abstime.tv_nsec >= NSEC_PER_SEC) - { - abstime.tv_sec++; - abstime.tv_nsec -= NSEC_PER_SEC; - } - - ptimeo = &abstime; - } -#endif - do { /* Check if remote end has closed connection. */ @@ -364,7 +341,8 @@ int usrsock_accept(FAR struct socket *psock, FAR struct sockaddr *addr, /* Wait for receive-avail (or abort, or timeout, or signal). */ - ret = net_timedwait(&state.reqstate.recvsem, ptimeo); + ret = net_timedwait(&state.reqstate.recvsem, + _SO_TIMEOUT(psock->s_rcvtimeo)); if (ret < 0) { if (ret == -ETIMEDOUT) diff --git a/net/usrsock/usrsock_dev.c b/net/usrsock/usrsock_dev.c index 26e94410015bc..a6f31badc0601 100644 --- a/net/usrsock/usrsock_dev.c +++ b/net/usrsock/usrsock_dev.c @@ -961,7 +961,6 @@ static int usrsockdev_close(FAR struct file *filep) FAR struct inode *inode = filep->f_inode; FAR struct usrsockdev_s *dev; FAR struct usrsock_conn_s *conn; - struct timespec abstime; int ret; DEBUGASSERT(inode); @@ -1004,17 +1003,7 @@ static int usrsockdev_close(FAR struct file *filep) * requests. */ - DEBUGVERIFY(clock_gettime(CLOCK_REALTIME, &abstime)); - - abstime.tv_sec += 0; - abstime.tv_nsec += 10 * NSEC_PER_MSEC; - if (abstime.tv_nsec >= NSEC_PER_SEC) - { - abstime.tv_sec++; - abstime.tv_nsec -= NSEC_PER_SEC; - } - - ret = net_timedwait(&dev->req.sem, &abstime); + ret = net_timedwait(&dev->req.sem, 10); if (ret < 0) { if (ret != -ETIMEDOUT && ret != -EINTR) diff --git a/net/usrsock/usrsock_recvfrom.c b/net/usrsock/usrsock_recvfrom.c index 00f9829129572..1b3e353e2e87f 100644 --- a/net/usrsock/usrsock_recvfrom.c +++ b/net/usrsock/usrsock_recvfrom.c @@ -227,10 +227,6 @@ ssize_t usrsock_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len, socklen_t addrlen = 0; socklen_t outaddrlen = 0; ssize_t ret; -#ifdef CONFIG_NET_SOCKOPTS - struct timespec abstime; -#endif - struct timespec *ptimeo = NULL; DEBUGASSERT(conn); @@ -297,25 +293,6 @@ ssize_t usrsock_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len, goto errout_unlock; } -#ifdef CONFIG_NET_SOCKOPTS - if (psock->s_rcvtimeo != 0) - { - DEBUGVERIFY(clock_gettime(CLOCK_REALTIME, &abstime)); - - /* Prepare timeout value for recvfrom. */ - - abstime.tv_sec += psock->s_rcvtimeo / DSEC_PER_SEC; - abstime.tv_nsec += (psock->s_rcvtimeo % DSEC_PER_SEC) * NSEC_PER_DSEC; - if (abstime.tv_nsec >= NSEC_PER_SEC) - { - abstime.tv_sec++; - abstime.tv_nsec -= NSEC_PER_SEC; - } - - ptimeo = &abstime; - } -#endif - do { /* Check if remote end has closed connection. */ @@ -354,7 +331,8 @@ ssize_t usrsock_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len, /* Wait for receive-avail (or abort, or timeout, or signal). */ - ret = net_timedwait(&state.reqstate.recvsem, ptimeo); + ret = net_timedwait(&state.reqstate.recvsem, + _SO_TIMEOUT(psock->s_rcvtimeo)); if (ret < 0) { if (ret == -ETIMEDOUT) diff --git a/net/usrsock/usrsock_sendto.c b/net/usrsock/usrsock_sendto.c index 14c05a88d25ec..3906cf555fe74 100644 --- a/net/usrsock/usrsock_sendto.c +++ b/net/usrsock/usrsock_sendto.c @@ -219,10 +219,6 @@ ssize_t usrsock_sendto(FAR struct socket *psock, FAR const void *buf, }; ssize_t ret; -#ifdef CONFIG_NET_SOCKOPTS - struct timespec abstime; -#endif - struct timespec *ptimeo = NULL; DEBUGASSERT(conn); @@ -283,25 +279,6 @@ ssize_t usrsock_sendto(FAR struct socket *psock, FAR const void *buf, goto errout_unlock; } -#ifdef CONFIG_NET_SOCKOPTS - if (psock->s_sndtimeo != 0) - { - DEBUGVERIFY(clock_gettime(CLOCK_REALTIME, &abstime)); - - /* Prepare timeout value for sendto. */ - - abstime.tv_sec += psock->s_sndtimeo / DSEC_PER_SEC; - abstime.tv_nsec += (psock->s_sndtimeo % DSEC_PER_SEC) * NSEC_PER_DSEC; - if (abstime.tv_nsec >= NSEC_PER_SEC) - { - abstime.tv_sec++; - abstime.tv_nsec -= NSEC_PER_SEC; - } - - ptimeo = &abstime; - } -#endif - do { /* Check if remote end has closed connection. */ @@ -340,7 +317,8 @@ ssize_t usrsock_sendto(FAR struct socket *psock, FAR const void *buf, /* Wait for send-ready (or abort, or timeout, or signal). */ - ret = net_timedwait(&state.recvsem, ptimeo); + ret = net_timedwait(&state.recvsem, + _SO_TIMEOUT(psock->s_sndtimeo)); if (ret < 0) { if (ret == -ETIMEDOUT) diff --git a/net/utils/net_lock.c b/net/utils/net_lock.c index f95d408883aea..376bf760cb62d 100644 --- a/net/utils/net_lock.c +++ b/net/utils/net_lock.c @@ -44,9 +44,11 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -89,8 +91,8 @@ static int _net_takesem(void) * Name: _net_timedwait ****************************************************************************/ -static int _net_timedwait(sem_t *sem, bool interruptable, - FAR const struct timespec *abstime) +static int +_net_timedwait(sem_t *sem, bool interruptable, unsigned int timeout) { unsigned int count; irqstate_t flags; @@ -108,17 +110,29 @@ static int _net_timedwait(sem_t *sem, bool interruptable, /* Now take the semaphore, waiting if so requested. */ - if (abstime != NULL) + if (timeout != UINT_MAX) { + struct timespec abstime; + + DEBUGVERIFY(clock_gettime(CLOCK_REALTIME, &abstime)); + + abstime.tv_sec += timeout / MSEC_PER_SEC; + abstime.tv_nsec += timeout % MSEC_PER_SEC * NSEC_PER_MSEC; + if (abstime.tv_nsec >= NSEC_PER_SEC) + { + abstime.tv_sec++; + abstime.tv_nsec -= NSEC_PER_SEC; + } + /* Wait until we get the lock or until the timeout expires */ if (interruptable) { - ret = nxsem_timedwait(sem, abstime); + ret = nxsem_timedwait(sem, &abstime); } else { - ret = nxsem_timedwait_uninterruptible(sem, abstime); + ret = nxsem_timedwait_uninterruptible(sem, &abstime); } } else @@ -340,7 +354,7 @@ int net_restorelock(unsigned int count) * * Input Parameters: * sem - A reference to the semaphore to be taken. - * abstime - The absolute time to wait until a timeout is declared. + * timeout - The relative time to wait until a timeout is declared. * * Returned Value: * Zero (OK) is returned on success; a negated errno value is returned on @@ -348,9 +362,9 @@ int net_restorelock(unsigned int count) * ****************************************************************************/ -int net_timedwait(sem_t *sem, FAR const struct timespec *abstime) +int net_timedwait(sem_t *sem, unsigned int timeout) { - return _net_timedwait(sem, true, abstime); + return _net_timedwait(sem, true, timeout); } /**************************************************************************** @@ -375,7 +389,7 @@ int net_timedwait(sem_t *sem, FAR const struct timespec *abstime) int net_lockedwait(sem_t *sem) { - return net_timedwait(sem, NULL); + return net_timedwait(sem, UINT_MAX); } /**************************************************************************** @@ -387,7 +401,7 @@ int net_lockedwait(sem_t *sem) * * Input Parameters: * sem - A reference to the semaphore to be taken. - * abstime - The absolute time to wait until a timeout is declared. + * timeout - The relative time to wait until a timeout is declared. * * Returned Value: * Zero (OK) is returned on success; a negated errno value is returned on @@ -395,10 +409,9 @@ int net_lockedwait(sem_t *sem) * ****************************************************************************/ -int net_timedwait_uninterruptible(sem_t *sem, - FAR const struct timespec *abstime) +int net_timedwait_uninterruptible(sem_t *sem, unsigned int timeout) { - return _net_timedwait(sem, false, abstime); + return _net_timedwait(sem, false, timeout); } /**************************************************************************** @@ -419,7 +432,7 @@ int net_timedwait_uninterruptible(sem_t *sem, int net_lockedwait_uninterruptible(sem_t *sem) { - return net_timedwait_uninterruptible(sem, NULL); + return net_timedwait_uninterruptible(sem, UINT_MAX); } /**************************************************************************** From 3c0d68fe08039d9702a7603e20c0329b1d0aa8a8 Mon Sep 17 00:00:00 2001 From: "chao.an" Date: Tue, 24 Dec 2019 19:57:34 +0800 Subject: [PATCH 3/3] inet_close: ensure the TCP_CLOSE can be delivered normally Change-Id: I657433806d5dc851ce9bd7722f191f467f9ad458 Signed-off-by: chao.an --- net/inet/inet_close.c | 93 +++++++++++++++++++++++++++++++++---------- 1 file changed, 73 insertions(+), 20 deletions(-) diff --git a/net/inet/inet_close.c b/net/inet/inet_close.c index 0cd5d6cf6d598..2b26a63347080 100644 --- a/net/inet/inet_close.c +++ b/net/inet/inet_close.c @@ -159,30 +159,30 @@ static uint16_t tcp_close_eventhandler(FAR struct net_driver_s *dev, goto end_wait; } - else if ((flags & TCP_NEWDATA) != 0) - { + #ifdef CONFIG_NET_TCP_WRITE_BUFFERS - /* Check if all outstanding bytes have been ACKed */ + /* Check if all outstanding bytes have been ACKed */ - if (conn->tx_unacked != 0 || !sq_empty(&conn->write_q)) - { - /* No... we are still waiting for ACKs. Drop any received data, but - * do not yet report TCP_CLOSE in the response. - */ + else if (conn->tx_unacked != 0 || !sq_empty(&conn->write_q)) + { + /* No... we are still waiting for ACKs. Drop any received data, but + * do not yet report TCP_CLOSE in the response. + */ + + dev->d_len = 0; + flags &= ~TCP_NEWDATA; + } - dev->d_len = 0; - flags &= ~TCP_NEWDATA; - } - else #endif /* CONFIG_NET_TCP_WRITE_BUFFERS */ - { - /* Drop data received in this state and make sure that TCP_CLOSE - * is set in the response - */ - dev->d_len = 0; - flags = (flags & ~TCP_NEWDATA) | TCP_CLOSE; - } + else + { + /* Drop data received in this state and make sure that TCP_CLOSE + * is set in the response + */ + + dev->d_len = 0; + flags = (flags & ~TCP_NEWDATA) | TCP_CLOSE; } UNUSED(conn); /* May not be used */ @@ -199,6 +199,55 @@ static uint16_t tcp_close_eventhandler(FAR struct net_driver_s *dev, } #endif /* NET_TCP_HAVE_STACK */ +/**************************************************************************** + * Name: tcp_close_txnotify + * + * Description: + * Notify the appropriate device driver that we are have data ready to + * be send (TCP) + * + * Input Parameters: + * psock - Socket state structure + * conn - The TCP connection structure + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef NET_TCP_HAVE_STACK +static inline void tcp_close_txnotify(FAR struct socket *psock, + FAR struct tcp_conn_s *conn) +{ +#ifdef CONFIG_NET_IPv4 +#ifdef CONFIG_NET_IPv6 + /* If both IPv4 and IPv6 support are enabled, then we will need to select + * the device driver using the appropriate IP domain. + */ + + if (psock->s_domain == PF_INET) +#endif + { + /* Notify the device driver that send data is available */ + + netdev_ipv4_txnotify(conn->u.ipv4.laddr, conn->u.ipv4.raddr); + } +#endif /* CONFIG_NET_IPv4 */ + +#ifdef CONFIG_NET_IPv6 +#ifdef CONFIG_NET_IPv4 + else /* if (psock->s_domain == PF_INET6) */ +#endif /* CONFIG_NET_IPv4 */ + { + /* Notify the device driver that send data is available */ + + DEBUGASSERT(psock->s_domain == PF_INET6); + netdev_ipv6_txnotify(conn->u.ipv6.laddr, conn->u.ipv6.raddr); + } +#endif /* CONFIG_NET_IPv6 */ +} +#endif /* NET_TCP_HAVE_STACK */ + /**************************************************************************** * Name: tcp_close_disconnect * @@ -288,7 +337,7 @@ static inline int tcp_close_disconnect(FAR struct socket *psock) { /* Set up to receive TCP data event callbacks */ - state.cl_cb->flags = (TCP_NEWDATA | TCP_DISCONN_EVENTS); + state.cl_cb->flags = (TCP_NEWDATA | TCP_POLL | TCP_DISCONN_EVENTS); state.cl_cb->event = tcp_close_eventhandler; /* A non-NULL value of the priv field means that lingering is @@ -309,6 +358,10 @@ static inline int tcp_close_disconnect(FAR struct socket *psock) nxsem_init(&state.cl_sem, 0, 0); nxsem_setprotocol(&state.cl_sem, SEM_PRIO_NONE); + /* Notify the device driver of the availability of TX data */ + + tcp_close_txnotify(psock, conn); + /* Wait for the disconnect event */ net_lockedwait(&state.cl_sem);