For datagram unix sockets, the `SO_SNDBUF` value imposes an upper limit on the size of outgoing datagrams.
Note: We don't support to change the buffer size yet, so only add support to getsockopt now.
Refs: https://man7.org/linux/man-pages/man7/unix.7.html
Signed-off-by: Zhe Weng <wengzhe@xiaomi.com>
1. Both IPv6 addresses and net masks should be stored in network byte
order
2. Fix last 2 bytes of mask applying (although it seldom triggers)
Signed-off-by: Zhe Weng <wengzhe@xiaomi.com>
Allows setting the advertised route lifetime, and also to set
it to 0 for advertising only the prefix.
From RFC4861:
A router might want to send Router Advertisements without advertising
itself as a default router. For instance, a router might advertise
prefixes for stateless address autoconfiguration while not wishing to
forward packets. Such a router sets the Router Lifetime field in
outgoing advertisements to zero.
==1729315==ERROR: AddressSanitizer: heap-use-after-free on address 0xf0501d60 at pc 0x032ffe43 bp 0xef4ed158 sp 0xef4ed148
READ of size 2 at 0xf0501d60 thread T0
#0 0x32ffe42 in nxsem_wait semaphore/sem_wait.c:94
#1 0x3548cf5 in _net_timedwait utils/net_lock.c:97
#2 0x3548f48 in net_sem_timedwait utils/net_lock.c:236
#3 0x3548f8c in net_sem_wait utils/net_lock.c:318
#4 0x350124d in local_accept local/local_accept.c:246
#5 0x3492719 in psock_accept socket/accept.c:149
#6 0x3492bcc in accept4 socket/accept.c:280
#7 0x662dc04 in accept net/lib_accept.c:50
#8 0x55c81ab in kvdb_loop kvdb/server.c:415
#9 0x55c860a in kvdbd_main kvdb/server.c:458
#10 0x33d968b in nxtask_startup sched/task_startup.c:70
#11 0x32ec039 in nxtask_start task/task_start.c:134
#12 0x34109be in pre_start sim/sim_initialstate.c:52
0xf0501d60 is located 288 bytes inside of 420-byte region [0xf0501c40,0xf0501de4)
freed by thread T0 here:
#0 0xf7aa6a3f in __interceptor_free ../../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:127
#1 0x73aa06e in host_free sim/posix/sim_hostmemory.c:192
#2 0x34131d6 in mm_free sim/sim_heap.c:230
#3 0x3409388 in free umm_heap/umm_free.c:49
#4 0x35631f3 in local_free local/local_conn.c:225
#5 0x3563f75 in local_release local/local_release.c:129
#6 0x34f5a32 in local_close local/local_sockif.c:785
#7 0x3496ee8 in psock_close socket/net_close.c:102
#8 0x36500bc in sock_file_close socket/socket.c:115
#9 0x3635f6c in file_close vfs/fs_close.c:74
#10 0x3632439 in nx_close_from_tcb inode/fs_files.c:670
#11 0x36324f3 in nx_close inode/fs_files.c:697
#12 0x3632557 in close inode/fs_files.c:735
#13 0x55be289 in property_set_ kvdb/client.c:210
#14 0x55c0309 in property_set_int32_ kvdb/common.c:226
#15 0x55c03f5 in property_set_int32_oneway kvdb/common.c:236
Signed-off-by: ligd <liguiding1@xiaomi.com>
Changed implementation to use the Kernel network stack when
usrsock daemon returns an error.
This change allows the Kernel network stack to be used instead
of UsrSock when opening a Socket at a time when a VPN configured
with TUN is enabled.
Some use cases, such as VPN, use both the device's network
stack with the Usrsock daemon and the Kernel's network stack.
Therefore, remove NET_TCP_NO_STACK/NET_UDP_NO_STACK select
from Usrsock's Kconfig.
The previous iob_trimhead added dev->iob->io_offset, so if the
input frame is not merged into the ofo segment, we need to reset
dev->iob->io_offset so that the subsequent tcp_send can properly
assemble packets.
Signed-off-by: zhanghongyu <zhanghongyu@xiaomi.com>
We may just free some TCP connections before monitor stopped, e.g.
sacrificie a TCP conn in `tcp_alloc` will just call `tcp_free` and reuse
the connection. But we noticed that the TCP monitor is not released in
`tcp_free` because it is mounted on `conn->connevents` instead of
`conn->sconn.list` while `tcp_free` only release the latter.
Signed-off-by: Zhe Weng <wengzhe@xiaomi.com>
with nonblocking sockets, POLLOUT is returned when the application
calls poll even if the send buffer is full
Signed-off-by: zhanghongyu <zhanghongyu@xiaomi.com>
Normally, `SO_ERROR` for disconn events will be set by `tcp_poll_eventhandler`, but when the socket is closed before poll, we should also set the `SO_ERROR`.
On Linux, `tcp_poll` returns `EPOLLERR` event when `sk->sk_err` has value but doesn't let `poll` fail (doesn't set `errno`). https://github.com/torvalds/linux/blob/v6.5/net/ipv4/tcp.c#L594-L596
Note: `sk->sk_err` can be get by socket option `SO_ERROR` on Linux, so `POLLERR` will always be together with `SO_ERROR`.
Common libs like curl may try to read `SO_ERROR` on `POLLERR`.
Signed-off-by: Zhe Weng <wengzhe@xiaomi.com>
Summary
The following compilation error occurs after configuring CONFIG_DEBUG_OPTLEVEL="-O3"
CC: local/local_fifo.c In file included from local/local_fifo.c:25:
In function 'local_format_name',
inlined from 'local_cs_name' at local/local_fifo.c:101:3,
inlined from 'local_create_fifos' at local/local_fifo.c:431:3:
local/local_fifo.c:84:16: error: '%x' directive output may be truncated writing between 1 and 8 bytes into a region of size between 5 and 112 [-Werror=format-truncation=]
84 | CONFIG_NET_LOCAL_VFS_PATH "/%s%s%" PRIx32,
| ^~~~~~~~~~~~~~~~~~~~~~~~~
Signed-off-by: wangming9 <wangming9@xiaomi.com>
conn->sendsize is used in rpmsg_socket_ept_cb() and
rpmsg_socket_connect_internal(), the connected event may be missed
as stated below:
1. in rpmsg_socket_connect_internal(), judge conn->sendsize == 0
and prepare to wait sendsem;
2. interrupt by rptun thread, rpmsg_socket_ept_cb() is called to
update conn->sendsize and post the sendsem, but the no one wait
rx sem yet, so not post (see rpmsg_socket_post());
3. return to rpmsg_socket_connect_internal() to wait the sendsem, but
has miss the connected event.
So add recvlock in rpmsg_socket_connect_internal() also.
Signed-off-by: Bowen Wang <wangbowen6@xiaomi.com>
After the sack is enabled and the ofosegs has gap, tcp cannot update the
tx_unacked, so the peer received packets are retransmitted after the
timer timeout.
So update tx_unacked first.
Signed-off-by: zhanghongyu <zhanghongyu@xiaomi.com>
Non-blocking sockets are almost never in the connected state when app try to
get result of connect success through poll, to avoid confusion because of
this error print, so downgrade the print level to warning.
Signed-off-by: zhanghongyu <zhanghongyu@xiaomi.com>
refer to https://man7.org/linux/man-pages/man7/ip.7.html
IP_MULTICAST_IF (since Linux 1.2)
Set the local device for a multicast socket. The argument
for setsockopt(2) is an ip_mreqn or (since Linux 3.5)
ip_mreq structure similar to IP_ADD_MEMBERSHIP, or an
in_addr structure. (The kernel determines which structure
is being passed based on the size passed in optlen.) For
getsockopt(2), the argument is an in_addr structure.
refer to https://man7.org/linux/man-pages/man7/ipv6.7.html
IPV6_MULTICAST_IF
Set the device for outgoing multicast packets on the
socket. This is allowed only for SOCK_DGRAM and SOCK_RAW
socket. The argument is a pointer to an interface index
(see netdevice(7)) in an integer.
testcase1:
TEST_IMPL(udp_multicast_interface) {
/* TODO(gengjiawen): Fix test on QEMU. */
RETURN_SKIP("Test does not currently work in QEMU");
int r;
uv_udp_send_t req;
uv_buf_t buf;
struct sockaddr_in addr;
struct sockaddr_in baddr;
close_cb_called = 0;
sv_send_cb_called = 0;
ASSERT(0 == uv_ip4_addr("239.255.0.1", TEST_PORT, &addr));
r = uv_udp_init(uv_default_loop(), &server);
ASSERT(r == 0);
ASSERT(0 == uv_ip4_addr("0.0.0.0", 0, &baddr));
r = uv_udp_bind(&server, (const struct sockaddr*)&baddr, 0);
ASSERT(r == 0);
r = uv_udp_set_multicast_interface(&server, "0.0.0.0");
ASSERT(r == 0);
/* server sends "PING" */
buf = uv_buf_init("PING", 4);
r = uv_udp_send(&req,
&server,
&buf,
1,
(const struct sockaddr*)&addr,
sv_send_cb);
ASSERT(r == 0);
ASSERT(close_cb_called == 0);
ASSERT(sv_send_cb_called == 0);
/* run the loop till all events are processed */
uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(sv_send_cb_called == 1);
ASSERT(close_cb_called == 1);
ASSERT(client.send_queue_size == 0);
ASSERT(server.send_queue_size == 0);
MAKE_VALGRIND_HAPPY();
return 0;
}
testcase2:
TEST_IMPL(udp_multicast_interface6) {
/* TODO(gengjiawen): Fix test on QEMU. */
RETURN_SKIP("Test does not currently work in QEMU");
int r;
uv_udp_send_t req;
uv_buf_t buf;
struct sockaddr_in6 addr;
struct sockaddr_in6 baddr;
if (!can_ipv6())
RETURN_SKIP("IPv6 not supported");
close_cb_called = 0;
sv_send_cb_called = 0;
ASSERT(0 == uv_ip6_addr("::1", TEST_PORT, &addr));
r = uv_udp_init(uv_default_loop(), &server);
ASSERT(r == 0);
ASSERT(0 == uv_ip6_addr("::", 0, &baddr));
r = uv_udp_bind(&server, (const struct sockaddr*)&baddr, 0);
ASSERT(r == 0);
r = uv_udp_set_multicast_interface(&server, "::1%lo0");
r = uv_udp_set_multicast_interface(&server, NULL);
ASSERT(r == 0);
/* server sends "PING" */
buf = uv_buf_init("PING", 4);
r = uv_udp_send(&req,
&server,
&buf,
1,
(const struct sockaddr*)&addr,
sv_send_cb);
ASSERT(r == 0);
ASSERT(close_cb_called == 0);
ASSERT(sv_send_cb_called == 0);
/* run the loop till all events are processed */
uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(sv_send_cb_called == 1);
ASSERT(close_cb_called == 1);
MAKE_VALGRIND_HAPPY();
return 0;
}
Signed-off-by: wangchen <wangchen41@xiaomi.com>
Using the macro places the buffers into .data section which means they
will consume the full buffer size of flash / read only memory as well.
Place the buffers into .bss to avoid this case.
Use PRIx64 which defines the width correctly regardless or architecture.
Fixes build error:
rpmsg/rpmsg_sockif.c:610:57: error: format '%llx' expects argument of type 'long long unsigned int', but argument 4 has type 'uint64_t' {aka 'long unsigned int'} [-Werror=format=]
610 | snprintf(conn->nameid, sizeof(conn->nameid), ":%llx", g_rpmsg_id++);
| ~~~^ ~~~~~~~~~~~~
| | |
| | uint64_t {aka long unsigned int}
| long long unsigned int
| %lx
- Fix `ip6_map_ipv4addr` and `ip6_get_ipv4addr` macro to work under
different endianness.
- Use `iob_reserve` instead of `iob_trimhead` in `udp_datahandler`.
- Because we may set `sockaddr_in6` into IPv4 header, which causes
`offset` become negative. `iob_reserve` can hold this case while
`iob_trimhead` cannot.
- Select IPv4 domain in send case.
Signed-off-by: Zhe Weng <wengzhe@xiaomi.com>
When do poll operation and the tcp connection state is TCP_ALLOCATED, eventset(POLLERR|POLLHUP) is return, causing the libuv poll_multiple_handles to fail.
Verification: Use the libuv test case ` uv_run_tests poll_multiple_handles`.
Signed-off-by: liqinhui <liqinhui@xiaomi.com>
Some programs use EAGAIN to determine whether all data has been read,
so cancel the error print when the error code is EAGAIN.
Signed-off-by: zhanghongyu <zhanghongyu@xiaomi.com>
Example of /proc/PID/group/fd in this case:
FD OFLAGS TYPE POS PATH
17 67 9 0 socket:[domain 16, type 2, proto 0]
Signed-off-by: Zhe Weng <wengzhe@xiaomi.com>
Verification:
Write a packet, the length is bigger than CONFIG_DEV_FIFO_SIZE.
The return value should be -1, and the errno is EMSGSIZE.
Signed-off-by: liqinhui <liqinhui@xiaomi.com>
Verifiction:
Write a bigger packet and read the packet using a smaller buffer.
The return length of reading should be the length of smaller buffer.
Signed-off-by: liqinhui <liqinhui@xiaomi.com>
The error log is as follows:
tcp/tcp_send_buffered.c:376:57: runtime error: member access within misaligned
address 0x10075942 for type 'struct tcp_sack_s', which requires 4 byte alignment
Signed-off-by: liqinhui <liqinhui@xiaomi.com>
The netdev of link-local address cannot be auto decided, and the link-local address should always be reguarded as address on local network.
The problem we met:
When using `icmpv6_autoconfig` with multiple netdev, the `icmpv6_neighbor` may take out wrong netdev with ip address already set, then it may send solicitation with wrong address (`dev->d_ipv6draddr`) on wrong device, and regard the link-local address as conflict (because `dev->d_ipv6draddr` exists on this network).
Signed-off-by: Zhe Weng <wengzhe@xiaomi.com>
The memory allocated with strdup and asprintf is done via lib_malloc
so we need to use lib_free to deallocate memory otherwise the assertion
"Free memory from the wrong heap" is hit with flat mode and user separated
heap enabled mode.
Signed-off-by: Petro Karashchenko <petro.karashchenko@gmail.com>
net_lock/unlock is a big lock and repleace it to internal pool lock
to avoid the priority inversion problem.
Signed-off-by: zhangyuan21 <zhangyuan21@xiaomi.com>
Signed-off-by: Bowen Wang <wangbowen6@xiaomi.com>
By:
1. Take out net_ip_binding_laddr/raddr macro
2. INET6_ADDRSTRLEN is long enough for all address buffer and no need to
add 0 to the end of buffer since inet_ntop will do so
Signed-off-by: Zhe Weng <wengzhe@xiaomi.com>
In tcp protocol, if no ports are bound, Add random ports during the listening phase
libuvtestcase:
TEST_IMPL(tcp_listen_without_bind) {
int r;
uv_tcp_t server;
r = uv_tcp_init(uv_default_loop(), &server);
ASSERT(r == 0);
r = uv_listen((uv_stream_t*)&server, 128, NULL);
ASSERT(r == 0);
MAKE_VALGRIND_HAPPY();
return 0;
}
Signed-off-by: wangchen <wangchen41@xiaomi.com>
CC: libssh/src/auth.c
1ipfrag/ipv4_frag.c: In function 'ipv4_fragout':
ipfrag/ipv4_frag.c:224:7: error: 'ref' may be used uninitialized in this function [-Werror-maybe-uninitialized]
224 | lmemcpy(ipv4, ref, iphdrlen);
ipfrag/ipv4_frag.c:364:26: note: 'ref' was declared here
364 | FAR struct ipv4_hdr_s *ref;
CC: tls/task initinfo c
Signed-off-by: wangyingdong <wangyingdong@xiaomi.com>
We have IPV6_UNICAST_HOPS and IPV6_MULTICAST_HOPS in ipv6_setsockopt,
but only IP_MULTICAST_TTL in ipv4_setsockopt. So add IP_TTL support.
Signed-off-by: Zhe Weng <wengzhe@xiaomi.com>
When using IOB queue to store readahead data, we use one IOB for each
UDP packet. Then if the packets are very small, like 10Bytes per packet,
we'll use ~1600 IOBs just for 16KB recv buffer size, which is wasteful
and dangerous. So change conn->readahead to a single IOB chain like TCP.
Benefits:
- Using memory and IOBs more efficiently (small packets are common in
UDP)
Side effects:
- UDP recv buffer size may count the overhead
- A little bit drop in performance (<1%, more seek & copy)
Signed-off-by: Zhe Weng <wengzhe@xiaomi.com>
if client is a noblocking socket, user can do close when server has not yet
invoke accept interface, so we need remove this socket from server.lc_waiters.
avoid server socket access the freed memory.
==936564==ERROR: AddressSanitizer: heap-use-after-free on address 0xf23071c8 at pc 0x58eaac3b bp 0xf0b9e218 sp 0xf0b9e208
READ of size 4 at 0xf23071c8 thread T0
#0 0x58eaac3a in dq_remfirst queue/dq_remfirst.c:45
#1 0x58fd1efe in local_accept local/local_accept.c:141
#2 0x58f66df6 in psock_accept socket/accept.c:149
#3 0x58f672a4 in accept4 socket/accept.c:280
#4 0x5be9ee0c in accept net/lib_accept.c:50
#5 0x592d6a5d in uv__accept libuv/src/unix/core.c:502
#6 0x5930d83b in uv__server_io libuv/src/unix/stream.c:550
#7 0x592efbde in uv__io_poll libuv/src/unix/posix-poll.c:335
#8 0x592d649a in uv_run libuv/src/unix/core.c:387
#9 0x5a7180f7 in service_schedule_loop service/common/service_loop.c:146
#10 0x591f300b in pthread_startup pthread/pthread_create.c:59
#11 0x5be8134f in pthread_start pthread/pthread_create.c:139
#12 0x58ee2762 in pre_start sim/sim_initialstate.c:53
Signed-off-by: zhanghongyu <zhanghongyu@xiaomi.com>
Add the proccessing logic of udp socketpair, and modify the
logic of sending and receiving for udp socketpair.
Verification:
- Use the socketpair interface to create a pair of local udp sockets,
and perform read and write operations.
Signed-off-by: liqinhui <liqinhui@xiaomi.com>
In order to support the compilation of third-party library, we encounter
some situations where the macro is not defined, refer to the common
implementation of other systems and add relevant definitions.
Signed-off-by: zhanghongyu <zhanghongyu@xiaomi.com>
1. Update all CMakeLists.txt to adapt to new layout
2. Fix cmake build break
3. Update all new file license
4. Fully compatible with current compilation environment(use configure.sh or cmake as you choose)
------------------
How to test
From within nuttx/. Configure:
cmake -B build -DBOARD_CONFIG=sim/nsh -GNinja
cmake -B build -DBOARD_CONFIG=sim:nsh -GNinja
cmake -B build -DBOARD_CONFIG=sabre-6quad/smp -GNinja
cmake -B build -DBOARD_CONFIG=lm3s6965-ek/qemu-flat -GNinja
(or full path in custom board) :
cmake -B build -DBOARD_CONFIG=$PWD/boards/sim/sim/sim/configs/nsh -GNinja
This uses ninja generator (install with sudo apt install ninja-build). To build:
$ cmake --build build
menuconfig:
$ cmake --build build -t menuconfig
--------------------------
2. cmake/build: reformat the cmake style by cmake-format
https://github.com/cheshirekow/cmake_format
$ pip install cmakelang
$ for i in `find -name CMakeLists.txt`;do cmake-format $i -o $i;done
$ for i in `find -name *\.cmake`;do cmake-format $i -o $i;done
Co-authored-by: Matias N <matias@protobits.dev>
Signed-off-by: chao an <anchao@xiaomi.com>
In file included from local/local_fifo.c:25:
In function ‘local_format_name’,
inlined from ‘local_hd_name’ at local/local_fifo.c:132:3,
inlined from ‘local_open_receiver’ at local/local_fifo.c:661:3:
local/local_fifo.c:77:16: warning: ‘%s’ directive output may be truncated writing up to 107 bytes into a region of size 100 [-Wformat-truncation=]
77 | CONFIG_NET_LOCAL_VFS_PATH "/%s%s", inpath, suffix);
| ^~~~~~~~~~~~~~~~~~~~~~~~~
local/local_fifo.c: In function ‘local_open_receiver’:
local/local_fifo.c:82:44: note: format string is defined here
82 | CONFIG_NET_LOCAL_VFS_PATH "/%s%s%" PRIx32,
| ^~
In function ‘local_format_name’,
inlined from ‘local_hd_name’ at local/local_fifo.c:132:3,
inlined from ‘local_open_receiver’ at local/local_fifo.c:661:3:
local/local_fifo.c:76:7: note: ‘snprintf’ output between 12 and 119 bytes into a destination of size 109
76 | snprintf(outpath, LOCAL_FULLPATH_LEN - 1,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
77 | CONFIG_NET_LOCAL_VFS_PATH "/%s%s", inpath, suffix);
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Signed-off-by: chao an <anchao@xiaomi.com>
There're some apps trying to set too large SO_SNDBUF and SO_RCVBUF, which may use all IOBs in one socket and block all other network traffic.
Note:
Linux silently limits SO_SNDBUF to be less than `sysctl_wmem_max`, so we can also do this limit without returning any error.
Signed-off-by: Zhe Weng <wengzhe@xiaomi.com>
The udp connection structure contains the field, "domain", which defines which address family it belongs to. Prior to this change, this field was only populated correctly if IPv4 and IPv6 was enabled. As a result, packet information was not processed in udp_recvpktinfo, as expected when the appropriate socket option was enabled.
There is no control over whether a valid index is input when user use
ioctl to get netdev information, so removing this assertion will allow
ENODEV to be returned.
Signed-off-by: zhanghongyu <zhanghongyu@xiaomi.com>
Updated alt1250 driver with regarding to the following changes.
- Add LTE hibernation feature
- Split source code per module
- Some refactoring
- Some bug fixes
ICMP's conn->dev is changing in icmp_sendmsg, when sending to different
address, or when error occurs (like NETDEV_DOWN). Then the poll callback
cannot be dropped from previous dev in free, because the dev is wrong.
So add dev to struct icmp_poll_s just like struct udp_poll_s.
Signed-off-by: Zhe Weng <wengzhe@xiaomi.com>
When a task needs to send data, a callback is allocated and the
transmission is happening in a worker task through devif_send.
Synchronization between the two tasks (sender & worker) is
achieved by a semaphore.
If devif_send fails, this semaphore was never posted, leaving
the sending task blocked indefinitely. This commit fixes this
by checking the return code of netif_send, and posting this
semaphore in case of failure.
Polling then stops, and execution is resumed on the sending
task.
warning: (NET_SOLINGER) selects NET_UDP_NOTIFIER which has unmet direct dependencies
(NET && NET_UDP && !NET_UDP_NO_STACK && SCHED_WORKQUEUE)
Signed-off-by: chao an <anchao@xiaomi.com>
Problem:
When tcp_close_work starts to run in LPWORK, if another event comes and
calls tcp_free before tcp_close_work takes net_lock, the tcp_free will
be called twice and cause double free.
Signed-off-by: Zhe Weng <wengzhe@xiaomi.com>
This is a refactored version of the SLIP network driver. Updates
include:
1. The original design started two kernel threads per SLIP device.
The refactored version uses file_poll to essentially be driven
by the UART RX and TX interrupts and pushes work to the low
priority work queue.
2. The SLIP byte un-/stuffing is more efficient now, using memcpy
instead of handling each byte individually.
3. The switch of the old SLIP driver to IOBs caused buffer overwrites
if packets were sent that would not fit into a single IOB. This is
fixed now.
Signed-off-by: Michael Jung <michael.jung@secore.ly>
When do socket bind, if the connection domain is not equal to the bound address type, this will cause the stack-buffer-overflow.
Signed-off-by: liqinhui <liqinhui@xiaomi.com>
- NewReno congestion control algorithm is used to solve the problem
of network congestion breakdown. NewReno congestion control includes
slow start, collision avoidance, fast retransmission, and fast
recovery. The implementation refers to RFC6582 and RFC5681.
- In addition, we optimize the congestion algorithm. In the conflict
avoidance stage, the maximum congestion window max_cwnd is used to
limit the excessive growth of cwnd and prevent network jitter
caused by congestion. Maximum congestion window max_cwnd is updated
with the current congestion window cwnd and the update weight is
0.875 when an RTO timeout occurs.
Signed-off-by: liqinhui <liqinhui@xiaomi.com>
recvmsg() will incorrectly return 0 if the count of sema before waiting is greater than 0,
This commit will reinitialize the sema count before waiting:
1181 static ssize_t rpmsg_socket_recvmsg(FAR struct socket *psock,
1182 FAR struct msghdr *msg, int flags)
1183 {
...
1255 ret = net_sem_timedwait(&conn->recvsem,
1256 _SO_TIMEOUT(conn->sconn.s_rcvtimeo)); // recvsem.sem_count == 1; return 0
...
1264 if (!conn->recvdata) // recvdata not consumed; goto else
1265 {
1266 ret = conn->recvlen;
1267 }
1268 else
1269 {
1270 conn->recvdata = NULL;
1271 }
...
1282 return ret; // BUGON! incorrectly return 0 to user
1283 }
Signed-off-by: chao an <anchao@xiaomi.com>
Added simple support for IPV6_UNICAST_HOPS and IPV6_UNICAST_HOPS, the application can configure the ttl parameters of the socket in user mode.
Signed-off-by: zhanghongyu <zhanghongyu@xiaomi.com>
RFC 1191
When a router is unable to forward a datagram because it exceeds the
MTU of the next-hop network and its Don't Fragment bit is set, the
router is required to return an ICMP Destination Unreachable message
to the source of the datagram, with the Code indicating
"fragmentation needed and DF set". To support the Path MTU Discovery
technique specified in this memo, the router MUST include the MTU of
that next-hop network in the low-order 16 bits of the ICMP header
field that is labelled "unused" in the ICMP specification [7]. The
high-order 16 bits remain unused, and MUST be set to zero. Thus, the
message has the following format:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Type = 3 | Code = 4 | Checksum |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| unused = 0 | Next-Hop MTU |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Internet Header + 64 bits of Original Datagram Data |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
RFC 1185
Packet Too Big Message
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Type | Code | Checksum |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| MTU |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| As much of invoking packet |
+ as will fit without the ICMPv6 packet +
| exceeding 576 octets |
IPv6 Fields:
Destination Address
Copied from the Source Address field of the invoking
packet.
ICMPv6 Fields:
Type 2
Code 0
MTU The Maximum Transmission Unit of the next-hop link.
Description
A Packet Too Big MUST be sent by a router in response to a packet
that it cannot forward because the packet is larger than the MTU of
the outgoing link. The information in this message is used as part
of the Path MTU Discovery process [RFC-1191].
Signed-off-by: wangchen <wangchen41@xiaomi.com>
Commit 4d6a8663fa made pipes and
named pipes block when opening for O_WRONLY or O_RDONLY. Local
sockets, however, require `local_open_client_tx` to be non-blocking
to enable the server side to prevent the server side from blocking.
If set otherwise, it would deadly block. This commit sets the FIFO
as non-blocking temporarily, open the TX side and, if originally
blocking - restores it to that state.
added IPV6_RECVHOPLIMIT support so that fd of SOCK_RAW ICMPV6 can obtain ttl
information, some network related tools use this feature.
Signed-off-by: zhanghongyu <zhanghongyu@xiaomi.com>
utils/net_cmsg.c: In function 'cmsg_append':
utils/net_cmsg.c:82:23: error: pointer of type 'void *' used in arithmetic [-Werror=pointer-arith]
82 | msg->msg_control += cmsgspace;
| ^~
cc1: all warnings being treated as errors
Using void pointers in arithmetic operations is a GCC extension, it is
not supported by the standard. Because what is the size of a void ?
move the IPPROTO_IP/IPPROTO_IPV6 flag into the socket_conn_s structure to
make it more than just control udp.
Signed-off-by: zhanghongyu <zhanghongyu@xiaomi.com>
The third-party library we are porting will send and receive ICMPV6 messages
(router_advert / router_solicit / neighbor_advert / neighbor_solicit etc.)
from the user mode itself, so we added the SOCK_RAW related implementation
for ICMPV6.
Signed-off-by: zhanghongyu <zhanghongyu@xiaomi.com>
since iob offload, ipvx_dev_forward will remove d_iob, if there are multiple
devices, d_iob will be NULL when dev_forward is entered second time. and the
device that receives the packet cannot process the packet after forwarding it
so the iob copy is added.
Signed-off-by: zhanghongyu <zhanghongyu@xiaomi.com>
- Before IOB offload, srcaddr / src_addr_size / ifindex are written into
IOB by iob_trycopyin, so io_pktlen > 0 is always true, this check is
correct at that time. (It won't fail with zero-length UDP datagram.)
- After IOB offload, srcaddr / src_addr_size / ifindex are written into
offset 0, without increasing io_pktlen. So this check will fail with
zero-length UDP datagram now.
- We need to support zero-length UDP datagram and this check is
unnecessary at this point.
- https://stackoverflow.com/questions/5307031/how-to-detect-receipt-of-a-0-length-udp-datagram
- https://github.com/apache/nuttx/blob/nuttx-12.1.0/net/udp/udp_callback.c#L214
Signed-off-by: Zhe Weng <wengzhe@xiaomi.com>
adapts to third-party code compilation. in the process of porting ConnMan,
we encounter some situations where the structure is not defined, or the
returned data types do not match the expectations. Refer to the common
implementation of other systems and add relevant definitions.
Signed-off-by: zhanghongyu <zhanghongyu@xiaomi.com>
If TCP_FIN is received before the user calls accept, the later accept will
report an error, then the previously received data cannot be read.
operation flow:
tcp_server_listen -> tcp_client_connect -> tcp_client_send ->
tcp_client_close -> tcp_server_accept(fix this error) -> tcp_server_recv
Signed-off-by: zhanghongyu <zhanghongyu@xiaomi.com>
adapts to third-party code compilation. in the process of porting ConnMan,
multiple control message options are enabled, such as IPV6_RECVPKTINFO and
IPV6_RECVHOPLIMIT, so I changed the Filling implementation of the control
message.
Signed-off-by: zhanghongyu <zhanghongyu@xiaomi.com>
Timestamp location in can message has changed,
In the original logic timestamp is saved at the end of the data segment:
io_data
-------------------------------------------------
| CAN message | Time Stamp |
-------------------------------------------------
|<--------------- io_len ---------------->|
In the new structure timestamps will reuse NET_LL_GUARDSIZE to isolate CAN messages:
io_data io_offset
-------------------------------------------------
| Time Stamp | CAN message |
-------------------------------------------------
|<-------- io_len --------->|
This PR will:
1. Increase NET_LL_GUARDSIZE to 16 (sizeof(struct timeval)) if NET_CAN && NET_TIMESTAMP are enabled
2. Apply timestamp to adapt to the new structure
Signed-off-by: chao an <anchao@xiaomi.com>
We have a case that an http server gives out-of-ordered ACKs, and NuttX client makes `ofoseg`s with length 0, trying to rebuild / put them into `ofosegs` array, which is not intended (no available data and should be skipped). This breaks later logic and finally crashed in `tcp_ofoseg_bufsize` (`ofosegs[i].data` is `NULL`, which should never happen in normal logic).
Note:
- `iob_trimhead` won't return `NULL` when it's applying on normal IOB.
- Keep `dev->d_iob == NULL` to avoid `iob_trimhead` changed.
- `iob_free_chain` will do nothing when applied to `NULL`.
Signed-off-by: Zhe Weng <wengzhe@xiaomi.com>
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.