A net context in LISTENING mode waits for incoming connections, once
a new connection is established a new net context is spawned which
is responsible for handling the new connection.
Therefore when closing a LISTENING context it is not useful to send FIN
as it is never connected. Actually closing the connection would be done
by calling close on the spawned net context which is returned by the
accept call.
Signed-off-by: Léonard Bise <leonard.bise@gmail.com>
The code was leaking memory in TX side when there was lot of
incoming packets. The reason was that the net_pkt_sent() flag
was manipulated in two threads which caused races. The solution
is to move the sent flag check only to tcp.c.
Fixes#23246
Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
IPv4 header options length will be stored in ipv4_opts_len
in net_pkt structure. Now IPv4 header length will be in
net_pkt ip_hdr_len + ipv4_opts_len. So modified relevant
places of ip header length calculation for IPv4.
Signed-off-by: Ravi kumar Veeramally <ravikumar.veeramally@linux.intel.com>
In order to avoid net_pkt ref count going to <0, do not unref
the packet if it was not sent in the first place. This can happen
if the connection was closed while we are waiting packets to be sent.
Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
Do not print warning if transitioning from LISTEN -> CLOSED which
happens when the socket is closed.
Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
The initial state from CLOSED -> ESTABLISHED caused error
to be printed by state validator. This is unnecessary, so add
this as a valid state to validator.
Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
Handle this corner case with TCP connection closing:
1) Client A connects, it is accepted and can send data to us
2) Client B connects, the application needs to call accept()
before we will receive any data from client A to the application.
The app has not yet called accept() at this point (for
whatever reason).
3) Client B then disconnects and we receive FIN. The connection
cleanup is a bit tricky as the client is in half-connected state
meaning that the connection is in established state but the
accept_q in socket queue contains still data which needs to be
cleared.
4) Client A then disconnects, all data is sent etc
The above was not working correctly as the system did not handle the
step 3) properly. The client B was accepted in the application even
if the connection was closing.
After this commit, the commit called "net: tcp: Accept connections
only in LISTENING state" and related other commits are no longer
needed and are reverted.
Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
The earlier code was always queuing the FIN that is sent when
connection is closed. This caused long delay (200 ms) before the peer at
the other end noticed that the connection was actually closed.
Now check if there is nothing in the queue, then send the FIN
immediately. If there is some data in the queue, flush it when a valid
ack has been received.
Fixes#19678
Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
Issue noticed with following scenario.
1) TCP server is listening for connections but will handle
only one connection at a time (e.g. echo-server sample)
2) Client A connects, and the connection is accepted.
3) Client B connects, instead of denying a connection,
it is "auto" accepted (this is the actual bug) even
if the application has not called accept().
4) After the connection A is closed, the connection B
gets accepted by application but now the closed
connection A will cause confusion in the net-stack
5) This confusion can cause memory leak or double free
in the TCP core.
It is not easy to trigger this issue because it depends
on timing of the connections A & B.
Fixes: #18308
Signed-off-by: Ravi kumar Veeramally <ravikumar.veeramally@linux.intel.com>
If we are closing connection before the connection was established,
then unref the context so that the cleanup is done properly.
Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
This commit is an implementation of 6LoCAN, a 6Lo adaption layer for
Controller Area Networks. 6LoCAN is not yet standardised.
Signed-off-by: Alexander Wachter <alexander.wachter@student.tugraz.at>
Skip the TCP options before giving the data to application.
Without this, the TCP options would be passed to the application.
Fixes#17055
Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
move misc/byteorder.h to sys/byteorder.h and
create a shim for backward-compatibility.
No functional changes to the headers.
A warning in the shim can be controlled with CONFIG_COMPAT_INCLUDES.
Related to #16539
Signed-off-by: Anas Nashif <anas.nashif@intel.com>
Found a few annoying typos and figured I better run script and
fix anything it can find, here are the results...
Signed-off-by: Anas Nashif <anas.nashif@intel.com>
This reverts commit 9cd547f53b.
The commit we are reverting, fixed originally the issue that was
seen with zperf. There we freed the net_pkt too early while it was
still waiting for a TCP ACK. The commit 9cd547f5 seemd to fix that
issue but it was causing issues in dump_http_server sample app which
then started to leak memory. No issues were seen with echo-server
with or without the commit 9cd547f5.
So the lessons learned here is that one needs to test with multiple
network sample apps like dump_http_server, echo_server and zperf
before considering TCP fixes valid, especially fixes that touch
ref counting issues.
Fixes#15031
The next commit will fix the zperf free memory access patch.
Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
The network packet ref count was not properly increased when
the TCP was retried. This meant that the second time the packet
was sent, the device driver managed to release the TCP frame even
if we had not got ACK to it.
Somewhat long debug log follows:
The net_pkt 0x08072d5c is created, we write 1K data into it, initial ref
count is 1.
net_pkt_write: pkt 0x08072d5c data 0x08075d40 length 1024
net_tcp_queue_data: Queue 0x08072d5c len 1024
net_tcp_trace: pkt 0x08072d5c src 5001 dst 5001
net_tcp_trace: seq 0x15d2aa09 (366127625) ack 0x7f67d918
net_tcp_trace: flags uAPrsf
net_tcp_trace: win 1280 chk 0x0bea
net_tcp_queue_pkt: pkt 0x08072d5c new ref 2 (net_tcp_queue_pkt:850)
At this point, the ref is 2. Then the packet is sent as you see below.
net_pkt_ref_debug: TX [13] pkt 0x08072d5c ref 2 net_tcp_queue_pkt():850
net_tcp_send_data: Sending pkt 0x08072d5c (1084 bytes)
net_pkt_unref_debug: TX [13] pkt 0x08072d5c ref 1 (ethernet_send():597)
Ref is still correct, packet is still alive. We have not received ACK,
so the packet is resent.
tcp_retry_expired: ref pkt 0x08072d5c new ref 2 (tcp_retry_expired:233)
net_pkt_ref_debug: TX [10] pkt 0x08072d5c ref 2 tcp_retry_expired():233
net_pkt_unref_debug: TX [10] pkt 0x08072d5c ref 1 ... (net_if_tx():173)
net_pkt_unref_debug: TX [10] pkt 0x08072d5c ref 0 ... (net_if_tx():173)
Reference count is now wrong, it should have been 1. This is because we
did not increase the ref count when packet was placed first time into
sent list in tcp.c:tcp_retry_expired().
The fix is quite simple as you can see from this commit.
Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
Since the new packet flow came in, payload comes at the end so udp
length for instance is known only when we "finalize" the packet.
However such finalization was still under the condition of chksum
offload, like it used to be in the former flow (udp headers were
inserted). This is obviously wrong but that was not caught with
existing driver in master as none of these drivers offloading
chksum calculation.
Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
And also to the relevant callbacks.
That parameter is not used anywhere so it is useless.
Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
Now that legacy - and unrelated - function named net_pkt_get_data has
been removed, we can rename net_pkt_get_data_new relevantly.
Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
There is no need for these anymore: all is dictated by the position of
the net_pkt's cursor now
- actual cursor position is like the former appdata attribute
- net_pkt_remaining_data() is like the former appdatalen attribute
Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
Multiple flag bits were set so the ACK flag set was not checked
properly which meant that connection establishment was not
successfull.
Fixes#13943
Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
When closing the socket, zsock_close_ctx() would call
net_context_accept() when the socket was in "LISTEN" state.
This would result in an error log message for "Identical
connection handler already found" because the connection
context was already created because the initial
zsock_listen_ctx() called net_context_accept() to set up
the socket at the beginning. This change adds a test to
check if the callback is NULL which indicates this
close state and avoids the error message.
Signed-off-by: david leach <david.leach@nxp.com>
The sending of the final FIN message was being put on the sent_list
to be handled by the retry logic and being sent directly. But in
the case of a socket that never had a connection, the logic after
the direct send would decrement the reference on the packet which
would cause the retry logic to eventually have a situation where
the pkt is on the sent_list queue but the buffer associated with
the packet is freed back to slab. The code would then get a null
pointer to the tcp header and would fault when setting the crc to
zero on frdm-k64f platform.
Fixes#13489, #13301
Signed-off-by: david leach <david.leach@nxp.com>
There are issues using lowercase min and max macros when compiling a C++
application with a third-party toolchain such as GNU ARM Embedded when
using some STL headers i.e. <chrono>.
This is because there are actual C++ functions called min and max
defined in some of the STL headers and these macros interfere with them.
By changing the macros to UPPERCASE, which is consistent with almost all
other pre-processor macros this naming conflict is avoided.
All files that use these macros have been updated.
Signed-off-by: Carlos Stuart <carlosstuart1970@gmail.com>
Now that legacy net_pkt_clone function has been removed, the new
function can be renamed accordingly.
Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
It is now useless as the only function using it
(net_pkt_set_appdata_values) got removed.
Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
Let's not call net_pkt_set_appdata_values() which will be more costly
since it will need to parse all over again the packet to grab the tcp
header. Instead, let's use the tcp header pointer we have already and
set the appdata attributes directly.
Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
As we are adding more protocol families and protocol types
to connection handlers, some values might be same across
different types. Current connection handler only stores
proto type to match the handler, which is not enough if
we add more types. Also combination of family and types
may vary too. So adding family to connection handler to
figure out best match.
Also changing proto variable in net_conn from u8_t to u16_t.
net_context has 16 bit proto.
Signed-off-by: Ravi kumar Veeramally <ravikumar.veeramally@linux.intel.com>
If status is 0, both ip_hdr and proto_hdr will own a pointer to the
relevant IP and Protocol headers. In order to know which of ipv4/ipv6
and udp/tcp one will need to use respectively net_pkt_family(pkt) and
net_context_get_ip_proto(context).
Having access to those headers directly, many callbacks will not need
to parse the packet again no get the src/dst addresses or the src/dst
ports. This will be change after this commit.
Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
Though these are currently used by the core only, it will be then used
by net_context as well. This one of the steps to get rid of net_pkt's
appdata/appdatalen attributes.
Also normalizing all ip/proto parameters name to ip_hdr and proto_hdr.
Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
Only next to be removed functions like net_tcp_set_checksum() are left
untouched. All the rest is switched.
Adding net_tcp_finalize() to follow the same logic as for UDP and else.
Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
This proovse to drastically reduce runtime overhead as it does not need
to parse IP nor TCP header all over again in a lot of places.
Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>