complete federation destination caching preempting getaddrinfo(3).

fixed some clippy lints and spacing adjusted

Signed-off-by: Jason Volk <jason@zemos.net>
Signed-off-by: strawberry <strawberry@puppygock.gay>
This commit is contained in:
Jason Volk 2024-03-17 02:20:23 -04:00 committed by June
parent 6fe0ea05b8
commit 95ea665649
4 changed files with 50 additions and 32 deletions

1
Cargo.lock generated
View file

@ -2062,6 +2062,7 @@ dependencies = [
"tokio-rustls", "tokio-rustls",
"tokio-socks", "tokio-socks",
"tower-service", "tower-service",
"trust-dns-resolver",
"url", "url",
"wasm-bindgen", "wasm-bindgen",
"wasm-bindgen-futures", "wasm-bindgen-futures",

View file

@ -106,6 +106,7 @@ default-features = false
features = [ features = [
"rustls-tls-native-roots", "rustls-tls-native-roots",
"socks", "socks",
"trust-dns",
] ]
# all the serde stuff # all the serde stuff

View file

@ -365,7 +365,10 @@ async fn find_actual_destination(destination: &'_ ServerName) -> (FedDest, FedDe
None => { None => {
if let Some(pos) = destination_str.find(':') { if let Some(pos) = destination_str.find(':') {
debug!("2: Hostname with included port"); debug!("2: Hostname with included port");
let (host, port) = destination_str.split_at(pos); let (host, port) = destination_str.split_at(pos);
query_and_cache_override(host, host, port.parse::<u16>().unwrap_or(8448)).await;
FedDest::Named(host.to_owned(), port.to_owned()) FedDest::Named(host.to_owned(), port.to_owned())
} else { } else {
debug!("Requesting well known for {destination}"); debug!("Requesting well known for {destination}");
@ -378,30 +381,23 @@ async fn find_actual_destination(destination: &'_ ServerName) -> (FedDest, FedDe
None => { None => {
if let Some(pos) = delegated_hostname.find(':') { if let Some(pos) = delegated_hostname.find(':') {
debug!("3.2: Hostname with port in .well-known file"); debug!("3.2: Hostname with port in .well-known file");
let (host, port) = delegated_hostname.split_at(pos); let (host, port) = delegated_hostname.split_at(pos);
query_and_cache_override(host, host, port.parse::<u16>().unwrap_or(8448)).await;
FedDest::Named(host.to_owned(), port.to_owned()) FedDest::Named(host.to_owned(), port.to_owned())
} else { } else {
debug!("Delegated hostname has no port in this branch"); debug!("Delegated hostname has no port in this branch");
if let Some(hostname_override) = query_srv_record(&delegated_hostname).await { if let Some(hostname_override) = query_srv_record(&delegated_hostname).await {
debug!("3.3: SRV lookup successful"); debug!("3.3: SRV lookup successful");
let force_port = hostname_override.port();
if let Ok(override_ip) = services() let force_port = hostname_override.port();
.globals query_and_cache_override(
.dns_resolver() &delegated_hostname,
.lookup_ip(hostname_override.hostname()) &hostname_override.hostname(),
.await force_port.unwrap_or(8448),
{ )
services().globals.tls_name_override.write().unwrap().insert( .await;
delegated_hostname.clone(),
(override_ip.iter().collect(), force_port.unwrap_or(8448)),
);
} else {
debug!(
"Using SRV record {}, but could not resolve to IP",
hostname_override.hostname()
);
}
if let Some(port) = force_port { if let Some(port) = force_port {
FedDest::Named(delegated_hostname, format!(":{port}")) FedDest::Named(delegated_hostname, format!(":{port}"))
@ -410,6 +406,7 @@ async fn find_actual_destination(destination: &'_ ServerName) -> (FedDest, FedDe
} }
} else { } else {
debug!("3.4: No SRV records, just use the hostname from .well-known"); debug!("3.4: No SRV records, just use the hostname from .well-known");
query_and_cache_override(&delegated_hostname, &delegated_hostname, 8448).await;
add_port_to_hostname(&delegated_hostname) add_port_to_hostname(&delegated_hostname)
} }
} }
@ -421,21 +418,14 @@ async fn find_actual_destination(destination: &'_ ServerName) -> (FedDest, FedDe
match query_srv_record(&destination_str).await { match query_srv_record(&destination_str).await {
Some(hostname_override) => { Some(hostname_override) => {
debug!("4: SRV record found"); debug!("4: SRV record found");
let force_port = hostname_override.port();
if let Ok(override_ip) = let force_port = hostname_override.port();
services().globals.dns_resolver().lookup_ip(hostname_override.hostname()).await query_and_cache_override(
{ &hostname,
services().globals.tls_name_override.write().unwrap().insert( &hostname_override.hostname(),
hostname.clone(), force_port.unwrap_or(8448),
(override_ip.iter().collect(), force_port.unwrap_or(8448)), )
); .await;
} else {
debug!(
"Using SRV record {}, but could not resolve to IP",
hostname_override.hostname()
);
}
if let Some(port) = force_port { if let Some(port) = force_port {
FedDest::Named(hostname.clone(), format!(":{port}")) FedDest::Named(hostname.clone(), format!(":{port}"))
@ -445,6 +435,7 @@ async fn find_actual_destination(destination: &'_ ServerName) -> (FedDest, FedDe
}, },
None => { None => {
debug!("5: No SRV record found"); debug!("5: No SRV record found");
query_and_cache_override(&destination_str, &destination_str, 8448).await;
add_port_to_hostname(&destination_str) add_port_to_hostname(&destination_str)
}, },
} }
@ -453,7 +444,6 @@ async fn find_actual_destination(destination: &'_ ServerName) -> (FedDest, FedDe
} }
}, },
}; };
debug!("Actual destination: {actual_destination:?}");
// Can't use get_ip_with_port here because we don't want to add a port // Can't use get_ip_with_port here because we don't want to add a port
// to an IP address if it wasn't specified // to an IP address if it wasn't specified
@ -467,9 +457,29 @@ async fn find_actual_destination(destination: &'_ ServerName) -> (FedDest, FedDe
} else { } else {
FedDest::Named(hostname, ":8448".to_owned()) FedDest::Named(hostname, ":8448".to_owned())
}; };
debug!("Actual destination: {actual_destination:?} hostname: {hostname:?}");
(actual_destination, hostname) (actual_destination, hostname)
} }
async fn query_and_cache_override(overname: &'_ str, hostname: &'_ str, port: u16) {
match services().globals.dns_resolver().lookup_ip(hostname.to_owned()).await {
Ok(override_ip) => {
debug!("Caching result of {:?} overriding {:?}", hostname, overname);
services()
.globals
.tls_name_override
.write()
.unwrap()
.insert(overname.to_owned(), (override_ip.iter().collect(), port));
},
Err(e) => {
debug!("Got {:?} for {:?} to override {:?}", e.kind(), hostname, overname);
},
}
}
async fn query_srv_record(hostname: &'_ str) -> Option<FedDest> { async fn query_srv_record(hostname: &'_ str) -> Option<FedDest> {
fn handle_successful_srv(srv: &SrvLookup) -> Option<FedDest> { fn handle_successful_srv(srv: &SrvLookup) -> Option<FedDest> {
srv.iter().next().map(|result| { srv.iter().next().map(|result| {
@ -501,6 +511,10 @@ async fn query_srv_record(hostname: &'_ str) -> Option<FedDest> {
} }
async fn request_well_known(destination: &str) -> Option<String> { async fn request_well_known(destination: &str) -> Option<String> {
if !services().globals.tls_name_override.read().unwrap().contains_key(destination) {
query_and_cache_override(destination, destination, 8448).await;
}
let response = services() let response = services()
.globals .globals
.default_client() .default_client()

View file

@ -495,6 +495,7 @@ fn reqwest_client_builder(config: &Config) -> Result<reqwest::ClientBuilder> {
}); });
let mut reqwest_client_builder = reqwest::Client::builder() let mut reqwest_client_builder = reqwest::Client::builder()
.trust_dns(true)
.pool_max_idle_per_host(0) .pool_max_idle_per_host(0)
.connect_timeout(Duration::from_secs(60)) .connect_timeout(Duration::from_secs(60))
.timeout(Duration::from_secs(60 * 5)) .timeout(Duration::from_secs(60 * 5))
@ -522,6 +523,7 @@ fn url_preview_reqwest_client_builder(config: &Config) -> Result<reqwest::Client
}); });
let mut reqwest_client_builder = reqwest::Client::builder() let mut reqwest_client_builder = reqwest::Client::builder()
.trust_dns(true)
.pool_max_idle_per_host(0) .pool_max_idle_per_host(0)
.connect_timeout(Duration::from_secs(60)) .connect_timeout(Duration::from_secs(60))
.timeout(Duration::from_secs(60 * 5)) .timeout(Duration::from_secs(60 * 5))