104 Commits

Author SHA1 Message Date
whitequark
34c3a8c905 Rewrite the ARP cache to allow for flood protection and expiration. 2017-11-21 10:53:55 +00:00
Egor Karavaev
907f3659a4 Make Error::Unaddressable ignored for ICMP sockets as well. 2017-11-13 14:16:03 +00:00
Egor Karavaev
752ae033db ICMP sockets don't end ICMP packets processing. 2017-11-13 14:16:03 +00:00
whitequark
ffcd3ab80d Style. NFCI. 2017-11-09 02:07:24 +00:00
Dan Robertson
ef4af850e0 Add ICMP sockets
- Add support for ICMP sockets
 - Add tests for ICMP sockets
 - Rename proto-<type> features to socket-<type>
 - Update documentation
2017-11-09 00:08:24 +00:00
Philipp Oppermann
4ae84ab36a Store plain DeviceT instead of Managed<_> in EthernetInterface 2017-11-08 09:34:35 +00:00
whitequark
f58cc4bcbb Rename proto-* features back to socket-*.
A proto-* feature does not make sense for ICMP, where the protocol
is always enabled, but sockets, not.
2017-11-06 09:51:03 +00:00
whitequark
fd7109b2e4 Rename a few tests. NFC. 2017-11-04 02:42:51 +00:00
Philipp Oppermann
198fe239f1 Redesign the phy::Device trait to avoid Drop impls. 2017-11-03 23:15:07 +00:00
Dan Robertson
d1d80ca121 Do not send ICMPv4 responses to broadcasts
- Do not send ICMPv4 responses for packets with a broadcast destination
   address.
   - Do not send DstUnreachable with ProtoUnreachable on receipt of a
     packet with an unknown protocol with a non-unicast destination
     address.
   - Do not send DstUnreachable with PortUnreachable on receipt of a
     UDP packet when no sockets are listening on the destination port
     and the destination address is a non-unicast address.
 - Send the correct amount of the original datagram when sending Destination
   Unreachable error responses.
   - Do not assume that a ip datagram has a payload when sending a proto
     unreachable ICMPv4 error response.
 - Add tests to iface tests.
   - Ensure ICMP error responses are correctly formed when the
     datagram has no payload.
   - Ensure ICMP error responses are correctly handled for UDP packets
     when no socket is listening on the destination port.
   - Ensure the correct amount of the original payload is returned in
     Destination Unreachable responses.
2017-11-01 06:34:10 +00:00
Dan Robertson
7a2271dfd6 Tests: Add basic interface tests
- Add tests for the following
   - ICMP error responses are not sent in response to broadcast requests
   - ARP requests are responded to and inserted into the cache
   - ARP requests for someone else are not responded to, but the sender
     is still inserted in the cache
2017-10-28 19:33:01 +00:00
whitequark
7e4971df32 Rename Cargo features: socket-* → proto-*. 2017-10-25 00:20:40 +00:00
whitequark
581e7b3f6f Simplify. NFC. 2017-10-24 23:12:55 +00:00
Dan Robertson
fea462837d Implement set_ttl for Tcp and Udp sockets
- Add the ttl member to the IpRepr
 - Add the ttl member along with setters and getters to the tcp and udp
   socket types
 - Add unit tests for the new set_ttl parameter
 - Update usage of IpRepr to include the ttl value
2017-10-24 23:02:18 +00:00
whitequark
7c6cd6b9a3 Dump malformed ingress packets at DEBUG log level. 2017-10-24 20:37:52 +00:00
Egor Karavaev
096ce02ac4 Implement a SocketRef smart pointer to detect state changes. 2017-10-05 03:44:20 +00:00
whitequark
067fb2ddc9 Fix a typo. 2017-10-04 01:54:39 +00:00
whitequark
b0fc1d9542 Explain the return value of poll(). 2017-10-03 20:41:45 +00:00
whitequark
d88ef3c8d3 Drop the pretense that anyone cares about non-IP over Ethernet.
To be precise, I'm talking about IPX, AppleTalk and DECnet here,
not things like PPPoE, ATAoE, FCoE, or PTP, which make sense
to implement on top of EthernetInterface but do not work on
the same level on top of it as IP.
2017-10-03 15:17:29 +00:00
Egor Karavaev
331dc10780 Add support for IPv4 default gateway. 2017-10-03 15:17:29 +00:00
whitequark
d16e0bd212 Formatting. NFC. 2017-10-03 14:27:01 +00:00
Steffen Butzer
d5147efb82 support hardware based checksum settings in during packet send/recv
- makes sure the checksum is zeroed when not emitted by software
  (This is required by some implementations such as STM32 to work properly)
