Browse Source

use dns cache

master
Jonathan Cobb 4 years ago
parent
commit
04e6538f68
4 changed files with 503 additions and 21 deletions
  1. +359
    -0
      Cargo.lock
  2. +4
    -1
      Cargo.toml
  3. +105
    -2
      src/lib.rs
  4. +35
    -18
      src/main.rs

+ 359
- 0
Cargo.lock View File

@@ -104,15 +104,18 @@ name = "bubble-flexrouter"
version = "0.1.0"
dependencies = [
"clap",
"futures",
"futures-channel",
"futures-core",
"futures-util",
"http",
"hyper",
"hyper-tls",
"lru",
"os_info",
"pnet",
"tokio",
"tower",
"trust-dns-resolver",
]

@@ -122,6 +125,12 @@ version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38"

[[package]]
name = "cc"
version = "1.0.59"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "66120af515773fb005778dc07c261bd201ec8ce50bd6e7144c927753fe013381"

[[package]]
name = "cfg-if"
version = "0.1.10"
@@ -143,6 +152,22 @@ dependencies = [
"vec_map",
]

[[package]]
name = "core-foundation"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57d24c7a13c43e870e37c1556b74555437870a04514f7685f5b354e090567171"
dependencies = [
"core-foundation-sys",
"libc",
]

[[package]]
name = "core-foundation-sys"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b3a71ab494c0b5b860bdc8407ae08978052417070c2ced38573a9157ad75b8ac"

[[package]]
name = "enum-as-inner"
version = "0.3.3"
@@ -161,6 +186,21 @@ version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"

[[package]]
name = "foreign-types"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
dependencies = [
"foreign-types-shared",
]

[[package]]
name = "foreign-types-shared"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"

