Commit Graph

380 Commits

Author SHA1 Message Date
whitequark e38ec8f397 Update README.
We don't really care about fast open one way or another, this entry
was a misunderstanding of RFC 793's behavior wrt data in SYN packets.
2017-09-22 19:20:24 +00:00
whitequark 711c05f7b1 Make TCP more RFC 5681 compliant wrt immediate ACKs. 2017-09-22 18:57:47 +00:00
whitequark a5a9bb44c9 Clarify inline TCP documentation. 2017-09-22 18:40:23 +00:00
whitequark a1b2605af7 Revert "Keep dispatching packets from a socket as long as there are any."
This reverts commit 51b2f18d1165bf7257de8894df101299cc93b094.

There's no throughput difference so far as I could measure, but
this greatly increases worst-case latency. At some later point
we could perhaps pass a deadline to the poll function, but for now
reverting this is simple enough.
2017-09-22 18:09:18 +00:00
whitequark 05a480575c Keep dispatching packets from a socket as long as there are any.
Typically, the poll function is used as a part of a larger RTOS.
If we only dispatch one packet per socket per poll() call,
then we have to wait for a complete scheduler roundtrip,
which is potentially a lot of time, and as a result we are
not filling the peer's window efficiently.
2017-09-22 17:55:49 +00:00
whitequark b90cee43bb Fix a warning. 2017-09-22 17:38:58 +00:00
whitequark 8166037a91 Handle buffer wraparound in TCP reassembly code. 2017-09-22 17:10:51 +00:00
whitequark 075a2ebb83 Make sure all side-effectful RingBuffer methods are #[must_use].
Some of them already use Result, but the ones that can return
an empty slice (or a slice shorter than requested) also must have
their return value (at least) checked.
2017-09-22 17:08:46 +00:00
whitequark 0bbab2aeed Add RingBuffer::{enqueue_allocated,dequeue_allocated}.
These should be used instead of enqueue_many because they do not
require the caller to handle wraparound explicitly.
2017-09-22 17:04:56 +00:00
whitequark e6bf27d078 Add RingBuffer::{read_allocated,write_unallocated}. 2017-09-22 16:23:37 +00:00
whitequark 5aae15aaba Fix an issue where TCP packets would have zero IP payload length. 2017-09-22 10:14:26 +00:00
whitequark a9d6a9b7b8 Fix a few warnings. 2017-09-22 10:06:40 +00:00
whitequark 7a2cd7842d Implement reassembly of out-of-order TCP segments. 2017-09-22 10:06:40 +00:00
whitequark b6e4e23868 Clean up PSH flag handling. 2017-09-22 08:15:29 +00:00
whitequark d7da46fd3b Do not clear remote_last_ts in TcpSocket::set_timeout().
After this change, if an 1s timeout is set on a socket that received
no packet for 2s, it will be instantly aborted, which seems
more reasonable. Also, this makes the `self.remote_last_ts.is_none()`
branch in TcpSocket::dispatch() actually behave as described.
2017-09-22 06:16:58 +00:00
whitequark f23bfe2014 Clean up and document TCP MSS calculations. 2017-09-22 06:02:03 +00:00
whitequark ba2d7f483a Implement a buffer (re)assembler. 2017-09-20 20:46:15 +00:00
whitequark 2c4222a0b6 smoltcp;:parsing → smoltcp::parsers. 2017-09-20 20:18:50 +00:00
whitequark 9281733209 Implement TCP timeouts. 2017-09-18 11:05:40 +00:00
whitequark fe80bca19d Implement TCP keep-alive. 2017-09-16 10:54:59 +00:00
whitequark be0dcb145c Fix warnings. 2017-09-15 06:05:41 +00:00
whitequark e8788be3a0 RingBuffer::{empty,full}→is_{empty,full}.
Query methods in Rust conventionally start with the "is" prefix.
2017-09-08 23:23:40 +00:00
whitequark 5ffce2c1a6 Remove Error::Rejected.
This wasn't an actual error, just a poorly designed communication
mechanism between sockets and whatever lies on the layer below them.
2017-09-08 00:59:46 +00:00
Egor Karavaev 8404fe908c Factor out TcpSocket::accepts. 2017-09-08 00:57:42 +00:00
Egor Karavaev 02b699e18c Factor out UdpSocket::accepts. 2017-09-08 00:57:19 +00:00
Egor Karavaev b4d6a53e34 Factor out RawSocket::accepts. 2017-09-08 00:56:42 +00:00
whitequark 9b242c7099 Send a challenge ACK in response to an unacceptable TCP ACK. 2017-09-08 00:11:44 +00:00
whitequark 844843c4bc Remove RingBuffer::set_len().
set_len() with a positive length change is better represented
with enqueue(), and set_len() with a negative length change
is not really a valid operation on its own.
2017-09-07 23:54:39 +00:00
whitequark 1102bd94e7 Refactor the "random access" ring buffer interface. 2017-09-07 23:47:42 +00:00
whitequark 5dc0353b2a Refactor the "continuous" ring buffer interface.
This also makes TcpSocket::{send,recv}_slice slightly more efficient
in case when the slice wraps around the corresponding buffer,
halving the necessary amount of calls.
2017-09-07 21:17:31 +00:00
whitequark a9719f4a13 Merge the TCP ring buffer and generic ring buffer.
This adds a few methods to RingBuffer that don't quite fit into
its interface (the slice ones), but we can fix that later.
2017-09-07 00:09:34 +00:00
whitequark 27a23ed3c3 Don't instantly ACK every received TCP segment.
This is prohibited by RFC 1122. Instead, aggregate them, and respond
once in the egress function.

