srv_rs/
lib.rs

1#![deny(missing_docs)]
2#![warn(broken_intra_doc_links)]
3
4/*!
5Rust client for communicating with services located by DNS SRV records.
6
7# Introduction
8
9SRV Records, as defined in [RFC 2782](https://tools.ietf.org/html/rfc2782),
10are DNS records of the form
11
12`_Service._Proto.Name TTL Class SRV Priority Weight Port Target`
13
14For instance, a DNS server might respond with the following SRV records for
15`_http._tcp.example.com`:
16
17```text
18_http._tcp.example.com. 60 IN SRV 1 100 443 test1.example.com.
19_http._tcp.example.com. 60 IN SRV 2 50  443 test2.example.com.
20_http._tcp.example.com. 60 IN SRV 2 50  443 test3.example.com.
21```
22
23A client wanting to communicate with this example service would first try to
24communicate with `test1.example.com:443` (the record with the lowest
25priority), then with the other two (in a random order, since they are of the
26same priority) should the first be unavailable.
27
28`srv-rs` handles the lookup and caching of SRV records as well as the ordered
29selection of targets to use for communication with SRV-located services.
30It presents this service in the following interface:
31
32```
33# #[tokio::main]
34# async fn main() {
35use srv_rs::{SrvClient, Execution, resolver::libresolv::LibResolv};
36let client = SrvClient::<LibResolv>::new("_http._tcp.example.com");
37client.execute(Execution::Serial, |address: http::Uri| async move {
38    // Communicate with the service at `address`
39    // `hyper` is used here as an example, but it is in no way required
40    hyper::Client::new().get(address).await
41})
42.await;
43# }
44```
45
46[`SrvClient::new`] creates a client (that should be reused to take advantage of
47caching) for communicating with the service located by `_http._tcp.example.com`.
48[`SrvClient::execute`] takes in a future-producing closure (emulating async
49closures, which are currently unstable) and executes the closure on a series of
50targets parsed from the discovered SRV records, stopping and returning the
51first `Ok` or last `Err` it obtains.
52
53# Alternative Resolvers and Target Selection Policies
54
55`srv-rs` provides multiple resolver backends for SRV lookup and by default uses
56a target selection policy that maintains affinity for the last target it has
57used successfully. Both of these behaviors can be changed by implementing the
58[`SrvResolver`] and [`Policy`] traits, respectively.
59
60The provided resolver backends are enabled by the following features:
61
62- `libresolv` (via [`LibResolv`])
63- `trust-dns` (via [`trust_dns_resolver::AsyncResolver`])
64
65[`SrvResolver`]: resolver::SrvResolver
66[`Policy`]: policy::Policy
67[`LibResolv`]: resolver::libresolv::LibResolv
68*/
69
70mod client;
71pub use client::{policy, Error, Execution, SrvClient};
72
73mod record;
74pub use record::SrvRecord;
75
76pub mod resolver;
77
78#[doc(hidden)]
79pub const EXAMPLE_SRV: &str = "_http._tcp.srv-client-rust.deshaw.org";