Commit Graph

118 Commits

Author SHA1 Message Date
Paul Sokolovsky
268c0e3310 net: tcp: Add MSS option on sending SYN request
Currently, we add TCP options only to SYN+ACK reply to peer's SYN
(i.e. passive open). For consistency, add them also when we send
SYN ourselves (active open). In both cases, we add just MSS option
currently.

Signed-off-by: Paul Sokolovsky <paul.sokolovsky@linaro.org>
2018-06-13 08:45:54 -04:00
Paul Sokolovsky
4dd61f8897 net: tcp: Process zero window probes when our recv_wnd == 0
The IP stack drops any TCP segment which doesn't fit into our
receive window. However, we still must accept Zero Window Probe
segments, which are segments, usually with data length of 1, which
a peer sends to us after we stayed with zero window for some time.
In this case, we need to repeat an ACK with the old ack number.

Signed-off-by: Paul Sokolovsky <paul.sokolovsky@linaro.org>
2018-06-11 17:30:04 -04:00
Paul Sokolovsky
eb3ecf6e66 net: shell: conn: Always show TCP state
It's rather confusing to not see current TCP state in any way (it
makes distinguishing different TCP contexts very hard). And nobody
can know/remember that it's printed with CONFIG_NET_DEBUG_TCP
defined. So, just make it be printed always (initially I thought
about printing just numeric value if CONFIG_NET_DEBUG_TCP isn't
defined, but why, if we can print symbolic name easily).

Also, add a hint that defining CONFIG_NET_DEBUG_TCP will still
print even more info (like unacked pkt list) - similarly to
similar helpful hints we have in other parts of net shell.

Signed-off-by: Paul Sokolovsky <paul.sokolovsky@linaro.org>
2018-06-11 17:21:58 -04:00
Jukka Rissanen
48ac4a372c net: Convert raw timeout values to use K_MSEC() macro
This one converts "raw" timeout value to use K_MSEC() macro
in order to make clear how long the timeout is.

Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
2018-05-28 17:20:11 -04:00
Paul Sokolovsky
89f57c225a net: tcp: Define single config option for TIME_WAIT delay
Previously, there was a boolean CONFIG_NET_TCP_TIME_WAIT setting
("master switch") and numeric CONFIG_NET_TCP_2MSL_TIME setting,
both named not ideally (there were both NET_TCP_TIME_WAIT and
CONFIG_NET_TCP_TIME_WAIT symbols in the source, with very different
meaning; "2MSL_TIME" was also a roundabout way to refer to
TIME_WAIT state time). In addition to that, some code was defining
adhoc, hardcoded duplicates for these settings.

CONFIG_NET_TCP_2MSL_TIME was also measured in seconds, giving
poor precision control for this resource-tying setting.

Instead, replace them all with the single
CONFIG_NET_TCP_TIME_WAIT_DELAY setting, measured in milliseconds.
The value of 0 means that TIME_WAIT state is skipped.

Fixes: #7459

Signed-off-by: Paul Sokolovsky <paul.sokolovsky@linaro.org>
2018-05-16 11:03:49 +03:00
Michael Scott
2c987298f2 net: tcp: expose some TCP helper functions
Similar to UDP, some drivers can make use of the following functions:
net_tcp_get_hdr()
net_tcp_set_hdr()

Let's expose them as <net/tcp.h> and change all internal references
to "tcp_internal.h".

Signed-off-by: Michael Scott <michael@opensourcefoundries.com>
2018-05-15 18:07:47 +03:00
Paul Sokolovsky
460a6c77c5 net: tcp: send_syn_segment: Log packet before it's sent
After successful send, the packet is automatically cleared, so
trying to call print_send_info() on it leads to errors:

[net/pkt] [ERR] net_pkt_tcp_data: NULL fragment data!
[net/tcp] [ERR] net_tcp_get_hdr: NULL TCP header!

(if error logging enabled).

This change is similar to how print_send_info() is called in
existing send_reset() function of this source file.

