Commit graph

144 commits

Author SHA1 Message Date
Jukka Rissanen
b519ba54f5 net: tcp2: Only accept a valid RST packet
If the seq number is not valid, then drop incoming RST.

Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
2020-11-16 14:29:07 +02:00
Jukka Rissanen
be4380f5e2 net: tcp2: Remove unnecessary data length calculation
The data length is already calculated in tcp_in() so no need
to do it again in tcp_data_get(). Just pass the length to the
tcp_data_get() function.

Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
2020-11-16 14:22:13 +02:00
Jukka Rissanen
db6dac3bcf net: tcp2: Fix sending to 6lo based networks
Do not send the original pkt in 6lo based networks as in those
the IPv6 header is mangled and we would not be able to do any
resends of the original pkt. So for 6lo networks, clone the
pkt and send it to peer. The original pkt is kept in sent list
in case we need to resend to peer.

Fixes #29771

Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
2020-11-06 18:58:17 +02:00
Jukka Rissanen
d4320eedf2 net: tcp2: Update statistics
The amount of sent bytes and transmit errors should update
network statistics.

Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
2020-11-06 09:50:02 -06:00
Jukka Rissanen
c31148b04c net: tcp2: Update seq when peer closes connection
If the peer ACKs data when it closes the connection, update
our sequence number accordinly. The connection would eventually
be terminated but this will avoid extra resends by the peer.

Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
2020-11-04 11:17:47 +02:00
Jukka Rissanen
f50c9e11f0 net: tcp2: Avoid deadlock when closing the connection
When a connection is being closed, it is possible that the application
will have a lock to net_context and TCP2 connection lock. If we then
receive a final TCP2 ACK and close the connection, the locking order
get switched and TCP2 will first try to get its own lock and then the
net_context lock. This will lead to deadlock as the locking ordering
is now mixed.

The solution is to unref the TCP connection after releasing the
connection lock. The TCP connection unref function will anyway get the
lock so no need to do double locking.

Fixes #29444

Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
2020-11-04 11:16:53 +02:00
Jukka Rissanen
0f9ec427bc net: tcp2: Lock conn when sending data from work queue
If we are sending data directly, we already have TCP lock so
there is no need to do any locking. But when data is re-sent,
the work queue handler is doing the sending so we need to lock
the TCP connection.

Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
2020-10-21 12:57:23 -05:00
Jukka Rissanen
735fcc63bf net: tcp2: Pass data to application without any TCP locks
When receiving data that needs to be passed the data to application,
queue it for short time so that we do not have TCP connection lock
held. This way if the application wants to send data, there is no
possibility that the connection lock would prevent sending data.

Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
2020-10-21 12:57:23 -05:00
Jukka Rissanen
3b6155bbf5 net: tcp2: Fix TCP connection from Windows 10
Windows 10 sends ECN-Echo and Congestion Window Reduced (CWR) flags
together with SYN flag in the connection establishment but the code
did not ignore these flags and send just SYN back (instead of SYN|ACK).
This caused the connection establishement in application level to
fail as the application was never notified about it.

Fixes #29258

Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
2020-10-19 15:25:56 +03:00
Jukka Rissanen
d3283231a5 net: tcp2: Socket was accepted too early
The TCP2 was calling accept callback before actually finalizing
the connection attempt.

Fixes #29164

Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
2020-10-14 12:17:54 +03:00
Jukka Rissanen
8bb83454b4 net: tcp2: Do not assert when cancelling send timer
No real need to assert when the send timer is cancelled. Just
check if there is re-transmission going on and do nothing if
there is not.

Fixes #28758

Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
2020-10-01 14:19:07 +03:00
Jukka Rissanen
cace577d68 net: tcp2: Local accepted socket was not bound
The local and accepted socket was not bound which caused the
local address to be set as NULL. This then caused issues when
zsock_getsockname() was called by the application.

Fixes #28735

Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
2020-10-01 14:19:07 +03:00
Jukka Rissanen
baf83c2faf net: tcp2: Lock connection when running from work queue
We run various TCP function from work queue. Make sure the
connection lock is taken before accessing the connection.

Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
2020-09-28 14:25:13 +03:00
Jukka Rissanen
a95ae6712f net: tcp2: Access k_work in k_delayed_work using field name
Instead of casting k_delayed_work directly to k_work, use the
k_work field name. This avoids warnings from Coverity and
allows the code to work even if the k_delayed_work fields are
re-ordered in the future.

Coverity-CID: 214346
Fixes #28659

Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
2020-09-24 13:29:13 -05:00
David Komel
c067463791 net: tcp2: fix sysworkq corruption in tcp_conn_unref()
Bug description:
When in tcp_conn_unref(), in case one of the delayed works is already
submitted to sysworkq (after delay period), e.g. send_timer, the check
of k_delayed_work_remaining_get() prevents calling
k_delayed_work_cancel().
This leads to corrupting sysworkq when zeroing struct tcp* conn.
Note that the "next" pointer for the work queue is part of the struct
work (in _reserved field). Which is, in this case, a member of struct
tcp.

