Bug Description:
The original code always used conn->pollinfo[0] (the first element) to store
new poll setup context, regardless of whether that slot was already in use.
This caused multiple poll operations on the same CAN socket to overwrite each
other's context, leading to:
- Lost poll waiters when multiple threads poll the same socket
- Memory corruption in pollfd structures
- Undefined behavior when poll_teardown tries to clean up
Root Cause:
The code directly assigned `info = conn->pollinfo` without checking if the
slot was available, effectively always using pollinfo[0]. When a second
thread called poll() on the same socket, it would overwrite the first
thread's poll context.
Solution:
1. Initialize info to NULL instead of conn->pollinfo
2. Before setting up poll, iterate through all CONFIG_NET_CAN_NPOLLWAITERS
slots to find the first free slot (where fds == NULL)
3. Return -EBUSY if no free slots are available
4. During teardown, properly mark the slot as free by setting fds = NULL
Additional Changes:
- Added CONFIG_NET_CAN_NPOLLWAITERS Kconfig option (default 4) to make the
maximum number of concurrent poll waiters configurable
- Changed hardcoded array size from 4 to CONFIG_NET_CAN_NPOLLWAITERS
- Fixed lock ordering in teardown to ensure fds is cleared before unlock
Impact:
- Enables multiple threads to safely poll the same CAN socket concurrently
- Prevents poll context corruption in multi-threaded applications
- Provides proper resource management with -EBUSY when all slots are full
- Makes the number of supported concurrent pollers configurable per use case
Signed-off-by: dongjiuzhu1 <dongjiuzhu1@xiaomi.com>
This commit removes unnecessary file duplication and memory allocation when
passing file descriptors through Unix domain sockets, leveraging the new
filep reference counting framework.
Background:
With the new filep framework, file structures (filep) can be safely shared
across processes using reference counting. When passing file descriptors
through SCM_RIGHTS control messages on local sockets, the previous
implementation unnecessarily duplicated the entire file structure.
Changes:
1. In local_sendctl() (sender side):
- Removed allocation of filep2 structure (kmm_zalloc)
- Removed file_dup2() call that copied the file structure
- Now directly stores the original filep with its reference count
- Eliminates memory allocation overhead and potential failure points
2. In local_recvctl() (receiver side):
- Changed from file_close() + kmm_free() to file_put()
- file_put() properly decrements reference count and handles cleanup
- Consistent with the new filep reference counting model
3. In local_freectl() (cleanup on error):
- Changed from file_close() + kmm_free() to file_put()
- Ensures proper reference count management during error paths
Technical Details:
The new filep framework ensures that:
- Multiple file descriptors across different processes can reference the
same underlying filep structure safely
- Reference counting (via file_get/file_put) manages lifetime correctly
- The underlying file object is only released when all references are gone
This change is safe because file_dup() in the receiver already calls
file_get() internally to increment the reference count for the new fd,
so the filep remains valid after the sender calls file_put().
Signed-off-by: dongjiuzhu1 <dongjiuzhu1@xiaomi.com>
According rfc793 p69, from state SYN-RECEIVED to state TIME-WAIT, if the incoming segment is not acceptable, an acknowledgment should be sent in reply (unless the RST bit is set):
<SEQ=SND.NXT><ACK=RCV.NXT><CTL=ACK>
Signed-off-by: wenquan1 <wenquan1@xiaomi.com>
According rfc793 p69, In SYN-RCVD state, if the incoming segment is not acceptable, an acknowledgment should be sent in reply (unless the RST bit is set):
<SEQ=SND.NXT><ACK=RCV.NXT><CTL=ACK>
Signed-off-by: wenquan1 <wenquan1@xiaomi.com>
According to RFC793, the flags of TCP reply packet should be as follows:
1. `RST` if flags of request packet has `ACK`
2. `RST|ACK` if flags of request packet has no `ACK`, at the same time, the sequence should be set to zero.
Signed-off-by: wenquan1 <wenquan1@xiaomi.com>
if update is called after tx, in an environment with very low
latency (such as a simulator), the received arp_response will
be overwritten by update (NULL), resulting in arp learning success,
but the packets are always not sent correctly and are converted
into arp packets.
Signed-off-by: zhanghongyu <zhanghongyu@xiaomi.com>
Wait a fixed number of milliseconds before sending a retry ARP request for the same destination if the IP address mapping is not exist to prevent ARP flooding
Signed-off-by: wenquan1 <wenquan1@xiaomi.com>
when a arp response reached, it should notify all tasks waiting the address. if the address is unreachable, do not send arp request to prevent arp flooding.
Signed-off-by: wenquan1 <wenquan1@xiaomi.com>
in multi-core cpu, tcp_free and tcp_timer_expiry->tcp_timer will work in parallel, after tcp_free call work_cancle, tcp->timer will call tcp_update_timer to re-add work to worker queue, then tcp_free free conn, in this condition, it will result use after free.
Signed-off-by: wenquan1 <wenquan1@xiaomi.com>
According RFC793,p72~p73 In states from ESTABLISHED to LASTACK:"If the ACK acks something not yet sent (SEG.ACK > SND.NXT) then send an ACK, drop the segment, and return"
Signed-off-by: wenquan1 <wenquan1@xiaomi.com>
in the current process, if tcpstate is at TCP_FIN_WAIT_1, TCP_CLOSING,
and TCP_LAST_ACK, and the peer does not reply TCP_ACK, it will be
retransmitted permanently. to avoid continuous occupation of resources,
now when the retransmission equals TCP_MAXRTX, a reset message will be
sent and the conn resources will be reclaimed in tcp_close_work.
Signed-off-by: zhanghongyu <zhanghongyu@xiaomi.com>
since we added TCP_TXCLOSE and TCP_RXCLOSE, only RST-like exception
flows now trigger TCP_CLOSE events, so replace the remaining
TCP_CLOSE with TCP_ABORT.
Signed-off-by: zhanghongyu <zhanghongyu@xiaomi.com>
notify the local waiting recv process; otherwise, after the peer TX
is closed, the wait of the recv process will continue to wait.
Signed-off-by: zhanghongyu <zhanghongyu@xiaomi.com>
shutdown should send TCP_FIN packet.
close should send TCP_RST packet when the data in readahead has not been
read and NEW_DATA has arrived.
send TCP_FIN packet when in other cases.
Signed-off-by: zhanghongyu <zhanghongyu@xiaomi.com>
after the listener fd is closed, the half-open connections associated
with the listener are not reclaimed. According to the protocol standard,
they should be reclaimed in a timely manner.
Signed-off-by: zhanghongyu <zhanghongyu@xiaomi.com>
According RFC1122 3.2.2.1, A host SHOULD generate Destination Unreachable messages with code: 2(Protocol Unreachable), when the designated transport protocol is not supported.
Signed-off-by: wenquan1 <wenquan1@xiaomi.com>
UDP and PKT will hold the dev lock and conn lock when calling back the
protocol stack from the network dirver. At this time, if the poll_notify
notifies usrsock_server and executes poll_teardown, a conn double lock
will appear. so we changed the lock to a recursive lock
sched_dumpstack
/home/work/ssd1/workspace/MiRTOS-062-dev-system-CI/nuttx/Libs/libc/sched/sched_dumpstack.c:71
__assert
/home/work/ssd1/workspace/MiRTOS-062-dev-system-CI/nuttx/libs/libc/assert/lib_assert.c:49
nxsem_wait_slow
/home/work/ssd1/workspace/MiRTOS-062-dev-system-CI/nuttx/sched/semaphore/sem_wait.c:102 (discriminator 1)
nxmutex_lock
/home/work/ssd1/workspace/MiRTOS-062-dev-system-CI/nuttx/include/nuttx/mutex.h:514
udp_pollteardown
/home/work/ssd1/workspace/MiRTOS-062-dev-system-CI/nuttx/net/udp/udp_netpoll.c:278
usrsock_rpmsg_poll_setup
/home/work/ssd1/workspace/MiRTOS-062-dev-system-CI/nuttx/drivers/usrsock/usrsock_rpmsg_server.c:1232
usrsock_rpmsg_poll_cb
/home/work/ssd1/workspace/MiRTOS-062-dev-system-CI/nuttx/drivers/usrsock/usrsock_rpmsg_server.c:1299
poll_notify
/home/work/ssd1/workspace/MiRTOS-062-dev-system-CI/nuttx/fs/vfs/fs_poll.c:296
udp_poll_eventhandler
/home/work/ssd1/workspace/MiRTOS-062-dev-system-CI/nuttx/net/udp/udp_netpoll.c:105
devif_conn_event
/home/work/ssd1/workspace/MiRTOS-062-dev-system-CI/nuttx/net/devif/devif_callback.c:481
udp_callback
/home/work/ssd1/workspace/MiRTOS-062-dev-system-CI/nuttx/net/udp/udp_callback.c:324
udp_input_conn
/home/work/ssd1/workspace/MiRTOS-062-dev-system-CI/nuttx/net/udp/udp_input.c:150
ipv4_in
/home/work/ssd1/workspace/MiRTOS-062-dev-system-CI/nuttx/net/devif/ipv4_input.c:425
ipv4_input
/home/work/ssd1/workspace/MiRTOS-062-dev-system-CI/nuttx/net/devif/ipv4_input.c:533
tun_net_receive_tun
/home/work/ssd1/workspace/MiRTOS-062-dev-system-CI/nuttx/drivers/net/tun.c:574
tun_net_receive_tun
/home/work/ssd1/workspace/MiRTOS-062-dev-system-CI/nuttx/drivers/net/tun.c:574
file_writev_compat
/home/work/ssd1/workspace/MiRTOS-062-dev-system-CI/nuttx/fs/vfs/fs_write.c:89
rpmsgdev_write_handler
/home/work/ssd1/workspace/MiRTOS-062-dev-system-CI/nuttx/drivers/misc/rpmsgdev_server.c:354
rpmsg_virtio_process_rx_buffer
/home/work/ssd1/workspace/MiRTOS-062-dev-system-CI/nuttx/drivers/rpmsg/rpmsg_virtio.c:256
rpmsg_virtio_rx_worker
/home/work/ssd1/workspace/MiRTOS-062-dev-system-CI/nuttx/drivers/rpmsg/rpmsg_virtio.c:291
work_dispatch
/home/work/ssd1/workspace/MiRTOS-062-dev-system-CI/nuttx/sched/wqueue/kwork_thread.c:233
work_thread
/home/work/ssd1/workspace/MiRTOS-062-dev-system-CI/nuttx/sched/wqueue/kwork_thread.c:293
nxtask_start
/home/work/ssd1/workspace/MiRTOS-062-dev-system-CI/nuttx/sched/task/task_start.c:99
Signed-off-by: zhanghongyu <zhanghongyu@xiaomi.com>
add net_lock in the tcp_callback_cleanup & Set the devif_callback_s of
tcp_callback_s to a two-dimensional pointer.
Signed-off-by: wangchen <wangchen41@xiaomi.com>