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.
|
||||
//!
|
||||
//! 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::net::SocketAddr;
|
||||
@@ -49,19 +50,22 @@ use crate::{
|
||||
|
||||
/// Resolve a [`TargetAddr`] to a `SocketAddr` (egress-side DNS; the
|
||||
/// ssh `-D` semantic — ADR-012: resolution is the provider's job). IP
|
||||
/// targets resolve directly; domain targets resolve via the blocking
|
||||
/// resolver (`std::net::ToSocketAddrs` — the POC #2 `LocalEgress`
|
||||
/// shape; the first address wins).
|
||||
pub(crate) fn resolve_target(addr: &TargetAddr) -> Result<SocketAddr, EgressError> {
|
||||
/// targets resolve directly; domain targets resolve via
|
||||
/// [`tokio::net::lookup_host`] (the non-blocking resolver — review 003
|
||||
/// S-1's blocking-`to_socket_addrs` residue retired; the first address
|
||||
/// wins, upstream parity).
|
||||
pub(crate) async fn resolve_target(addr: &TargetAddr) -> Result<SocketAddr, EgressError> {
|
||||
match addr {
|
||||
TargetAddr::Ip(sa) => Ok(*sa),
|
||||
TargetAddr::Domain(domain, port) => {
|
||||
use std::net::ToSocketAddrs;
|
||||
(domain.as_str(), *port)
|
||||
.to_socket_addrs()
|
||||
let addrs = tokio::net::lookup_host((domain.as_str(), *port))
|
||||
.await
|
||||
.map_err(|e| EgressError::Unreachable(format!("resolve {domain}: {e}")))?
|
||||
.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> {
|
||||
let addrs: Vec<SocketAddr> = match &target {
|
||||
TargetAddr::Ip(sa) => vec![*sa],
|
||||
TargetAddr::Domain(domain, port) => {
|
||||
use std::net::ToSocketAddrs;
|
||||
(domain.as_str(), *port)
|
||||
.to_socket_addrs()
|
||||
.map_err(|e| SocksDialError::HostUnreachable(format!("resolve {domain}: {e}")))?
|
||||
.collect()
|
||||
}
|
||||
TargetAddr::Domain(domain, port) => tokio::net::lookup_host((domain.as_str(), *port))
|
||||
.await
|
||||
.map_err(|e| SocksDialError::HostUnreachable(format!("resolve {domain}: {e}")))?
|
||||
.collect(),
|
||||
};
|
||||
if addrs.is_empty() {
|
||||
return Err(SocksDialError::HostUnreachable(format!(
|
||||
@@ -176,7 +177,7 @@ impl Egress for LocalEgress {
|
||||
fn send(&mut self, addr: TargetAddr, payload: Bytes) -> BoxFuture<'_, Result<(), EgressError>> {
|
||||
let sock = Arc::clone(&self.sock);
|
||||
Box::pin(async move {
|
||||
let dest = resolve_target(&addr)?;
|
||||
let dest = resolve_target(&addr).await?;
|
||||
sock.send_to(&payload, dest)
|
||||
.await
|
||||
.map(|_| ())
|
||||
|
||||
Reference in new issue
Block a user