diff --git a/src/error.rs b/src/error.rs index 3803243..00a73cc 100644 --- a/src/error.rs +++ b/src/error.rs @@ -15,6 +15,22 @@ impl From for Error { } } +impl From for Error { + fn from(err: std::net::AddrParseError) -> Self { + Self { + message: err.to_string(), + } + } +} + +impl From for Error { + fn from(err: smoltcp::iface::RouteTableFull) -> Self { + Self { + message: format!("{err:?}"), + } + } +} + impl From<&str> for Error { fn from(err: &str) -> Self { Self { diff --git a/src/lib.rs b/src/lib.rs index e3f869d..b09ee97 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -76,8 +76,8 @@ impl std::fmt::Display for ProxyType { } } -pub fn main_entry(tun: &str, proxy: Proxy, options: Options) { - let mut ttp = TunToProxy::new(tun, options); +pub fn main_entry(tun: &str, proxy: Proxy, options: Options) -> Result<(), Error> { + let mut ttp = TunToProxy::new(tun, options)?; match proxy.proxy_type { ProxyType::Socks5 => { ttp.add_connection_manager(Socks5Manager::new(proxy.addr, proxy.credentials)); @@ -86,7 +86,5 @@ pub fn main_entry(tun: &str, proxy: Proxy, options: Options) { ttp.add_connection_manager(HttpManager::new(proxy.addr, proxy.credentials)); } } - if let Err(e) = ttp.run() { - log::error!("{e}"); - } + ttp.run() } diff --git a/src/main.rs b/src/main.rs index 50a0d53..7cb0797 100644 --- a/src/main.rs +++ b/src/main.rs @@ -47,5 +47,7 @@ fn main() { options = options.with_virtual_dns(); } - main_entry(&args.tun, args.proxy, options); + if let Err(e) = main_entry(&args.tun, args.proxy, options) { + log::error!("{e}"); + } } diff --git a/src/tun2proxy.rs b/src/tun2proxy.rs index 64732cd..4dcf7e5 100644 --- a/src/tun2proxy.rs +++ b/src/tun2proxy.rs @@ -17,7 +17,7 @@ use std::convert::{From, TryFrom}; use std::fmt::{Display, Formatter}; use std::io::{Read, Write}; use std::net::Shutdown::Both; -use std::net::{IpAddr, SocketAddr}; +use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr}; use std::os::unix::io::AsRawFd; use std::rc::Rc; use std::str::FromStr; @@ -286,45 +286,29 @@ pub(crate) struct TunToProxy<'a> { } impl<'a> TunToProxy<'a> { - pub(crate) fn new(interface: &str, options: Options) -> Self { - let tun = TunTapInterface::new(interface, Medium::Ip).unwrap(); - let poll = Poll::new().unwrap(); - poll.registry() - .register( - &mut SourceFd(&tun.as_raw_fd()), - TCP_TOKEN, - Interest::READABLE, - ) - .unwrap(); + pub(crate) fn new(interface: &str, options: Options) -> Result { + let tun = TunTapInterface::new(interface, Medium::Ip)?; + let poll = Poll::new()?; + poll.registry().register( + &mut SourceFd(&tun.as_raw_fd()), + TCP_TOKEN, + Interest::READABLE, + )?; let config = Config::new(); let mut virt = VirtualTunDevice::new(tun.capabilities()); + let gateway4: Ipv4Addr = std::net::Ipv4Addr::from_str("0.0.0.1")?; + let gateway6: Ipv6Addr = std::net::Ipv6Addr::from_str("::1")?; let mut iface = Interface::new(config, &mut virt); iface.update_ip_addrs(|ip_addrs| { - ip_addrs - .push(IpCidr::new( - std::net::Ipv4Addr::from_str("0.0.0.1").unwrap().into(), - 0, - )) - .unwrap(); - ip_addrs - .push(IpCidr::new( - std::net::Ipv6Addr::from_str("::1").unwrap().into(), - 0, - )) - .unwrap() + ip_addrs.push(IpCidr::new(gateway4.into(), 0)).unwrap(); + ip_addrs.push(IpCidr::new(gateway6.into(), 0)).unwrap() }); - iface - .routes_mut() - .add_default_ipv4_route(std::net::Ipv4Addr::from_str("0.0.0.1").unwrap().into()) - .unwrap(); - iface - .routes_mut() - .add_default_ipv6_route(std::net::Ipv6Addr::from_str("::1").unwrap().into()) - .unwrap(); + iface.routes_mut().add_default_ipv4_route(gateway4.into())?; + iface.routes_mut().add_default_ipv6_route(gateway6.into())?; iface.set_any_ip(true); - Self { + let tun = Self { tun, poll, iface, @@ -336,7 +320,8 @@ impl<'a> TunToProxy<'a> { device: virt, options, write_sockets: Default::default(), - } + }; + Ok(tun) } pub(crate) fn add_connection_manager(&mut self, manager: Rc) { diff --git a/tests/proxy.rs b/tests/proxy.rs index fe3125f..74e1a32 100644 --- a/tests/proxy.rs +++ b/tests/proxy.rs @@ -146,7 +146,7 @@ mod tests { } Ok(Fork::Child) => { prctl::set_death_signal(signal::SIGKILL as isize).unwrap(); // 9 == SIGKILL - main_entry( + let _ = main_entry( TUN_TEST_DEVICE, test.proxy, Options::new().with_virtual_dns(),