psock_tcp_send will enter busyloop state when no IOB keeps at unavailable state
when the socket is blocking socket and this will cause WDT.
According to socket's manpage, -1 should be returned while errno set to EAGAIN
if send/recv timeout was set.
Here's the description:
SO_RCVTIMEO and SO_SNDTIMEO
Specify the receiving or sending timeouts until reporting an error. The argument is a struct timeval. If an input or output function blocks for this period of time, and data has been sent or received, the return value of that function will be the amount of data transferred; if no data has been transferred and the timeout has been reached then -1 is returned with errno set to EAGAIN or EWOULDBLOCK, or EINPROGRESS (for connect(2)) just as if the socket was specified to be nonblocking. If the timeout is set to zero (the default) then the operation will never timeout. Timeouts only have effect for system calls that perform socket I/O (e.g., read(2), recvmsg(2), send(2), sendmsg(2)); timeouts have no effect for select(2), poll(2), epoll_wait(2), and so on.
Signed-off-by: liangchaozhong <liangchaozhong@xiaomi.com>
UDP linger timeout will be wrongly converted to UINT_MAX by _SO_TIMEOUT() when it is set to 0,
net/socket/socket.h:
|
| # define _SO_TIMEOUT(t) ((t) ? (t) * MSEC_PER_DSEC : UINT_MAX)
net/udp/udp_close.c:
|
| if (_SO_GETOPT(conn->sconn.s_options, SO_LINGER))
| {
| timeout = _SO_TIMEOUT(conn->sconn.s_linger);
| }
this change will correct this behavior, if the linger is set to 0, the timeout value should be 0
Signed-off-by: chao an <anchao@xiaomi.com>
1. Remove tcp_txdrain() from close() to avoid indefinitely block
2. Send TCP_RST immediately if linger timeout
Signed-off-by: chao an <anchao@xiaomi.com>
Merge conflicts lead to code being placed in thre wrong place
The debug code should placed in tcp_send() not tcp_synack()
Signed-off-by: chao an <anchao@xiaomi.com>
if the wrbuffer does not have enough space to send the rest of
the data, then the send function will loop infinitely in nonblock
mode, add send timeout check to avoid this issue.
Signed-off-by: chao an <anchao@xiaomi.com>
Allocate the device buffer only if the protocol really need to send data.
not all protocols require the driver to prepare additional iob before
sending, especially UDP, each iob reserves l2/l3 header in advance
after prepare write buffer, net device could reuse this entry to send directly
Signed-off-by: chao an <anchao@xiaomi.com>
When trying to use iperf2, we found it comsumes all the IOB when sending UDP packets, then devif_poll has no IOB to send the packet out, so speed drops to 0 and never recovers.
Signed-off-by: Zhe Weng <wengzhe@xiaomi.com>
epoll_wait collects revent by checking fds->revent,
but local_socket will copy fds to the other two private pollfd shandow struct,
then the pipe_poll will not be able to update fds->revent directly,
so need local_socket save fds and implement a private poll_notify function
to passing revent to original fds->revent.
Signed-off-by: zhanghongyu <zhanghongyu@xiaomi.com>
Previously, the devif_poll works in this flow:
devif_poll_xx -> bstop = callback -> continue if !bstop -> poll another
Now we split the polling and callback, so it should work like:
devif_poll_connections -> return true if callback need to be called
-> bstop = callback -> loop if !bstop -> poll again
Conditions:
poll_connections == 0, d_len == 0, break, return 0
poll_connections == 1, d_len == 0, break, return 1 (other stop case,
don't callback)
poll_connections == 1, d_len > 0, callback == 1, break, return 1
poll_connections == 1, d_len > 0, callback == 0, loop
Signed-off-by: Zhe Weng <wengzhe@xiaomi.com>
When ipv4_input/ipv6_input called by devif_loopback writes wrong data into buffer (another bug we're fixing), the else block does nothing but only record the 'dropped' statistic, then infinite loop happens.
Refers to previous lo device with dropping logic:
https://github.com/apache/nuttx/blob/releases/11.0/drivers/net/loopback.c#L178-L180
Signed-off-by: Zhe Weng <wengzhe@xiaomi.com>
Fragmentation of network data will intensify iob consumption, if
the device receives a message storm of fragmented packets, the iob
cache will not be effectively used, this is not allowed on iot devices
since the resources of such devices are limited. Of course, this
also takes some disadvantages: data needs to be copied.
This option will brings some balance on resource-constrained devices,
enable this config to reduce the consumption of iob, the received iob
buffers will be merged into the contiguous iob chain.
Signed-off-by: chao an <anchao@xiaomi.com>
If ipforward consumes all the IOB, devif_poll will not poll any more. Without polling, ipforward will not release any IOB, then all the network stack may fail with no IOB available.
Signed-off-by: Zhe Weng <wengzhe@xiaomi.com>
Problem:
- `iob_copyout` to `d_buf` doesn't set `io_len` of the IOB, so `devif_poll` failed to copy the data into `buf` by `iob_copyout`
Modification:
- Just Move the IOB in `devif_forward`.
Signed-off-by: Zhe Weng <wengzhe@xiaomi.com>
Loopback device will consume the d_iob packet in upper layer protocol,
in order to avoid null pointer access, reprepare iob buffer before polling connections
Signed-off-by: chao an <anchao@xiaomi.com>
l3/l4 stack will decouple the reference of d_buf gradually, Only legacy
devices still retain d_buf support, new net devices will use d_iob
Signed-off-by: chao an <anchao@xiaomi.com>
Fix icmpv6_reply logic broken by commit 48311cc61f and 391b501639.
- 48311cc61f "Fix unaligned memory access when creating ICMP Port Unreachable messages"
- It removed `htonl` function outside `data`, then the byte order may be wrong, so add `htons` back.
- 391b501639 "net: extract l3 header build code into new functions"
- It mis-removed the `memmove`, and the icmpv6 has no payload copied after this commit.
Signed-off-by: Zhe Weng <wengzhe@xiaomi.com>
Set IPv4 flag before processing ipforward, otherwise the ICMP packet responded by ipforward may sometimes be regarded as IPv6.
Signed-off-by: Zhe Weng <wengzhe@xiaomi.com>
Split out ipv4_nat_in/outbound_internal which returns entry instead of error code, for later ICMP error types, does not change any current logic.
Reason: Outer packet doesn't have information of port, so we need to find entry by inner packet, and apply the entry to outer packet.
| Outer Packet: SRC = Peer IP<No Port>, DST = External IP<No Port> |
| Inner Packet: SRC = External IP:Port, DST = Peer IP:Port |
Signed-off-by: Zhe Weng <wengzhe@xiaomi.com>
This commit is for later ICMP error types processing, and does not change any current logic.
Reason for supporting both side of modification is that an inbound ICMP Error MSG may carry original packet like this:
| IP HDR: SRC = Peer IP, DST = External IP |
| ICMP HDR: ERROR MSG |
| <Origin> IP HDR: SRC = External IP, DST = Peer IP |
| <Origin> L4 HDR: SRC = External Port, DST = Peer Port |
So we need to support inbound translation (External -> Local) on SRC or DST of each header.
And so do the outbound direction.
Signed-off-by: Zhe Weng <wengzhe@xiaomi.com>
devif_loopback needs to be applied on l2 data, and was broken by commit below, now fix it.
| commit 8850dee746
| Author: chao an <anchao@xiaomi.com>
| Date: Sun Nov 27 03:31:07 2022 +0800
|
| net/devif: move preprocess of txpoll into common code
|
| Signed-off-by: chao an <anchao@xiaomi.com>
Signed-off-by: Zhe Weng <wengzhe@xiaomi.com>
devif/ipv4_input.c: In function ‘ipv4_in’:
devif/ipv4_input.c:305:15: warning: declaration of ‘ret’ shadows a previous local [-Wshadow]
305 | int ret = ipv4_forward(dev, ipv4);
| ^~~
devif/ipv4_input.c:151:7: note: shadowed declaration is here
151 | int ret = OK;
| ^~~
Signed-off-by: chao an <anchao@xiaomi.com>
The following APIs need to be overriden by the arch after enabling
CONFIG_NET_ARCH_CHKSUM, move these functions to the common header
file to avoid prototype conflicts
uint16_t chksum(uint16_t sum, FAR const uint8_t *data, uint16_t len);
uint16_t net_chksum(FAR uint16_t *data, uint16_t len);
uint16_t ipv4_upperlayer_chksum(FAR struct net_driver_s *dev, uint8_t proto);
uint16_t ipv6_upperlayer_chksum(FAR struct net_driver_s *dev,
uint8_t proto, unsigned int iplen);
uint16_t ipv4_chksum(FAR struct ipv4_hdr_s *ipv4);
Signed-off-by: chao an <anchao@xiaomi.com>
TX poll callback in device lo(loopback) can be replaced by devif_loopback()
from devif_poll() hook, remove duplicate code to reuse this logic
Signed-off-by: chao an <anchao@xiaomi.com>
Add link layer length in loopback is unnecessary after below change checkin:
| commit 6fa60627eb
| Author: chao an <anchao@xiaomi.com>
| Date: Sun Nov 27 02:13:21 2022 +0800
|
| net/devif/ip: build l2 header on the IP layer
|
| Signed-off-by: chao an <anchao@xiaomi.com>
Signed-off-by: chao an <anchao@xiaomi.com>
fix build break if enable CONFIG_NET_IPv6 only
In file included from tcp/tcp_sendfile.c:38:
tcp/tcp_sendfile.c: In function ‘sendfile_eventhandler’:
tcp/tcp_sendfile.c:173:27: error: ‘struct tcp_conn_s’ has no member named ‘domain’
173 | DEBUGASSERT(conn->domain == PF_INET6);
| ^~
Signed-off-by: chao an <anchao@xiaomi.com>