2017-10-02 21:40:08 +00:00
Steffen Butzer
9b1b0b4bde phy: introduce hardware based checksum settings, rename DeviceLimits
this contains a rename of occurrences of
DeviceLimits -> DeviceCapabilities.
2017-10-02 21:40:08 +00:00
whitequark
cedf66a733 Enforce some lints. 2017-09-25 00:46:53 +00:00
whitequark
a983c629b9 Allow disabling any of: raw, TCP or UDP sockets. 2017-09-25 00:20:22 +00:00
Egor Karavaev
0454c3f8f6 Uncomment associated constants. 2017-09-24 23:25:18 +00:00
whitequark
546b3670ef 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
51b2f18d11 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
Egor Karavaev
a2c66fdd88 Factor out TcpSocket::accepts. 2017-09-08 00:57:42 +00:00
Egor Karavaev
44cf21b91b Factor out UdpSocket::accepts. 2017-09-08 00:57:19 +00:00
Egor Karavaev
5303501173 Factor out RawSocket::accepts. 2017-09-08 00:56:42 +00:00
whitequark
6ebcddd077 According to RFC 1122, unsupported IP options MUST be ignored. 2017-09-01 19:31:09 +00:00
whitequark
3fff475c8f An unaddressable egress packet should not be a reportable error. 2017-09-01 10:30:56 +00:00
whitequark
017210ea28 Exhaustion of transmit buffers should not be a reportable error. 2017-08-31 16:27:50 +00:00
whitequark
b92708596a 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
1ece71a774 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
39464a53fc Compute soft deadline in poll() and use nonblocking sockets.
Before this commit, anything that touched RawSocket or TapInterface
worked partly by accident and partly because of a horrible crutch
that resulted in massive latencies as well as inevitable packet loss
every time an ARP request had to be issued. Also, there was no way
to use poll() other than by continuously calling it in a busy loop.

After this commit, poll() indicates when the earliest timer expires,
and so the caller can sleep until that moment (or until packets
arrive).

Note that there is a subtle problem remaining: every time poll()
is called, every socket with a pending outbound packet whose
IP address doesn't correspond to a MAC address will send a new
ARP request, resulting in potentially a whole lot of such requests.
ARP rate limiting is a separate topic though.
2017-08-29 19:47:11 +00:00
whitequark
2354e0b29d Clarify a function name. 2017-08-28 12:45:33 +00:00
whitequark
8ae9b21b64 Break up the EthernetInterface::dispatch macro atrocity into functions.
There wasn't any real reason for it to be a macro, it was ugly
and unreadable, and it resulted in combinatorial bloat when compiled.
2017-08-28 05:49:56 +00:00
whitequark
43a547fb0c Factor out packet parsing from Socket::process.
Not only is it incredibly wasteful, but this information is
in any case already necessary within the EthernetInterface::process_*
methods.
2017-08-28 05:48:16 +00:00
whitequark
3974dc780f Get rid of unused arguments in Socket::{process,dispatch}.
I've left those "for consistency" but it just implies data
dependencies where there are none, and bloats signatures.
2017-08-28 04:14:25 +00:00
whitequark
ab0eccd213 Get rid of IpPayload and indirection in Socket::dispatch.
This was just completely pointless, and only served to obfuscate
the data path and make testing harder.
2017-08-28 03:56:34 +00:00
whitequark
ad9fa282e6 Unify EthernetInterface::{send_response,emit} transmit paths. 2017-08-28 02:11:04 +00:00
whitequark
917f89e14b Use FnOnce, not FnMut, in Socket::dispatch() functions.
There was never any reason to use FnMut and this significantly
simplifies the job of the borrow checker.
2017-08-28 00:59:33 +00:00
whitequark
72359cdd37 Radically simplify and optimize TCP packet dispatch.
This commit completely reworks packet dispatch in TCP sockets,
and brings significant improvements to processing as well.

In particular:
  * Challenge ACKs now do not reset retransmit timer; instead,
    TcpSocket::process directly returns a TcpRepr without altering
    any internal state at all.
  * Retransmit and close (aka TIME-WAIT) timers are unified
    and restructured into a enum that actually matches semantics
    of the timers.
  * If a packet cannot be emitted, no internal state is changed.
  * The dispatch of RST packets in case of connection abort
    is brought in line with dispatch of all other packets.
  * Packet dispatch now follows a series of steps with clean
    separation of concerns, like packet processing:
      1. If we should retransmit, update state to assume that
         all in-flight packets are lost.
      2. Prepare the packet that would be sent next, considering
         the in-flight packets, if any.
      3. Check if the packet contains anything new, or it's the same
         as the one already in flight. If it is, bail.
      4. Finalize and try to actually transmit the packet.
         If we can't do that, bail.
      5. Update the internal state to reflect that the packet
         we've just sent is in flight.
2017-08-25 03:53:31 +00:00
whitequark
bc2a894c00 Rework responses to TCP packets and factor in RST replies to TcpSocket. 2017-08-22 22:32:05 +00:00
whitequark
7e6e379e09 Fix a typo that broke ARP replies. 2017-08-22 07:44:43 +00:00
whitequark
77ffe7c065 Simplify ARP handling code in EthernetInterface. 2017-08-21 07:28:38 +00:00
whitequark
ca6fa2d423 Assert that the transmit frame returned by driver has right length.
We checked for frames too short before, but frames too long are
troublesome too, since e.g. TCP and UDP do not carry an explicit
payload length in their headers.
2017-08-06 15:09:55 +00:00
whitequark
5bf64586cd Get rid of Result<_, ()>.
The use of this type has several drawbacks:
  * It does not allow distinguishing between different error
    conditions. In fact, we wrongly conflated some of them
    before this commit.
  * It does not allow propagation via ? and requires manual use
    of map_err, which is especially tiresome for downstream code.
  * It prevents us from expanding the set of error conditions
    even if right now we have only one.
  * It prevents us from blanket using Result<T> everywhere
    (a nitpick at most).

Instead, use Result<T, Error> everywhere, and differentiate error
conditions where applicable.
2017-07-27 13:55:47 +00:00