diff --git a/leaf/src/lib.rs b/leaf/src/lib.rs index b1bfc34c3..2414189e5 100644 --- a/leaf/src/lib.rs +++ b/leaf/src/lib.rs @@ -333,9 +333,6 @@ pub struct StartOptions { // Enable auto reload, take effect only when "auto-reload" feature is enabled. #[cfg(feature = "auto-reload")] pub auto_reload: bool, - // The service path to protect outbound sockets on Android. - #[cfg(target_os = "android")] - pub socket_protect_path: Option, // Tokio runtime options. pub runtime_opt: RuntimeOption, } @@ -370,11 +367,6 @@ pub fn start(rt_id: RuntimeId, opts: StartOptions) -> Result<(), Error> { let rt = new_runtime(&opts.runtime_opt)?; let _g = rt.enter(); - #[cfg(target_os = "android")] - if let Some(p) = opts.socket_protect_path.as_ref() { - rt.block_on(proxy::set_socket_protect_path(p.to_owned())); - } - let mut tasks: Vec = Vec::new(); let mut runners = Vec::new(); diff --git a/leaf/src/option/mod.rs b/leaf/src/option/mod.rs index c64320dba..76cabac58 100644 --- a/leaf/src/option/mod.rs +++ b/leaf/src/option/mod.rs @@ -131,6 +131,15 @@ lazy_static! { outbound_binds }; + /// Sets the RPC service endpoint for protecting outbound sockets on Android to + /// avoid infinite loop. The `path` is treated as a Unix domain socket endpoint. + /// The RPC service simply listens for incoming connections, reads an int32 on + /// each connection, treats it as the file descriptor to protect, writes back 0 + /// on success. + pub static ref SOCKET_PROTECT_PATH: String = { + get_env_var_or("SOCKET_PROTECT_PATH", "".to_string()) + }; + pub static ref GATEWAY_MODE: bool = { get_env_var_or("GATEWAY_MODE", false) }; diff --git a/leaf/src/proxy/mod.rs b/leaf/src/proxy/mod.rs index b93b9c80a..51053ed2a 100644 --- a/leaf/src/proxy/mod.rs +++ b/leaf/src/proxy/mod.rs @@ -106,32 +106,18 @@ pub trait Color { fn color(&self) -> colored::Color; } -#[cfg(target_os = "android")] -lazy_static! { - static ref SOCKET_PROTECT_PATH: Mutex> = Mutex::new(None); -} - #[derive(Debug)] pub enum OutboundBind { Ip(SocketAddr), Interface(String), } -// Sets the RPC service endpoint for protecting outbound sockets on Android to -// avoid infinite loop. The `path` is treated as a Unix domain socket endpoint. -// The RPC service simply listens for incoming connections, reads an int32 on -// each connection, treats it as the file descriptor to protect, writes back 0 -// on success. -#[cfg(target_os = "android")] -pub async fn set_socket_protect_path(path: String) { - SOCKET_PROTECT_PATH.lock().await.replace(path); -} - #[cfg(target_os = "android")] -async fn protect_socket(socket: S) -> io::Result<()> { - if let Some(path) = SOCKET_PROTECT_PATH.lock().await.as_ref() { - let mut stream = UnixStream::connect(path).await?; - stream.write_i32(socket.as_raw_fd() as i32).await?; +async fn protect_socket(fd: RawFd) -> io::Result<()> { + // TODO Warns about empty protect path? + if !option::SOCKET_PROTECT_PATH.is_empty() { + let mut stream = UnixStream::connect(&*option::SOCKET_PROTECT_PATH).await?; + stream.write_i32(fd as i32).await?; if stream.read_i32().await? != 0 { return Err(io::Error::new( io::ErrorKind::Other, @@ -295,7 +281,7 @@ pub async fn new_udp_socket(indicator: &SocketAddr) -> io::Result { bind_socket(&socket, indicator).await?; #[cfg(target_os = "android")] - protect_socket(&socket).await?; + protect_socket(socket.as_raw_fd()).await?; UdpSocket::from_std(socket.into()) } @@ -326,7 +312,7 @@ async fn tcp_dial_task(dial_addr: SocketAddr) -> io::Result<(AnyStream, SocketAd bind_socket(&socket, &dial_addr).await?; #[cfg(target_os = "android")] - protect_socket(&socket).await?; + protect_socket(socket.as_raw_fd()).await?; trace!("tcp dialing {}", &dial_addr); let stream = timeout( diff --git a/leaf/src/util.rs b/leaf/src/util.rs index bfe4b7e09..58feaa39a 100644 --- a/leaf/src/util.rs +++ b/leaf/src/util.rs @@ -24,8 +24,6 @@ fn get_start_options( config: crate::Config::File(config_path), #[cfg(feature = "auto-reload")] auto_reload, - #[cfg(target_os = "android")] - socket_protect_path: None, runtime_opt: crate::RuntimeOption::SingleThread, }; } @@ -34,8 +32,6 @@ fn get_start_options( config: crate::Config::File(config_path), #[cfg(feature = "auto-reload")] auto_reload, - #[cfg(target_os = "android")] - socket_protect_path: None, runtime_opt: crate::RuntimeOption::MultiThreadAuto(stack_size), }; } @@ -43,8 +39,6 @@ fn get_start_options( config: crate::Config::File(config_path), #[cfg(feature = "auto-reload")] auto_reload, - #[cfg(target_os = "android")] - socket_protect_path: None, runtime_opt: crate::RuntimeOption::MultiThread(threads, stack_size), } }