Signed-off-by: Paul Sokolovsky <paul.sokolovsky@linaro.org>
2018-04-26 07:55:21 +03:00
Marcin Niestroj
ac661a0779 net: tcp: Cancel fin_timer in FIN_WAIT_2 instead FIN_WAIT_1
According to RFC 793 we should wait for FIN in FIN_WAIT_1 and
FIN_WAIT_2 states. Receiving ACK in FIN_WAIT_1 just moves us to
FIN_WAIT_2 state.

Right now TCP connection is never closed if FIN is not received
in FIN_WAIT_2 state. Fix that by keeping fin_timer active in
FIN_WAIT_2 state, but canceling it just after FIN is received.

Fixes: 124c067027 ("net: tcp: Cancel the fin_timer on FIN message
  in FIN_WAIT1 state")
Signed-off-by: Marcin Niestroj <m.niestroj@grinn-global.com>
2018-04-11 17:27:20 +03:00
Jukka Rissanen
1443ff0f5e net: stats: Make statistics collection per network interface
Instead of one global statistics, collect statistics information
separately for each network interface. This per interface statistics
collection is optional but turned on by default. It can be turned
off if needed, in which case only global statistics are collected.

Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
2018-04-10 13:29:39 +03:00
Ruslan Mstoi
9705f4af46 net: tcp: Fix crash from SYN flood
SYN flood causes crash in RX thread due to NULL pointer access. After
the crash available RX memory is zero, hence echo server does not
respond to echo request.

Signed-off-by: Ruslan Mstoi <ruslan.mstoi@intel.com>
2018-04-03 14:17:24 +03:00
Patrik Flykt
e9b00eae75 net: tcp: Move TCP stack to tcp.c
Move core TCP functionality from net_context.c to tcp.c. Create empty
functions that the compiler can remove if TCP is not configured. As a
result remove TCP ifdefs from net_context.

Signed-off-by: Patrik Flykt <patrik.flykt@intel.com>
2018-03-29 12:39:43 +03:00
Patrik Flykt
cfc6b56203 net: context: Factor out TCP receive window handling
Receive window is needed only for TCP.

Signed-off-by: Patrik Flykt <patrik.flykt@intel.com>
2018-03-29 12:39:43 +03:00
Patrik Flykt
08110d8295 net: context: Factor out TCP context listen state
Factor out TCP context listening state change.

Signed-off-by: Patrik Flykt <patrik.flykt@intel.com>
2018-03-29 12:39:43 +03:00
Patrik Flykt
b5c74b9706 net: context: Refactor queueing of a TCP FIN when closing socket
Queue a TCP FIN packet when needed if the socket was connected or
listening and where FIN wasn't already received.

Signed-off-by: Patrik Flykt <patrik.flykt@intel.com>
2018-03-29 12:39:43 +03:00
Patrik Flykt
081e0eb8af net: context: Refactor net_tcp_send_data()
Refactor net_tcp_send_data() by adding callback information in the
function.

Signed-off-by: Patrik Flykt <patrik.flykt@intel.com>
2018-03-29 12:39:43 +03:00
Patrik Flykt
34d82eb949 net: context: Factor out code for TCP receive
Create a function for TCP receive.

Signed-off-by: Patrik Flykt <patrik.flykt@intel.com>
2018-03-29 12:39:43 +03:00
Patrik Flykt
8236e1e5cd net: context: Factor out TCP header length checking
TCP header length checking is needed by net_context.c.

Signed-off-by: Patrik Flykt <patrik.flykt@intel.com>
2018-03-29 12:39:43 +03:00
Patrik Flykt
3b579ffb90 net: context: Refactor sendto()
Refactor sendto() code so that destination address and its validity
is checked first, followed by offloading verification. Move context
and shutdown checks into TCP queueing function.

Signed-off-by: Patrik Flykt <patrik.flykt@intel.com>
2018-03-29 12:39:43 +03:00
Jukka Rissanen
47dafffb67 net: if: Separate IP address configuration from net_if
Move IP address settings from net_if to separate structs.
This is needed for VLAN support.

Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
2018-03-27 10:06:54 -04:00
Ravi kumar Veeramally
18422de8da net: tcp: Provide local address in TCP reset message preparation
If context is bound to IPv6 unspecified addresss and some port
number, then unspecified address is passed in TCP reset packet
message preparation. Eventually packet dropped at the peer.

Signed-off-by: Ravi kumar Veeramally <ravikumar.veeramally@linux.intel.com>
2018-02-13 13:37:20 +02:00
Ravi kumar Veeramally
1f20111ef3 net: tcp: Do not handle packet re-transmission in TCP ACK
Zephyr doesn't have luxury to create re-transmit timer per packet. So
it has different methods to handle packets in queue. But re-sending
packets on valid ack messages causing issues.

E.g. A TCP node sent two packets (packet-1, packet-2). Peer replied
two ACKs (ACK-1 and ACK-2), and these two ACK's are at rx_thread
queue. Now ACK-1 is handled and reference of packet-1 is freed
from sent list. Then if condiftion (valid ACK and connection
state is ESTABLISHED) notices that, sent list is not empty.
Restart the timer, modify sent flag and resend packets in a
list. Here packet-2 is sent again, even though ACK-2 is already
received. Situation is worse if there are more packets in the
list.

So only start the re-transmit timer in-case queue is not empty. It
allows rx_thread to handle all incoming packets (in this e.g ACKs).
When the re-trasmit timer expires, it sends the packets which
are left in queue.

Signed-off-by: Ravi kumar Veeramally <ravikumar.veeramally@linux.intel.com>
2018-02-13 13:37:20 +02:00
Paul Sokolovsky
fbaa3b1724 net: tcp: prepare_segment: Return detailed error codes.
prepare_segment() returned NULL in case of any error, which then
net_context_send() translated into -EINVAL. That's highly confusing
though, because a common case of failure for prepare_segment() is
being unable to allocate data fragment(s) (for TCP header, etc.)
So, return output pkt by reference, and detailed error status as
a return value.

Signed-off-by: Paul Sokolovsky <paul.sokolovsky@linaro.org>
2018-02-01 13:13:32 +01:00
Paul Sokolovsky
cb140154b0 net: tcp Remove recv_max_ack field from struct net_tcp
This field is set and maintained, but not actually used for anything.
The only purpose for it would be to validate ACK numbers from peer,
but such a validation is now implemented by using send_seq field
directly.

Fixes: #4653

Signed-off-by: Paul Sokolovsky <paul.sokolovsky@linaro.org>
2018-01-15 15:08:22 +02:00
Paul Sokolovsky
e36f67d1d9 net: tcp: Remove incorrect logging of "ACK errors"
Case #1: If ACK received and our retransmit (i.e. unacked) queue is
empty, it's error. It's incorrect because TCP requires ACK to set for
every packet of established connection. For example, if we didn't
send anything to peer, but it sends us new data, it will reuse the
older ack number. It doesn't acknowledge anything new on our side,
but it's not an error in any way.

Case #2: If retransmit queue is only partially acknowledged, it's an
error. Consider that we have 2 packets in the queue, with sequence
numbers (inclusive) 100-199 and 200-399. There's nothing wrong if
we receive ACK with number 200 - it just acknowledges first packet,
we can remove and finish processing. Second packet remains in the
queue to be acknowledged later.

Fixes: #5504

Signed-off-by: Paul Sokolovsky <paul.sokolovsky@linaro.org>
2018-01-15 15:07:49 +02:00
Paul Sokolovsky
ac7b1291da net: tcp: Validate incoming ACK number
Per RFC 793:

  A new acknowledgment (called an "acceptable ack"), is one for which
  the inequality below holds:

    SND.UNA < SEG.ACK =< SND.NXT

If acknowledgement is received for sequence number which wasn't yet
sent, log an error and ignore it.

Signed-off-by: Paul Sokolovsky <paul.sokolovsky@linaro.org>
2018-01-15 15:07:49 +02:00
Ravi kumar Veeramally
a0371ae92f net: tcp: Add initial support for TIMEWAIT timer
Right now in FIN_WAIT1 state, if we receive FIN+ACK message, then
tcp state changed to FIN_WAIT2 on ACK flag and immediately on FIN
flag state changed to TIME_WAIT. Then final ACK is prepared and sent
(in queue at-least) to peer. Again immediately state changed to
TCP_CLOSED, where context is freed. net_context_put frees context
and releases tcp connection. Final ACK packet which is in queue
is dropped.

As a side effect of freed ACK packet, peer device keep on sending
FIN+ACK messages (that's why we see a lot of "TCP spurious
retransimission" messages in wireshark). As a result
of context free (respective connection handler also removed), we see
lot of packets dropped at connection input handler and replying with
ICMP error messages (destination unreachable).

To fix this issue, timewait timer support is required. When tcp
connection state changed to TIMEWAIT state, it should wait until
TIMEWAIT_TIMETOUT before changing state to TCP_CLOSED. It's
appropriate to close the tcp connection after timewait timer expiry.

Note: Right now timeout value is constant (250ms). But it should
be 2 * MSL (Maximum segment lifetime).

Signed-off-by: Ravi kumar Veeramally <ravikumar.veeramally@linux.intel.com>
2017-12-31 11:58:27 -05:00
june li
c6407659f3 net: tcp: Add the frag back to caller allocated net_pkt
The original fragment chain of incoming packet will be lost and leaked
in case of early error, add frag back to packet and
let the caller do unref.

Fixes #4323

Signed-off-by: june li <junelizh@foxmail.com>
2017-11-15 12:28:18 +02:00
Paul Sokolovsky
b86b079f32 net: tcp: net_tcp_parse_opts: Convert MSS value to host byte order
Signed-off-by: Paul Sokolovsky <paul.sokolovsky@linaro.org>
2017-11-09 17:00:26 +02:00
Paul Sokolovsky
cdea2bfab7 net: tcp: Add support for TCP options parsing
Add a generic function for TCP option parsing. So far we're
interested only in MSS option value, so that's what it handles.
Use it to parse MSS value in net_context incoming SYN packet
handler.

Signed-off-by: Paul Sokolovsky <paul.sokolovsky@linaro.org>
2017-11-08 16:19:57 +02:00
Paul Sokolovsky
bc88ad750b net: tcp: Handle storage of TCP send MSS
MSS is Maximum Segment Size (data payload) of TCP. In SYN packets,
each side of the connection shares an MSS it wants to use (receive)
via the corresponding TCP option. If the option is not available,
the RFC mandates use of the value 536.

This patch handles storage of the send MSS (in the TCP structure,
in TCP backlog), with follow up patch handling actual parsing it
from the SYN TCP options.

Signed-off-by: Paul Sokolovsky <paul.sokolovsky@linaro.org>
2017-11-08 16:19:57 +02:00
Jukka Rissanen
dd7b4bae28 net: tcp: Do not run expire function in ISR context
The expire function can call net_context_unref() which tries to
get a semaphore with K_FOREVER. This is not allowed in interrupt
context. To overcome this, run the expire functionality from
system work queue instead.

Fixes #4683

Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
2017-11-06 17:16:46 +02:00
Andrei Emeltchenko
90721238c7 net: tcp: Print retry count in retransmission attempts
Print also retry count when retransmitting packets.

Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
2017-11-01 10:00:02 +02:00
Andrei Emeltchenko
86272907d8 net: Add initial retransmission timeout config option
Add option to set initial Retransmission Timeout value. The value is
different from NET_TCP_ACK_TIMEOUT since latter affects TCP states
timeout when waiting for ACK for example.

Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
2017-10-31 13:09:30 +02:00
Paul Sokolovsky
c469b7fc9f net: tcp: Avoid spurious seqno decrements
There were decrements of TCP sequence numbers, inherited from FNET
stack implementation, as was used as an initial base. RFC793 does
not specify conditions for decrementing sequence numbers, so such
decrements are an artifact of FNET implementation. In Zephyr code,
we had to compensate for these decrements by extra increments
(including an increment-by-2). So, remove decrements and associated
extra increments to simplify the code.

Signed-off-by: Paul Sokolovsky <paul.sokolovsky@linaro.org>
2017-10-25 14:19:04 +03:00
Jukka Rissanen
059959c83e net: tcp: Do not unref caller allocated net_pkt
If the caller has passed net_pkt to prepare_segment(), then
it is caller responsibility to unref it in a case of error.

Fixes #4292

Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
2017-10-13 17:23:25 -07:00
Jukka Rissanen
cab505f0c2 net: tcp: Use real MTU size for MSS for IPv6
Instead of hard coded 1280 bytes MSS, use the MTU of the link
for MSS. The minimal MSS is still 1280 which is mandated by
IPv6 RFC.

Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
2017-10-10 10:53:00 -04:00
Jukka Rissanen
025cf55e55 Revert "net: tcp: Queue FIN instead of sending it immediately"
This reverts commit 817245c564.

In certain cases the peer seems to discard the FIN packet we are
sending, which means that the TCP stream is not closed properly.
This needs more work so revert this for time being.

Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
2017-09-02 04:52:34 -04:00
Jukka Rissanen
817245c564 net: tcp: Queue FIN instead of sending it immediately
If network context is closed, send FIN by placing it to the end
of send queue instead of sending it immediately. This way all
pending data is sent before the connection is closed.

Jira: ZEP-1853

Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
2017-08-31 11:58:24 -04:00
Jukka Rissanen
75de00225f net: tcp: Print more info if net_pkt was not sent
Useful in debugging if we get information why the TCP packet was
not sent.

Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
2017-08-30 08:12:10 -04:00
Jukka Rissanen
5b29631623 net: tcp: Recover a situation if the first net_buf is too short
This is very unlikely to happen but the device will access null
pointer if we do not properly check the return value of header
check function.

Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
2017-08-30 08:12:10 -04:00
Jukka Rissanen
d2efe6027c net: tcp: Use packet clone function to copy the frags
Using memcpy() to copy net_pkt is not safe because there are
pointers inside. So use the new net_pkt_clone() to do that.

Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
2017-08-30 08:12:10 -04:00
Luiz Augusto von Dentz
9147b53d76 net: Remove check for k_delayed_work_cancel
k_delayed_work_cancel now only fail if it hasn't been submitted which
means it is not in use anyway so it safe to reset its data regardless
of its return.

Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2017-08-25 15:34:40 -04:00
Jukka Rissanen
0a978ea5ef net: tcp: Send data only in established state
If we are not in ESTABLISHED state, then there is no need to
try to resend any pending data packets.

Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
2017-08-16 14:50:57 -04:00
Jukka Rissanen
e08716001a net: tcp: Do not re-send already sent packets
If the expire send timer expires, then it sends the packet.
If that happens, then we must not try to send the same packet
again if we receive ACK etc. which can cause re-sends to happen.

Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
2017-08-16 14:50:57 -04:00
Jukka Rissanen
0674e03790 net: tcp: Remove unused variable
There was two pkt variables in net_tcp_ack_received() so removing
the extra one.

Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
2017-08-16 14:50:57 -04:00
Jukka Rissanen
cdec73d21e net: tcp: Only do ref when resending if we could send the packet
If the packet sending is slow then we must NOT increment the ref
count when re-sending it. This is unlikely but can happen if there
are lot of debug prints etc. extra activities that prevent the driver
to actually send the packet fast enough.

Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
2017-08-16 14:50:57 -04:00
Jukka Rissanen
f8ea1a59ea net: tcp: Add more debugging to TCP code
Useful when investigating issues.

Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
2017-08-16 14:50:57 -04:00
Jukka Rissanen
5325c4b594 net: tcp: Set the TCP sent flag after really sending pkt
Make sure that the sent flag is only set after we have really
sent the packet and the driver has verified that.
If the net_pkt_set_sent() is called while still in tcp.c, then
depending on how fast the device is, it might happen that the
retry timer expires before the packet is actually sent. This was
seen in frdm-k64f with ethernet and various debug prints activated.

Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
2017-08-16 14:50:57 -04:00
Andrew Boie
2e32e815ba net: fix net_tcp_state_str() declaration
The second 'const' is misguided, indicating that the returns pointer
value itself cannot be changed, but since pointers are passed by value
anyway this is not useful and was generating warnings with XCC.

The leading 'const' indicates that the memory pointed to is constant,
which is all we needed.

Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
2017-08-16 10:59:10 -07:00
Jukka Rissanen
d8e13c0c45 net: tcp: Make do_ref_if_needed() a macro
This is needed in order to get information which function is
doing the ref. With inline function this was not possible.

Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
2017-08-14 11:06:34 +03:00