diff --git a/lightning-net-tokio/Cargo.toml b/lightning-net-tokio/Cargo.toml index a911b3d22be..1d385857285 100644 --- a/lightning-net-tokio/Cargo.toml +++ b/lightning-net-tokio/Cargo.toml @@ -15,10 +15,14 @@ edition = "2021" all-features = true rustdoc-args = ["--cfg", "docsrs"] +[features] +socks = ["tokio-socks"] + [dependencies] bitcoin = "0.32.2" lightning = { version = "0.2.0", path = "../lightning" } tokio = { version = "1.35", features = [ "rt", "sync", "net", "time" ] } +tokio-socks = { version = "0.5", optional = true } [dev-dependencies] tokio = { version = "1.35", features = [ "macros", "rt", "rt-multi-thread", "sync", "net", "time" ] } diff --git a/lightning-net-tokio/src/lib.rs b/lightning-net-tokio/src/lib.rs index 068f77a84bb..dffa1d3ce28 100644 --- a/lightning-net-tokio/src/lib.rs +++ b/lightning-net-tokio/src/lib.rs @@ -470,6 +470,33 @@ where } } +/// Like [`connect_outbound`], but routes the TCP connection through a SOCKS5 proxy. +/// +/// `proxy_addr` is the address of the SOCKS5 proxy (e.g. `127.0.0.1:1080`). +/// The proxy connects to `addr` on our behalf, then we hand the resulting stream to +/// [`setup_outbound`]. +/// +/// Available only when the `socks` feature is enabled. +#[cfg(feature = "socks")] +#[cfg_attr(docsrs, doc(cfg(feature = "socks")))] +pub async fn connect_outbound_via_socks5( + peer_manager: PM, their_node_id: PublicKey, addr: SocketAddr, proxy_addr: SocketAddr, +) -> Option> +where + PM::Target: APeerManager, +{ + let connect_fut = async { + tokio_socks::tcp::Socks5Stream::connect(proxy_addr, addr) + .await + .map(|s| s.into_inner().into_std().unwrap()) + }; + if let Ok(Ok(stream)) = time::timeout(Duration::from_secs(10), connect_fut).await { + Some(setup_outbound(peer_manager, their_node_id, stream)) + } else { + None + } +} + const SOCK_WAKER_VTABLE: task::RawWakerVTable = task::RawWakerVTable::new( clone_socket_waker, wake_socket_waker,