android: sets socket protect path from env var

This commit is contained in:
eric
2021-08-27 08:36:57 +08:00
parent 8f8ecc6469
commit 9dcbc6e50a
4 changed files with 16 additions and 35 deletions

View File

@@ -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<String>,
// 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<Runner> = Vec::new();
let mut runners = Vec::new();

View File

@@ -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)
};

View File

@@ -106,32 +106,18 @@ pub trait Color {
fn color(&self) -> colored::Color;
}
#[cfg(target_os = "android")]
lazy_static! {
static ref SOCKET_PROTECT_PATH: Mutex<Option<String>> = 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<S: AsRawFd>(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<UdpSocket> {
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(

View File

@@ -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),
}
}