Skip to content

Commit

Permalink
Update dependencies, refactor code, and enhance logging and ASN mappi…
Browse files Browse the repository at this point in the history
…ng feature
  • Loading branch information
nullchinchilla committed Sep 7, 2024
1 parent 7814a24 commit a87537d
Show file tree
Hide file tree
Showing 8 changed files with 66 additions and 12 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

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

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ license = "ISC"


[patch.crates-io]
#smolscale = { path = "../smolscale" }
#ipstack-geph = { path = "../ipstack-geph" }


[profile.release]
Expand Down
5 changes: 1 addition & 4 deletions binaries/geph5-client/src/vpn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,7 @@ mod dummy;
#[cfg(any(target_os = "android", target_os = "ios"))]
pub use dummy::*;

use std::{
net::Ipv4Addr,
time::{Duration, Instant},
};
use std::{net::Ipv4Addr, time::Instant};

use anyctx::AnyCtx;
use anyhow::Context;
Expand Down
2 changes: 1 addition & 1 deletion binaries/geph5-client/src/vpn/linux.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ pub(super) async fn packet_shuffle(
loop {
let n = read.read(&mut buf).await?;
let buf = &buf[..n];
tracing::trace!(n, buf = hex::encode(buf), "captured packet from TUN");
tracing::trace!(n, "captured packet from TUN");
send_captured.send(Bytes::copy_from_slice(buf)).await?;
}
};
Expand Down
1 change: 1 addition & 0 deletions binaries/geph5-exit/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ fastrand = "2.1.0"
tachyonix = "0.3.0"
clap = { version = "4.5.8", features = ["derive"] }
smol-timeout2 = "0.6.1"
flate2 = "1.0.33"

[target.'cfg(not(target_env = "msvc"))'.dependencies]
tikv-jemallocator = "0.5"
57 changes: 52 additions & 5 deletions binaries/geph5-exit/src/listen.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use anyhow::Context;
use ed25519_dalek::{Signer, VerifyingKey};
use flate2::read::GzDecoder;
use futures_util::{AsyncReadExt, TryFutureExt};
use geph5_broker_protocol::{
AccountLevel, BrokerClient, ExitDescriptor, Mac, Signed, DOMAIN_EXIT_DESCRIPTOR,
Expand All @@ -16,9 +17,11 @@ use picomux::{LivenessConfig, PicoMux};
use sillad::{listener::Listener, tcp::TcpListener, EitherPipe, Pipe};
use smol::future::FutureExt as _;
use std::{
net::IpAddr,
collections::BTreeMap,
io::BufRead,
net::{IpAddr, SocketAddr},
str::FromStr,
sync::atomic::Ordering,
sync::{atomic::Ordering, Arc, LazyLock},
time::{Duration, SystemTime},
};
use stdcode::StdcodeSerializeExt;
Expand Down Expand Up @@ -134,6 +137,8 @@ async fn broker_loop() -> anyhow::Result<()> {

async fn c2e_loop() -> anyhow::Result<()> {
let mut listener = TcpListener::bind(CONFIG_FILE.wait().c2e_listen).await?;
let ip_to_asn = get_ip_to_asn_map().await?;
tracing::info!(len = ip_to_asn.len(), "loaded ASN mapping");
loop {
let c2e_raw = match listener.accept().await {
Ok(conn) => conn,
Expand All @@ -142,6 +147,24 @@ async fn c2e_loop() -> anyhow::Result<()> {
continue;
}
};

let test_addr = async {
let remote_addr: SocketAddr = c2e_raw.remote_addr().unwrap().parse()?;
if let SocketAddr::V4(remote_addr) = remote_addr {
let (_, (asn, country)) = ip_to_asn
.range(remote_addr.ip().to_bits()..)
.next()
.context("ASN lookup failed")?;
tracing::debug!(asn, country, remote_addr = display(remote_addr), "got ASN");
if CONFIG_FILE.wait().country_blacklist.contains(country) {
anyhow::bail!("rejected connection from blacklisted country")
}
}
anyhow::Ok(())
};
if let Err(err) = test_addr.await {
tracing::warn!(err = debug(err), "addr testing failed");
}
smolscale::spawn(
handle_client(c2e_raw).map_err(|e| tracing::warn!("client died suddenly with {e}")),
)
Expand Down Expand Up @@ -199,8 +222,6 @@ async fn handle_client(mut client: impl Pipe) -> anyhow::Result<()> {
// execute the authentication
let client_hello: ClientHello = stdcode::deserialize(&read_prepend_length(&mut client).await?)?;

tracing::debug!("client_hello received");

let keys: Option<([u8; 32], [u8; 32])>;
let exit_hello_inner: ExitHelloInner = match client_hello.crypt_hello {
ClientCryptHello::SharedSecretChallenge(key) => {
Expand Down Expand Up @@ -250,8 +271,34 @@ async fn handle_client(mut client: impl Pipe) -> anyhow::Result<()> {
let metadata = String::from_utf8_lossy(stream.metadata()).to_string();
smolscale::spawn(
proxy_stream(ratelimit.clone(), stream)
.map_err(|e| tracing::debug!(metadata = display(metadata), "stream died with {e}")),
.map_err(|e| tracing::trace!(metadata = display(metadata), "stream died with {e}")),
)
.detach();
}
}

async fn get_ip_to_asn_map() -> anyhow::Result<BTreeMap<u32, (u32, String)>> {
let url = "https://iptoasn.com/data/ip2asn-v4-u32.tsv.gz";
let response = reqwest::get(url).await?;
let bytes = response.bytes().await?;

let decoder = GzDecoder::new(&bytes[..]);
let reader = std::io::BufReader::new(decoder);

let mut map = BTreeMap::new();

for line in reader.lines() {
let line = line?;
let fields: Vec<&str> = line.split('\t').collect();

if fields.len() >= 4 {
let range_end: u32 = fields[1].parse()?;
let as_number: u32 = fields[2].parse()?;
let country_code = fields[3].to_string();

map.insert(range_end, (as_number, country_code));
}
}

Ok(map)
}
7 changes: 7 additions & 0 deletions binaries/geph5-exit/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ struct ConfigFile {
country: CountryCode,
city: String,

#[serde(default = "default_country_blacklist")]
country_blacklist: Vec<String>,

#[serde(default = "default_free_ratelimit")]
free_ratelimit: u32,

Expand All @@ -61,6 +64,10 @@ fn default_total_ratelimit() -> u32 {
125000
}

fn default_country_blacklist() -> Vec<String> {
vec!["CN".to_string(), "IR".to_string()]
}

#[derive(Deserialize)]
struct BrokerConfig {
url: String,
Expand Down
3 changes: 2 additions & 1 deletion binaries/geph5-exit/src/proxy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use std::{
};

use anyhow::Context;

use futures_util::{io::BufReader, AsyncReadExt, AsyncWriteExt};
use moka::future::Cache;

Expand Down Expand Up @@ -36,7 +37,7 @@ pub async fn proxy_stream(ratelimit: RateLimiter, stream: picomux::Stream) -> an
.dial()
.await
.context("failed to dial")?;
tracing::debug!(
tracing::trace!(
protocol,
dest_host = display(dest_host),
latency = debug(start.elapsed()),
Expand Down

0 comments on commit a87537d

Please sign in to comment.