Commit Graph

151 Commits

Author SHA1 Message Date
chao.an
0636c17a63 net/tcp: wave hands on background
The time consuming of tcp waving hands(close(2)) will be affected
by network jitter, especially the wireless device cannot receive
the last-ack under worst environment, in this change we move the
tcp close callback into background and invoke the resource free
from workqueue, which will avoid the user application from being
blocked for a long time and unable to return in the call of close

Signed-off-by: chao.an <anchao@xiaomi.com>
2022-06-09 18:19:25 +03:00
zhanghongyu
3f8b71924f tcp: move wd_timer from wifi driver to tcp stack
Signed-off-by: zhanghongyu <zhanghongyu@xiaomi.com>
2022-05-28 16:29:51 +08:00
Xiang Xiao
d8b97d7ae8 net/tcp: Use the relative value for keep alive timer
unify the timer process logic as other tcp state

Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
2022-05-18 18:40:41 +03:00
Xiang Xiao
9072eecc30 sched/wqueue: Change the return type of work_notifier_teardown to void
Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
2022-05-14 00:35:29 +03:00
zhanghongyu
c50d7e174f net: tcp/udp/icmp/icmpv6 add FIONSPACE support
Signed-off-by: zhanghongyu <zhanghongyu@xiaomi.com>
2022-04-02 13:39:38 +08:00
Xiang Xiao
7028531e74 net/tcp: Remove tcp_listen_initialize
Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
2022-03-12 19:24:17 +02:00
Alexander Lunev
404ceffae2 tcp: added debug asserts and logging to investigate the rare (conn->dev == NULL) bug in callback handlers 2022-02-26 11:48:07 -03:00
chao.an
1911ae2192 net/tcp: add interface tcp_wrbuffer_timedalloc()
add new interface to support alloc wrbuffer with timeout

Signed-off-by: chao.an <anchao@xiaomi.com>
2022-02-17 21:27:39 +01:00
chao.an
e749f6ca7e net/tcp/monitor: do not migrate the state to close
1. remove the unnecessary interfaces tcp_close_monitor()

socket flags(s_flags) is a global state for net connection
remove the incorrect update for stop monitor

2. do not start the tcp monitor from duplicated psock

the tcp monitor has already registered in connect callback

------------------------------------------------------------
This patch also fix the telnet issue reported by:
https://github.com/apache/incubator-nuttx/pull/5434#issuecomment-1035600651

the orignal session fd is closed after dup, the connect state
has incorrectly migrated to close:

drivers/net/telnet.c:
 977 static int telnet_session(FAR struct telnet_session_s *session)
 ...
 1031   ret = psock_dup2(psock, &priv->td_psock);
 ...
 1082   nx_close(session->ts_sd);

Signed-off-by: chao.an <anchao@xiaomi.com>
2022-02-11 18:56:40 +09:00
chao.an
8fb2468785 net/tcp: remove the socket hook reference from netdev callback
Signed-off-by: chao.an <anchao@xiaomi.com>
2022-02-10 15:04:33 -03:00
chao.an
8f63596063 net/tcp: replace the common connect prologue
Signed-off-by: chao.an <anchao@xiaomi.com>
2022-02-10 15:04:33 -03:00
chao.an
39e142243d net/tcp/udp: move the send callback into tcp/udp structure
Signed-off-by: chao.an <anchao@xiaomi.com>
2022-02-10 15:04:33 -03:00
Alexander Lunev
2a6de301ee net/tcp: transformed NET_TCP_FAST_RETRANSMIT_WATERMARK option to boolean.
According to RFC 5681 (3.2) the TCP Fast Retransmit algorithm should start
if the threshold of 3 duplicate ACKs is reached.
Thus the threshold should be a constant, not an integer option.
2022-01-26 11:50:48 +08:00
Alexander Lunev
64dd669749 net/tcp/sendfile: retransmit only one the earliest not acknowledged segment
(according to RFC 6298 (5.4)). The issue is the same as it was in tcp_send_unbuffered.c.
2022-01-20 18:37:39 +08:00
Alexander Lunev
0f080cdeaf net/tcp/sendfile: NET_TCP_WRITE_BUFFERS and NET_SENDFILE were inconsistent with each other:
tcp_sendfile() reads data directly from a file and does not use NET_TCP_WRITE_BUFFERS data flow
even if CONFIG_NET_TCP_WRITE_BUFFERS option is enabled.
Despite this, tcp_sendfile relied on NET_TCP_WRITE_BUFFERS specific flow control variables that
were idle during sendfile operation. Thus it was a total inconsistency.