[[package]]
name = "fuchsia-zircon"
version = "0.3.3"
@@ -185,6 +225,7 @@ checksum = "1e05b85ec287aac0dc34db7d4a569323df697f9c55b99b15d6b4ef8cde49f613"
dependencies = [
"futures-channel",
"futures-core",
"futures-executor",
"futures-io",
"futures-sink",
"futures-task",
@@ -207,12 +248,35 @@ version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "59f5fff90fd5d971f936ad674802482ba441b6f09ba5e15fd8b39145582ca399"

[[package]]
name = "futures-executor"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "10d6bb888be1153d3abeb9006b11b02cf5e9b209fda28693c31ae1e4e012e314"
dependencies = [
"futures-core",
"futures-task",
"futures-util",
]

[[package]]
name = "futures-io"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "de27142b013a8e869c14957e6d2edeef89e97c289e69d042ee3a49acd8b51789"

[[package]]
name = "futures-macro"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d0b5a30a4328ab5473878237c447333c093297bded83a4983d10f4deea240d39"
dependencies = [
"proc-macro-hack",
"proc-macro2",
"quote",
"syn",
]

[[package]]
name = "futures-sink"
version = "0.3.5"
@@ -237,11 +301,14 @@ dependencies = [
"futures-channel",
"futures-core",
"futures-io",
"futures-macro",
"futures-sink",
"futures-task",
"memchr",
"pin-project",
"pin-utils",
"proc-macro-hack",
"proc-macro-nested",
"slab",
]

@@ -377,6 +444,19 @@ dependencies = [
"want",
]

[[package]]
name = "hyper-tls"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d979acc56dcb5b8dddba3917601745e877576475aa046df3226eabdecef78eed"
dependencies = [
"bytes",
"hyper",
"native-tls",
"tokio",
"tokio-tls",
]

[[package]]
name = "idna"
version = "0.2.0"
@@ -589,6 +669,24 @@ dependencies = [
"winapi 0.3.9",
]

[[package]]
name = "native-tls"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b0d88c06fe90d5ee94048ba40409ef1d9315d86f6f38c2efdaad4fb50c58b2d"
dependencies = [
"lazy_static",
"libc",
"log 0.4.11",
"openssl",
"openssl-probe",
"openssl-sys",
"schannel",
"security-framework",
"security-framework-sys",
"tempfile",
]

[[package]]
name = "net2"
version = "0.2.34"
@@ -622,6 +720,39 @@ version = "1.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "260e51e7efe62b592207e9e13a68e43692a7a279171d6ba57abd208bf23645ad"

[[package]]
name = "openssl"
version = "0.10.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8d575eff3665419f9b83678ff2815858ad9d11567e082f5ac1814baba4e2bcb4"
dependencies = [
"bitflags 1.2.1",
"cfg-if",
"foreign-types",
"lazy_static",
"libc",
"openssl-sys",
]

[[package]]
name = "openssl-probe"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de"

[[package]]
name = "openssl-sys"
version = "0.9.58"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a842db4709b604f0fe5d1170ae3565899be2ad3d9cbc72dedc789ac0511f78de"
dependencies = [
"autocfg",
"cc",
"libc",
"pkg-config",
"vcpkg",
]

[[package]]
name = "os_info"
version = "2.0.8"
@@ -670,6 +801,12 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"

[[package]]
name = "pkg-config"
version = "0.3.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d36492546b6af1463394d46f0c834346f31548646f6ba10849802c9c9a27ac33"

[[package]]
name = "pnet"
version = "0.26.0"
@@ -765,6 +902,18 @@ version = "0.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c36fa947111f5c62a733b652544dd0016a43ce89619538a8ef92724a6f501a20"

[[package]]
name = "proc-macro-hack"
version = "0.5.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "99c605b9a0adc77b7211c6b1f722dcb613d68d66859a44f3d485a6da332b0598"

[[package]]
name = "proc-macro-nested"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eba180dafb9038b050a4c280019bbedf9f2467b61e5d892dcad585bb57aadc5a"

[[package]]
name = "proc-macro2"
version = "1.0.19"
@@ -854,6 +1003,15 @@ version = "0.6.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26412eb97c6b088a6997e05f69403a802a92d520de2f8e63c2b65f9e0f47c4e8"

[[package]]
name = "remove_dir_all"
version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7"
dependencies = [
"winapi 0.3.9",
]

[[package]]
name = "resolv-conf"
version = "0.6.3"
@@ -876,6 +1034,39 @@ version = "0.3.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda"

[[package]]
name = "schannel"
version = "0.1.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f05ba609c234e60bee0d547fe94a4c7e9da733d1c962cf6e59efa4cd9c8bc75"
dependencies = [
"lazy_static",
"winapi 0.3.9",
]

[[package]]
name = "security-framework"
version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "64808902d7d99f78eaddd2b4e2509713babc3dc3c85ad6f4c447680f3c01e535"
dependencies = [
"bitflags 1.2.1",
"core-foundation",
"core-foundation-sys",
"libc",
"security-framework-sys",
]

[[package]]
name = "security-framework-sys"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "17bf11d99252f512695eb468de5516e5cf75455521e69dfe343f3b74e4748405"
dependencies = [
"core-foundation-sys",
"libc",
]

[[package]]
name = "serde"
version = "1.0.115"
@@ -982,6 +1173,20 @@ dependencies = [
"unicode-xid 0.0.3",
]

[[package]]
name = "tempfile"
version = "3.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9"
dependencies = [
"cfg-if",
"libc",
"rand",
"redox_syscall",
"remove_dir_all",
"winapi 0.3.9",
]

[[package]]
name = "term"
version = "0.4.6"
@@ -1082,6 +1287,16 @@ dependencies = [
"syn",
]

[[package]]
name = "tokio-tls"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a70f4fcd7b3b24fb194f837560168208f669ca8cb70d0c4b862944452396343"
dependencies = [
"native-tls",
"tokio",
]

[[package]]
name = "tokio-util"
version = "0.3.1"
@@ -1096,12 +1311,138 @@ dependencies = [
"tokio",
]

[[package]]
name = "tower"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd3169017c090b7a28fce80abaad0ab4f5566423677c9331bb320af7e49cfe62"
dependencies = [
"futures-core",
"tower-buffer",
"tower-discover",
"tower-layer",
"tower-limit",
"tower-load-shed",
"tower-retry",
"tower-service",
"tower-timeout",
"tower-util",
]

[[package]]
name = "tower-buffer"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4887dc2a65d464c8b9b66e0e4d51c2fd6cf5b3373afc72805b0a60bce00446a"
dependencies = [
"futures-core",
"pin-project",
"tokio",
"tower-layer",
"tower-service",
"tracing",
]

[[package]]
name = "tower-discover"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0f6b5000c3c54d269cc695dff28136bb33d08cbf1df2c48129e143ab65bf3c2a"
dependencies = [
"futures-core",
"pin-project",
"tower-service",
]

[[package]]
name = "tower-layer"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a35d656f2638b288b33495d1053ea74c40dc05ec0b92084dd71ca5566c4ed1dc"

[[package]]
name = "tower-limit"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "92c3040c5dbed68abffaa0d4517ac1a454cd741044f33ab0eefab6b8d1361404"
dependencies = [
"futures-core",
"pin-project",
"tokio",
"tower-layer",
"tower-load",
"tower-service",
]

[[package]]
name = "tower-load"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8cc79fc3afd07492b7966d7efa7c6c50f8ed58d768a6075dd7ae6591c5d2017b"
dependencies = [
"futures-core",
"log 0.4.11",
"pin-project",
"tokio",
"tower-discover",
"tower-service",
]

[[package]]
name = "tower-load-shed"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9f021e23900173dc315feb4b6922510dae3e79c689b74c089112066c11f0ae4e"
dependencies = [
"futures-core",
"pin-project",
"tower-layer",
"tower-service",
]

[[package]]
name = "tower-retry"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6727956aaa2f8957d4d9232b308fe8e4e65d99db30f42b225646e86c9b6a952"
dependencies = [
"futures-core",
"pin-project",
"tokio",
"tower-layer",
"tower-service",
]

[[package]]
name = "tower-service"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e987b6bf443f4b5b3b6f38704195592cca41c5bb7aedd3c3693c7081f8289860"

[[package]]
name = "tower-timeout"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "127b8924b357be938823eaaec0608c482d40add25609481027b96198b2e4b31e"
dependencies = [
"pin-project",
"tokio",
"tower-layer",
"tower-service",
]

[[package]]
name = "tower-util"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d1093c19826d33807c72511e68f73b4a0469a3f22c2bd5f7d5212178b4b89674"
dependencies = [
"futures-core",
"futures-util",
"pin-project",
"tower-service",
]

[[package]]
name = "tracing"
version = "0.1.19"
@@ -1110,9 +1451,21 @@ checksum = "6d79ca061b032d6ce30c660fded31189ca0b9922bf483cd70759f13a2d86786c"
dependencies = [
"cfg-if",
"log 0.4.11",
"tracing-attributes",
"tracing-core",
]

[[package]]
name = "tracing-attributes"
version = "0.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "80e0ccfc3378da0cce270c946b676a376943f5cd16aeba64568e7939806f4ada"
dependencies = [
"proc-macro2",
"quote",
"syn",
]

[[package]]
name = "tracing-core"
version = "0.1.15"
@@ -1221,6 +1574,12 @@ dependencies = [
"percent-encoding",
]

[[package]]
name = "vcpkg"
version = "0.2.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6454029bf181f092ad1b853286f23e2c507d8e8194d01d92da4a55c274a5508c"

[[package]]
name = "vec_map"
version = "0.8.2"


+ 4
- 1
Cargo.toml View File

@@ -9,15 +9,18 @@ edition = "2018"

[dependencies]
clap = "2.33.0"
futures = "0.3.5"
futures-core = { version = "0.3", default-features = false }
futures-channel = "0.3"
futures-util = { version = "0.3", default-features = false }
http = "0.2.1"
hyper = "0.13.7"
hyper = { version = "0.13.7", features = ["stream"] }
hyper-tls = "0.4.3"
lru = "0.6.0"
os_info = { version = "2.0.8", default-features = false }
pnet = "0.26.0"
tokio = { version = "0.2.22", features = ["full"] }
tower = "0.3.1"
trust-dns-resolver = "0.19.5"

[profile.release]


+ 105
- 2
src/lib.rs View File

@@ -1,17 +1,29 @@
use std::net::SocketAddr;
use std::future::Future;
use std::net::{SocketAddr, IpAddr};
use std::process::{Command, Stdio};
use std::sync::Arc;
use std::io::Error;
use std::pin::Pin;
use std::task::{self, Poll};

use hyper::{Body, Response};
use hyper::client::connect::dns::Name;

use lru::LruCache;

use os_info::{Info, Type};

use tower::Service;

use tokio::runtime::Runtime;
use tokio::sync::Mutex;
use tokio::task::{JoinHandle, LocalSet};

use trust_dns_resolver::TokioAsyncResolver;
use trust_dns_resolver::config::{NameServerConfig, Protocol, ResolverConfig, ResolverOpts};
use futures_util::task::FutureObj;
use futures_util::TryFutureExt;
use futures::stream::{Unfold, Once};

pub async fn create_resolver (dns1_sock : SocketAddr, dns2_sock : SocketAddr) -> TokioAsyncResolver {
let mut resolver_config : ResolverConfig = ResolverConfig::new();
@@ -104,6 +116,7 @@ pub async fn resolve_with_cache(host : &str,
}
}


pub fn needs_static_route(ip_string : &String) -> bool {
println!("needs_static_route: checking ip={:?}", ip_string);
let info : Info = os_info::get();
@@ -176,4 +189,94 @@ pub fn bad_request (message : &str) -> Result<Response<Body>, hyper::Error> {
let mut resp = Response::new(Body::from(String::from(message)));
*resp.status_mut() = http::StatusCode::BAD_REQUEST;
return Ok(resp);
}
}

#[derive(Clone)]
pub struct CacheResolver {
_resolver: Arc<TokioAsyncResolver>,
_cache : Arc<Mutex<LruCache<String, String>>>
}

impl CacheResolver {
pub fn new(resolver : Arc<TokioAsyncResolver>, cache : Arc<Mutex<LruCache<String, String>>>) -> Self {
CacheResolver { _resolver: resolver, _cache: cache }
}
}

pub struct IpAddrs {
ip: IpAddr,
addr: SocketAddr,
iter: std::vec::IntoIter<SocketAddr>,
}

pub struct CacheAddrs {
inner: IpAddrs,
}

pub struct CacheFuture {
inner: JoinHandle<Result<IpAddrs, std::io::Error>>
}

pub async fn resolve_to_result(host : String,
resolver : Arc<TokioAsyncResolver>,
cache: Arc<Mutex<LruCache<String, String>>>) -> Result<IpAddrs, Error>{
let ip = resolve_with_cache(host.as_str(), &resolver, cache).await;
let ip_addr: IpAddr = ip.parse().unwrap();
let sock = SocketAddr::new(ip_addr, 0);
Ok(IpAddrs { ip: ip_addr, addr: sock, iter: vec![sock].into_iter() })
}

impl Service<Name> for CacheResolver {
type Response = CacheAddrs;
type Error = std::io::Error;
type Future = CacheFuture;

fn poll_ready(&mut self, _cx: &mut task::Context<'_>) -> Poll<Result<(), std::io::Error>> {
Poll::Ready(Ok(()))
}

fn call(&mut self, name: Name) -> CacheFuture {
println!("+++++++ resolving host={:?}", name.as_str());
let resolver : Arc<TokioAsyncResolver> = self._resolver.clone();
let cache: Arc<Mutex<LruCache<String, String>>> = self._cache.clone();
let addrs = tokio::task::spawn(
resolve_to_result(String::from(name.as_str()), resolver, cache)
// resolve_with_cache(host.as_str(), &resolver, cache)
);
CacheFuture { inner: addrs }
}
}

impl Future for CacheFuture {
type Output = Result<CacheAddrs, std::io::Error>;

fn poll(mut self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> Poll<Self::Output> {
Pin::new(&mut self.inner).poll(cx).map(|res| match res {
Ok(Ok(addrs)) => Ok(CacheAddrs { inner: addrs }),
Ok(Err(err)) => Err(err),
Err(join_err) => {
if join_err.is_cancelled() {
Err(std::io::Error::new(std::io::ErrorKind::Interrupted, join_err))
} else {
panic!("gai background task failed: {:?}", join_err)
}
}
})
}
}

impl Iterator for IpAddrs {
type Item = SocketAddr;
#[inline]
fn next(&mut self) -> Option<SocketAddr> {
self.iter.next()
}
}

impl Iterator for CacheAddrs {
type Item = IpAddr;

fn next(&mut self) -> Option<Self::Item> {
self.inner.next().map(|sa| sa.ip())
}
}

+ 35
- 18
src/main.rs View File

@@ -1,10 +1,11 @@
#![deny(warnings)]
//#![deny(warnings)]

extern crate lru;

use std::convert::Infallible;
use std::net::SocketAddr;
use std::net::{IpAddr, SocketAddr};
use std::sync::Arc;
use std::iter;

use clap::{Arg, ArgMatches, App};

@@ -13,6 +14,9 @@ use futures_util::future::try_join;
use hyper::service::{make_service_fn, service_fn};
use hyper::upgrade::Upgraded;
use hyper::{Body, Client, Method, Request, Response, Server};
use hyper::client::Builder;
use hyper::client::HttpConnector;
use hyper_tls::HttpsConnector;

use lru::LruCache;

@@ -34,9 +38,6 @@ type HttpClient = Client<hyper::client::HttpConnector>;
// $ curl -i https://www.some_domain.com/
#[tokio::main]
async fn main() {
let client = HttpClient::new();
let gateway = Arc::new(ip_gateway());

let args : ArgMatches = App::new("bubble-flexrouter")
.version("0.1.0")
.author("Jonathan Cobb <jonathan@getbubblenow.com>")
@@ -57,13 +58,30 @@ async fn main() {
.takes_value(true))
.get_matches();

let dns1_sock : SocketAddr = format!("{}:53", args.value_of("dns1").unwrap()).parse().unwrap();
let dns2_sock : SocketAddr = format!("{}:53", args.value_of("dns2").unwrap()).parse().unwrap();
let resolver = Arc::new(create_resolver(dns1_sock, dns2_sock).await);
let addr = SocketAddr::from(([127, 0, 0, 1], 8100));
let dns1_ip = args.value_of("dns1").unwrap();
let dns1_sock : SocketAddr = format!("{}:53", dns1_ip).parse().unwrap();
let dns2_ip = args.value_of("dns2").unwrap();
let dns2_sock : SocketAddr = format!("{}:53", dns2_ip).parse().unwrap();

let async_resolver = create_resolver(dns1_sock, dns2_sock).await;
// let res_ref : &'static TokioAsyncResolver = &async_resolver;
// let async_resolver = create_resolver(dns1_sock, dns2_sock).await;
// let res_ref : &'static TokioAsyncResolver = &async_resolver;

// let resolver = Arc::new(res_ref);
let resolver = Arc::new(async_resolver);
let addr = SocketAddr::from(([127, 0, 0, 1], 8100));
let resolver_cache = Arc::new(Mutex::new(LruCache::new(1000)));

let http_resolver = CacheResolver::new(resolver.clone(), resolver_cache.clone());
let connector = HttpConnector::new_with_resolver(http_resolver);
let https = HttpsConnector::new_with_connector(connector);
let client
= Client::builder().build::<hyper_tls::HttpsConnector<HttpConnector<CacheResolver>>, hyper::Body>(https);
//let client = HttpClient::new();
let gateway = Arc::new(ip_gateway());


let make_service = make_service_fn(move |_| {
let client = client.clone();
let gateway = gateway.clone();
@@ -90,7 +108,7 @@ async fn main() {
}
}

async fn proxy(client: HttpClient,
async fn proxy(client: Client<HttpsConnector<HttpConnector<CacheResolver>>>,
gateway: Arc<String>,
resolver: Arc<TokioAsyncResolver>,
resolver_cache: Arc<Mutex<LruCache<String, String>>>,
@@ -123,10 +141,11 @@ async fn proxy(client: HttpClient,
// Note: only after client received an empty body with STATUS_OK can the
// connection be upgraded, so we can't return a response inside
// `on_upgrade` future.
if let Some(addr) = host_addr(req.uri()) {
if let Some(addr) = host_addr(req.uri(), &ip_string) {
tokio::task::spawn(async move {
match req.into_body().on_upgrade().await {
Ok(upgraded) => {
println!(">>>> CONNECT: tunnelling to addr={:?}", addr);
if let Err(e) = tunnel(upgraded, addr).await {
eprintln!("server io error: {}", e);
};
@@ -137,19 +156,17 @@ async fn proxy(client: HttpClient,

Ok(Response::new(Body::empty()))
} else {
eprintln!("CONNECT host is not socket addr: {:?}", req.uri());
let mut resp = Response::new(Body::from("CONNECT must be to a socket address"));
*resp.status_mut() = http::StatusCode::BAD_REQUEST;

Ok(resp)
eprintln!(">>> CONNECT host is not socket addr: {:?}", req.uri());
return bad_request("CONNECT must be to a socket address");
}
} else {
// ensure client resolves hostname to the same IP we resolved
client.request(req).await
}
}

fn host_addr(uri: &http::Uri) -> Option<SocketAddr> {
uri.authority().and_then(|auth| auth.as_str().parse().ok())
fn host_addr(uri: &http::Uri, ip: &String) -> Option<SocketAddr> {
Some(SocketAddr::new(ip.parse().unwrap(), u16::from(uri.port().unwrap())))
}

// Create a TCP connection to host:port, build a tunnel between the connection and


Loading…
Cancel
Save