Skip to content

Commit 94f72c9

Browse files
authored
Merge pull request #500 from smoltcp-rs/window-scale-fixes
Window scale fixes
2 parents 027f255 + 6a08274 commit 94f72c9

File tree

14 files changed

+587
-328
lines changed

14 files changed

+587
-328
lines changed

.github/workflows/test.yml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,6 @@ jobs:
4343
# Test alloc feature which requires nightly.
4444
- rust: nightly
4545
features: alloc medium-ethernet proto-ipv4 proto-ipv6 socket-raw socket-udp socket-tcp socket-icmp
46-
- rust: nightly
47-
features: alloc proto-ipv4 proto-ipv6 socket-raw socket-udp socket-tcp socket-icmp
4846
steps:
4947
- uses: actions/checkout@v2
5048
- uses: actions-rs/toolchain@v1

src/iface/interface.rs

Lines changed: 159 additions & 142 deletions
Large diffs are not rendered by default.

src/lib.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,15 @@ compile_error!("You must enable at least one of the following features: proto-ip
105105
))]
106106
compile_error!("If you enable the socket feature, you must enable at least one of the following features: socket-raw, socket-udp, socket-tcp, socket-icmp");
107107

108+
#[cfg(all(
109+
feature = "socket",
110+
not(any(
111+
feature = "medium-ethernet",
112+
feature = "medium-ip",
113+
))
114+
))]
115+
compile_error!("If you enable the socket feature, you must enable at least one of the following features: medium-ip, medium-ethernet");
116+
108117
#[cfg(all(feature = "defmt", feature = "log"))]
109118
compile_error!("You must enable at most one of the following features: defmt, log");
110119

src/phy/mod.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,17 @@ pub struct DeviceCapabilities {
230230
pub checksum: ChecksumCapabilities,
231231
}
232232

233+
impl DeviceCapabilities {
234+
pub fn ip_mtu(&self) -> usize {
235+
match self.medium {
236+
#[cfg(feature = "medium-ethernet")]
237+
Medium::Ethernet => self.max_transmission_unit - crate::wire::EthernetFrame::<&[u8]>::header_len(),
238+
#[cfg(feature = "medium-ip")]
239+
Medium::Ip => self.max_transmission_unit,
240+
}
241+
}
242+
}
243+
233244
/// Type of medium of a device.
234245
#[derive(Debug, Eq, PartialEq, Copy, Clone)]
235246
#[cfg_attr(feature = "defmt", derive(defmt::Format))]

