Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature] Support CloudFlare Warp in VPN block #2100

Open
Bad3r opened this issue Nov 9, 2024 · 2 comments · May be fixed by #2149
Open

[Feature] Support CloudFlare Warp in VPN block #2100

Bad3r opened this issue Nov 9, 2024 · 2 comments · May be fixed by #2149

Comments

@Bad3r
Copy link

Bad3r commented Nov 9, 2024

It would be great if the VPN block could indicate if CloudFlare Warp is connected.

@Bad3r
Copy link
Author

Bad3r commented Dec 7, 2024

my bad attempt using AI to do this since I don't know rust:

use std::process::Stdio;
use tokio::process::Command;

use crate::blocks::prelude::*;

use super::{Driver, Status};

pub struct WarpDriver;

impl WarpDriver {
    pub async fn new() -> WarpDriver {
        WarpDriver
    }

    async fn run_network_command(arg: &str) -> Result<()> {
        Command::new("warp-cli")
            .args([arg])
            .stdin(Stdio::null())
            .stdout(Stdio::null())
            .spawn()
            .error(format!("Problem running warp-cli command: {arg}"))?
            .wait()
            .await
            .error(format!("Problem running warp-cli command: {arg}"))?;
        Ok(())
    }

    async fn find_line(stdout: &str, needle: &str) -> Option<String> {
        stdout
            .lines()
            .find(|s| s.contains(needle))
            .map(|s| s.to_owned())
    }
}

#[async_trait]
impl Driver for WarpDriver {
    async fn get_status(&self) -> Result<Status> {
        let stdout = Command::new("warp-cli")
            .args(["status"])
            .output()
            .await
            .error("Problem running warp-cli command")?
            .stdout;

        let stdout = String::from_utf8(stdout).error("warp-cli produced non-UTF8 output")?;
        let line_status = Self::find_line(&stdout, "Status:").await;

        if line_status.is_none() {
            return Ok(Status::Error);
        }
        let line_status = line_status.unwrap();

        if line_status.ends_with("Disconnected") {
            return Ok(Status::Disconnected);
        } else if line_status.ends_with("Connected") {
            return Ok(Status::Connected { country: String::from("Unknown"), country_flag: String::from("🌐") });
        }
        Ok(Status::Error)
    }

    async fn toggle_connection(&self, status: &Status) -> Result<()> {
        match status {
            Status::Connected { .. } => Self::run_network_command("disconnect").await?,
            Status::Disconnected => Self::run_network_command("connect").await?,
            Status::Error => (),
        }
        Ok(())
    }
}

issues and limitations:

  1. warp does not show up in network interfaces i.e it doesn't use something like tun0
  2. region and country does not affect warp since it just connects to the closest server.

currently I am using a shell script to monitor it instead:

#!/bin/sh

log_file="/var/log/cloudflare-warp/cfwarp_service_log.txt"
last_status=""

tail -F "$log_file" | {
    while IFS= read -r line; do
        case "$line" in
        *ResponseStatus:*)
            current_status=$(printf "%s" "$line" | awk -F'ResponseStatus: ' '{print $2}' | awk '{print $1}')
            if [ "$current_status" != "$last_status" ]; then
                if [ "$current_status" = "Connected" ] || [ "$current_status" = "Connecting" ]; then
                    notify-send -u normal "Warp Status" "$current_status"
                else
                    notify-send -u critical -t 10000 "Warp Status" "$current_status"
                fi
                last_status="$current_status"
            fi
            ;;
        esac
    done
}

@vats004
Copy link
Contributor

vats004 commented Mar 21, 2025

Hi @Bad3r
I was working on this and thought it was okay to leave country and flag as blanks

@vats004 vats004 linked a pull request Mar 21, 2025 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants