diff --git a/mullvad-daemon/src/api.rs b/mullvad-daemon/src/api.rs index 3e69e03d1452..f1244f1a633d 100644 --- a/mullvad-daemon/src/api.rs +++ b/mullvad-daemon/src/api.rs @@ -31,26 +31,41 @@ pub enum Message { } // TODO(markus): Create a builder for this -// TODO(markus): Document. See `AppVersionInfo` for an example of good docs. -/// Emitted when the active access method changes. +/// A [`NewAccessMethodEvent`] is emitted when the active access method changes. +/// Which access method that should be active at any given time is decided by +/// the [`AccessModeSelector`] spawned when the daemon starts. +/// +/// This event is emitted in two scenarios: +/// * When the pub struct NewAccessMethodEvent { - pub settings: AccessMethodSetting, + /// The new active [`AccessMethodSetting`]. + pub setting: AccessMethodSetting, + /// The endpoint which represents how to connect to the Mullvad API and + /// which clients are allowed to initiate such a connection. pub endpoint: AllowedEndpoint, /// If the daemon should notify clients about the new access method. pub announce: bool, /// It is up to the daemon to actually allow traffic to/from /// `api_endpoint` by updating the firewall. This `Sender` allows the /// daemon to communicate when that action is done. - //TODO(markus): Can this be converted to a oneshot? pub update_finished_tx: oneshot::Sender<()>, } -// TODO(markus): Comment this struct +/// This struct represent a concrete API endpoint (in the form of an +/// [`ApiConnectionMode`] and [`AllowedEndpoint`]) which has been derived from +/// some [`AccessMethodSetting`] (most likely the currently active access +/// method). These logically related values are sometimes useful to group +/// together into one value, which is encoded by [`ResolvedConnectionMode`]. #[derive(Clone)] pub struct ResolvedConnectionMode { + /// The connection strategy to be used by the `mullvad-api` crate when + /// initialzing API requests. pub connection_mode: ApiConnectionMode, + /// The actual endpoint of the Mullvad API and which clients should be + /// allowed to initialize a connection to this endpoint. pub endpoint: AllowedEndpoint, - /// This is the setting which was resolved into `connection_mode` and `endpoint`. + /// This is the [`AccessMethodSetting`] which resolved into + /// `connection_mode` and `endpoint`. pub setting: AccessMethodSetting, } @@ -285,7 +300,7 @@ impl AccessModeSelector { let (update_finished_tx, update_finished_rx) = oneshot::channel(); let event = NewAccessMethodEvent { - settings, + setting: settings, endpoint, update_finished_tx, announce: true, diff --git a/mullvad-daemon/src/lib.rs b/mullvad-daemon/src/lib.rs index 9bcee0af1e35..71e1ee55900a 100644 --- a/mullvad-daemon/src/lib.rs +++ b/mullvad-daemon/src/lib.rs @@ -1242,23 +1242,28 @@ where } async fn handle_access_method_event(&mut self, event: NewAccessMethodEvent) { + let (completion_tx, completion_rx) = oneshot::channel(); + // update the firewall. + self.send_tunnel_command(TunnelCommand::AllowEndpoint(event.endpoint, completion_tx)); + // If the `NewAccessMethodEvent` should be announced to any client + // listening for updates of the currently active access method, we need + // to clone the handle to the broadcaster of such events. The + // announcement should be made after the firewall policy has been + // updated, since the new access method will be useless before then. let mut maybe_event_listener = if event.announce { Some(self.event_listener.clone()) } else { None }; - let (completion_tx, completion_rx) = oneshot::channel(); - // update the firewall. - self.send_tunnel_command(TunnelCommand::AllowEndpoint(event.endpoint, completion_tx)); tokio::spawn(async move { // Wait for the firewall policy to be updated. let _ = completion_rx.await; + // Let the emitter of this event know that the firewall has been updated. + let _ = event.update_finished_tx.send(()); // Notify clients about the change if necessary. if let Some(event_listener) = maybe_event_listener.take() { - event_listener.notify_new_access_method_event(event.settings); + event_listener.notify_new_access_method_event(event.setting); } - // Let the emitter of this event know that the firewall has been updated. - let _ = event.update_finished_tx.send(()); }); } @@ -2430,7 +2435,7 @@ where let (update_finished_tx, update_finished_rx) = oneshot::channel(); let event = api::NewAccessMethodEvent { endpoint, - settings: setting, + setting, // Do not emit this event to clients. announce: false, update_finished_tx, @@ -2460,7 +2465,7 @@ where let (update_finished_tx, update_finished_rx) = oneshot::channel(); let event = api::NewAccessMethodEvent { endpoint, - settings: setting, + setting, // Do not emit this event to clients. announce: false, update_finished_tx,