use clap::Parser;
use crate::helpers::{Helpers, Res};
#[derive(Parser, Debug, Clone)]
#[command(name = "rsocks", version, about, long_about = None)]
pub struct Config {
#[arg(long, env = "RS_LISTEN_INTERFACE")]
pub listen_interface: Option<String>,
#[arg(long, env = "RS_ENDPOINT_INTERFACE")]
pub endpoint_interface: Option<String>,
#[arg(long, env = "RS_PORT", default_value_t = 1080)]
pub port: u16,
#[arg(long, env = "RS_BUFFER_SIZE", default_value_t = 2048)]
pub buffer_size: usize,
#[arg(long, env = "RS_READ_TIMEOUT", default_value_t = 60_000)]
pub read_timeout: u64,
#[arg(long, env = "RS_ACCEPT_CIDR", default_value = "0.0.0.0/0")]
pub accept_cidr: String,
}
impl Config {
pub fn listen_ip(&self) -> Res<String> {
Self::interface_ip(self.listen_interface.as_deref())
}
pub fn endpoint_ip(&self) -> Res<String> {
Self::interface_ip(self.endpoint_interface.as_deref())
}
fn interface_ip(interface: Option<&str>) -> Res<String> {
match interface {
Some(name) => Ok(Helpers::get_interface_ip(name)?.to_string()),
None => Ok("0.0.0.0".to_owned()),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use clap::Parser;
use pretty_assertions::assert_eq;
#[test]
fn cli_flags_override_defaults() {
let config = Config::parse_from(["rsocks", "--port", "9050", "--read-timeout", "0", "--accept-cidr", "10.0.0.0/8"]);
assert_eq!(config.port, 9050);
assert_eq!(config.read_timeout, 0);
assert_eq!(config.accept_cidr, "10.0.0.0/8");
}
#[test]
fn unspecified_interface_resolves_to_wildcard() {
let config = Config::parse_from(["rsocks", "--port", "1"]);
assert_eq!(config.listen_ip().unwrap(), "0.0.0.0");
assert_eq!(config.endpoint_ip().unwrap(), "0.0.0.0");
}
}