Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Set my ip #348

Merged
merged 1 commit into from
Dec 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading