Commit Graph

272 Commits (250a84e51329f6b282764ce0406ed1747cadb258)

Author SHA1 Message Date
whitequark 250a84e513 Implement a Device that emits a stream in libpcap format. 2017-07-23 14:56:24 +00:00
whitequark e381f6ec3f Fix an off-by-three-orders-of-magnitude error. 2017-07-23 12:03:56 +00:00
whitequark cf37a34443 Fix argument order in Tracer::new callbacks. 2017-07-23 12:01:53 +00:00
whitequark a9e6b49aa6 Rename into_lower → into_inner. 2017-07-23 10:20:05 +00:00
whitequark aeba4f9bc6 Clean up some type variable names and trait bounds. NFC. 2017-07-23 10:15:56 +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 fe6fb087e5 Move macros into their own module.
This allows us to use `enum_with_unknown` in `phy`.
2017-07-23 07:54:36 +00:00
whitequark eae7907f60 Add EthernetTracer, a specialization of Tracer for EthernetFrame.
This makes the loopback example much nicer, #[cfg]-wise.
2017-07-23 06:28:00 +00:00
whitequark 6dd833f1f7 Use proper clock mocking in the loopback example. 2017-07-23 06:08:13 +00:00
whitequark bdfc47d633 Log correct delay when performing TCP retransmit.
Before, the delay was erroneously multiplied by 2 and also did not
take processing delay into account.
2017-07-23 05:09:38 +00:00
whitequark 051169a49d Determine MTU in TapInterface instead of hardcoding 1536. 2017-07-23 04:40:35 +00:00
whitequark 94796a566b Document the loopback. 2017-07-14 03:30:00 +00:00
whitequark 75ddbe9776 Add a bare-metal usage example. 2017-07-14 03:18:11 +00:00
whitequark 312ff93c86 Remove default impl for Device::limits().
We should not assume any default MTU.
2017-07-14 03:18:11 +00:00
whitequark f3e54966fd LoopbackInterface → Loopback. 2017-07-14 01:17:06 +00:00
whitequark 63ab7d4e7a Implement loopback interfaces.
This also adds a default implementation of Device::limits.
2017-07-14 01:14:40 +00:00
whitequark 5556f09351 Annotate all simple getters with #[inline]. 2017-07-04 18:46:36 +00:00
whitequark 3f9805b2c1 Remove *Socket::{process,dispatch} from public interface.
These no longer have to be public, since our required Rust version
has pub(crate).
2017-06-30 20:55:46 +00:00
whitequark 938fb99070 In {Tcp,Udp}Socket::process, make protocol check an assertion.
We filter sockets by type upstream of the process() calls.
2017-06-30 19:17:14 +00:00
whitequark 6cc2d494ca Travis: require build on stable Rust to succeed. 2017-06-29 16:09:01 +00:00
whitequark 2c1e234b91 Remove Socket::{process,dispatch} from public interface.
These no longer have to be public, since our required Rust version
has pub(crate). In addition Socket::process is not used at all.
2017-06-29 15:56:03 +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
whitequark 6cd8cb4422 Transmit actual UDP checksum of all-zeroes as all-ones instead. 2017-06-26 16:57:21 +00:00
whitequark cbf6e5cdbc Try to trigger fast retransmit when we detect a missing TCP segment.
The changes in this commit affect the following scenario:
  * Remote end sends octets 1..2, they are delivered and buffered
    on local end;
  * Remote end sends octets 3..4, they are lost;
  * Remote end sends octets 5..6, they are delivered but cannot
    be buffered on local end because we don't perform reassembly.

Before this commit, we would silently drop the segment with octets
5..6, relying on retransmission timer on the remote end. This works,
but can result in severe decrease in throughput. After this commit,
we send a duplicate ACK, which may trigger fast retransmit, if
implemented by the congestion control algorithm on the remote end.
2017-06-26 08:44:07 +00:00
whitequark 62c9b7d6fa In examples, trace the packets being dropped by the fault injector. 2017-06-26 08:44:07 +00:00
whitequark 02abd7a983 In examples, print packet dumps with timestamps, too.
This helps debugging retransmit issues.
2017-06-26 08:01:00 +00:00
whitequark 2704a10dd8 Add missing #[derive]s on wire::IpVersion. 2017-06-26 06:06:18 +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 0f0c545755 Make sure representation emission covers every octet of the buffer.
Also fix a bug where TcpRepr::emit would not clear the urgent
pointer.
2017-06-26 03:44:36 +00:00
whitequark 050dd788c1 Set TCP PSH flag when sending the last buffered data. 2017-06-25 23:12:30 +00:00
whitequark b86d22701d Expose PSH flag in TcpRepr. 2017-06-25 08:20:25 +00:00
whitequark db75f70fa3 Fix a few typos in TCP socket code (NFC). 2017-06-25 08:05:37 +00:00
whitequark 0a9c5d52dd Remove an unnecessary length check. 2017-06-24 16:34:55 +00:00
whitequark 74823b0dff try! → ? 2017-06-24 16:34:32 +00:00
whitequark 023d8deea5 Disable checksum validation on wire level when fuzzing. 2017-06-24 15:26:15 +00:00
whitequark fce23593fc Fix insufficient length validation in TCP packets.
Found via cargo-fuzz.
2017-06-24 12:29:39 +00:00
whitequark c73af2b247 Fix insufficient length validation in UDP packets.
Found via cargo-fuzz.
2017-06-24 12:15:18 +00:00
whitequark 6790eac6d9 Fix a crash parsing a malformed IPv4 packet.
Found via cargo-fuzz.
2017-06-24 12:02:34 +00:00
whitequark 9f8db1d8f9 Factor out wire::tcp::field::OPTIONS. 2017-06-24 12:02:34 +00:00
whitequark 315b51d7da Fix a crash parsing a truncated TCP packet with options.
Found via cargo-fuzz.
2017-06-24 11:48:17 +00:00
whitequark 6842d7013d Fix a crash parsing malformed TCP options.
Found via cargo-fuzz.
2017-06-24 11:48:17 +00:00
whitequark c09e96a657 Fix a crash printing a malformed TCP packet.
Found via cargo-fuzz.
2017-06-24 11:48:13 +00:00
whitequark 3eaa96957c Add packet parser fuzzer. 2017-06-24 11:43:12 +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 cc5fb0e5ef Clean up a few doctests. 2017-06-24 09:02:12 +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
whitequark adc51fab7f Actually export socket::SocketSetItem publicly.
It was unintentionally left unnameable. Fixes #14.
2017-06-21 03:57:13 +00:00