Skip to content

Commit

Permalink
Reduce calls to default_net
Browse files Browse the repository at this point in the history
  • Loading branch information
kiron1 committed Dec 24, 2024
1 parent 9a50d66 commit b3ca29c
Show file tree
Hide file tree
Showing 8 changed files with 102 additions and 17 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion paclib/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ edition = "2021"
[dependencies]
boa_engine.workspace = true
boa_gc.workspace = true
default-net.workspace = true
detox_net.workspace = true
gc.workspace = true
http.workspace = true
Expand Down
56 changes: 43 additions & 13 deletions paclib/src/engine.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
use boa_engine::{Context, JsNativeError, JsResult, JsString, JsValue, NativeFunction, Source};
use http::Uri;
use std::convert::Infallible;
use std::net::IpAddr;
use std::result::Result;
use std::sync::{Arc, Mutex};
use std::time::Instant;
use tracing::{field::debug, instrument};

Expand All @@ -12,6 +15,7 @@ const PAC_UTILS: &str = include_str!("pac_utils.js");

pub struct Engine<'a> {
js: Context<'a>,
my_ip_addr: Arc<Mutex<IpAddr>>,
}

impl<'a> Engine<'a> {
Expand All @@ -28,12 +32,6 @@ impl<'a> Engine<'a> {
NativeFunction::from_fn_ptr(dns_resolve),
)
.expect("register_global_property");
js.register_global_builtin_callable(
"myIpAddress",
0,
NativeFunction::from_fn_ptr(my_ip_address),
)
.expect("register_global_property");

let dns_cache = js
.eval(Source::from_bytes("new _DnsCache();"))
Expand All @@ -53,7 +51,27 @@ impl<'a> Engine<'a> {
}

pub fn new() -> Self {
Self { js: Self::mkjs() }
let my_ip_addr = Arc::new(Mutex::new(IpAddr::from(std::net::Ipv4Addr::new(
127, 0, 0, 1,
))));
let mut js = Self::mkjs();
// # Safety
// We do not capture any varaibles which would require tracing.
unsafe {
js.register_global_builtin_callable(
"myIpAddress",
0,
NativeFunction::from_closure({
let ip = my_ip_addr.clone();
move |this, args, ctx| my_ip_address(&ip, this, args, ctx)
}),
)
.expect("register_global_property");
}
Self {
js,
my_ip_addr,
}
}

pub fn with_pac_script(pac_script: &str) -> Result<Self, PacScriptError> {
Expand All @@ -71,7 +89,14 @@ impl<'a> Engine<'a> {
Ok(())
}

#[instrument(level = "debug", skip(self), err, ret(Display), fields(duration))]
pub fn set_my_ip_address(&mut self, addr: IpAddr) -> Result<(), Infallible> {
if let Ok(mut ip) = self.my_ip_addr.lock() {
*ip = addr;
}
Ok(())
}

#[instrument(level = "debug", skip(self), ret, fields(duration))]
pub fn find_proxy(&mut self, uri: &Uri) -> Result<Proxies, FindProxyError> {
let host = uri.host().ok_or(FindProxyError::NoHost)?;

Expand Down Expand Up @@ -162,11 +187,16 @@ fn dns_resolve(_this: &JsValue, args: &[JsValue], context: &mut Context) -> JsRe
Ok(value)
}

fn my_ip_address(_this: &JsValue, _args: &[JsValue], _ctx: &mut Context) -> JsResult<JsValue> {
let ip = default_net::get_default_interface()
.ok()
.and_then(|i| i.ipv4.first().map(|i| i.addr.to_string()))
.unwrap_or_else(|| String::from("127.0.0.1"));
fn my_ip_address(
ip: &Arc<Mutex<IpAddr>>,
_this: &JsValue,
_args: &[JsValue],
_ctx: &mut Context,
) -> JsResult<JsValue> {
let ip = ip
.lock()
.map(|ip| ip.to_string())
.unwrap_or_else(|_| String::from("127.0.0.1"));
Ok(JsValue::from(JsString::from(ip)))
}

Expand Down
19 changes: 19 additions & 0 deletions paclib/src/evaluator.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use http::Uri;
use std::convert::Infallible;
use std::net::IpAddr;
use std::sync::{mpsc, Arc, Mutex};
use std::thread;
use tokio::sync::oneshot;
Expand All @@ -14,10 +16,12 @@ pub struct Evaluator {

type FindProxyResult = Result<Proxies, FindProxyError>;
type SetPacScriptResult = Result<(), PacScriptError>;
type SetMyIpAddressResult = Result<(), Infallible>;

enum Action {
FindProxy(Uri, oneshot::Sender<FindProxyResult>),
SetPacScript(Option<String>, oneshot::Sender<SetPacScriptResult>),
SetMyIpAddress(IpAddr, oneshot::Sender<SetMyIpAddressResult>),
}

impl Evaluator {
Expand Down Expand Up @@ -65,6 +69,10 @@ impl Evaluator {
let r = engine.set_pac_script(script.as_deref());
result.send(r).ok();
}
Action::SetMyIpAddress(addr, result) => {
let r = engine.set_my_ip_address(addr);
result.send(r).ok();
}
}
}
}
Expand Down Expand Up @@ -92,6 +100,17 @@ impl Evaluator {
}
rx.await.expect("receive")
}

pub async fn set_my_ip_address(&self, addr: IpAddr) -> SetMyIpAddressResult {
let (tx, rx) = oneshot::channel::<SetMyIpAddressResult>();
{
let sender = self.sender.lock().unwrap();
if let Some(ref sender) = *sender {
sender.send(Action::SetMyIpAddress(addr, tx)).expect("send");
}
}
rx.await.expect("receive")
}
}

