local: the non-blocking resolver — tokio lookup_host replaces the blocking to_socket_addrs
- resolve_target + local_tcp_dial resolve via tokio::net::lookup_host (the blocking std resolver parked the pump on resolver latency — the review 003 S-1-adjacent residue); the module doc's blocking caveat retired - semantics unchanged: the dial keeps its try-all-addresses loop, the egress keeps first-address (upstream parity) Verification: cargo test --features local (15 suites green), clippy --all-targets --all-features -D warnings clean, fmt clean.
This commit is contained in:
1 parent
4d9796be64
commit
086aeb4135
1 file changed
+18
-17
+18
-17
@@ -30,7 +30,8 @@
|
|||||||
//! the client-gone teardown.
|
//! the client-gone teardown.
|
||||||
//!
|
//!
|
||||||
//! Resolution is the provider's job (ADR-012): domain targets/destinations
|
//! Resolution is the provider's job (ADR-012): domain targets/destinations
|
||||||
//! resolve here, at the seam — the ssh `-D` semantic.
|
//! resolve here, at the seam — the ssh `-D` semantic, via the
|
||||||
|
//! non-blocking [`tokio::net::lookup_host`] resolver.
|
||||||
|
|
||||||
use std::io::ErrorKind;
|
use std::io::ErrorKind;
|
||||||
use std::net::SocketAddr;
|
use std::net::SocketAddr;
|
||||||
@@ -49,19 +50,22 @@ use crate::{
|
|||||||
|
|
||||||
/// Resolve a [`TargetAddr`] to a `SocketAddr` (egress-side DNS; the
|
/// Resolve a [`TargetAddr`] to a `SocketAddr` (egress-side DNS; the
|
||||||
/// ssh `-D` semantic — ADR-012: resolution is the provider's job). IP
|
/// ssh `-D` semantic — ADR-012: resolution is the provider's job). IP
|
||||||
/// targets resolve directly; domain targets resolve via the blocking
|
/// targets resolve directly; domain targets resolve via
|
||||||
/// resolver (`std::net::ToSocketAddrs` — the POC #2 `LocalEgress`
|
/// [`tokio::net::lookup_host`] (the non-blocking resolver — review 003
|
||||||
/// shape; the first address wins).
|
/// S-1's blocking-`to_socket_addrs` residue retired; the first address
|
||||||
pub(crate) fn resolve_target(addr: &TargetAddr) -> Result<SocketAddr, EgressError> {
|
/// wins, upstream parity).
|
||||||
|
pub(crate) async fn resolve_target(addr: &TargetAddr) -> Result<SocketAddr, EgressError> {
|
||||||
match addr {
|
match addr {
|
||||||
TargetAddr::Ip(sa) => Ok(*sa),
|
TargetAddr::Ip(sa) => Ok(*sa),
|
||||||
TargetAddr::Domain(domain, port) => {
|
TargetAddr::Domain(domain, port) => {
|
||||||
use std::net::ToSocketAddrs;
|
let addrs = tokio::net::lookup_host((domain.as_str(), *port))
|
||||||
(domain.as_str(), *port)
|
.await
|
||||||
.to_socket_addrs()
|
|
||||||
.map_err(|e| EgressError::Unreachable(format!("resolve {domain}: {e}")))?
|
.map_err(|e| EgressError::Unreachable(format!("resolve {domain}: {e}")))?
|
||||||
.next()
|
.next()
|
||||||
.ok_or_else(|| EgressError::Unreachable(format!("resolve {domain}: no addresses")))
|
.ok_or_else(|| {
|
||||||
|
EgressError::Unreachable(format!("resolve {domain}: no addresses"))
|
||||||
|
})?;
|
||||||
|
Ok(addrs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -96,13 +100,10 @@ pub fn tcp_dial() -> DialFn {
|
|||||||
async fn local_tcp_dial(target: TargetAddr) -> Result<TargetHandle, SocksDialError> {
|
async fn local_tcp_dial(target: TargetAddr) -> Result<TargetHandle, SocksDialError> {
|
||||||
let addrs: Vec<SocketAddr> = match &target {
|
let addrs: Vec<SocketAddr> = match &target {
|
||||||
TargetAddr::Ip(sa) => vec![*sa],
|
TargetAddr::Ip(sa) => vec![*sa],
|
||||||
TargetAddr::Domain(domain, port) => {
|
TargetAddr::Domain(domain, port) => tokio::net::lookup_host((domain.as_str(), *port))
|
||||||
use std::net::ToSocketAddrs;
|
.await
|
||||||
(domain.as_str(), *port)
|
.map_err(|e| SocksDialError::HostUnreachable(format!("resolve {domain}: {e}")))?
|
||||||
.to_socket_addrs()
|
.collect(),
|
||||||
.map_err(|e| SocksDialError::HostUnreachable(format!("resolve {domain}: {e}")))?
|
|
||||||
.collect()
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
if addrs.is_empty() {
|
if addrs.is_empty() {
|
||||||
return Err(SocksDialError::HostUnreachable(format!(
|
return Err(SocksDialError::HostUnreachable(format!(
|
||||||
@@ -176,7 +177,7 @@ impl Egress for LocalEgress {
|
|||||||
fn send(&mut self, addr: TargetAddr, payload: Bytes) -> BoxFuture<'_, Result<(), EgressError>> {
|
fn send(&mut self, addr: TargetAddr, payload: Bytes) -> BoxFuture<'_, Result<(), EgressError>> {
|
||||||
let sock = Arc::clone(&self.sock);
|
let sock = Arc::clone(&self.sock);
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
let dest = resolve_target(&addr)?;
|
let dest = resolve_target(&addr).await?;
|
||||||
sock.send_to(&payload, dest)
|
sock.send_to(&payload, dest)
|
||||||
.await
|
.await
|
||||||
.map(|_| ())
|
.map(|_| ())
|
||||||
|
|||||||
Reference in new issue
Block a user