Updating control logic

This commit is contained in:
Ryan Summers 2021-03-12 17:28:00 +01:00
parent c491962b3f
commit 39c3e7ef1f
2 changed files with 26 additions and 8 deletions

View File

@ -58,7 +58,7 @@ pub struct Client {
/// When to send next request
next_egress: Instant,
/// When any existing DHCP address will expire.
lease_expiration: Instant,
lease_expiration: Option<Instant>,
transaction_id: u32,
}
@ -104,7 +104,7 @@ impl Client {
raw_handle,
next_egress: now,
transaction_id: 1,
lease_expiration: now,
lease_expiration: None,
}
}
@ -201,7 +201,7 @@ impl Client {
// once we receive the ack, we can pass the config to the user
let config = if dhcp_repr.message_type == DhcpMessageType::Ack {
let lease_duration = dhcp_repr.lease_duration.unwrap_or(DEFAULT_RENEW_INTERVAL * 2);
self.lease_expiration = now + Duration::from_secs(lease_duration.into());
self.lease_expiration = Some(now + Duration::from_secs(lease_duration.into()));
// RFC 2131 indicates clients should renew a lease halfway through its expiration.
self.next_egress = now + Duration::from_secs((lease_duration / 2).into());
@ -256,8 +256,9 @@ impl Client {
_ => false
};
if now >= self.lease_expiration || retries_exceeded {
net_debug!("DHCP lease expiration / retries exceeded");
let lease_expired = self.lease_expiration.map_or(false, |expiration| now >= expiration);
if lease_expired || retries_exceeded {
self.reset(now);
// Return a config now so that user code assigns the
// 0.0.0.0/0 address, which will be used sending a DHCP
@ -292,12 +293,12 @@ impl Client {
lease_duration: None,
dns_servers: None,
};
let mut send_packet = |iface, endpoint, dhcp_repr| {
send_packet(iface, raw_socket, &endpoint, &dhcp_repr, checksum_caps)
.map(|()| None)
};
match self.state {
ClientState::Discovering => {
self.next_egress = now + Duration::from_secs(DISCOVER_TIMEOUT);
@ -352,6 +353,7 @@ impl Client {
net_trace!("DHCP reset");
self.state = ClientState::Discovering;
self.next_egress = now;
self.lease_expiration = None;
}
}

View File

@ -877,7 +877,7 @@ mod test {
0x00, 0x00, 0x39, 0x2, 0x5, 0xdc, 0x37, 0x04, 0x01, 0x03, 0x06, 0x2a, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
];
static ACK_BYTES: &[u8] = &[
static ACK_DNS_SERVER_BYTES: &[u8] = &[
0x02, 0x01, 0x06, 0x00, 0xcc, 0x34, 0x75, 0xab, 0x00, 0x00, 0x80, 0x00, 0x0a, 0xff, 0x06, 0x91,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0xff, 0x06, 0xfe, 0x34, 0x17, 0xeb, 0xc9,
0xaa, 0x2f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@ -901,6 +901,11 @@ mod test {
0x01, 0x4a, 0x06, 0xa3, 0x01, 0x4a, 0x07, 0x2e, 0x01, 0x08, 0xff
];
static ACK_LEASE_TIME_BYTES: &[u8] = &[
// TODO: Fill out.
0x00,
];
const IP_NULL: Ipv4Address = Ipv4Address([0, 0, 0, 0]);
const CLIENT_MAC: EthernetAddress = EthernetAddress([0x0, 0x0b, 0x82, 0x01, 0xfc, 0x42]);
const DHCP_SIZE: u16 = 1500;
@ -1051,8 +1056,9 @@ mod test {
#[test]
fn test_parse_ack_dns_servers() {
let packet = Packet::new_unchecked(ACK_BYTES);
let packet = Packet::new_unchecked(ACK_DNS_SERVER_BYTES);
let repr = Repr::parse(&packet).unwrap();
// The packet described by ACK_BYTES advertises 4 DNS servers
// Here we ensure that we correctly parse the first 3 into our fixed
// length-3 array (see issue #305)
@ -1061,4 +1067,14 @@ mod test {
Some(Ipv4Address([163, 1, 74, 7])),
Some(Ipv4Address([163, 1, 74, 3]))]));
}
#[test]
fn test_parse_ack_lease_duration() {
let packet = Packet::new_unchecked(ACK_LEASE_TIME_BYTES);
let repr = Repr::parse(&packet).unwrap();
// Verify that the lease time in the ACK is properly parsed. The packet contains a lease
// duration of 600s.
assert_eq!(repr.lease_duration, Some(600));
}
}