use self::{
config::{Config, ConfigError},
connection::Endpoint,
socks5::Server as Socks5Server,
};
use env_logger::Builder as LoggerBuilder;
use quinn::{ConnectError, ConnectionError};
use rustls::Error as RustlsError;
use std::{env, io::Error as IoError, process};
use thiserror::Error;
use tuic_quinn::Error as ModelError;
mod config;
mod connection;
mod socks5;
mod utils;
#[tokio::main]
async fn main() {
let cfg = match Config::parse(env::args_os()) {
Ok(cfg) => cfg,
Err(ConfigError::Version(msg) | ConfigError::Help(msg)) => {
println!("{msg}");
process::exit(0);
}
Err(err) => {
eprintln!("{err}");
process::exit(1);
}
};
LoggerBuilder::new()
.filter_level(cfg.log_level)
.format_module_path(false)
.format_target(false)
.init();
match Endpoint::set_config(cfg.relay) {
Ok(()) => {}
Err(err) => {
eprintln!("{err}");
process::exit(1);
}
}
match Socks5Server::set_config(cfg.local).await {
Ok(()) => {}
Err(err) => {
eprintln!("{err}");
process::exit(1);
}
}
Socks5Server::start().await;
}
#[derive(Debug, Error)]
pub enum Error {
#[error(transparent)]
Io(#[from] IoError),
#[error(transparent)]
Connect(#[from] ConnectError),
#[error(transparent)]
Connection(#[from] ConnectionError),
#[error(transparent)]
Model(#[from] ModelError),
#[error("load native certificates error: {0}")]
LoadNativeCerts(IoError),
#[error(transparent)]
Rustls(#[from] RustlsError),
#[error("{0}: {1}")]
Socket(&'static str, IoError),
#[error("timeout establishing connection")]
Timeout,
#[error("cannot resolve the server name")]
DnsResolve,
#[error("received packet from an unexpected source")]
WrongPacketSource,
#[error("invalid socks5 authentication")]
InvalidSocks5Auth,
}