We have projects that need to sense ip address changes in time,
and set ip address or clear ip address through netlink
so the relevant implementation is added.
The usage and command structure are consistent with linux
Signed-off-by: zhanghongyu <zhanghongyu@xiaomi.com>
The rpmsg addr get from socket accept has rp_family=0, which is not
intended, to avoid wrong logic in other place, set the rp_family
in ns_bind function.
Signed-off-by: Zhe Weng <wengzhe@xiaomi.com>
According to RFC 2525, Section 2.17:
"When an application closes a connection in such a way that it can no longer read any received data, the TCP SHOULD, per section 4.2.2.13 of RFC 1122, send a RST if there is any unread received data, or if any new data is received."
When our TCP socket is closed (even when the thread has exited), the peer can keep sending data and NuttX keeps replying ACK (we've tried for ~12h). This is not a good behavior (also different from Linux), so send RST instead of ACK for data receiving in FIN_WAIT.
Signed-off-by: Zhe Weng <wengzhe@xiaomi.com>
Problem:
A SOCK_CTRL socket may be led to udp_pollsetup but never reaches
udp_pollteardown, it seems that we shouldn't call udp_pollsetup for
other socket types.
Signed-off-by: Zhe Weng <wengzhe@xiaomi.com>
There might be some cases that we receive an event after socket is closed because of out-of-ordered rpmsg, since it may not cause problem, we may omit the error.
Also change log level to err when returning negated errno, because if we return negated errno, we'll directly trigger RPMSG_ASSERT outside, so we need at least an error message to indicate the reason.
Signed-off-by: Zhe Weng <wengzhe@xiaomi.com>
SOCK_CTRL is added to provide special control over network drivers
and daemons. Currently, SOCK_DGRAM and SOCK_STREAM perform this control,
but these use socket resources. In the case of usersocket in particular,
this is a waste of the device's limited socket resources.
The priorities for finding a network adapter are as follows:
1. if laddr is not ANY, use laddr to find device;
2. if laddr is ANY, and bound index is not 0, use bound index
to find device;
3. if laddr is ANY and no device is bound, use raddr to find
device.
Signed-off-by: zhanghongyu <zhanghongyu@xiaomi.com>
SOCK_CTRL is added to provide special control over network drivers
and daemons. Currently, SOCK_DGRAM and SOCK_STREAM perform this control,
but these use socket resources. In the case of usersocket in particular,
this is a waste of the device's limited socket resources.
1.
net/slip.c:865:29: warning: unused variable ‘priv’ [-Wunused-variable]
865 | FAR struct slip_driver_s *priv =
| ^~~~
net/slip.c: In function ‘slip_rmmac’:
net/slip.c:895:29: warning: unused variable ‘priv’ [-Wunused-variable]
895 | FAR struct slip_driver_s *priv =
| ^~~~
2.
local/local_sendmsg.c: In function ‘local_sendmsg’:
local/local_sendmsg.c:423:18: warning: ‘count’ may be used uninitialized in this function [-Wmaybe-uninitialized]
423 | return count;
| ^~~~~
local/local_sendmsg.c:131:11: warning: ‘i’ may be used uninitialized in this function [-Wmaybe-uninitialized]
131 | while (i-- > 0)
| ~^~
local/local_sendmsg.c:71:7: note: ‘i’ was declared here
71 | int i;
| ^
Signed-off-by: chao an <anchao@xiaomi.com>
1.
ipfrag/ipv4_frag.c: In function ‘ipv4_fragin’:
ipfrag/ipv4_frag.c:184:22: warning: ‘head’ may be used uninitialized in this function [-Wmaybe-uninitialized]
184 | ipv4->len[1] = head->io_pktlen & 0xff;
| ~~~~^~~~~~~~~~~
ipfrag/ipv4_frag.c:123:21: note: ‘head’ was declared here
123 | FAR struct iob_s *head;
| ^~~~
2.
devif/ipv6_input.c: In function ‘ipv6_in’:
devif/ipv6_input.c:60:33: error: ‘TCPIPv6BUF’ undeclared (first use in this function); did you mean ‘UDPIPv6BUF’?
60 | #define PAYLOAD ((FAR uint8_t *)TCPIPv6BUF)
| ^~~~~~~~~~
3.
nat/ipv4_nat.c: In function ‘ipv4_nat_inbound_icmp’:
nat/ipv4_nat.c:67:30: error: ‘TCP_HDRLEN’ undeclared (first use in this function); did you mean ‘UDP_HDRLEN’?
67 | ((proto) == IP_PROTO_TCP ? TCP_HDRLEN : \
| ^~~~~~~~~~
nat/ipv4_nat.c:323:47: note: in expansion of macro ‘L4_HDRLEN’
323 | inner_l4hdrlen = MIN(inner_l4len, L4_HDRLEN(inner->proto));
| ^~~~~~~~~
Signed-off-by: chao an <anchao@xiaomi.com>
Receiving an ACK indicating TCP Window Update will not set ACKDATA flag (because tx_unacked is 0) in our TCP stack. Then this ACK won't let us send anything after receiving it, even if it updates snd_wnd. So we need to check whether we can send data immediately when our snd_wnd is updated (especially from 0), otherwise we will only send next data after timer expiry.
Signed-off-by: Zhe Weng <wengzhe@xiaomi.com>
NuttX kernel should not use the syscall functions, especially after
enabling CONFIG_SCHED_INSTRUMENTATION_SYSCALL, all system functions
will be traced to backend, which will impact system performance.
Signed-off-by: chao an <anchao@xiaomi.com>
Regression by:
| commit 7fce145b30
| Author: chao an <anchao@xiaomi.com>
| Date: Mon Jan 30 21:36:39 2023 +0800
|
| net/devif: check the net device before use
|
| Signed-off-by: chao an <anchao@xiaomi.com>
Signed-off-by: chao an <anchao@xiaomi.com>
Issue:
TCP rx buffer is freed after 4-way handshake with current design.
3 socket's rx buffer might be consumed during ffmpeg switch music procedure,
and this might cause IOB exhausted.
Solution:
free TCP rx buffer immediately in tcp_close to make sure IOB won't be
exhausted.
Signed-off-by: 梁超众 <liangchaozhong@xiaomi.com>
Signed-off-by: chao an <anchao@xiaomi.com>
This reverts commit fbe641a916.
This issue already fixed by below change:
| commit 715785245c
| Author: chao an <anchao@xiaomi.com>
| Date: Mon Jan 16 12:37:44 2023 +0800
|
| net/tcp: fix potential busy loop in tcp_send_buffered.c
|
| 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>
Signed-off-by: chao an <anchao@xiaomi.com>
tcp_input:
If we didn't find an active connection that expected the packet,
If the SYN flag isn't set,
It is an old packet and we send a RST.
conn is NULL when this case
Signed-off-by: zhanghongyu <zhanghongyu@xiaomi.com>
The following build error happens when CONFIG_NET_IPv6 is enabled and CONFIG_NET_UDP is not enabled.
inet/ipv6_setsockopt.c:132:19: error: invalid use of undefined type 'struct udp_conn_s'
132 | conn->flags |= _UDP_FLAG_PKTINFO;
| ^~
inet/ipv6_setsockopt.c:132:30: error: '_UDP_FLAG_PKTINFO' undeclared (first use in this function)
132 | conn->flags |= _UDP_FLAG_PKTINFO;
| ^~~~~~~~~~~~~~~~~
inet/ipv6_setsockopt.c:132:30: note: each undeclared identifier is reported only once for each function it appears in
inet/ipv6_setsockopt.c:136:19: error: invalid use of undefined type 'struct udp_conn_s'
136 | conn->flags &= ~_UDP_FLAG_PKTINFO;
Signed-off-by: 梁超众 <liangchaozhong@xiaomi.com>
When using PIPE connect to a file, ENOTSOCK or ECONNREFUSED should be returned
and when using PIPE connect to invalid pipe name, ENOENT should be returned in libuv
Signed-off-by: yintao <yintao@xiaomi.com>
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>