azalea_protocol/
resolve.rs1use std::{
4 net::{IpAddr, SocketAddr},
5 sync::LazyLock,
6};
7
8pub use hickory_resolver::ResolveError;
9use hickory_resolver::{
10 Name, TokioResolver, config::ResolverConfig, name_server::TokioConnectionProvider,
11};
12use tracing::warn;
13
14use crate::address::ServerAddr;
15
16#[doc(hidden)]
17#[deprecated(note = "Renamed to ResolveError")]
18pub type ResolverError = ResolveError;
19
20static RESOLVER: LazyLock<TokioResolver> = LazyLock::new(|| {
21 TokioResolver::builder(TokioConnectionProvider::default())
22 .unwrap_or_else(|_| {
23 warn!("System DNS resolver unavailable; falling back to Google DNS.");
24 TokioResolver::builder_with_config(
25 ResolverConfig::google(),
26 TokioConnectionProvider::default(),
27 )
28 })
29 .build()
30});
31
32pub async fn resolve_address(mut address: &ServerAddr) -> Result<SocketAddr, ResolveError> {
36 let redirect = resolve_srv_redirect(address).await;
37 if let Ok(redirect_target) = &redirect {
38 address = redirect_target;
39 }
40
41 resolve_ip_without_redirects(address).await
42}
43
44async fn resolve_ip_without_redirects(address: &ServerAddr) -> Result<SocketAddr, ResolveError> {
45 if let Ok(ip) = address.host.parse::<IpAddr>() {
46 return Ok(SocketAddr::new(ip, address.port));
48 }
49
50 let name = Name::from_ascii(&address.host)?;
51 let lookup_ip = RESOLVER.lookup_ip(name).await?;
52
53 let ip = lookup_ip
54 .iter()
55 .next()
56 .ok_or(hickory_resolver::ResolveError::from(
57 "No A/AAAA record found",
58 ))?;
59
60 Ok(SocketAddr::new(ip, address.port))
61}
62
63async fn resolve_srv_redirect(address: &ServerAddr) -> Result<ServerAddr, ResolveError> {
64 if address.port != 25565 {
65 return Err(ResolveError::from("Port must be 25565 to do a SRV lookup"));
66 }
67
68 let query = format!("_minecraft._tcp.{}", address.host);
69 let res = RESOLVER.srv_lookup(query).await?;
70
71 let srv = res
72 .iter()
73 .next()
74 .ok_or(ResolveError::from("No SRV record found"))?;
75 Ok(ServerAddr {
76 host: srv.target().to_ascii(),
77 port: srv.port(),
78 })
79}