srv_rs/resolver/
trust_dns.rs

1//! SRV resolver backed by [`trust_dns_resolver`].
2
3use super::SrvResolver;
4use crate::SrvRecord;
5use async_trait::async_trait;
6use std::time::Instant;
7use trust_dns_resolver::{
8    error::ResolveError,
9    proto::{rr::rdata::SRV, DnsHandle},
10    AsyncResolver, ConnectionProvider, Name,
11};
12
13#[async_trait]
14impl<C, P> SrvResolver for AsyncResolver<C, P>
15where
16    C: DnsHandle,
17    P: ConnectionProvider<Conn = C>,
18{
19    type Record = SRV;
20    type Error = ResolveError;
21
22    async fn get_srv_records_unordered(
23        &self,
24        srv: &str,
25    ) -> Result<(Vec<Self::Record>, Instant), Self::Error> {
26        let lookup = self.srv_lookup(srv).await?;
27        let valid_until = lookup.as_lookup().valid_until();
28        Ok((lookup.into_iter().collect(), valid_until))
29    }
30}
31
32impl SrvRecord for SRV {
33    type Target = Name;
34
35    fn target(&self) -> &Self::Target {
36        self.target()
37    }
38
39    fn port(&self) -> u16 {
40        self.port()
41    }
42
43    fn priority(&self) -> u16 {
44        self.priority()
45    }
46
47    fn weight(&self) -> u16 {
48        self.weight()
49    }
50}
51
52#[cfg(test)]
53mod tests {
54    use super::*;
55
56    #[tokio::test]
57    async fn srv_lookup() -> Result<(), ResolveError> {
58        let (records, _) = AsyncResolver::tokio_from_system_conf()
59            .await?
60            .get_srv_records_unordered(crate::EXAMPLE_SRV)
61            .await?;
62        assert_ne!(records.len(), 0);
63        Ok(())
64    }
65
66    #[tokio::test]
67    async fn srv_lookup_ordered() -> Result<(), ResolveError> {
68        let (records, _) = AsyncResolver::tokio_from_system_conf()
69            .await?
70            .get_srv_records(crate::EXAMPLE_SRV)
71            .await?;
72        assert_ne!(records.len(), 0);
73        assert!((0..records.len() - 1).all(|i| records[i].priority() <= records[i + 1].priority()));
74        Ok(())
75    }
76
77    #[tokio::test]
78    async fn get_fresh_uris() -> Result<(), ResolveError> {
79        let resolver = AsyncResolver::tokio_from_system_conf().await?;
80        let client = crate::SrvClient::<_>::new_with_resolver(crate::EXAMPLE_SRV, resolver);
81        let (uris, _) = client.get_fresh_uri_candidates().await.unwrap();
82        assert_ne!(uris, Vec::<http::Uri>::new());
83        Ok(())
84    }
85
86    #[tokio::test]
87    async fn invalid_host() {
88        AsyncResolver::tokio_from_system_conf()
89            .await
90            .unwrap()
91            .get_srv_records("_http._tcp.foobar.deshaw.com")
92            .await
93            .unwrap_err();
94    }
95
96    #[tokio::test]
97    async fn malformed_srv_name() {
98        AsyncResolver::tokio_from_system_conf()
99            .await
100            .unwrap()
101            .get_srv_records("_http.foobar.deshaw.com")
102            .await
103            .unwrap_err();
104    }
105
106    #[tokio::test]
107    async fn very_malformed_srv_name() {
108        AsyncResolver::tokio_from_system_conf()
109            .await
110            .unwrap()
111            .get_srv_records("  @#*^[_hsd flt.com")
112            .await
113            .unwrap_err();
114    }
115
116    #[tokio::test]
117    async fn srv_name_containing_nul_terminator() {
118        AsyncResolver::tokio_from_system_conf()
119            .await
120            .unwrap()
121            .get_srv_records("_http.\0_tcp.foo.com")
122            .await
123            .unwrap_err();
124    }
125}