The packet socket implementation did not fill the address structure
provided by the application. This commit fixes this.
Note, that the implementation needs to cover two cases: SOCK_RAW and
SOCK_DGRAM. In the first case, the information is extracted directly
from the L2 header (curently only Ethernet supported). In latter case,
the header is already removed from the packet as the L2 has already
processed the packet, so the information is obtained from the net_pkt
structure.
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
There is a potential, corner case scenario, where a deadlock can occur
between TCP and socket layers, when both ends of the connection transmit
data.
The scenario is as follows:
* Both ends of the connection transmit data,
* Zephyr side send() call gets blocked due to filing the TX window
* The next incoming packet is data packet, not updating the RX window
on the peer side or acknowledging new data. The TCP layer will
attepmt to notify the new data to the socket layer, by calling the
registered callback. This will block the RX thread processing the TCP
layer, as the socket mutex is already acquired by the blocked send()
call.
* No further packets are processed until the socket mutex is freed,
which does not happen as the only way to unblock send() is process
a new ACK, either updating window size or a acknowledging data.
The connection stalls until send() times out.
The deadlock is not permament, as both threads get unlocked once send()
times out. It effectively breaks the active connection though.
Fix this, by unlocking the socket mutex for the time the send() call is
idle. Once the TCP layer notifies that the window is available again,
the mutex is acquired back.
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
Move the CAN bus network driver from drivers/can to drivers/net as it
implements a network driver, not a CAN controller driver.
Use a separate Kconfig for enabling the CAN bus network driver instead of
piggybacking on the SocketCAN Kconfig. This allows for other
(e.g. out-of-tree) SocketCAN transports.
Signed-off-by: Henrik Brix Andersen <hebad@vestas.com>
Some errors can occur in the sending process that have to be handled
in a polling fasion instead of blocking using semaphores. In this case
apply an exponentially growing backoff time. This will allow for fast
reactions in most situations and prevents high system loads in case
resolving the situation takes a little longer.
Signed-off-by: Sjors Hettinga <s.a.hettinga@gmail.com>
When an operation on the socket is not supported by the implementation,
which is the case for some drivers, set errno to a value that reflects
this situation rather than signalling an error with the file descriptor.
Signed-off-by: Ulf Lilleengen <lulf@redhat.com>
Logging v1 has been removed and log_strdup wrapper function is no
longer needed. Removing the function and its use in the tree.
Signed-off-by: Krzysztof Chruscinski <krzysztof.chruscinski@nordicsemi.no>
Prevent local "addrlen_copy" variable from being used uninitialized in
accept() userspace verification function.
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
To improve the performance with small chunks send, implement Nagle's
algorithm. Provide the option TCP_NODELAY to disable the algorithm.
Signed-off-by: Sjors Hettinga <s.a.hettinga@gmail.com>
Fragmented data passed to sendmsg() should be sent as a single datagram in
case of datagram sockets (i.e. DTLS connection). Right now that is not
happening now, as each fragment is sent separately, which works fine only
for stream sockets.
There is no mbedTLS API for 'gather' write at this moment. This means that
implementing sendmsg() would require allocating contiguous memory area at
Zephyr TLS socket level and copying all data fragments before passing to
mbedTLS library. While this might be a good option for future, let's just
check if data passed to sendmsg() API consists of a single memory region
and can be sent using single send request. Return EMSGSIZE error if there
are more then one data fragments.
Signed-off-by: Marcin Niestroj <m.niestroj@emb.dev>
Implement POLLOUT for stream sockets, based on newly introduced tx_sem
functionality of the TCP stack.
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
Utilize the TCP semaphore monitoring transmit status at the socket
layer. This allows to resume transfer as soon as possible instead of
waiting blindly.
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
Make use of the status field, reported by TCP, in the socket receive
callback. This allows to differentiate a graceful connection shutdown
from actual errors at TCP level (transmission timeout or RST received).
In case of error reported from TCP layer, set a new SOCK_ERROR flag on
the socket, and store the error code in the net_context user_data.
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
In order to bring consistency in-tree, migrate all subsystems code to
the new prefix <zephyr/...>. Note that the conversion has been scripted,
refer to zephyrproject-rtos#45388 for more details.
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
Socket offloading has been in the tree for a while and improved a lot
over time (from a simple define-based API override to a complex
vtable-based solution, supporting mutliple offloaded interfaces). As the
feature is heavily used by certain vendors (Nordic and its nRF Connect
SDK), I propose to move it out of experimental phase.
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
Introduce TLS socket options, which allow to configure session caching
on a socket.
The cache can be enabled on a socket with TLS_SESSION_CACHE option.
Once cache is enabled on a socket, the session will be stored for re-use
after a sucessfull handshake. If a socket is attempting to connect to a
host for which session is stored, the session will be resumed and mbed
TLS will attempt to use a simplified handshake procedure.
The server-side management of sessions is fully controlled by mbed TLS
after session caching is enabled on a socket.
The other TLS_SESSION_CACHE_PURGE option allows to clear all of the
cache entries, releasing the memory allocated for sessions.
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
The function setsockopt() option TLS_CIPHERSUITE_LIST
allows the user to set a specific list of ciphersuites
when using the Zephyr native + Mbed TLS stack. However, the
list provided was not actually being used later for
handshaking.
This adds the missing calls to mbedtls_ssl_conf_ciphersuites()
to use the list provided. If none was provided, fall back
to the default list as determined by Mbed TLS from Kconfig
values.
Signed-off-by: Pete Skeggs <peter.skeggs@nordicsemi.no>
In some cases (for examples when offloaded socket implementation does
not implement TLS functionality) it could be desired to create a native
TLS socket with an underlying offloaded socket.
This cannot be achieved with SO_BINDTODEVICE option only, as TLS socket
type is not really associated with a particular interface - it either
has to be offloaded, or a fully native socket is created (native TLS on
a native interface).
In order to address the problem, introduce TLS_NATIVE socket option.
This option instructs the socket dispatcher layer to create a native TLS
socket. As with the socket dispatcher the underlying socket
implementation is not decided during TLS socket creation, therefore it's
possible to use SO_BINDTODEVICE to choose either native or offloaded
interface for the underlying socket.
Additionally remove NET_SOCKETS_OFFLOAD_TLS Kconfig option, as it's no
longer needed with an runtime option to select whether to offload TLS or
not.
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
Add an intermediate socket implementation called socket dispatcher. This
layer can be used along with the socket offloading, to postpone the
actual socket creation until a first operation on a socket is executed.
This approach leaves an opening to bind a socket to a particular
offloaded network interface, and thus offloaded socket implementation,
using SO_BINDTODEVICE socket option. Thanks to this, it is now possible
to use multiple offloaded sockets implementations along with native
sockets, and easily select which socket should use with network
interface (even if it's an offloaded interface).
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
Introduce set/get SO_SNDBUF option using the setsockopt
function. In addition, for TCP, check the sndbuf value
before queuing data.
Signed-off-by: Mohan Kumar Kumar <mohankm@fb.com>
'optval' in setsockopt(..., SO_BINDTODEVICE, ...) was casted explicitly
from 'const void *' to 'struct ifreq *'. Rely on C implicit casting from
'const void *' to 'const struct ifreq *' and simply update variable
type. This prevents unwanted modification of ifreq value in the future.
Signed-off-by: Marcin Niestroj <m.niestroj@emb.dev>
This option will be used as default socket priority by offloaded socket
drivers.
Describe how to prioritize native TLS over offloaded TLS (and vice
versa) using sockets priorities.
Signed-off-by: Marcin Niestroj <m.niestroj@grinn-global.com>
Introduce set/get SO_RCVBUF option using the setsockopt
function. In addition, use the rcvbuf value to set the
tcp recv window.
Signed-off-by: Mohan Kumar Kumar <mohankm@fb.com>
The ARRAY_SIZE macro uses sizeof and thus the return
type should be an unsigned value. size_t is typically
the type used for sizeof and fits well for the
ARRAY_SIZE macro as well.
Signed-off-by: Emil Gydesen <emil.gydesen@nordicsemi.no>
The verification function for accept() did not take into account that
addr and addrlen pointers provided could be NULL.
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
TCP module can report EAGAIN in case TX window is full. This should not
be forwarded to the application, as blocking socket is not supposed to
return EAGAIN.
Fix this for sendmsg by implementing the same mechanism for handling TX
errors as for regular send/sendto operations.
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
According to Kconfig guidelines, boolean prompts must not start with
"Enable...". The following command has been used to automate the changes
in this patch:
sed -i "s/bool \"[Ee]nables\? \(\w\)/bool \"\U\1/g" **/Kconfig*
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
Add basic shutdown() implementation of TLS sockets, which basically
calls shutdown() on underlying wrapped sockets.
Signed-off-by: Marcin Niestroj <m.niestroj@grinn-global.com>
Add basic shutdown() implementation for net_context sockets, which
handles only SHUT_RD as 'how' parameter and returns -ENOTSUP for SHUT_WR
and SHUT_RDWR. The main use case to cover is to allow race-free wakeup
of threads calling recv() on the same socket.
Signed-off-by: Marcin Niestroj <m.niestroj@grinn-global.com>
So far shutdown() implementation was a noop and just resulted in warning
logs. Add shutdown() method into socket vtable. Call it if provided and
fallback into returning -ENOTSUP if not.
Signed-off-by: Marcin Niestroj <m.niestroj@grinn-global.com>
Add implementation of net_tcp_update_recv_wnd() function.
Move the window deacreasing code to the tcp module - receive window
has to be decreased before sending ACK, which was not possible when
window was decreased in the receive callback function.
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
There is no releavnce between CAN sockets and offloading that would
prevent one from working with another, therefore it's not right to
allow CAN sockets to be build only if offloading is disabled. Fix the
wrong dependency in socket CMakeLists.txt file.
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
Fix net_pkt leak by increasing net_context the reference count earlier
in the zsock_accepted_cb() with instalment of the
zsock_received_cb() callback.
And consequently flushing recv_q and decrement net_context
reference count if zsock_accept_ctx() fails.
Signed-off-by: Daniel Nejezchleb <dnejezchleb@hwg.cz>
In case system workqueue processing is delayed for any reason, and
resolver callback is executed after getaddrinfo() call already timed
out, the system would crash as the callback makes use of the user data
allocated on the stack within getaddrinfo() function.
Prevent that, by cancelling the DNS request explicitly from the
getaddrinfo() context, therefore preventing the resolver callback
from being executed after the getaddrinfo() call ends.
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
The previous approach to detect if the underlying transport was closed
(by checking the return value of `mbedtls_ssl_read()` was not right,
since the function call does not request any data - therefore 0 as a
return value is perfectly fine.
Instead, rely on the underlying transport ZSOCK_POLLHUP event - if it
reports that the connection ended, forward the event to the application.
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
Report ZSOCK_POLLHUP event if peer closed the connection, and thus the
socket is in EOF state.
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
According to MbedTLS API documentation, its session must be reset if
mbedtls_ssl_handshake returns something other than:
- 0
- MBEDTLS_ERR_SSL_WANT_READ
- MBEDTLS_ERR_SSL_WANT_WRITE
- MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS
- MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS
In MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS and
MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS cases the function must be called
again when operation is ready. These cases now return -EAGIN or
continue to retry if it's a blocking call.
Signed-off-by: Ramiro Merello <rmerello@itba.edu.ar>
Add EtherCAT protocol support, now applications can
transmit/receive EtherCAT packets via RAW socket.
Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
Simplify common `getsockname()` implementation by using VTABLE_CALL()
macro, in the same way as other socket calls do. This additionally
allows to cover the case, when `getsockname()` is not implemnented by
particular socket implementation, preventing the crash.
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
Replace unpacked in6_addr structures with raw buffers in net_ipv6_hdr
struct, to prevent compiler warnings about unaligned access.
Remove __packed parameter from `struct net_6lo_context` since the
structure isn't really serialized.
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
Replace unpacked in_addr structures with raw buffers in net_ipv4_hdr
struct, to prevent compiler warnings about unaligned access.
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
Add TLS socket option "TLS_CERT_NOCOPY" to prevent the copy of
certificates to mbedTLS heap if possible.
Add support to provide a chain of DER certificates by registering
them with multiple tags.
Signed-off-by: Lucas Dietrich <ld.adecy@gmail.com>
Change the wording of the warning printed when there is no entropy to
hopefully remove any doubt that there might be security in TLS without
an entropy source. TLS connections with insufficient entropy are
trivially decodable, and should not be relied on for any type of
security.
Signed-off-by: David Brown <david.brown@linaro.org>
`ztls_socket_data_check()` function ignored a fact when
`mbedtls_ssl_read()` indicated that the underlying TCP connection was
closed. Fix this by returning `-ENOTCONN` in such case, allowing
`poll()` to detect such event.
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
With the introduction of `EXPERIMENTAL` and `WARN_EXPERIMENTAL` in
Zephyr all subsys/net and drivers/ethernet/Kconfig.e1000 settings
having `[EXPERIMENTAL]` in their prompt has has been updated to include
`select EXPERIMENTAL` so that developers can enable warnings when
experimental features are enabled.
The following settings has EXPERIMENTAL removed as they are considered
mature:
- NET_OFFLOAD
- NET_PROMISCUOUS_MODE
Signed-off-by: Torsten Rasmussen <Torsten.Rasmussen@nordicsemi.no>
The irq_lock() usage here is incompatible with SMP systems, and one's
first reaction might be to convert it to a spinlock.
But are those irq_lock() instances really necessary?
Commit 6161ea2542 ("net: socket: socketpair: mitigate possible race
condition") doesn't say much:
> There was a possible race condition between sock_is_nonblock()
> and k_sem_take() in spair_read() and spair_write() that was
> mitigated.
A possible race without the irq_lock would be:
thread A thread B
| |
+ spair_write(): |
+ is_nonblock = sock_is_nonblock(spair); [false]
* [preemption here] |
| + spair_ioctl():
| + res = k_sem_take(&spair->sem, K_FOREVER);
| + [...]
| + spair->flags |= SPAIR_FLAG_NONBLOCK;
| * [preemption here]
+ res = k_sem_take(&spair->sem, K_NO_WAIT); [-1]
+ if (res < 0) { |
+ if (is_nonblock) { [skipped] }
* res = k_sem_take(&spair->sem, K_FOREVER); [blocks here]
| + [...]
But the version with irq_lock() isn't much better:
thread A thread B
| |
| + spair_ioctl():
| + res = k_sem_take(&spair->sem, K_FOREVER);
| + [...]
| * [preemption here]
+ spair_write(): |
+ irq_lock(); |
+ is_nonblock = sock_is_nonblock(spair); [false]
+ res = k_sem_take(&spair->sem, K_NO_WAIT); [-1]
+ irq_unlock(); |
* [preemption here] |
| + spair->flags |= SPAIR_FLAG_NONBLOCK;
| + [...]
| + k_sem_give(&spair->sem);
| + spair_read():
| + res = k_sem_take(&spair->sem, K_NO_WAIT);
| * [preemption here]
+ if (res < 0) { |
+ if (is_nonblock) { [skipped] }
* res = k_sem_take(&spair->sem, K_FOREVER); [blocks here]
In both cases the last k_sem_take(K_FOREVER) will block despite
SPAIR_FLAG_NONBLOCK being set at that moment. Other race scenarios
exist too, and on SMP they are even more likely.
The only guarantee provided by the irq_lock() is to make sure that
whenever the semaphore is acquired then the is_nonblock value is always
current. A better way to achieve that and be SMP compatible is to simply
move the initial sock_is_nonblock() *after* the k_sem_take() and remove
those irq_locks().
Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
Mbed TLS 3.0 removes the definition for MBED_ERR_SSL_PEER_VERIFY_FAILED,
since non of its code ever returns that value. Since there isn't really
a perfect response, instead return a somewhat generic response
indicating this was unexpected.
Signed-off-by: David Brown <david.brown@linaro.org>
Several fields of structures in mbedTLS 3.0 are now private. To access
them directly is necessary to define MBEDTLS_ALLOW_PRIVATE_ACCESS.
That is a temporary fix, the proper solution is not access directly
but using proper API.
Signed-off-by: Flavio Ceolin <flavio.ceolin@intel.com>