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>