diff --git a/moli-curl/examples/websocket_owner_probe/http.rs b/moli-curl/examples/websocket_owner_probe/http.rs index 68d06d289..6e3ee782c 100644 --- a/moli-curl/examples/websocket_owner_probe/http.rs +++ b/moli-curl/examples/websocket_owner_probe/http.rs @@ -109,7 +109,7 @@ fn request( context: (), origin: None, deadline: Some(Instant::now() + Duration::from_secs(10)), - dns_resolution: CurlDnsResolution::curl_managed(), + dns_resolution: CurlDnsResolution::no_shared_resolution(), priority: 1, label: "owner probe HTTP".into(), }) diff --git a/moli-curl/src/dns_adapter.rs b/moli-curl/src/dns_adapter.rs index e41341ffc..a24822189 100644 --- a/moli-curl/src/dns_adapter.rs +++ b/moli-curl/src/dns_adapter.rs @@ -12,10 +12,12 @@ use crate::NetworkAddressPolicy; /// Curl-side policy for DNS ownership before a transfer enters the multi set. /// -/// `origin == None` means curl owns name resolution. `Some` means the transfer +/// `origin == None` means no shared origin lookup is required. The configured +/// curl handle may already have a fixed address, use an IP literal or proxy, or +/// deliberately retain libcurl's resolver behavior. `Some` means the transfer /// must first wait in [`CurlDnsOwnerResidence`]. After that residence installs -/// the exact address list with `CURLOPT_RESOLVE`, this object transitions back -/// to curl-managed so a requeued transfer cannot resolve twice. +/// the exact address list with `CURLOPT_RESOLVE`, the shared lookup is consumed +/// so a requeued transfer cannot resolve twice. #[derive(Debug)] pub struct CurlDnsResolution { origin: Option>, @@ -32,10 +34,22 @@ struct CurlDnsOriginResolution { } impl CurlDnsResolution { - pub fn curl_managed() -> Self { + /// Creates a policy that does not request Moli's shared origin resolver. + /// + /// This keeps `moli-curl` transport-neutral: callers may use an IP literal, + /// preconfigure `CURLOPT_RESOLVE`, delegate the target to a proxy, or retain + /// libcurl's resolver behavior. + pub fn no_shared_resolution() -> Self { Self { origin: None } } + #[deprecated( + note = "use `no_shared_resolution`; no shared lookup does not necessarily mean curl performs DNS" + )] + pub fn curl_managed() -> Self { + Self::no_shared_resolution() + } + pub fn resolve_origin(target: DnsTarget, static_entries: Vec) -> Self { let policy_target = format!("{}:{}", target.host(), target.port()); Self { @@ -279,7 +293,7 @@ mod tests { } #[test] - fn installed_origin_transitions_back_to_curl_managed() { + fn installed_origin_consumes_shared_resolution() { let target = DnsTarget::new("example.test", 443); let mut policy = CurlDnsResolution::resolve_origin(target.clone(), Vec::new()); let mut easy = Easy2::new(TestHandler); diff --git a/moli-curl/src/http.rs b/moli-curl/src/http.rs index 10d14a7be..f7b868349 100644 --- a/moli-curl/src/http.rs +++ b/moli-curl/src/http.rs @@ -45,9 +45,10 @@ pub struct CurlMultiJob { pub deadline: Option, /// DNS ownership chosen by the caller before this transfer enters curl. /// - /// A curl-managed policy preserves libcurl's resolver behavior. A shared - /// origin policy parks the transfer outside the curl multi handle set until - /// the bounded system resolver publishes an answer. + /// A no-shared-resolution policy leaves the already configured curl handle + /// in charge of routing; it may need no DNS lookup at all. A shared-origin + /// policy parks the transfer outside the curl multi handle set until the + /// bounded system resolver publishes an answer. pub dns_resolution: CurlDnsResolution, /// Higher values start before lower values when jobs are queued. pub priority: u8, diff --git a/moli-curl/src/http/registry.rs b/moli-curl/src/http/registry.rs index ac7510fdb..356d5a5e8 100644 --- a/moli-curl/src/http/registry.rs +++ b/moli-curl/src/http/registry.rs @@ -531,7 +531,7 @@ mod tests { context: label.to_owned(), origin, deadline: None, - dns_resolution: CurlDnsResolution::curl_managed(), + dns_resolution: CurlDnsResolution::no_shared_resolution(), priority, label: label.to_owned(), } diff --git a/moli-curl/src/http/scheduling.rs b/moli-curl/src/http/scheduling.rs index c9e0e93a4..7f18e31e7 100644 --- a/moli-curl/src/http/scheduling.rs +++ b/moli-curl/src/http/scheduling.rs @@ -153,7 +153,7 @@ mod tests { context: label.to_owned(), origin, deadline: None, - dns_resolution: CurlDnsResolution::curl_managed(), + dns_resolution: CurlDnsResolution::no_shared_resolution(), priority, label: label.to_owned(), } diff --git a/moli-curl/src/runtime/owner/tests.rs b/moli-curl/src/runtime/owner/tests.rs index 658c77ef3..5bbc16147 100644 --- a/moli-curl/src/runtime/owner/tests.rs +++ b/moli-curl/src/runtime/owner/tests.rs @@ -40,7 +40,7 @@ fn request( port: Some(address.port()), }), deadline, - dns_resolution: CurlDnsResolution::curl_managed(), + dns_resolution: CurlDnsResolution::no_shared_resolution(), priority: 1, label: path.to_owned(), } diff --git a/moli-curl/src/runtime/tests.rs b/moli-curl/src/runtime/tests.rs index c096c2f4e..3152f3eed 100644 --- a/moli-curl/src/runtime/tests.rs +++ b/moli-curl/src/runtime/tests.rs @@ -51,7 +51,7 @@ fn submitted_identity_reaches_the_matching_runtime_completion() { context: "matching-context".to_owned(), origin: None, deadline: None, - dns_resolution: CurlDnsResolution::curl_managed(), + dns_resolution: CurlDnsResolution::no_shared_resolution(), priority: 1, label: "identity-test".to_owned(), }) @@ -87,7 +87,7 @@ fn http_sender_does_not_keep_owner_alive_and_returns_rejected_job() { context: vec![7; 1024], origin: None, deadline: None, - dns_resolution: CurlDnsResolution::curl_managed(), + dns_resolution: CurlDnsResolution::no_shared_resolution(), priority: 1, label: "closed".into(), }) diff --git a/moli-curl/src/websocket.rs b/moli-curl/src/websocket.rs index 1a4daba2d..37fe5d56e 100644 --- a/moli-curl/src/websocket.rs +++ b/moli-curl/src/websocket.rs @@ -58,7 +58,7 @@ impl CurlWebSocketRequest { proxy: None, proxy_headers: Vec::new(), tls: CurlTlsConfig::default(), - dns_resolution: CurlDnsResolution::curl_managed(), + dns_resolution: CurlDnsResolution::no_shared_resolution(), handshake_timeout: Duration::from_secs(30), } } diff --git a/moli-curl/src/websocket/tests/shared.rs b/moli-curl/src/websocket/tests/shared.rs index 043fa5d92..93d4985c0 100644 --- a/moli-curl/src/websocket/tests/shared.rs +++ b/moli-curl/src/websocket/tests/shared.rs @@ -56,7 +56,7 @@ fn request(url: &str, handler: HttpCapture, timeout: Duration) -> CurlMultiJob Result { match curl_dns_admission(config, url, proxy_route)? { - FetchCurlDnsAdmission::CurlManaged => Ok(CurlDnsResolution::curl_managed()), + FetchCurlDnsAdmission::NoSharedResolution => Ok(CurlDnsResolution::no_shared_resolution()), FetchCurlDnsAdmission::SharedResolver(target) => { let policy = config.network_address_policy(); Ok(CurlDnsResolution::resolve_origin( @@ -50,13 +50,13 @@ fn curl_dns_admission( proxy_route: &HttpProxyRoute, ) -> Result { if !matches!(url.scheme(), "http" | "https") { - return Ok(FetchCurlDnsAdmission::CurlManaged); + return Ok(FetchCurlDnsAdmission::NoSharedResolution); } let Some(Host::Domain(host)) = url.host() else { - return Ok(FetchCurlDnsAdmission::CurlManaged); + return Ok(FetchCurlDnsAdmission::NoSharedResolution); }; let Some(port) = url.port_or_known_default() else { - return Ok(FetchCurlDnsAdmission::CurlManaged); + return Ok(FetchCurlDnsAdmission::NoSharedResolution); }; if proxy_route.is_proxy() { if config.network_address_policy().is_enforced() { @@ -64,10 +64,10 @@ fn curl_dns_admission( "cannot enforce network address policy for proxied hostname `{host}` in `{url}`; the proxy must not resolve an unchecked target hostname" ); } - return Ok(FetchCurlDnsAdmission::CurlManaged); + return Ok(FetchCurlDnsAdmission::NoSharedResolution); } if resolve_host_resolve_override_ips(config.http_host_resolve(), host, port)?.is_some() { - return Ok(FetchCurlDnsAdmission::CurlManaged); + return Ok(FetchCurlDnsAdmission::NoSharedResolution); } Ok(FetchCurlDnsAdmission::SharedResolver(DnsTarget::new( host, port, @@ -121,21 +121,21 @@ mod tests { } #[test] - fn ip_literals_and_matching_host_resolve_entries_stay_curl_managed() { + fn ip_literals_and_matching_host_resolve_entries_need_no_shared_resolution() { let mut config = FetchConfig::default(); assert_eq!( admission(&config, "http://127.0.0.1/path", &HttpProxyRoute::Direct,), - FetchCurlDnsAdmission::CurlManaged + FetchCurlDnsAdmission::NoSharedResolution ); assert_eq!( admission(&config, "http://[::1]/path", &HttpProxyRoute::Direct,), - FetchCurlDnsAdmission::CurlManaged + FetchCurlDnsAdmission::NoSharedResolution ); config.set_http_host_resolve(vec!["example.test:80:127.0.0.1".to_owned()]); assert_eq!( admission(&config, "http://example.test/path", &HttpProxyRoute::Direct,), - FetchCurlDnsAdmission::CurlManaged + FetchCurlDnsAdmission::NoSharedResolution ); assert_eq!( admission(&config, "http://other.test/path", &HttpProxyRoute::Direct,), @@ -145,7 +145,7 @@ mod tests { } #[test] - fn selected_proxy_route_uses_curl_resolution() { + fn selected_proxy_route_needs_no_shared_origin_resolution() { let config = FetchConfig::default(); assert_eq!( @@ -154,7 +154,7 @@ mod tests { "https://api.example.test/path", &HttpProxyRoute::Proxy("http://proxy.test:8080".to_owned()), ), - FetchCurlDnsAdmission::CurlManaged + FetchCurlDnsAdmission::NoSharedResolution ); }