Instead of configuring the ifaces ip address when a dhcp server offers
and ip, we now use the requested_ip option, based on the offered ip
(yiaddr). The user now only has to configure the iface once the dhcp
transaction has completed (Ack'd).
Prior to this change, the neighbor cache would get limited even when the
device failed to process our arp packet, which could put the socket in
the waiting state in the next poll.
This change only limits the cache rate if the device successfully
consumed our packet.
Previously, the window update was sent anytime it changed. This is
not desirable for 2 reasons:
- It would send window updates in TimeWait or Closed states, which is incorrect.
- It would send window updates in states where we've already received the
remote side's FIN, such as CloseWait. This is not necessarily incorrect, but
is useless, since the remote side is not going to send us more data, therefore
it's not interested in our window size anymore.
This allows applications to distinguish whether the remote end has
gracefully closed the connection with a FIN (in which case it has
received all the data intact), or the connection has failed due to e.g. a
RST or a timeout (in which case the received data may be truncated).
Previously, `ack_reply()` was sending the ack number present in `remote_last_ack`,
which is only updated by `dispatch`. This means the ack replies could contain
a wrong, old ack number.
Most of the time this simply caused wasting an extra roundtrip until the socket state
settles down, but in extreme cases it could lead to an infinite loop of packets, such
as in https://github.com/smoltcp-rs/smoltcp/issues/338Fixes#338
This fixes build on latest nightly. The cause of the breakage
is this commit:
7c4ca59f4b
which added a #[must_use = "if you don't need the old value, you
can just assign the new value directly"] hint to mem::replace.
When packet buffer's payload buffer does not have enough contiguous
window left, the ring buffer roll over uses an incorrect size
causing the ring buffer pointer not resetting to the head.
When the payload enqueued is larger than 1/2 of the payload ring
buffer, this bug will cause the slice returned by
`PacketBuffer::enqueue` to not match the requested size, and
trigger `debug_assert` in debug profile or size mismatch panic in
`copy_from_slice` when compiled in release profile.
Although ordering is not specified in the spec, some implementations expect
some ordering (unforntunately I have found one that does, and blocks outbound
packets due to 'invalid tcp options').
Instead of configuring the ifaces ip address when a dhcp server offers
and ip, we now use the requested_ip option, based on the offered ip
(yiaddr). The user now only has to configure the iface once the dhcp
transaction has completed (Ack'd).
Disable ethernet-related features and framing based on a feature gate.
Add a no-ethernet option to Travis.
notes:
- allow(unused) is added when not using ethernet feature
- Don't run pretty-print doctest, ethernet is optional.
Closes: #308
Approved by: whitequark
The OPT_DOMAIN_NAME_SERVER DHCP option field can advertise an unbounded
DNS servers, but we currently use a fixed length array to store these
servers. This commit ensures only the first 3 (highest priority) servers
are used.
Fixes#305.
`TCPSocket` buffers are type `RingBuffer<'a, _>` whilst other
socket types have buffers with type `PacketBuffer<'a, 'b,
_>`.
There is an enum over socket types `pub enum Socket<'a, 'b: 'a>`,
which is in turn used by `set::Item` and `SocketSet`. The lifetime
`'b` is not required for `TcpSocket`, but the `Into<Socket>`
implementation for `TCPSocket` specifies the `'static` lifetime for
`'b`.
Therefore using `TCPSocket` in a `SocketSet` currently requires the
lifetime `'b` for other sockets to be `'static` which is unnecessarily
restrictive. This patch fixes this.
The lifetime signature of socket specifies `'b: 'a`, that is `'b`
outlives `'a`. Instead of `'static`, this is also satisfied by
`impl<'a> Into<Socket<'a, 'a>> for TcpSocket<'a>` as `'a` "outlives"
`'a` by definition.
The example
[here](https://gist.github.com/richardeoin/b562e79d0d499e00a8bf4944f00594d9)
fails to compile without this patch.
Closes: #304
Approved by: whitequark
Using move semantics allows an Option to keep track of the
initialization state while satisfying the borrow checker. This replaces
the functionality that the 'consumed' flag had before. It also retains
the smaller object size since the Option of a reference can use the
representation of the null pointer, which is an invalid reference, as a
niche for the None variant.
Closes: #301
Approved by: whitequark
Since 0.4.4, log uses #[macro_export(local_inner_macros)], which is
the right thing to do, but it breaks our CI because of a now-unused
\#[macro_use(log)].
This didn't ever actually cause UB because the drop implementation
should have compiled to a no-op under all conditions; `finish` is
a part of a patchset that never got in. (Even if it didn't, the code
should have been dynamically sound, under all but the most strict
interpretations of Rust's aliasing requirements.)
But it's still a problem, at least because there is a warning for
this potential unsoundness that will become an error in the future.
So everything else aside, we can't use this pattern going forward.
For now, remove the Drop impl, exploiting the fact that `finish`
is a no-op. Going forward this will likely require unsafe code, or
some fundamental change in the way SocketRef is implemented, but
I could not come up with any way to do it. :(
Actually, this is not a new requirement at all; because we do not
check the minimum version on CI, some dependencies on 1.28 have
already sneaked in. In particular, our required version of the crate
managed only works on 1.28+.
This allows us to use:
(1.28)
- ops::RangeBounds
- num::NonZero
Some trait bounds were added to make sure everything builds on 1.28.
This doesn't affect downstream code because log 0.3.9 is a facade
crate implemented in terms of log 0.4, and so log 0.3 and log 0.4
APIs can be used together.