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>