Skip to content

Commit ca4a98a

Browse files
committed
Make DhcpRepr use an Option<Vec<Ipv4Address>>
1 parent 03e830b commit ca4a98a

File tree

2 files changed

+73
-63
lines changed

2 files changed

+73
-63
lines changed

src/socket/dhcpv4.rs

Lines changed: 36 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -424,7 +424,6 @@ impl<'a> Socket<'a> {
424424
.dns_servers
425425
.iter()
426426
.flatten()
427-
.flatten()
428427
.filter(|s| s.is_unicast())
429428
.for_each(|a| {
430429
// This will never produce an error, as both the arrays and `dns_servers`
@@ -779,8 +778,6 @@ mod test {
779778
const DNS_IP_1: Ipv4Address = Ipv4Address([1, 1, 1, 1]);
780779
const DNS_IP_2: Ipv4Address = Ipv4Address([1, 1, 1, 2]);
781780
const DNS_IP_3: Ipv4Address = Ipv4Address([1, 1, 1, 3]);
782-
const DNS_IPS_ARR: [Option<Ipv4Address>; DHCP_MAX_DNS_SERVER_COUNT] =
783-
[Some(DNS_IP_1), Some(DNS_IP_2), Some(DNS_IP_3)];
784781
const DNS_IPS: &[Ipv4Address] = &[DNS_IP_1, DNS_IP_2, DNS_IP_3];
785782

786783
const MASK_24: Ipv4Address = Ipv4Address([255, 255, 255, 0]);
@@ -858,19 +855,21 @@ mod test {
858855
..DHCP_DEFAULT
859856
};
860857

861-
const DHCP_OFFER: DhcpRepr = DhcpRepr {
862-
message_type: DhcpMessageType::Offer,
863-
server_ip: SERVER_IP,
864-
server_identifier: Some(SERVER_IP),
858+
fn dhcp_offer() -> DhcpRepr<'static> {
859+
DhcpRepr {
860+
message_type: DhcpMessageType::Offer,
861+
server_ip: SERVER_IP,
862+
server_identifier: Some(SERVER_IP),
865863

866-
your_ip: MY_IP,
867-
router: Some(SERVER_IP),
868-
subnet_mask: Some(MASK_24),
869-
dns_servers: Some(DNS_IPS_ARR),
870-
lease_duration: Some(1000),
864+
your_ip: MY_IP,
865+
router: Some(SERVER_IP),
866+
subnet_mask: Some(MASK_24),
867+
dns_servers: Some(Vec::from_slice(DNS_IPS).unwrap()),
868+
lease_duration: Some(1000),
871869

872-
..DHCP_DEFAULT
873-
};
870+
..DHCP_DEFAULT
871+
}
872+
}
874873

875874
const DHCP_REQUEST: DhcpRepr = DhcpRepr {
876875
message_type: DhcpMessageType::Request,
@@ -883,19 +882,21 @@ mod test {
883882
..DHCP_DEFAULT
884883
};
885884

886-
const DHCP_ACK: DhcpRepr = DhcpRepr {
887-
message_type: DhcpMessageType::Ack,
888-
server_ip: SERVER_IP,
889-
server_identifier: Some(SERVER_IP),
885+
fn dhcp_ack() -> DhcpRepr<'static> {
886+
DhcpRepr {
887+
message_type: DhcpMessageType::Ack,
888+
server_ip: SERVER_IP,
889+
server_identifier: Some(SERVER_IP),
890890

891-
your_ip: MY_IP,
892-
router: Some(SERVER_IP),
893-
subnet_mask: Some(MASK_24),
894-
dns_servers: Some(DNS_IPS_ARR),
895-
lease_duration: Some(1000),
891+
your_ip: MY_IP,
892+
router: Some(SERVER_IP),
893+
subnet_mask: Some(MASK_24),
894+
dns_servers: Some(Vec::from_slice(DNS_IPS).unwrap()),
895+
lease_duration: Some(1000),
896896

897-
..DHCP_DEFAULT
898-
};
897+
..DHCP_DEFAULT
898+
}
899+
}
899900

900901
const DHCP_NAK: DhcpRepr = DhcpRepr {
901902
message_type: DhcpMessageType::Nak,
@@ -954,11 +955,11 @@ mod test {
954955

955956
recv!(s, [(IP_BROADCAST, UDP_SEND, DHCP_DISCOVER)]);
956957
assert_eq!(s.poll(), None);
957-
send!(s, (IP_RECV, UDP_RECV, DHCP_OFFER));
958+
send!(s, (IP_RECV, UDP_RECV, dhcp_offer()));
958959
assert_eq!(s.poll(), None);
959960
recv!(s, [(IP_BROADCAST, UDP_SEND, DHCP_REQUEST)]);
960961
assert_eq!(s.poll(), None);
961-
send!(s, (IP_RECV, UDP_RECV, DHCP_ACK));
962+
send!(s, (IP_RECV, UDP_RECV, dhcp_ack()));
962963

963964
assert_eq!(
964965
s.poll(),
@@ -994,7 +995,7 @@ mod test {
994995
recv!(s, time 20_000, [(IP_BROADCAST, UDP_SEND, DHCP_DISCOVER)]);
995996

996997
// check after retransmits it still works
997-
send!(s, time 20_000, (IP_RECV, UDP_RECV, DHCP_OFFER));
998+
send!(s, time 20_000, (IP_RECV, UDP_RECV, dhcp_offer()));
998999
recv!(s, time 20_000, [(IP_BROADCAST, UDP_SEND, DHCP_REQUEST)]);
9991000
}
10001001

@@ -1003,7 +1004,7 @@ mod test {
10031004
let mut s = socket();
10041005

10051006
recv!(s, time 0, [(IP_BROADCAST, UDP_SEND, DHCP_DISCOVER)]);
1006-
send!(s, time 0, (IP_RECV, UDP_RECV, DHCP_OFFER));
1007+
send!(s, time 0, (IP_RECV, UDP_RECV, dhcp_offer()));
10071008
recv!(s, time 0, [(IP_BROADCAST, UDP_SEND, DHCP_REQUEST)]);
10081009
recv!(s, time 1_000, []);
10091010
recv!(s, time 5_000, [(IP_BROADCAST, UDP_SEND, DHCP_REQUEST)]);
@@ -1013,7 +1014,7 @@ mod test {
10131014
recv!(s, time 20_000, [(IP_BROADCAST, UDP_SEND, DHCP_REQUEST)]);
10141015

10151016
// check after retransmits it still works
1016-
send!(s, time 20_000, (IP_RECV, UDP_RECV, DHCP_ACK));
1017+
send!(s, time 20_000, (IP_RECV, UDP_RECV, dhcp_ack()));
10171018

10181019
match &s.state {
10191020
ClientState::Renewing(r) => {
@@ -1029,7 +1030,7 @@ mod test {
10291030
let mut s = socket();
10301031

10311032
recv!(s, time 0, [(IP_BROADCAST, UDP_SEND, DHCP_DISCOVER)]);
1032-
send!(s, time 0, (IP_RECV, UDP_RECV, DHCP_OFFER));
1033+
send!(s, time 0, (IP_RECV, UDP_RECV, dhcp_offer()));
10331034
recv!(s, time 0, [(IP_BROADCAST, UDP_SEND, DHCP_REQUEST)]);
10341035
recv!(s, time 5_000, [(IP_BROADCAST, UDP_SEND, DHCP_REQUEST)]);
10351036
recv!(s, time 10_000, [(IP_BROADCAST, UDP_SEND, DHCP_REQUEST)]);
@@ -1041,7 +1042,7 @@ mod test {
10411042
recv!(s, time 70_000, [(IP_BROADCAST, UDP_SEND, DHCP_DISCOVER)]);
10421043

10431044
// check it still works
1044-
send!(s, time 60_000, (IP_RECV, UDP_RECV, DHCP_OFFER));
1045+
send!(s, time 60_000, (IP_RECV, UDP_RECV, dhcp_offer()));
10451046
recv!(s, time 60_000, [(IP_BROADCAST, UDP_SEND, DHCP_REQUEST)]);
10461047
}
10471048

@@ -1050,7 +1051,7 @@ mod test {
10501051
let mut s = socket();
10511052

10521053
recv!(s, time 0, [(IP_BROADCAST, UDP_SEND, DHCP_DISCOVER)]);
1053-
send!(s, time 0, (IP_RECV, UDP_RECV, DHCP_OFFER));
1054+
send!(s, time 0, (IP_RECV, UDP_RECV, dhcp_offer()));
10541055
recv!(s, time 0, [(IP_BROADCAST, UDP_SEND, DHCP_REQUEST)]);
10551056
send!(s, time 0, (IP_SERVER_BROADCAST, UDP_RECV, DHCP_NAK));
10561057
recv!(s, time 0, [(IP_BROADCAST, UDP_SEND, DHCP_DISCOVER)]);
@@ -1074,7 +1075,7 @@ mod test {
10741075
_ => panic!("Invalid state"),
10751076
}
10761077

1077-
send!(s, time 500_000, (IP_RECV, UDP_RECV, DHCP_ACK));
1078+
send!(s, time 500_000, (IP_RECV, UDP_RECV, dhcp_ack()));
10781079
assert_eq!(s.poll(), None);
10791080

10801081
match &s.state {
@@ -1099,7 +1100,7 @@ mod test {
10991100
recv!(s, time 875_000, [(IP_SEND, UDP_SEND, DHCP_RENEW)]);
11001101

11011102
// check it still works
1102-
send!(s, time 875_000, (IP_RECV, UDP_RECV, DHCP_ACK));
1103+
send!(s, time 875_000, (IP_RECV, UDP_RECV, dhcp_ack()));
11031104
match &s.state {
11041105
ClientState::Renewing(r) => {
11051106
// NOW the expiration gets bumped

src/wire/dhcpv4.rs

Lines changed: 37 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
use bitflags::bitflags;
44
use byteorder::{ByteOrder, NetworkEndian};
55
use core::iter;
6+
use heapless::Vec;
67

78
use super::{Error, Result};
89
use crate::wire::arp::Hardware;
@@ -582,7 +583,7 @@ impl<'a, T: AsRef<[u8]> + AsMut<[u8]> + ?Sized> Packet<&'a mut T> {
582583
/// length) is set to `6`.
583584
///
584585
/// The `options` field has a variable length.
585-
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
586+
#[derive(Debug, PartialEq, Eq, Clone)]
586587
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
587588
pub struct Repr<'a> {
588589
/// This field is also known as `op` in the RFC. It indicates the type of DHCP message this
@@ -645,7 +646,7 @@ pub struct Repr<'a> {
645646
/// the client is interested in.
646647
pub parameter_request_list: Option<&'a [u8]>,
647648
/// DNS servers
648-
pub dns_servers: Option<[Option<Ipv4Address>; MAX_DNS_SERVER_COUNT]>,
649+
pub dns_servers: Option<Vec<Ipv4Address, MAX_DNS_SERVER_COUNT>>,
649650
/// The maximum size dhcp packet the interface can receive
650651
pub max_size: Option<u16>,
651652
/// The DHCP IP lease duration, specified in seconds.
@@ -683,9 +684,9 @@ impl<'a> Repr<'a> {
683684
if self.lease_duration.is_some() {
684685
len += 6;
685686
}
686-
if let Some(dns_servers) = self.dns_servers {
687+
if let Some(dns_servers) = &self.dns_servers {
687688
len += 2;
688-
len += dns_servers.iter().flatten().count() * core::mem::size_of::<u32>();
689+
len += dns_servers.iter().count() * core::mem::size_of::<u32>();
689690
}
690691
if let Some(list) = self.parameter_request_list {
691692
len += list.len() + 2;
@@ -773,13 +774,13 @@ impl<'a> Repr<'a> {
773774
parameter_request_list = Some(data);
774775
}
775776
(field::OPT_DOMAIN_NAME_SERVER, _) => {
776-
let mut servers = [None; MAX_DNS_SERVER_COUNT];
777-
let chunk_size = 4;
778-
for (server, chunk) in servers.iter_mut().zip(data.chunks(chunk_size)) {
779-
if chunk.len() != chunk_size {
780-
return Err(Error);
781-
}
782-
*server = Some(Ipv4Address::from_bytes(chunk));
777+
let mut servers = Vec::new();
778+
const IP_ADDR_BYTE_LEN: usize = 4;
779+
for chunk in data.chunks(IP_ADDR_BYTE_LEN) {
780+
// We ignore push failures because that will only happen
781+
// if we attempt to push more than 4 addresses, and the only
782+
// solution to that is to support more addresses.
783+
servers.push(Ipv4Address::from_bytes(chunk)).ok();
783784
}
784785
dns_servers = Some(servers);
785786
}
@@ -901,13 +902,12 @@ impl<'a> Repr<'a> {
901902
})?;
902903
}
903904

904-
if let Some(dns_servers) = self.dns_servers {
905+
if let Some(dns_servers) = &self.dns_servers {
905906
const IP_SIZE: usize = core::mem::size_of::<u32>();
906907
let mut servers = [0; MAX_DNS_SERVER_COUNT * IP_SIZE];
907908

908909
let data_len = dns_servers
909910
.iter()
910-
.flatten()
911911
.enumerate()
912912
.inspect(|(i, ip)| {
913913
servers[(i * IP_SIZE)..((i + 1) * IP_SIZE)].copy_from_slice(ip.as_bytes());
@@ -1210,11 +1210,14 @@ mod test {
12101210
fn test_emit_offer_dns() {
12111211
let repr = {
12121212
let mut repr = offer_repr();
1213-
repr.dns_servers = Some([
1214-
Some(Ipv4Address([163, 1, 74, 6])),
1215-
Some(Ipv4Address([163, 1, 74, 7])),
1216-
Some(Ipv4Address([163, 1, 74, 3])),
1217-
]);
1213+
repr.dns_servers = Some(
1214+
Vec::from_slice(&[
1215+
Ipv4Address([163, 1, 74, 6]),
1216+
Ipv4Address([163, 1, 74, 7]),
1217+
Ipv4Address([163, 1, 74, 3]),
1218+
])
1219+
.unwrap(),
1220+
);
12181221
repr
12191222
};
12201223
let mut bytes = vec![0xa5; repr.buffer_len()];
@@ -1226,11 +1229,14 @@ mod test {
12261229

12271230
assert_eq!(
12281231
repr_parsed.dns_servers,
1229-
Some([
1230-
Some(Ipv4Address([163, 1, 74, 6])),
1231-
Some(Ipv4Address([163, 1, 74, 7])),
1232-
Some(Ipv4Address([163, 1, 74, 3]))
1233-
])
1232+
Some(
1233+
Vec::from_slice(&[
1234+
Ipv4Address([163, 1, 74, 6]),
1235+
Ipv4Address([163, 1, 74, 7]),
1236+
Ipv4Address([163, 1, 74, 3]),
1237+
])
1238+
.unwrap()
1239+
)
12341240
);
12351241
}
12361242

@@ -1263,11 +1269,14 @@ mod test {
12631269
// length-3 array (see issue #305)
12641270
assert_eq!(
12651271
repr.dns_servers,
1266-
Some([
1267-
Some(Ipv4Address([163, 1, 74, 6])),
1268-
Some(Ipv4Address([163, 1, 74, 7])),
1269-
Some(Ipv4Address([163, 1, 74, 3]))
1270-
])
1272+
Some(
1273+
Vec::from_slice(&[
1274+
Ipv4Address([163, 1, 74, 6]),
1275+
Ipv4Address([163, 1, 74, 7]),
1276+
Ipv4Address([163, 1, 74, 3])
1277+
])
1278+
.unwrap()
1279+
)
12711280
);
12721281
}
12731282

0 commit comments

Comments
 (0)