use async_trait::async_trait;
use geph5_broker_protocol::ExitConstraint;
use nanorpc::nanorpc_derive;
use serde::{Deserialize, Serialize};
#[cfg(target_os = "macos")]
pub const MANAGER_CONTROL_SOCK: &str = "/var/run/geph/control.sock";
#[cfg(all(unix, not(target_os = "macos")))]
pub const MANAGER_CONTROL_SOCK: &str = "/run/geph/control.sock";
#[cfg(windows)]
pub const MANAGER_CONTROL_PIPE: &str = r"\\.\pipe\geph-manager-control";
#[cfg(unix)]
pub type ManagerTransport = nanorpc_sillad::DialerTransport<sillad::unix::UnixDialer>;
#[cfg(windows)]
pub type ManagerTransport = nanorpc_sillad::DialerTransport<sillad::windows_pipe::NamedPipeDialer>;
pub fn manager_control_transport() -> ManagerTransport {
#[cfg(unix)]
{
nanorpc_sillad::DialerTransport(sillad::unix::UnixDialer {
path: MANAGER_CONTROL_SOCK.into(),
})
}
#[cfg(windows)]
{
nanorpc_sillad::DialerTransport(sillad::windows_pipe::NamedPipeDialer {
name: MANAGER_CONTROL_PIPE.to_string(),
})
}
}
pub fn manager_control_client() -> GephCtlClient {
GephCtlClient::from(manager_control_transport())
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]
#[serde(rename_all = "snake_case")]
pub enum ConnState {
Disconnected,
Connecting,
Connected,
}
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct ExitInfo {
pub hostname: String,
pub country: String,
pub city: String,
pub load: f32,
pub allows_free: bool,
}
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct AccountInfo {
pub user_id: u64,
pub level: String,
pub plus_expires_unix: Option<u64>,
pub bw_used_mb: Option<u32>,
pub bw_limit_mb: Option<u32>,
}
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct Status {
pub state: ConnState,
pub exit: Option<ExitInfo>,
pub total_rx_bytes: f64,
pub total_tx_bytes: f64,
}
#[derive(Serialize, Deserialize, Clone, Debug, Default)]
pub struct SessionContext {
#[serde(default)]
pub uid: u32,
#[serde(default)]
pub gid: Option<u32>,
#[serde(default)]
pub home: Option<String>,
#[serde(default)]
pub dbus_session_bus_address: Option<String>,
#[serde(default)]
pub xdg_runtime_dir: Option<String>,
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]
pub struct ProxySettings {
pub autoconf: bool,
pub listen_all: bool,
pub socks5_port: u16,
pub http_port: u16,
}
impl Default for ProxySettings {
fn default() -> Self {
Self {
autoconf: true,
listen_all: false,
socks5_port: 9909,
http_port: 9910,
}
}
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
pub struct TunnelSettings {
pub exit_constraint: ExitConstraint,
pub proxy: Option<ProxySettings>,
pub vpn: bool,
pub allow_lan: bool,
pub allow_direct: bool,
#[serde(default)]
pub passthrough_china: bool,
#[serde(default)]
pub session_metadata: serde_json::Value,
}
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct SettingsView {
pub logged_in: bool,
pub exit_constraint: ExitConstraint,
pub connected: bool,
pub proxy: Option<ProxySettings>,
pub vpn: bool,
pub allow_lan: bool,
pub allow_direct: bool,
pub passthrough_china: bool,
pub session_metadata: serde_json::Value,
}
impl SettingsView {
pub fn tunnel_settings(&self) -> TunnelSettings {
TunnelSettings {
exit_constraint: self.exit_constraint.clone(),
proxy: self.proxy.clone(),
vpn: self.vpn,
allow_lan: self.allow_lan,
allow_direct: self.allow_direct,
passthrough_china: self.passthrough_china,
session_metadata: self.session_metadata.clone(),
}
}
}
#[nanorpc_derive]
#[async_trait]
pub trait GephCtlProtocol {
async fn login(&self, secret: String) -> Result<AccountInfo, String>;
async fn logout(&self, session: SessionContext) -> Result<(), String>;
async fn account(&self) -> Result<AccountInfo, String>;
async fn connect(&self, session: SessionContext) -> Result<(), String>;
async fn disconnect(&self, session: SessionContext) -> Result<(), String>;
async fn reconnect(&self, session: SessionContext) -> Result<(), String>;
async fn status(&self) -> Result<Status, String>;
async fn get_settings(&self) -> Result<SettingsView, String>;
async fn apply_settings(
&self,
settings: TunnelSettings,
session: SessionContext,
) -> Result<(), String>;
async fn list_exits(&self) -> Result<Vec<ExitInfo>, String>;
async fn logs(&self, count: usize) -> Result<Vec<String>, String>;
async fn daemon_rpc(
&self,
method: String,
params: Vec<serde_json::Value>,
) -> Result<serde_json::Value, String>;
}