mirror of
https://github.com/outbackdingo/firezone.git
synced 2026-01-27 18:18:55 +00:00
chore(connlib): make peer pure by taking utc time from parameters (#4773)
This came up while working on #2030 and thinking about testing `Peer`. Not entirely convinced of taking both `Instant` and `DateTime<Utc>` but unless we convert the expiration to an instant, which would bring a bunch of new problems, I don't see another way to do this.
This commit is contained in:
@@ -266,12 +266,14 @@ impl GatewayState {
|
||||
earliest(self.next_expiry_resources_check, self.node.poll_timeout())
|
||||
}
|
||||
|
||||
pub fn handle_timeout(&mut self, now: Instant) {
|
||||
pub fn handle_timeout(&mut self, now: Instant, utc_now: DateTime<Utc>) {
|
||||
self.node.handle_timeout(now);
|
||||
|
||||
match self.next_expiry_resources_check {
|
||||
Some(next_expiry_resources_check) if now >= next_expiry_resources_check => {
|
||||
self.peers.iter_mut().for_each(|p| p.expire_resources());
|
||||
self.peers
|
||||
.iter_mut()
|
||||
.for_each(|p| p.expire_resources(utc_now));
|
||||
self.peers.retain(|_, p| !p.is_emptied());
|
||||
|
||||
self.next_expiry_resources_check = Some(now + EXPIRE_RESOURCES_INTERVAL);
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
//! [Tunnel] is the main entry-point for this crate.
|
||||
|
||||
use boringtun::x25519::StaticSecret;
|
||||
use chrono::Utc;
|
||||
use connlib_shared::{
|
||||
messages::{ClientId, GatewayId, Relay, RelayId, ResourceId, ReuseConnection},
|
||||
Callbacks, Result,
|
||||
@@ -201,7 +202,7 @@ where
|
||||
self.device_read_buf.as_mut(),
|
||||
)? {
|
||||
Poll::Ready(io::Input::Timeout(timeout)) => {
|
||||
self.role_state.handle_timeout(timeout);
|
||||
self.role_state.handle_timeout(timeout, Utc::now());
|
||||
continue;
|
||||
}
|
||||
Poll::Ready(io::Input::Device(packet)) => {
|
||||
|
||||
@@ -101,9 +101,9 @@ impl ClientOnGateway {
|
||||
self.resources.is_empty()
|
||||
}
|
||||
|
||||
pub(crate) fn expire_resources(&mut self) {
|
||||
pub(crate) fn expire_resources(&mut self, now: DateTime<Utc>) {
|
||||
self.resources
|
||||
.retain(|_, (_, e)| !e.is_some_and(|e| e <= Utc::now()));
|
||||
.retain(|_, (_, e)| !e.is_some_and(|e| e <= now));
|
||||
}
|
||||
|
||||
pub(crate) fn remove_resource(&mut self, resource: &ResourceId) {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
use crate::{ClientEvent, ClientState, GatewayState};
|
||||
use chrono::{DateTime, Utc};
|
||||
use connlib_shared::{
|
||||
messages::{ResourceDescription, ResourceDescriptionCidr, ResourceId},
|
||||
proptest::cidr_resource,
|
||||
@@ -38,6 +39,7 @@ proptest_state_machine::prop_state_machine! {
|
||||
/// [`proptest`] manipulates this using [`Transition`]s and we assert it against [`ReferenceState`].
|
||||
struct TunnelTest {
|
||||
now: Instant,
|
||||
utc_now: DateTime<Utc>,
|
||||
|
||||
client: ClientState,
|
||||
gateway: GatewayState,
|
||||
@@ -52,6 +54,7 @@ struct TunnelTest {
|
||||
#[derive(Clone, Debug)]
|
||||
struct ReferenceState {
|
||||
now: Instant,
|
||||
utc_now: DateTime<Utc>,
|
||||
client_priv_key: [u8; 32],
|
||||
gateway_priv_key: [u8; 32],
|
||||
|
||||
@@ -73,6 +76,7 @@ impl StateMachineTest for TunnelTest {
|
||||
) -> Self::SystemUnderTest {
|
||||
Self {
|
||||
now: ref_state.now,
|
||||
utc_now: ref_state.utc_now,
|
||||
client: ClientState::new(StaticSecret::from(ref_state.client_priv_key)),
|
||||
gateway: GatewayState::new(StaticSecret::from(ref_state.gateway_priv_key)),
|
||||
logger: tracing_subscriber::fmt()
|
||||
@@ -108,8 +112,9 @@ impl StateMachineTest for TunnelTest {
|
||||
}
|
||||
Transition::Tick { millis } => {
|
||||
state.now += Duration::from_millis(millis);
|
||||
state.utc_now += Duration::from_millis(millis);
|
||||
state.client.handle_timeout(state.now);
|
||||
state.gateway.handle_timeout(state.now);
|
||||
state.gateway.handle_timeout(state.now, state.utc_now);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -257,13 +262,19 @@ impl ReferenceStateMachine for ReferenceState {
|
||||
type Transition = Transition;
|
||||
|
||||
fn init_state() -> proptest::prelude::BoxedStrategy<Self::State> {
|
||||
(any::<[u8; 32]>(), any::<[u8; 32]>(), Just(Instant::now()))
|
||||
(
|
||||
any::<[u8; 32]>(),
|
||||
any::<[u8; 32]>(),
|
||||
Just(Instant::now()),
|
||||
Just(Utc::now()),
|
||||
)
|
||||
.prop_filter(
|
||||
"client and gateway priv key must be different",
|
||||
|(c, g, _)| c != g,
|
||||
|(c, g, _, _)| c != g,
|
||||
)
|
||||
.prop_map(|(client_priv_key, gateway_priv_key, now)| Self {
|
||||
.prop_map(|(client_priv_key, gateway_priv_key, now, utc_now)| Self {
|
||||
now,
|
||||
utc_now,
|
||||
client_priv_key,
|
||||
gateway_priv_key,
|
||||
client_resources: IpNetworkTable::new(),
|
||||
|
||||
Reference in New Issue
Block a user