E.g. because of the issue, TCP socket used by sendfile() operation never issued
FIN packet on close() command, and the TCP connection hung up.

As a result of the fix, simultaneously enabled CONFIG_NET_TCP_WRITE_BUFFERS and
CONFIG_NET_SENDFILE options can coexist.
2022-01-17 01:42:41 +08:00
Petro Karashchenko
8d3bf05fd2 include: fix double include pre-processor guards
Signed-off-by: Petro Karashchenko <petro.karashchenko@gmail.com>
2022-01-16 11:11:14 -03:00
Alexander Lunev
19dc121a4f net/tcp(unbuffered): fixed an issue with tx_unacked overflow that occurred if NET_TCP_WINDOW_SCALE option was enabled.
If the remote TCP receiver advertised TCP window size greater than 64 KB
and TCP ACK packets returned to the NuttX TCP sender with a significant delay,
tx_unacked variable overflowed and further TCP send stalled forever
(until TCP re-connection).
2021-12-27 11:05:01 -06:00
Alexander Lunev
1e07b6d528 net/tcp(unbuffered): retransmit only one the earliest not acknowledged segment
(according to RFC 6298 (5.4)).
2021-11-10 12:21:07 -06:00
chao.an
c132e5bed4 net/tcp: sanity check for the listen address
Signed-off-by: chao.an <anchao@xiaomi.com>
2021-09-23 23:07:57 -07:00
Alexander Lunev
36fbedcbfc net/devif/devif_callback.c: corrected the connection event list to work as FIFO instead of LIFO.
In case of enabled packet forwarding mode, packets were forwarded in a reverse order
because of LIFO behavior of the connection event list.
The issue exposed only during high network traffic. Thus the event list started to grow
that resulted in changing the order of packets inside of groups of several packets
like the following: 3, 2, 1, 6, 5, 4, 8, 7 etc.

Remarks concerning the connection event list implementation:
* Now the queue (list) is FIFO as it should be.
* The list is singly linked.
* The list has a head pointer (inside of outer net_driver_s structure),
  and a tail pointer is added into outer net_driver_s structure.
* The list item is devif_callback_s structure.
  It still has two pointers to two different list chains (*nxtconn and *nxtdev).
* As before the first argument (*dev) of the list functions can be NULL,
  while the other argument (*list) is effective (not NULL).
* An extra (*tail) argument is added to devif_callback_alloc()
  and devif_conn_callback_free() functions.
* devif_callback_alloc() time complexity is O(1) (i.e. O(n) to fill the whole list).
* devif_callback_free() time complexity is O(n) (i.e. O(n^2) to empty the whole list).
* devif_conn_event() time complexity is O(n).
2021-09-18 21:01:39 -05:00
YAMAMOTO Takashi
1b82f1c749 tcp_input: snd_wnd processing
* Do not accept the window in old segments.
  Implement SND.WL1/WL2 things in the RFC.

