use clap::Parser;
use anyhow::Result;
pub mod args;
pub mod commands;
mod ui;
pub mod server;
pub mod utils;
use args::{Cli, Commands};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
rustls::crypto::ring::default_provider().install_default()
.expect("Failed to install rustls crypto provider");
let cli = Cli::parse();
let is_tui = if let Commands::Run { ui, .. } = &cli.command {
*ui
} else {
false
};
if is_tui {
let file = std::fs::OpenOptions::new()
.create(true)
.write(true)
.truncate(true)
.open("relay-core.log")?;
tracing_subscriber::fmt()
.with_env_filter(tracing_subscriber::EnvFilter::from_default_env().add_directive(tracing::Level::INFO.into()))
.with_writer(std::sync::Mutex::new(file))
.with_ansi(false)
.init();
} else {
tracing_subscriber::fmt()
.with_env_filter(tracing_subscriber::EnvFilter::from_default_env().add_directive(tracing::Level::INFO.into()))
.init();
}
match cli.command {
Commands::Run {
listen,
control_port,
udp_tproxy_port,
ca_cert,
ca_key,
rules,
#[cfg(feature = "script")]
script,
#[cfg(feature = "script")]
script_watch,
ui,
transparent,
output,
save_stream,
api_port,
} => {
#[cfg(feature = "script")]
commands::run::execute(listen, control_port, udp_tproxy_port, ca_cert, ca_key, rules, script, script_watch, ui, transparent, output, save_stream, api_port).await?;
#[cfg(not(feature = "script"))]
commands::run::execute(listen, control_port, udp_tproxy_port, ca_cert, ca_key, rules, ui, transparent, output, save_stream, api_port).await?;
},
#[cfg(any(feature = "transparent-linux", feature = "transparent-macos"))]
Commands::Proxy { action } => {
if let Err(e) = commands::proxy::handle_transparent_command(action) {
eprintln!("Proxy command failed: {}", e);
std::process::exit(1);
}
},
Commands::Rules { action } => {
commands::rules::execute(action)?;
},
#[cfg(feature = "script")]
Commands::Scripts { action } => {
commands::scripts::execute(action).await?;
},
Commands::Ca { action } => {
commands::ca::execute(action)?;
},
Commands::Flows { control_url, output } => {
commands::flows::execute(control_url, output).await?;
},
Commands::Intercept { action, control_url } => {
commands::flows::execute_intercept(action, control_url).await?;
},
Commands::Metrics { proxy_url, output } => {
commands::metrics::execute(proxy_url, output).await?;
}
}
Ok(())
}