src/socket/dhcpv4.rs

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
use crate::{Error, Result};
2-
use crate::wire::{EthernetAddress, IpProtocol, IpAddress,
2+
use crate::wire::{IpProtocol, IpAddress,
33
Ipv4Cidr, Ipv4Address, Ipv4Repr,
44
UdpRepr, UDP_HEADER_LEN,
55
DhcpPacket, DhcpRepr, DhcpMessageType, DHCP_CLIENT_PORT, DHCP_SERVER_PORT, DHCP_MAX_DNS_SERVER_COUNT};
66
use crate::wire::dhcpv4::{field as dhcpv4_field};
7-
use crate::socket::SocketMeta;
7+
use crate::socket::{SocketMeta, Context};
88
use crate::time::{Instant, Duration};
99
use crate::socket::SocketHandle;
1010

@@ -150,7 +150,7 @@ impl Dhcpv4Socket {
150150
self.max_lease_duration = max_lease_duration;
151151
}
152152

153-
pub(crate) fn poll_at(&self) -> PollAt {
153+
pub(crate) fn poll_at(&self, _cx: &Context) -> PollAt {
154154
let t = match &self.state {
155155
ClientState::Discovering(state) => state.retry_at,
156156
ClientState::Requesting(state) => state.retry_at,
@@ -159,7 +159,7 @@ impl Dhcpv4Socket {
159159
PollAt::Time(t)
160160
}
161161

162-
pub(crate) fn process(&mut self, now: Instant, ethernet_addr: EthernetAddress, ip_repr: &Ipv4Repr, repr: &UdpRepr, payload: &[u8]) -> Result<()> {
162+
pub(crate) fn process(&mut self, cx: &Context, ip_repr: &Ipv4Repr, repr: &UdpRepr, payload: &[u8]) -> Result<()> {
163163
let src_ip = ip_repr.src_addr;
164164

165165
// This is enforced in interface.rs.
@@ -179,7 +179,7 @@ impl Dhcpv4Socket {
179179
return Ok(());
180180
}
181181
};
182-
if dhcp_repr.client_hardware_address != ethernet_addr { return Ok(()) }
182+
if dhcp_repr.client_hardware_address != cx.ethernet_address.unwrap() { return Ok(()) }
183183
if dhcp_repr.transaction_id != self.transaction_id { return Ok(()) }
184184
let server_identifier = match dhcp_repr.server_identifier {
185185
Some(server_identifier) => server_identifier,
@@ -199,7 +199,7 @@ impl Dhcpv4Socket {
199199
}
200200

201201
self.state = ClientState::Requesting(RequestState {
202-
retry_at: now,
202+
retry_at: cx.now,
203203
retry: 0,
204204
server: ServerInfo {
205205
address: src_ip,
@@ -209,7 +209,7 @@ impl Dhcpv4Socket {
209209
});
210210
}
211211
(ClientState::Requesting(state), DhcpMessageType::Ack) => {
212-
if let Some((config, renew_at, expires_at)) = Self::parse_ack(now, &dhcp_repr, self.max_lease_duration) {
212+
if let Some((config, renew_at, expires_at)) = Self::parse_ack(cx.now, &dhcp_repr, self.max_lease_duration) {
213213
self.config_changed = true;
214214
self.state = ClientState::Renewing(RenewState{
215215
server: state.server,
@@ -223,7 +223,7 @@ impl Dhcpv4Socket {
223223
self.reset();
224224
}
225225
(ClientState::Renewing(state), DhcpMessageType::Ack) => {
226-
if let Some((config, renew_at, expires_at)) = Self::parse_ack(now, &dhcp_repr, self.max_lease_duration) {
226+
if let Some((config, renew_at, expires_at)) = Self::parse_ack(cx.now, &dhcp_repr, self.max_lease_duration) {
227227
state.renew_at = renew_at;
228228
state.expires_at = expires_at;
229229
if state.config != config {
@@ -298,9 +298,13 @@ impl Dhcpv4Socket {
298298
Some((config, renew_at, expires_at))
299299
}
300300

301-
pub(crate) fn dispatch<F>(&mut self, now: Instant, ethernet_addr: EthernetAddress, ip_mtu: usize, emit: F) -> Result<()>
301+
pub(crate) fn dispatch<F>(&mut self, cx: &Context, emit: F) -> Result<()>
302302
where F: FnOnce((Ipv4Repr, UdpRepr, DhcpRepr)) -> Result<()> {
303303

304+
// note: Dhcpv4Socket is only usable in ethernet mediums, so the
305+
// unwrap can never fail.
306+
let ethernet_addr = cx.ethernet_address.unwrap();
307+
304308
// Worst case biggest IPv4 header length.
305309
// 0x0f * 4 = 60 bytes.
306310
const MAX_IPV4_HEADER_LEN: usize = 60;
@@ -324,7 +328,7 @@ impl Dhcpv4Socket {
324328
client_identifier: Some(ethernet_addr),
325329
server_identifier: None,
326330
parameter_request_list: Some(PARAMETER_REQUEST_LIST),
327-
max_size: Some((ip_mtu - MAX_IPV4_HEADER_LEN - UDP_HEADER_LEN) as u16),
331+
max_size: Some((cx.caps.ip_mtu() - MAX_IPV4_HEADER_LEN - UDP_HEADER_LEN) as u16),
328332
lease_duration: None,
329333
dns_servers: None,
330334
};
@@ -344,7 +348,7 @@ impl Dhcpv4Socket {
344348

345349
match &mut self.state {
346350
ClientState::Discovering(state) => {
347-
if now < state.retry_at {
351+
if cx.now < state.retry_at {
348352
return Err(Error::Exhausted)
349353
}
350354

@@ -354,12 +358,12 @@ impl Dhcpv4Socket {
354358
emit((ipv4_repr, udp_repr, dhcp_repr))?;
355359

356360
// Update state AFTER the packet has been successfully sent.
357-
state.retry_at = now + DISCOVER_TIMEOUT;
361+
state.retry_at = cx.now + DISCOVER_TIMEOUT;
358362
self.transaction_id = next_transaction_id;
359363
Ok(())
360364
}
361365
ClientState::Requesting(state) => {
362-
if now < state.retry_at {
366+
if cx.now < state.retry_at {
363367
return Err(Error::Exhausted)
364368
}
365369

@@ -380,21 +384,21 @@ impl Dhcpv4Socket {
380384
emit((ipv4_repr, udp_repr, dhcp_repr))?;
381385

382386
// Exponential backoff: Double every 2 retries.
383-
state.retry_at = now + (REQUEST_TIMEOUT << (state.retry as u32 / 2));
387+
state.retry_at = cx.now + (REQUEST_TIMEOUT << (state.retry as u32 / 2));
384388
state.retry += 1;
385389

386390
self.transaction_id = next_transaction_id;
387391
Ok(())
388392
}
389393
ClientState::Renewing(state) => {
390-
if state.expires_at <= now {
394+
if state.expires_at <= cx.now {
391395
net_debug!("DHCP lease expired");
392396
self.reset();
393397
// return Ok so we get polled again
394398
return Ok(())
395399
}
396400

397-
if now < state.renew_at {
401+
if cx.now < state.renew_at {
398402
return Err(Error::Exhausted)
399403
}
400404

@@ -413,7 +417,7 @@ impl Dhcpv4Socket {
413417
// of the remaining time until T2 (in RENEWING state) and one-half of
414418
// the remaining lease time (in REBINDING state), down to a minimum of
415419
// 60 seconds, before retransmitting the DHCPREQUEST message.
416-
state.renew_at = now + MIN_RENEW_TIMEOUT.max((state.expires_at - now) / 2);
420+
state.renew_at = cx.now + MIN_RENEW_TIMEOUT.max((state.expires_at - cx.now) / 2);
417421

418422
self.transaction_id = next_transaction_id;
419423
Ok(())

0 commit comments

Comments
 (0)