* Do not accept the window in the segment w/o ACK bit set.
  The window is an offset from the ack seq.
  (maybe it's simpler to just drop segments w/o ACK though)

* Subtract snd_wnd by the amount of the ack advancement.
2021-08-25 20:56:05 +08:00
chao.an
7d4502aca6 net/socket: add SO_SNDBUF support
Signed-off-by: chao.an <anchao@xiaomi.com>
2021-07-20 20:24:58 -07:00
YAMAMOTO Takashi
09f3a1ec8e tcp_send_buffered: throttle IOB allocations for send
Consider a bi-directional TCP connection:

1. we use all IOBs for tx queue
2. we advertize zero recv window because we have no free IOBs
3. if the peer tcp does the same thing,
   both sides advertize zero window and can not drain the tx queue.

For a similar stall to happen, the peer doesn't need to be
a naive tcp implementation like nuttx. A naive application blocking
on send() without draining its read buffer is enough.
(Probably such an application should be fixed to drain rx even
when tx is full. However, it's another story.)

This commit avoids the situation by prevent tx from grabbing
the all IOBs in the first place. (assuming CONFIG_IOB_THROTTLE > 0)
2021-07-14 15:08:18 +08:00
chao.an
d4ce70979e net/tcp: change all window relative value type to uint32_t
1. change all window relative value type to uint32_t
2. move window range validity check(UINT16_MAX) before assembling TCP header

Signed-off-by: chao.an <anchao@xiaomi.com>
2021-07-07 03:55:41 -05:00
chao.an
aab03ef86d net/tcp: add window scale support
Reference here:
https://tools.ietf.org/html/rfc1323

Signed-off-by: chao.an <anchao@xiaomi.com>
2021-07-07 03:55:41 -05:00
chao.an
b901f22c27 net/socket: add SO_RCVBUF support
Signed-off-by: chao.an <anchao@xiaomi.com>
2021-07-06 01:44:55 -05:00
chao.an
eabe535de7 net/inet: add support of FIONREAD
Signed-off-by: chao.an <anchao@xiaomi.com>
2021-07-05 06:20:52 -05:00
YAMAMOTO Takashi
52c237cb5f net/tcp/tcp.h: Update a comment about readahead 2021-06-30 06:40:13 -05:00
YAMAMOTO Takashi
4878b7729c tcp: simplify readahead
Do not bother to preserve segment boundaries in the tcp
readahead queues.

* Avoid wasting the tail IOB space for each segments.
  Instead, pack the newly received data into the tail space
  of the last IOB. Also, advertise the tail space as
  a part of the window.

* Use IOB chain directly. Eliminate IOB queue overhead.

* Allow to accept only a part of a segment.

* This change improves the memory efficiency.
  And probably more importantly, allows less-confusing
  recv window advertisement behavior.
  Previously, even when we advertise N bytes window,
  we often couldn't actually accept N bytes. Depending on
  the segment sizes and IOB configurations, it was causing
  segment drops.
  Also, the previous code was moving the right edge of the
  window back and forth too often, even when nothing in
  the system was competing on the IOBs. Shrinking the
  window that way is a kinda well known recipe to confuse
  the peer stack.
2021-06-30 06:22:14 +09:00
YAMAMOTO Takashi
eeafe070ec tcp.h: Add TCP_SEQ_ADD 2021-06-30 06:22:14 +09:00
YAMAMOTO Takashi
14ec75e7fc tcp: window update improvements
* Fixes the case where the window was small but not zero.

* tcp_recvfrom: Remove tcp_ackhandler. Instead, simply schedule TX for
  a possible window update and make tcp_appsend decide.

* Replace rcv_wnd (the last advertized window size value) with
  rcv_adv. (the window edge sequence number advertized to the peer)
  rcv_wnd was complicated to deal with because its base (rcvseq) is
  also moving.

* tcp_appsend: Send a window update even if there are no other reasons
  to send an ack.
  Namely, send an update if it increases the window by
    * 2 * mss
    * or the half of the max possible window size
2021-06-13 21:20:24 -05:00
YAMAMOTO Takashi
1f6fdf04b7 tcp: Extract MSS calculation from tcp_synack
I plan to use it for recv window update decision logic.
2021-06-13 21:20:24 -05:00
YAMAMOTO Takashi
433a2b27d9 tcp: add macros to deal with sequence number wraparound 2021-06-10 22:47:04 -05:00
YAMAMOTO Takashi
69b3f034a4 tcp: Move buffered/unbuffered common code to tcp_send.c 2021-06-03 21:33:10 -05:00
YAMAMOTO Takashi
09869e5d41 net/tcp/tcp.h: Remove unused extern g_netdevices 2021-03-30 12:27:50 -05:00
YAMAMOTO Takashi
837e1a72a4 tcp_send_buffered.c: improve tcp write buffering
* Send data chunk-by-chunk
  Note: A stream socket doesn't have atomicity requirement.

* Increase the chance to use full-sized segments

Benchmark numbers in my environment:

* Over ESP32 wifi
* The peer is NetBSD, which has traditional delayed ack TCP
* iperf uses 16384 bytes buffer

---

without this patch,
CONFIG_IOB_NBUFFERS=36
CONFIG_IOB_BUFSIZE=196

does not work.
see https://github.com/apache/incubator-nuttx/pull/2772#discussion_r592820639

---

without this patch,
CONFIG_IOB_NBUFFERS=128
CONFIG_IOB_BUFSIZE=196
```
nsh> iperf -c 192.168.8.1
       IP: 192.168.8.103

 mode=tcp-client sip=192.168.8.103:5001,dip=192.168.8.1:5001, interval=3, time=30

        Interval Bandwidth

   0-   3 sec,  4.11 Mbits/sec
   3-   6 sec,  4.63 Mbits/sec
   6-   9 sec,  4.89 Mbits/sec
   9-  12 sec,  4.63 Mbits/sec
  12-  15 sec,  4.85 Mbits/sec
  15-  18 sec,  4.85 Mbits/sec
  18-  21 sec,  5.02 Mbits/sec
  21-  24 sec,  3.67 Mbits/sec
  24-  27 sec,  4.94 Mbits/sec
  27-  30 sec,  4.81 Mbits/sec
   0-  30 sec,  4.64 Mbits/sec
nsh>
```

---

with this patch,
CONFIG_IOB_NBUFFERS=36
CONFIG_IOB_BUFSIZE=196
```
nsh> iperf -c 192.168.8.1
       IP: 192.168.8.103

 mode=tcp-client sip=192.168.8.103:5001,dip=192.168.8.1:5001, interval=3, time=30

        Interval Bandwidth

   0-   3 sec,  5.33 Mbits/sec
   3-   6 sec,  5.59 Mbits/sec
   6-   9 sec,  5.55 Mbits/sec
   9-  12 sec,  5.59 Mbits/sec
  12-  15 sec,  5.59 Mbits/sec
  15-  18 sec,  5.72 Mbits/sec
  18-  21 sec,  5.68 Mbits/sec
  21-  24 sec,  5.29 Mbits/sec
  24-  27 sec,  4.67 Mbits/sec
  27-  30 sec,  4.50 Mbits/sec
   0-  30 sec,  5.35 Mbits/sec
nsh>
```

---

with this patch,
CONFIG_IOB_NBUFFERS=128
CONFIG_IOB_BUFSIZE=196
```
nsh> iperf -c 192.168.8.1
       IP: 192.168.8.103

 mode=tcp-client sip=192.168.8.103:5001,dip=192.168.8.1:5001, interval=3, time=30

        Interval Bandwidth

   0-   3 sec,  5.51 Mbits/sec
   3-   6 sec,  4.67 Mbits/sec
   6-   9 sec,  4.54 Mbits/sec
   9-  12 sec,  5.42 Mbits/sec
  12-  15 sec,  5.37 Mbits/sec
  15-  18 sec,  5.11 Mbits/sec
  18-  21 sec,  5.07 Mbits/sec
  21-  24 sec,  5.29 Mbits/sec
  24-  27 sec,  5.77 Mbits/sec
  27-  30 sec,  4.63 Mbits/sec
   0-  30 sec,  5.14 Mbits/sec
nsh>
```
2021-03-22 01:12:59 -07:00
Alin Jerpelea
37d5c1b0d9 net: Author Gregory Nutt: update licenses to Apache
Gregory Nutt has submitted the SGA and we can migrate the licenses
 to Apache.

Signed-off-by: Alin Jerpelea <alin.jerpelea@sony.com>
2021-02-20 00:38:18 -08:00
Abdelatif Guettouche
7e3d4a5f29 net: Remove duplicate forward references.
Signed-off-by: Abdelatif Guettouche <abdelatif.guettouche@espressif.com>
2021-01-16 07:39:04 -08:00
Juha Niskanen
de1ad1fdb3 net: fix typos, incorrect comments, nxstyle
Signed-off-by: Juha Niskanen <juha.niskanen@haltian.com>
2020-12-13 09:06:28 -06:00
chao.an
8d0118569c [Performance]net/tcp: send the ACK in time after obtain ahead buffer from iobs
Request the TCP ACK to estimate the receive window after handle
any data already buffered in a read-ahead buffer.

Change-Id: Id998a1125dd2991d73ba4bef081ddcb7adea4f0d
Signed-off-by: chao.an <anchao@xiaomi.com>
2020-12-10 12:23:47 +09:00
chao.an
881dd9d62d net/tcp: add a member to record the current receiving window
Change-Id: Ic4c46d643a905fdd3a828e563eab4814da70dbe5
Signed-off-by: chao.an <anchao@xiaomi.com>
2020-12-10 12:23:47 +09:00
chao.an
794a6ec23d net/tcp: rename the winszie to snd_wnd to make the semantics more accurate
Change-Id: I8fdc7cf78a7f2cd53a30ef1de702b1a697c43238
Signed-off-by: chao.an <anchao@xiaomi.com>
2020-12-10 12:23:47 +09:00
chao.an
c2b0006dcd net/tcp: implement the fast retransmit
RFC2001: TCP Slow Start, Congestion Avoidance, Fast Retransmit,
         and Fast Recovery Algorithms

...

3.  Fast Retransmit
  Modifications to the congestion avoidance algorithm were proposed in
  1990 [3].  Before describing the change, realize that TCP may
  generate an immediate acknowledgment (a duplicate ACK) when an out-
  of-order segment is received (Section 4.2.2.21 of [1], with a note
  that one reason for doing so was for the experimental fast-
  retransmit algorithm).  This duplicate ACK should not be delayed.
  The purpose of this duplicate ACK is to let the other end know that a
  segment was received out of order, and to tell it what sequence
  number is expected.

  Since TCP does not know whether a duplicate ACK is caused by a lost
  segment or just a reordering of segments, it waits for a small number
  of duplicate ACKs to be received.  It is assumed that if there is
  just a reordering of the segments, there will be only one or two
  duplicate ACKs before the reordered segment is processed, which will
  then generate a new ACK.  If three or more duplicate ACKs are
  received in a row, it is a strong indication that a segment has been
  lost.  TCP then performs a retransmission of what appears to be the
  missing segment, without waiting for a retransmission timer to
  expire.

Change-Id: Ie2cbcecab507c3d831f74390a6a85e0c5c8e0652
Signed-off-by: chao.an <anchao@xiaomi.com>
2020-12-01 11:36:10 -06:00
chao.an
bf21056001 net/tcp: fallback to unthrottle pool to avoid deadlock
Add a fallback mechanism to ensure that there are still available
iobs for an free connection, Guarantees all connections will have
a minimum threshold iob to keep the connection not be hanged.

Change-Id: I59bed98d135ccd1f16264b9ccacdd1b0d91261de
Signed-off-by: chao.an <anchao@xiaomi.com>
2020-11-28 00:03:47 -06:00
GAEHWILER Reto
83745652c4 TCP-stack fix for stalled tcp sockets due to broken keepalive
Fixes an issue where tcp sockets with activated keepalives stalled and
were not properly closed. Poll would not indicate a POLLHUP and therefore
locks down the application.

* tcp_conn_s.tcp_conn_s & tcp_conn_s.keepintvl changed to uint32_t
  According RFC1122 keepidle MUST have a default of 2 hours.
2020-10-27 11:21:56 -07:00
Xiang Xiao
63e3054ced Don't need monitor IOB buffer empty event for POLLOUT implementation
It's enough to check the buffer available in the net event handler

Change-Id: I2d7c7a03675cf6eff6ffb42a81b7c7245253e92c
Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
2020-05-13 06:50:07 -06:00
Xiang Xiao
bd4e8e19d3 Run codespell -w against all files
and fix the wrong correction
2020-02-22 14:45:07 -06:00
chao.an
c65d8e6a23 net/socket: add MSG_DONTWAIT support
MSG_DONTWAIT (since Linux 2.2)
  Enables nonblocking operation; if the operation would block, the
  call fails with the error EAGAIN or EWOULDBLOCK. This provides
  similar behavior to setting the O_NONBLOCK flag (via the fcntl(2)
  F_SETFL operation), but differs in that MSG_DONTWAIT is a per-call
  option, whereas O_NONBLOCK is a setting on the open file description
  (see open(2)), which will affect all threads in the calling process
  and as well as other processes that hold file descriptors referring
  to the same open file description.
2020-02-19 12:21:28 -06:00
Juha Niskanen
15b78abccf Fix typos in comments 2020-02-14 08:50:45 -06:00
Gregory Nutt
6d4b86ff06 net/tcp/tcp.h: Correct spacing error introduced with the last PR. 2020-01-21 08:30:39 -06:00