Commit Graph

162 Commits

Author SHA1 Message Date
whitequark 05677dbd76 Fix 14185a16. 2017-12-18 11:42:55 +00:00
whitequark 19f52bd46c Do not fill neighbor cache with IPs not on the same network as us.
This is pointless (`route` doesn't even check the cache in that case)
and wastes cache space.
2017-12-18 11:06:26 +00:00
whitequark 8dd9bdeaad Trace neighbor discovery status on a per-socket basis.
This avoids delaying the first packets for new neighbors by
(at least) the ARP cache silence time, or potentially even
indefinitely.
2017-12-18 11:06:24 +00:00
Dan Robertson 888b098dca Process the Icmpv4Repr in IcmpSocket::process
- Use the Icmpv4Repr in IcmpSocket::process instead of the raw payload.
 - Update the IcmpSocket tests.
2017-12-09 00:10:09 +00:00
whitequark 26b8052ee9 Make packet dumps emitted for broken packets more useful.
Before this commit, only the outermost frame (the Ethernet one)
would be shown, which is really no help at all.
2017-12-08 07:11:08 +00:00
Jeremy Soller 8604eaa8f9 Allow receiving broadcast packets via UDP sockets. 2017-11-23 07:01:35 +00:00
whitequark ff530020dd Style. NFC. 2017-11-22 07:44:03 +00:00
whitequark 98a3ec8c3a Limit the rate at which sockets will request neighbor discovery.
The rate of emission of neighbor discovery packets is already
limited at the level of the entire neighbor cache, but poll()
would uselessly spin until the answer arrives (if ever).
2017-11-22 07:20:31 +00:00
whitequark eaa50d0003 Rewrite the ARP cache to allow for flood protection and expiration. 2017-11-21 10:53:55 +00:00
Egor Karavaev 1e809daf7a Make `Error::Unaddressable` ignored for ICMP sockets as well. 2017-11-13 14:16:03 +00:00
Egor Karavaev eb7d0e346e ICMP sockets don't end ICMP packets processing. 2017-11-13 14:16:03 +00:00
whitequark 19373c58c8 Style. NFCI. 2017-11-09 02:07:24 +00:00
Dan Robertson adb5014780 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 c3e07dad9a Store plain DeviceT instead of Managed<_> in EthernetInterface 2017-11-08 09:34:35 +00:00
whitequark d9fa7f6bc6 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 7039ec8b04 Rename a few tests. NFC. 2017-11-04 02:42:51 +00:00
Philipp Oppermann 6a8e21cec0 Redesign the phy::Device trait to avoid Drop impls. 2017-11-03 23:15:07 +00:00
Dan Robertson b64257812b 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 1cafcfc19f 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 a9a00baa49 Rename Cargo features: socket-* → proto-*. 2017-10-25 00:20:40 +00:00
whitequark a7e6a1b5ae Simplify. NFC. 2017-10-24 23:12:55 +00:00
Dan Robertson eef65d2676 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 4f689be81b Dump malformed ingress packets at DEBUG log level. 2017-10-24 20:37:52 +00:00
Egor Karavaev 19b1b764ed Implement a SocketRef smart pointer to detect state changes. 2017-10-05 03:44:20 +00:00
whitequark eb33cdcf68 Fix a typo. 2017-10-04 01:54:39 +00:00
whitequark b2cfb94b48 Explain the return value of poll(). 2017-10-03 20:41:45 +00:00
whitequark bf9584555c 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 5be76b8dc1 Add support for IPv4 default gateway. 2017-10-03 15:17:29 +00:00
whitequark 72481c2661 Formatting. NFC. 2017-10-03 14:27:01 +00:00
Steffen Butzer 61cb64406d 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 f9093d15aa 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 dd0f4b706a Enforce some lints. 2017-09-25 00:46:53 +00:00
whitequark 4826d37c45 Allow disabling any of: raw, TCP or UDP sockets. 2017-09-25 00:20:22 +00:00
Egor Karavaev 0e88617b82 Uncomment associated constants. 2017-09-24 23:25:18 +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
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 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 b585fbd368 Exhaustion of transmit buffers should not be a reportable error. 2017-08-31 16:27:50 +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 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 996389d653 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 cdf236412f Clarify a function name. 2017-08-28 12:45:33 +00:00
whitequark 695c61fd05 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 34db543cac 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 379bc60924 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 760174048d 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 bab5c0b7aa Unify EthernetInterface::{send_response,emit} transmit paths. 2017-08-28 02:11:04 +00:00
whitequark 1d01189278 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 5b2de544c8 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 9d0084171f Rework responses to TCP packets and factor in RST replies to TcpSocket. 2017-08-22 22:32:05 +00:00
whitequark 7c9a072dd2 Fix a typo that broke ARP replies. 2017-08-22 07:44:43 +00:00
whitequark 925e13b61a Simplify ARP handling code in EthernetInterface. 2017-08-21 07:28:38 +00:00
whitequark be1038f382 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 8d8a4ea583 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
whitequark d35fd9940e Fix ICMP error returned by EthernetInterface for unknown IP protocols. 2017-07-24 07:07:43 +00:00
whitequark 936bd44f8f Clean up socket error handling in EthernetInterface. 2017-07-24 07:01:35 +00:00
whitequark c8d714cd87 Reorganize EthernetInterface impl. NFC. 2017-07-24 06:56:06 +00:00
whitequark b97cacd521 Inject the current timestamp into Device::{transmit,receive}.
Various parts of smoltcp require an arrow of time; a monotonically
increasing timestamp. Most obviously this is TCP sockets, but
the tracer and the pcap writer devices also benefit from having
timestamps. There are a few ways this could be implemented:
  1. using a static Cell, global for the entire smoltcp crate;
  2. using a static method on Device;
  3. using an instance method on Device;
  4. passing the current timestamp into *Interface::poll.

The first two options are undesirable because they create a notion
of global clock, and interfere e.g. with mocking.
The third option is undesirable because not all devices are
inherently tied to a particular clock, e.g. a loopback device isn't.

Therefore, the timestamp is injected into both sockets and devices
through the *Interface::poll method.
2017-07-23 09:48:14 +00:00
whitequark 6ad8fea31f Fix a typo in 5c3fc493. 2017-06-27 21:51:56 +00:00
whitequark 04bd8a0051 Discard packets with non-unicast source addresses at IP level.
This is required by RFC 1122 and helps avoid "broadcast storms".
2017-06-26 17:01:23 +00:00
Egor Karavaev 4f2804e104 Don't reply to a TCP RST packet with another TCP RST packet. 2017-06-26 05:48:30 +00:00
Egor Karavaev 1e8cd1a65f Refactor EthernetInterface::poll.
Also, after this commit, we stop iterating over TCP/UDP sockets after
finding one that accepts the packet.
2017-06-26 05:48:27 +00:00
whitequark b86d22701d Expose PSH flag in TcpRepr. 2017-06-25 08:20:25 +00:00
whitequark 74823b0dff try! → ? 2017-06-24 16:34:32 +00:00
whitequark 8b27330c8b Do not attempt to validate length of packets being emitted.
This is a form of an uninitialized read bug; although safe it caused
panics. In short, transmit buffers received from the network stack
should be considered uninitialized (in practice they will often
contain previously transmitted packets or parts thereof). Wrapping
them with the only method we had (e.g. Ipv4Packet) treated the buffer
as if it contained a valid incoming packet, which can easily fail
with Error::Truncated.

This commit splits every `fn new(buffer: T) -> Result<Self, Error>`
method on a `Packet` into three smaller ones:
  * `fn check_len(&self) -> Result<(), Error>`, purely a validator;
  * `fn new(T) -> Self`, purely a wrapper;
  * `fn new_checked(T) -> Result<Self, Error>`, a validating wrapper.

This makes it easy to process ingress packets (using `new_checked`),
egress packets (using `new`), and, if needed, maintain the invariants
at any point during packet construction (using `check_len`).

Fixes #17.
2017-06-24 11:42:32 +00:00
whitequark be29789192 Fix an unimplemented!() invocation that should be unreachable!(). 2017-06-22 00:38:45 +00:00
whitequark 83cf86f1d0 Unbreak parsing of ICMP unreachable messages.
Fixes #16.
2017-06-21 04:08:33 +00:00
Egor Karavaev ca56baca65 Add `RawSocket`. 2017-06-21 03:29:31 +00:00
whitequark 1d46ccf432 fn Device::mtu() -> usize → Device::limits() -> DeviceLimits 2017-03-07 11:10:26 +00:00
whitequark 393ebbe682 Don't put non-unicast (IP or Ethernet) addresses into ARP cache.
Thanks @little-dude for pointing this out--it's probably a DoS bug.
2017-03-07 06:32:18 +00:00
whitequark 5137608aed Follow-up to b9e79d19; always process broadcast frames. 2017-03-06 04:00:13 +00:00
whitequark d25eebc0ef Ignore Ethernet frames for which we aren't a destination. 2017-03-06 03:58:19 +00:00
whitequark 0d32fcee5b Send an ARP request when the destination is not in cache. 2017-03-05 04:59:51 +00:00
whitequark bc1d65ea89 Send the TCP MSS option. 2017-01-27 02:56:27 +00:00
whitequark 077513fda6 Add support for TCP MSS option in TCP representation. 2017-01-27 02:56:27 +00:00
whitequark 591993014e Reject, not accept, TCP RST packets in LISTEN state.
These packets may have been destined for a different socket.
2017-01-17 04:33:37 +00:00
whitequark 578d7bce5f Calculate IP payload length from the total length field.
Before this commit, IP payload length was calculated by subtracting
the IP header length from the total underlying buffer length, which
fails if the underlying buffer has padding, e.g. like Ethernet
does.
2017-01-14 11:07:06 +00:00
whitequark 362c954624 Make interfaces not own the sockets. 2017-01-11 05:25:54 +00:00
whitequark 234e5ef29e Implement socket sets. 2017-01-11 04:05:41 +00:00
whitequark 0e006383f2 Use Managed/ManagedSlice for EthernetInterface. 2017-01-10 11:37:12 +00:00
whitequark 08ac98e4bc Reorder type parameters of Interface. 2017-01-01 08:18:25 +00:00
whitequark 27ccfc1bb0 Implement TCP retransmission. 2016-12-31 08:35:46 +00:00
whitequark a8fc4fd832 Improve the user-facing TCP socket API. 2016-12-27 17:49:40 +00:00
whitequark ea78053dc1 Factor out IpRepr into the wire module. 2016-12-26 11:20:20 +00:00
whitequark ea07e79bdf Group IP header parts in the socket layer as struct IpRepr. 2016-12-26 10:06:49 +00:00
whitequark bdfb99ea16 Validate TCP ACKs. 2016-12-25 09:22:49 +00:00
whitequark f46c77bdd6 Fix autoselection of source address. 2016-12-23 07:57:54 +00:00
whitequark 6d8d3cb29d Use correct sequence numbers in TCP RST packets. 2016-12-23 07:34:10 +00:00
whitequark 2f24fb263b Populate ARP cache from incoming IP packets. 2016-12-23 07:31:42 +00:00
whitequark 1ad8f9c9bd Implement conversion of incoming TCP connections into TCP streams. 2016-12-20 22:57:21 +00:00
whitequark 5a64a87dbe Reply with ICMP dest. unreachable or TCP RST from unused ports. 2016-12-20 19:18:35 +00:00
whitequark 0d9a8a417d Add some sanity into enumeration names (avoid "*Type"). 2016-12-20 13:54:11 +00:00
whitequark 095005a597 Empty transmit buffers before starting to receive. 2016-12-20 00:07:02 +00:00
whitequark f86fac2223 Sort out buffer lengths. 2016-12-19 23:50:04 +00:00
whitequark 2dc837be9d Fix lifetime variance. 2016-12-17 06:39:18 +00:00
whitequark 31e44445f5 Working UDP loopback. 2016-12-17 05:12:45 +00:00