impl Default for Evaluator {
Expand Down
1 change: 1 addition & 0 deletions proxydetox/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ unexpected_cfgs = { level = "warn", check-cfg = ['cfg(static_library)'] }
[dependencies]
clap.workspace = true
detox_auth.workspace = true
default-net.workspace = true
detox_net.workspace = true
dirs.workspace = true
futures-util.workspace = true
Expand Down
15 changes: 15 additions & 0 deletions proxydetox/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use options::{Authorization, Options};
use proxydetoxlib::server::Proxy;
use proxydetoxlib::socket;
use std::fs::File;
use std::net::IpAddr;
use std::result::Result;
use std::sync::Arc;
use tokio_stream::wrappers::TcpListenerStream;
Expand Down Expand Up @@ -134,6 +135,10 @@ async fn run(config: Arc<Options>) -> Result<(), proxydetoxlib::Error> {
.client_tcp_keepalive(config.client_tcp_keepalive.clone())
.build();

if let Some(my_ip) = config.my_ip_address {
context.set_my_ip_address(my_ip).await?;
}

let listeners = if let Some(name) = &config.activate_socket {
socket::activate_socket(name)?
.take()
Expand Down Expand Up @@ -174,9 +179,11 @@ async fn run(config: Arc<Options>) -> Result<(), proxydetoxlib::Error> {
tokio::select! {
_ = reload_trigger() => {
context.load_pac_file(&config.pac_file).await?;
context.set_my_ip_address(my_ip_address()).await?;
},
_ = direct_mode_trigger() => {
context.load_pac_file(&None).await?;
context.set_my_ip_address(my_ip_address()).await?;
},
_ = shutdown_trigger() => {
tracing::info!("shutdown requested");
Expand Down Expand Up @@ -253,3 +260,11 @@ async fn shutdown_trigger() {
async fn shutdown_trigger() {
tokio::signal::ctrl_c().await.expect("ctrl_c event");
}

fn my_ip_address() -> IpAddr {
let ipv4 = default_net::get_default_interface()
.ok()
.and_then(|i| i.ipv4.first().map(|i| i.addr))
.unwrap_or_else(|| std::net::Ipv4Addr::new(127, 0, 0, 1));
IpAddr::from(ipv4)
}
15 changes: 13 additions & 2 deletions proxydetox/src/options.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::{
ffi::OsString,
fs::read_to_string,
net::{IpAddr, SocketAddr},
net::{IpAddr, Ipv4Addr, SocketAddr},
path::{Path, PathBuf},
sync::Arc,
time::Duration,
Expand All @@ -28,6 +28,7 @@ pub enum Authorization {
pub struct Options {
pub log_level: LevelFilter,
pub pac_file: Option<PathOrUri>,
pub my_ip_address: Option<IpAddr>,
pub authorization: Authorization,
pub connect_timeout: Duration,
pub race_connect: bool,
Expand Down Expand Up @@ -173,6 +174,15 @@ impl Options {
.value_parser(is_file_or_http_uri)
.action(clap::ArgAction::Set),
)
.arg(
Arg::new("my_ip_address")
.long("my-ip-address")
.value_name("IP-ADDRESS")
.help(
"Custom IP address to be returned by the myIpAddress PAC function",
)
.action(clap::ArgAction::Set),
)
.arg(netrc_arg)
.arg(
Arg::new("proxytunnel")
Expand Down Expand Up @@ -308,7 +318,7 @@ impl From<ArgMatches> for Options {
listen.cloned().collect()
} else {
vec![SocketAddr::new(
IpAddr::V4(std::net::Ipv4Addr::new(127, 0, 0, 1)),
IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)),
3128,
)]
};
Expand Down Expand Up @@ -340,6 +350,7 @@ impl From<ArgMatches> for Options {
.get_one::<PathOrUri>("pac_file")
.cloned()
.or_else(|| which_pac_file().map(PathOrUri::Path)),
my_ip_address: m.get_one::<IpAddr>("my_ip_address").cloned(),
authorization,
proxytunnel: m.get_flag("proxytunnel"),
direct_fallback: m.get_flag("direct_fallback"),
Expand Down
10 changes: 10 additions & 0 deletions proxydetoxlib/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use http::Uri;
use paclib::ProxyOrDirect;
use std::fs::read_to_string;
use std::future::IntoFuture;
use std::net::IpAddr;
use std::sync::Arc;
use std::time::Duration;
use std::time::Instant;
Expand Down Expand Up @@ -106,6 +107,15 @@ impl Context {
.map_err(std::io::Error::other)
}

#[instrument(skip(self))]
pub async fn set_my_ip_address(&self, addr: IpAddr) -> std::io::Result<()> {
tracing::info!("update my IP address");
self.eval
.set_my_ip_address(addr)
.await
.map_err(std::io::Error::other)
}

/// Establish a connection to parent proxy.
///
/// In case of `CONNECT` the connesction will be established so far that `CONNECT` request is
Expand Down

0 comments on commit b3ca29c

Please sign in to comment.