Scenario leading to the bug:
(1) net_tcp_connect() is called from a work in sysworkq
(2) net_tcp_connect() submits conn->send_timer to sysworkq
(3) while net_tcp_connect() is waiting on connect_sem, delay period
    passes (z_timeout) and send_timer enters sysworkq work slist
(4) also, some other code (app) submits more works to queue, now pointed
    by conn->send_timer in sysworkq work list
(5) connection fails (no answer to SYN), causing a call to
    tcp_conn_unref()
(6) tcp_conn_unref() is calling tcp_send_queue_flush()
(7) checking k_delayed_work_remaining_get(&conn->send_timer) returns 0
    due to delay period end, but send_timer is still in sysworkq work
    slist (sysworkq thread still hasn't handled the work)
(8) BUG!: no call to k_delayed_work_cancel(&conn->send_timer)
(9) back in tcp_conn_unref(), a call to memset(conn, 0, sizeof(*conn))
    zeroes conn->send_timer
(10) conn->send_timer is pointed to in sysworkq work slist, but is
     zeroed, clearing pointer to following works submitted in stage (4)
(11) EFFECT! the works in stage (4) are never executed!!

NOTES:
* k_delayed_work_cancel(), handles both states:
  (1) delayed work pends on timeout and
  (2) work already in queue.
  So there is no need to check k_delayed_work_remaining_get()
* This is also relevant for conn->send_data_timer

Solution:
removing checks of k_delayed_work_remaining_get(), always calling
k_delayed_work_cancel() for work in struct tcp, in unref, before memset

Signed-off-by: David Komel <a8961713@gmail.com>
2020-09-23 08:37:44 -05:00
Kumar Gala
fe7dd725f0 net: tcp2: Fix build failures on 64-bit platforms
Since conn->send_data_total is of time size_t we need to use %zu or
we'll get build errors in sanitycheck on 64-bit platforms

Fixes #28605

Signed-off-by: Kumar Gala <kumar.gala@linaro.org>
2020-09-22 12:08:37 -05:00
Jukka Rissanen
0e49f5570c net: tcp2: Check that connection exists in net_tcp_put()
Unit test tests/net/tcp2/net.tcp2.simple might have conn set to
null so check it here.

Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
2020-09-18 22:07:53 -04:00
Jukka Rissanen
ac7866c663 net: tcp2: Fix connection termination
We need to have timer that closes the connection for good if
we do not get the FIN and ACK reponse from the peer.

If there is any pending data when application does close(),
send them before sending FIN.

Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
2020-09-18 22:07:53 -04:00
Jukka Rissanen
13a7baf1e4 net: tcp2: Bail out if new connection cannot be created
If there is some error during connection creation, just bail
out in order to avoid null pointer access.

Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
2020-09-18 22:07:53 -04:00
Jukka Rissanen
4e3060a26b net: tcp2: Retrigger resend if sending window is full
If we try to send data but the sending window is full, then
try to kick the resend of the pending data.

Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
2020-09-18 22:07:53 -04:00
Jukka Rissanen
69459507b6 net: tcp2: Fix connection state debugging
The log buffer was too short and debug messages were truncated.

Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
2020-09-18 22:07:53 -04:00
Jukka Rissanen
bd9f707098 net: tcp2: Print context state when closing connection
Useful in debugging.

Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
2020-09-18 22:07:53 -04:00
Jukka Rissanen
9cccf0ea55 net: tcp2: If the send window is full, do not try to send
If there is no space in the sending window, then return -EAGAIN
so that the caller may try later.

Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
2020-09-18 22:07:53 -04:00
Jukka Rissanen
29f0895b93 net: tcp2: Adjust the send window according to avail bufs
We should have a max value for sending window so that application
is not able to use all our net_bufs for queueing packets.

Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
2020-09-18 22:07:53 -04:00
Jukka Rissanen
ff2aff3a32 net: tcp2: Make sure the pkt if not null
If the send_queue pkt is null, then do not try to access it.

Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
2020-09-18 22:07:53 -04:00
Jukka Rissanen
3db319fbc3 net: tcp2: Avoid double free message
If there is an error, the net_context.c:context_sendto() will
free the net_pkt, so we must not do it here.

This commit fixes this error message:

<err> net_pkt: *** ERROR *** pkt 0x20421908 is freed already
                                     (context_sendto():1672)

Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
2020-09-18 22:07:53 -04:00
Jukka Rissanen
65a3b5a68e net: tcp2: Do not close connection if we run out of memory
Usually the out-of-memory situation will clear itself eventually,
so if that happens in TCP, then keep the connection running and
let the user to decide what to do next.

Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
2020-09-18 22:07:53 -04:00
Jukka Rissanen
80d04616de net: tcp2: Honor TCP retry count limit from Kconfig file
Instead of hardcoded value of 3, use the value from Kconfig file
so that user can tweak the TCP retry count.

Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
2020-09-18 22:07:53 -04:00
Jukka Rissanen
6dfb11c781 net: tcp2: Use safe version of slist macro in conn search
Use SYS_SLIST_FOR_EACH_CONTAINER_SAFE() macro when searching
the connection list so that we notice if new entries are added
or removed in the list.

Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
2020-09-18 22:07:53 -04:00
Jukka Rissanen
54d05efb34 net: tcp2: Use pointer to slist node
Instead of forcing the slist node to be first in the tcp struct,
use the pointer to node when accessing the slist. This way we
can change the ordering of fields in tcp struct.

Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
2020-09-18 22:07:53 -04:00
Jukka Rissanen
3e5a4d79b2 net: tcp2: Make sure all incoming data is given to app at eof
When the connection is terminated, make sure that any pending
data is feed to the application.

Fixes #28057

Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
2020-09-04 11:04:27 -04:00
Jukka Rissanen
9d064e6ae9 net: tcp2: Fix connection close ack values
If we receive a TCP segment with FIN | ACK | PSH flags, then
update the ack values properly.

Fixes #27982

Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
2020-09-03 18:04:01 -04:00
Jukka Rissanen
4f6145a478 net: tcp2: Fix connection close seq values
When connection is closed and we send ACK flag, use proper seq
values so that any data that is still in flight will get acked too.
Currently this assumes that window is still open.

Fixes #27876

Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
2020-09-02 18:49:35 +03:00
Jukka Rissanen
b143213dc1 net: tcp2: Remove the temporary connection handler
We need to remove the temporary connection handler after the
connection is established.

Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
2020-08-07 10:35:48 +03:00
Jukka Rissanen
e73e932153 net: tcp2: Check data length properly
The original return type of tcp_data_get() was unsigned and the
return value <0 was not checked properly.

Fixes #25723
Coverity-CID: 210559

Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
2020-08-05 08:50:42 +03:00
Jukka Rissanen
9e8c1b0bbf net: tcp2: Verify that options are read correctly
Remove the static buffer for TCP options. Make sure that the
options were read properly to temp buffer.

Fixes: #25729
Coverity-CID: 210056

Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
2020-08-04 16:18:18 +02:00
David D
2ebc16629b net: tcp2: zeroing conn after removing from slist
Bugfix: in tcp_conn_unref(), the conn was zeroed before removing it
from the connection list (tcp_conns).
Zeroing conn, results in zeroing its 'next' member,
which in effect removes all its following connections referred to
in tcp_conns linked list.
The solution is to move the memset() after sys_slist_find_and_remove().

Signed-off-by: David D <a8961713@gmail.com>
2020-07-27 13:27:55 +02:00
b046ca5409 net: tcp2: fix unaligned access in the TCP2 stack
The TCP2 stack does operations directly on the packet data which may
or may not be aligned.  The unaligned access causes a fault on the
Cortex-M0+ so use the UNALIGNED_* macros instead.

Signed-off-by: Michael Hope <mlhx@google.com>
2020-07-22 15:08:31 +03:00
Oleg Zhurakivskyy
87577cb599 net: tcp2: Implement a blocking connect
In order to implement a blocking connect, add a semaphore
and block on it in net_tcp_connect().

The semaphore is released when ESTABLISHED state is reached.

In case tcp_conn_unref() is called while waiting on the semaphore,
defer the unreference, tcp_conn_unref() will be called from
net_tcp_connect().

Signed-off-by: Oleg Zhurakivskyy <oleg.zhurakivskyy@intel.com>
2020-07-20 13:55:22 +03:00
Oleg Zhurakivskyy
ff8e08e6c7 net: tcp2: Refactor net_tcp_connect()
In order to improve readability, refactor and simplify
the control flow in net_tcp_connect().

Signed-off-by: Oleg Zhurakivskyy <oleg.zhurakivskyy@intel.com>
2020-07-20 13:55:22 +03:00
Oleg Zhurakivskyy
f4c2772622 net: tcp2: Check for SYN and ACK in SYN_SENT
In order for events to be correctly interpreted in SYN_SENT,
check for SYN and ACK simultaneosly.

Signed-off-by: Oleg Zhurakivskyy <oleg.zhurakivskyy@intel.com>
2020-07-20 13:55:22 +03:00
Oleg Zhurakivskyy
dc01cae8a6 net: tcp2: Send FIN only in ESTABLISHED state
net_tcp_put() can be called before ESTABLISHED state
is reached, send FIN only in ESTABLISHED state.

Signed-off-by: Oleg Zhurakivskyy <oleg.zhurakivskyy@intel.com>
2020-07-20 13:55:22 +03:00
Oleg Zhurakivskyy
fda94f7d06 net: tcp2: Fix dereference after null check in tcp_in()
Fix dereference after null check in tcp_in().

Coverity CID :210051

Fixes #25783

Signed-off-by: Oleg Zhurakivskyy <oleg.zhurakivskyy@intel.com>
2020-07-10 11:46:20 +02:00
Flavio Ceolin
c4f7faea10 random: Include header where it is used
Unit tests were failing to build because random header was included by
kernel_includes.h. The problem is that rand32.h includes a generated
file that is either not generated or not included when building unit
tests. Also, it is better to limit the scope of this file to where it is
used.

Signed-off-by: Flavio Ceolin <flavio.ceolin@intel.com>
2020-07-08 21:05:36 -04:00
Kumar Gala
a1b77fd589 zephyr: replace zephyr integer types with C99 types
git grep -l 'u\(8\|16\|32\|64\)_t' | \
		xargs sed -i "s/u\(8\|16\|32\|64\)_t/uint\1_t/g"
	git grep -l 's\(8\|16\|32\|64\)_t' | \
		xargs sed -i "s/s\(8\|16\|32\|64\)_t/int\1_t/g"

Signed-off-by: Kumar Gala <kumar.gala@linaro.org>
2020-06-08 08:23:57 -05:00
Kumar Gala
ff29d306c9 net: tcp2: Fix compile failure on native_posix_64
Need to use %zd in formatter string for net_pkt_get_len since it returns
a size_t otherwise we get something like:

	error: format ‘%d’ expects argument of type ‘int’, but argument
	3 has type ‘size_t’ {aka ‘long unsigned int’} [-Werror=format=]

Signed-off-by: Kumar Gala <kumar.gala@linaro.org>
2020-06-03 22:29:16 +02:00
Oleg Zhurakivskyy
cbea5c81bb net: tcp2: Fix pointer to local outside scope in th_get()
Fix pointer to local outside scope in th_get().

Coverity CID :209942

Fixes #25779

Signed-off-by: Oleg Zhurakivskyy <oleg.zhurakivskyy@intel.com>
2020-06-01 14:59:54 +02:00
Oleg Zhurakivskyy
6096efb3da net: tcp2: Implement the retransmission for the outgoing data
In order to support the retransmission for the outgoing data:

1. The outgoing data packet is appended to the send_data queue
   in net_tcp_queue_data().

2. tcp_send_queued_data() is called and will use tcp_send_data()
   to sends queued but unsent data packet by packet
   until there's an unsent data and the receiver's window isn't full.

   tcp_send_queued_data() subscribes send_data_timer
   that will handle retrasmissions with tcp_resend_data().

3. tcp_send_data() peeks a single chunk of data from the send_data
   queue that will not exceed the maximum segment size
   until the the receiver's window is full.

   tcp_send_data() uses conn->seq and conn->unack_len as the sequence
   number for the TCP packet.

   conn->unacked_len is advanced on each send.

4. On data acknowledgment:

   - acknowledged amount of data is removed from the beginning
     of the send_data queue
   - conn->seq is advanced by the acknowledged amount
   - conn->unacked_len is decremented by the acknowledged amount
   - send_data_timer is cancelled
   - tcp_send_queued_data() is called to send queued but
     prevoiusly unsent data

5. On timeout, tcp_resend_data() will reset conn->unack_len,
   peek one packet from the beginning of the send_queue and resend,
   terminating the connection on retries exceeded.

   Meanwhile the outgoing data tcp_send_queued_data() is just
   appended to the send_data but not sent.

   In case of the acknowledgement, tcp_send_queued_data() will
   start sending multiple packets until the receiver's window
   is full.

Signed-off-by: Oleg Zhurakivskyy <oleg.zhurakivskyy@intel.com>
2020-05-25 12:42:22 +02:00
Oleg Zhurakivskyy
58b7847afb net: tcp2: Extract the MSS from the TCP option value
Extract the maximum segment size (MSS) from the TCP option value.

Signed-off-by: Oleg Zhurakivskyy <oleg.zhurakivskyy@intel.com>
2020-05-25 12:42:22 +02:00
Oleg Zhurakivskyy
9efdbe19dd net: tcp2: Add send_win into the TCP connection
In order to support the send window, add send_win into
the TCP connection.

Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
Signed-off-by: Oleg Zhurakivskyy <oleg.zhurakivskyy@intel.com>
2020-05-25 12:42:22 +02:00