[dhcpv6] Deny unused results
Bug: 73468
Change-Id: If6af09a7f00e0fddc6b44caa8211147a0559761d
Reviewed-on: https://fuchsia-review.googlesource.com/c/fuchsia/+/514740
Reviewed-by: Jay Zhuang <jayzhuang@google.com>
Commit-Queue: Tamir Duberstein <tamird@google.com>
diff --git a/build/config/rust/BUILD.gn b/build/config/rust/BUILD.gn
index d46e3d9..b9c4f52 100644
--- a/build/config/rust/BUILD.gn
+++ b/build/config/rust/BUILD.gn
@@ -142,7 +142,6 @@
"//src/connectivity/location/*",
"//src/connectivity/lowpan/*",
"//src/connectivity/management/*",
- "//src/connectivity/network/dhcpv6/*",
"//src/connectivity/network/http-client/*",
"//src/connectivity/network/lib/*",
"//src/connectivity/network/netstack/*",
diff --git a/src/connectivity/network/dhcpv6/client/BUILD.gn b/src/connectivity/network/dhcpv6/client/BUILD.gn
index 31bf3f6..9d6f065 100644
--- a/src/connectivity/network/dhcpv6/client/BUILD.gn
+++ b/src/connectivity/network/dhcpv6/client/BUILD.gn
@@ -39,6 +39,8 @@
"src/main.rs",
"src/provider.rs",
]
+
+ configs -= [ "//build/config/rust:allow_unused_results" ]
}
fuchsia_component("component") {
diff --git a/src/connectivity/network/dhcpv6/client/src/main.rs b/src/connectivity/network/dhcpv6/client/src/main.rs
index f305591..58f67a3 100644
--- a/src/connectivity/network/dhcpv6/client/src/main.rs
+++ b/src/connectivity/network/dhcpv6/client/src/main.rs
@@ -12,8 +12,8 @@
anyhow::{Context as _, Error, Result},
fidl_fuchsia_net_dhcpv6::ClientProviderRequestStream,
fuchsia_async as fasync,
- fuchsia_component::server::ServiceFs,
- futures::{future, StreamExt, TryStreamExt},
+ fuchsia_component::server::{ServiceFs, ServiceFsDir},
+ futures::{future, StreamExt as _, TryStreamExt as _},
};
enum IncomingService {
@@ -26,8 +26,9 @@
let () = log::info!("starting");
let mut fs = ServiceFs::new_local();
- fs.dir("svc").add_fidl_service(IncomingService::ClientProvider);
- fs.take_and_serve_directory_handle()?;
+ let _: &mut ServiceFsDir<'_, _> =
+ fs.dir("svc").add_fidl_service(IncomingService::ClientProvider);
+ let _: &mut ServiceFs<_> = fs.take_and_serve_directory_handle()?;
fs.then(future::ok::<_, Error>)
.try_for_each_concurrent(None, |request| async {
diff --git a/src/connectivity/network/dhcpv6/core/BUILD.gn b/src/connectivity/network/dhcpv6/core/BUILD.gn
index 612aeb5..82542b4 100644
--- a/src/connectivity/network/dhcpv6/core/BUILD.gn
+++ b/src/connectivity/network/dhcpv6/core/BUILD.gn
@@ -25,6 +25,8 @@
"src/client.rs",
"src/lib.rs",
]
+
+ configs -= [ "//build/config/rust:allow_unused_results" ]
}
fuchsia_unittest_package("dhcpv6-core-test") {
diff --git a/src/connectivity/network/dhcpv6/core/src/client.rs b/src/connectivity/network/dhcpv6/core/src/client.rs
index f4e76af..65c3c0b 100644
--- a/src/connectivity/network/dhcpv6/core/src/client.rs
+++ b/src/connectivity/network/dhcpv6/core/src/client.rs
@@ -115,7 +115,7 @@
/// Holds data and provides methods for handling state transitions from information requesting
/// state.
-#[derive(Debug, Default)]
+#[derive(Debug, PartialEq)]
struct InformationRequesting {
retrans_timeout: Duration,
}
@@ -129,7 +129,7 @@
options_to_request: &[v6::OptionCode],
rng: &mut R,
) -> Transition {
- let info_req: Self = Default::default();
+ let info_req = Self { retrans_timeout: Default::default() };
info_req.send_and_schedule_retransmission(transaction_id, options_to_request, rng)
}
@@ -199,11 +199,10 @@
}
}
- let actions = vec![
+ let actions = std::array::IntoIter::new([
Action::CancelTimer(ClientTimerType::Retransmission),
Action::ScheduleTimer(ClientTimerType::Refresh, information_refresh_time),
- ]
- .into_iter()
+ ])
.chain(dns_servers.clone().map(|server_addrs| Action::UpdateDnsServers(server_addrs)))
.collect::<Vec<_>>();
@@ -217,7 +216,7 @@
}
/// Provides methods for handling state transitions from information received state.
-#[derive(Debug)]
+#[derive(Debug, PartialEq)]
struct InformationReceived {
/// Stores the DNS servers received from the reply.
dns_servers: Vec<Ipv6Addr>,
@@ -238,7 +237,7 @@
/// All possible states of a DHCPv6 client.
///
/// States not found in this enum are not supported yet.
-#[derive(Debug)]
+#[derive(Debug, PartialEq)]
enum ClientState {
/// Creating and (re)transmitting an information request, and waiting for a reply.
InformationRequesting(InformationRequesting),
@@ -257,7 +256,7 @@
fn reply_message_received<B: ByteSlice>(self, msg: v6::Message<'_, B>) -> Transition {
match self {
ClientState::InformationRequesting(s) => s.reply_message_received(msg),
- state => (state, vec![]),
+ state => (state, Vec::new()),
}
}
@@ -274,7 +273,7 @@
ClientState::InformationRequesting(s) => {
s.retransmission_timer_expired(transaction_id, options_to_request, rng)
}
- state => (state, vec![]),
+ state => (state, Vec::new()),
}
}
@@ -291,7 +290,7 @@
ClientState::InformationReceived(s) => {
s.refresh_timer_expired(transaction_id, options_to_request, rng)
}
- state => (state, vec![]),
+ state => (state, Vec::new()),
}
}
@@ -417,26 +416,28 @@
#[test]
fn test_information_request_and_reply() {
// Try to start information request with different list of requested options.
- for options in vec![
+ for options in std::array::IntoIter::new([
Vec::new(),
vec![v6::OptionCode::DnsServers],
vec![v6::OptionCode::DnsServers, v6::OptionCode::DomainList],
- ] {
+ ]) {
let (mut client, actions) = ClientStateMachine::start_information_request(
[0, 1, 2],
options.clone(),
StepRng::new(std::u64::MAX / 2, 0),
);
- assert_matches!(client.state, Some(ClientState::InformationRequesting(_)));
+ assert_eq!(
+ client.state,
+ Some(ClientState::InformationRequesting(InformationRequesting {
+ retrans_timeout: INFO_REQ_TIMEOUT,
+ }))
+ );
// Start of information requesting should send a information request and schedule a
// retransmission timer.
- let want_options = if options.is_empty() {
- Vec::new()
- } else {
- vec![v6::DhcpOption::Oro(options.clone())]
- };
+ let want_options =
+ if options.is_empty() { Vec::new() } else { vec![v6::DhcpOption::Oro(options)] };
let builder = v6::MessageBuilder::new(
v6::MessageType::InformationRequest,
client.transaction_id,
@@ -445,20 +446,19 @@
let mut want_buf = vec![0; builder.bytes_len()];
let () = builder.serialize(&mut want_buf);
assert_eq!(
- actions,
- vec![
+ actions[..],
+ [
Action::SendMessage(want_buf),
Action::ScheduleTimer(ClientTimerType::Retransmission, INFO_REQ_TIMEOUT)
]
);
+ let dns_servers = vec![std_ip_v6!("ff01::0102"), std_ip_v6!("ff01::0304")];
+
let test_dhcp_refresh_time = 42u32;
let options = [
v6::DhcpOption::InformationRefreshTime(test_dhcp_refresh_time),
- v6::DhcpOption::DnsServers(vec![
- std_ip_v6!("ff01::0102"),
- std_ip_v6!("ff01::0304"),
- ]),
+ v6::DhcpOption::DnsServers(dns_servers.clone()),
];
let builder =
v6::MessageBuilder::new(v6::MessageType::Reply, client.transaction_id, &options);
@@ -469,20 +469,23 @@
let actions = client.handle_message_receive(msg);
- assert_matches!(client.state, Some(ClientState::InformationReceived(_)));
+ {
+ let dns_servers = dns_servers.clone();
+ assert_eq!(
+ client.state,
+ Some(ClientState::InformationReceived(InformationReceived { dns_servers }))
+ );
+ }
// Upon receiving a valid reply, client should set up for refresh based on the reply.
assert_eq!(
- actions,
- vec![
+ actions[..],
+ [
Action::CancelTimer(ClientTimerType::Retransmission),
Action::ScheduleTimer(
ClientTimerType::Refresh,
Duration::from_secs(u64::from(test_dhcp_refresh_time)),
),
- Action::UpdateDnsServers(vec![
- std_ip_v6!("ff01::0102"),
- std_ip_v6!("ff01::0304")
- ]),
+ Action::UpdateDnsServers(dns_servers)
]
);
}
@@ -511,7 +514,7 @@
assert!(client.handle_message_receive(msg).is_empty());
// Messages with unsupported/unexpected types are discarded.
- for msg_type in vec![
+ for msg_type in std::array::IntoIter::new([
v6::MessageType::Solicit,
v6::MessageType::Advertise,
v6::MessageType::Request,
@@ -524,7 +527,7 @@
v6::MessageType::InformationRequest,
v6::MessageType::RelayForw,
v6::MessageType::RelayRepl,
- ] {
+ ]) {
let builder = v6::MessageBuilder::new(msg_type, client.transaction_id, &[]);
let mut buf = vec![0; builder.bytes_len()];
let () = builder.serialize(&mut buf);
@@ -544,8 +547,13 @@
);
// The client expects either a reply or retransmission timeout in the current state.
- client.handle_timeout(ClientTimerType::Refresh);
- assert_matches!(client.state, Some(ClientState::InformationRequesting(_)));
+ assert_eq!(client.handle_timeout(ClientTimerType::Refresh)[..], []);
+ assert_eq!(
+ client.state,
+ Some(ClientState::InformationRequesting(InformationRequesting {
+ retrans_timeout: INFO_REQ_TIMEOUT
+ }))
+ );
let builder = v6::MessageBuilder::new(v6::MessageType::Reply, client.transaction_id, &[]);
let mut buf = vec![0; builder.bytes_len()];
@@ -553,20 +561,35 @@
let mut buf = &buf[..]; // Implements BufferView.
let msg = v6::Message::parse(&mut buf, ()).expect("failed to parse test buffer");
// Transition to InformationReceived state.
- client.handle_message_receive(msg);
- assert_matches!(client.state, Some(ClientState::InformationReceived(_)));
+ assert_eq!(
+ client.handle_message_receive(msg)[..],
+ [
+ Action::CancelTimer(ClientTimerType::Retransmission),
+ Action::ScheduleTimer(ClientTimerType::Refresh, IRT_DEFAULT)
+ ]
+ );
+ assert_eq!(
+ client.state,
+ Some(ClientState::InformationReceived(InformationReceived { dns_servers: vec![] }))
+ );
let mut buf = vec![0; builder.bytes_len()];
let () = builder.serialize(&mut buf);
let mut buf = &buf[..]; // Implements BufferView.
let msg = v6::Message::parse(&mut buf, ()).expect("failed to parse test buffer");
// Extra replies received in information received state are ignored.
- client.handle_message_receive(msg);
- assert_matches!(client.state, Some(ClientState::InformationReceived(_)));
+ assert_eq!(client.handle_message_receive(msg)[..], []);
+ assert_eq!(
+ client.state,
+ Some(ClientState::InformationReceived(InformationReceived { dns_servers: vec![] }))
+ );
// Information received state should only respond to `Refresh` timer.
- client.handle_timeout(ClientTimerType::Retransmission);
- assert_matches!(client.state, Some(ClientState::InformationReceived(_)));
+ assert_eq!(client.handle_timeout(ClientTimerType::Retransmission)[..], []);
+ assert_eq!(
+ client.state,
+ Some(ClientState::InformationReceived(InformationReceived { dns_servers: vec![] }))
+ );
}
#[test]
@@ -604,7 +627,13 @@
let msg = v6::Message::parse(&mut buf, ()).expect("failed to parse test buffer");
// Transition to InformationReceived state.
- client.handle_message_receive(msg);
+ assert_eq!(
+ client.handle_message_receive(msg)[..],
+ [
+ Action::CancelTimer(ClientTimerType::Retransmission),
+ Action::ScheduleTimer(ClientTimerType::Refresh, IRT_DEFAULT)
+ ]
+ );
// Refresh should start another round of information request.
let actions = client.handle_timeout(ClientTimerType::Refresh);
@@ -616,8 +645,8 @@
let mut want_buf = vec![0; builder.bytes_len()];
let () = builder.serialize(&mut want_buf);
assert_eq!(
- actions,
- vec![
+ actions[..],
+ [
Action::SendMessage(want_buf),
Action::ScheduleTimer(ClientTimerType::Retransmission, INFO_REQ_TIMEOUT)
]