srv_rs/resolver/
mod.rs

1//! SRV resolvers.
2
3use crate::SrvRecord;
4use async_trait::async_trait;
5use rand::Rng;
6use std::time::Instant;
7
8#[cfg(feature = "libresolv")]
9pub mod libresolv;
10
11#[cfg(feature = "trust-dns")]
12mod trust_dns;
13
14/// Represents the ability to act as a SRV resolver.
15#[async_trait]
16pub trait SrvResolver: Send + Sync {
17    /// SRV record representation produced by the resolver.
18    type Record: SrvRecord;
19
20    /// Errors encountered during SRV resolution.
21    type Error: std::error::Error + 'static;
22
23    /// Gets the records corresponding to a srv name without sorting by priority
24    /// or shuffling based on weight, returning them along with the time they're
25    /// valid until.
26    async fn get_srv_records_unordered(
27        &self,
28        srv: &str,
29    ) -> Result<(Vec<Self::Record>, Instant), Self::Error>;
30
31    /// Gets the records corresponding to a srv name, sorting by priority and
32    /// shuffling based on weight, returning them along with the time they're
33    /// valid until.
34    async fn get_srv_records(
35        &self,
36        srv: &str,
37    ) -> Result<(Vec<Self::Record>, Instant), Self::Error> {
38        let (mut records, valid_until) = self.get_srv_records_unordered(srv).await?;
39        Self::order_srv_records(&mut records, rand::thread_rng());
40        Ok((records, valid_until))
41    }
42
43    /// Sorts SRV records by priority and weight per RFC 2782.
44    fn order_srv_records(records: &mut [Self::Record], mut rng: impl Rng) {
45        records.sort_by_cached_key(|record| record.sort_key(&mut rng));
46    }
47}