However, still instantly send challenge ACKs to trigger fast
retransmit.
2017-09-05 23:23:50 +00:00
whitequark bdb9c03081 Update feature list in README to mention everything from RFC 1122. 2017-09-03 12:03:55 +00:00
whitequark 8876d71802 According to RFC 1122, unsupported IP options MUST be ignored. 2017-09-01 19:31:09 +00:00
whitequark 7db21529e5 An unaddressable egress packet should not be a reportable error. 2017-09-01 10:30:56 +00:00
whitequark f8edf0faea Unbreak traffic shaper in the fault injector. 2017-08-31 21:39:01 +00:00
whitequark b585fbd368 Exhaustion of transmit buffers should not be a reportable error. 2017-08-31 16:27:50 +00:00
whitequark 6da3e5f217 Fix an inaccurate comment. 2017-08-31 14:33:10 +00:00
whitequark 47770a5ec2 Fix an unused import warning. 2017-08-31 14:31:32 +00:00
whitequark a71542b2f2 Allow querying the size of the TCP transmit and receive buffers.
This may be useful to e.g. ensure the complete transmit buffer
is flushed before proceeding.
2017-08-31 13:22:20 +00:00
whitequark 13dbe09fba TCP socket debug messages "sending <flags>" should be at DEBUG level.
They're not exceptional.
2017-08-31 12:39:05 +00:00
whitequark 9a5d056d7f Add a TCP data source endpoint to the server example. 2017-08-31 09:09:16 +00:00
whitequark 80e510c9e2 Dispatch a TCP ACK every time window increases at all.
Commit 21282fdb was not completely sufficient because e.g. receiving
one octet and then blocking meant that an ACK with window length
of one is then sent, and this isn't motivating the other TCP stacks
all that much.

In any case, preemptively notifying the peer of window size increase
can only be beneficial, modulo network congestion.
2017-08-31 00:14:29 +00:00
whitequark 5e48567297 Send a TCP ACK after window increases from zero to non-zero. 2017-08-30 23:09:31 +00:00
whitequark 6324d3384a More rigorously treat the TcpSocket::remote_last_ack field.
Zero is a valid sequence number, treating it as an absence of value
isn't any good. This is unlikely to cause any real harm but it
just isn't good practice, nor does it make for understandable code.
2017-08-30 22:40:07 +00:00
whitequark 41ceeea9ac Fix the TCP SEQ acceptability check.
It has nothing to do with the last ACK transmitted.
2017-08-30 22:26:35 +00:00
whitequark c2bc20e9bf Move the TCP receive window clamping hack downwards in stack.
Otherwise, our response ACKs did not get the clamping treatment,
and severe packet loss resulted.

Also, explain why it's needed and how it works.
2017-08-30 14:00:14 +00:00
whitequark d53bdab029 Fix Ipv4Packet::payload{,_mut}() returning overly long buffers.
These functions only skipped the header, but what they should have
done is cut the packet at its total length and skip the header.
Otherwise, if the buffer the IP packet is constructed from contains
padding, such as Ethernet packets, the payload would be too long.
2017-08-30 13:34:50 +00:00
whitequark 5a066fbc6c Return from EthernetInterface::poll() on errors, don't swallow them.
We still print them into our debug log though, because it has more
context; the caller may opt to ignore any poll errors and only
use the smoltcp debug log as a, well, debugging aid, or it could
print user-visible warnings to alert the user to unusual network
conditions.
2017-08-30 10:20:11 +00:00
whitequark 7b3574e6ee Rework TCP retransmit logic to be much more robust.
Before this commit, if the amount of data in the buffer caused it
to be split among many outgoing packets, and retransmit timer
was active, the socket would behave very erratically and flood
the peer.
2017-08-30 10:12:53 +00:00