diff options
| author | David Lönnhager <david.l@mullvad.net> | 2022-02-28 17:59:49 +0100 |
|---|---|---|
| committer | David Lönnhager <david.l@mullvad.net> | 2022-03-01 15:30:23 +0100 |
| commit | d2bdcd5878ae6ea748e10fe8e430b80548ec2fb5 (patch) | |
| tree | 47690c0d69b5793eaf0348faaa4440fe92abf84e /mullvad-daemon/src/api.rs | |
| parent | bcf3278eeb1b63f2ff8fa6ee68ab4cc8bb8b76fd (diff) | |
| download | mullvadvpn-d2bdcd5878ae6ea748e10fe8e430b80548ec2fb5.tar.xz mullvadvpn-d2bdcd5878ae6ea748e10fe8e430b80548ec2fb5.zip | |
Add proxy config generator to daemon
Diffstat (limited to 'mullvad-daemon/src/api.rs')
| -rw-r--r-- | mullvad-daemon/src/api.rs | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/mullvad-daemon/src/api.rs b/mullvad-daemon/src/api.rs new file mode 100644 index 0000000000..2ed689b418 --- /dev/null +++ b/mullvad-daemon/src/api.rs @@ -0,0 +1,54 @@ +use crate::DaemonEventSender; +use futures::{channel::oneshot, stream, Stream, StreamExt}; +use mullvad_rpc::proxy::ApiConnectionMode; +use talpid_core::mpsc::Sender; +use talpid_types::ErrorExt; + +pub(crate) struct ApiConnectionModeRequest { + pub response_tx: oneshot::Sender<ApiConnectionMode>, + pub retry_attempt: u32, +} + +/// Returns a stream that returns the next API bridge to try. +/// `initial_config` refers to the first config returned by the stream. The daemon is not notified +/// of this. +pub(crate) fn create_api_config_provider( + daemon_sender: DaemonEventSender<ApiConnectionModeRequest>, + initial_config: ApiConnectionMode, +) -> impl Stream<Item = ApiConnectionMode> + Unpin { + struct Context { + attempt: u32, + daemon_sender: DaemonEventSender<ApiConnectionModeRequest>, + } + + let ctx = Context { + attempt: 1, + daemon_sender, + }; + + Box::pin( + stream::once(async move { initial_config }).chain(stream::unfold( + ctx, + |mut ctx| async move { + ctx.attempt = ctx.attempt.wrapping_add(1); + let (response_tx, response_rx) = oneshot::channel(); + + let _ = ctx.daemon_sender.send(ApiConnectionModeRequest { + response_tx, + retry_attempt: ctx.attempt, + }); + + let new_config = response_rx.await.unwrap_or_else(|error| { + log::error!( + "{}", + error.display_chain_with_msg("Failed to receive API proxy config") + ); + // Fall back on unbridged connection + ApiConnectionMode::Direct + }); + + Some((new_config, ctx)) + }, + )), + ) +} |
