1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
//! Abstract traits for name service library
//!
//! # Traits
//!
//! There are four traits:
//!
//! * [`HostResolve`](trait.HostResolve.html)
//! -- resolves hostname to a list of IP addresses
//! (maps to `A` record in DNS)
//! * [`Resolve`](trait.Resolve.html)
//! -- resolves service name to a set of weighted and prioritized host:port
//! pairs ([`Address`](struct.Address.html) struct).
//! Maps to `SRV` record in DNS.
//! * [`HostSubscribe`](trait.HostSubscribe.html)
//! -- resolves hostname to a list of IP addresses and tracks changes of
//! the addresses
//! * [`Subscribe`](trait.Subscribe.html)
//! -- resolves service name to an [`Address`](struct.Address.html) and
//! subscribes on updates of the address
//!
//! And there are two address types:
//!
//! * [`IpList`](ip_list/struct.IpList.html) -- represents `Arc<Vec<IpAddr>>`
//! this is used as a result of hostname resolution and it should be converted
//! into an `Address` struct.
//! * [`Address`](addr/struct.Address.html) -- represets weighed and
//! prioritized list of addresses, this is what all user code should accept
//! for maximum flexibility.
//!
//! There are three category of users of the library:
//!
//! * Implementors of resolution methods
//! * Service authors
//! * Application writers
//!
//! Let's explain how to use traits to all of them.
//!
//! # Implementing A Resolver
//!
//! The `*Resolve` traits are used for ad-hoc resolution of the addresses.
//!
//! The `*Subscribe` traits are used to get updates for the name. If your
//! name service supports updates you should implement it. If not, there
//! are shims which periodically poll `resolve*` methods to get the
//! update functionality. Still if you want to poll again based on TTL value
//! and your resolver does have this value you might want to implement
//! `*Subscribe` traits too.
//!
//! But `abstract-ns` is not just for DNS subsystem. You may want `*.consul`
//! names to be resolved against consul and subscribe on updates in consul.
//! Another option is to use eureka, etcd, or zookeeper. All of them having
//! a way to deliver updates.
//!
//! # Writing Protocols
//!
//! In general, your library should depend on a minimum set of functionality
//! here. Here are the rules of thumb:
//!
//! 1. Clients: when you need to connect once, accept
//! `T: Future<Item=SocketAddr>`, there are adapters that pick a random
//! host from `Future<Item=Address>` returned by `PollResolver::resolve`
//! 2. Clients: when writing a connection pool, accept
//! `T: Stream<Item=Address>`, there are adapters to make that stream
//! by resolving a single name (into potentially multiple IP addresses),
//! a list of names, and a `Stream<Item=Vec<Name>>` (so that config is
//! adaptable). As well as adapters that help diffing the `Address`,
//! effectively allowing connection pool to adapt
//! (also take a look at [tk-pool])
//! 3. Servers: accept `T: AsyncRead + AsyncWrite`, we have
//! [tk-listen] crate that can turn all kinds of configuration
//! into actually accepted connections.
//! 4. Servers: if you need more control accept `TcpStream`
//! or `Stream<io::Result<TcpStream>>`, this provides same flexibility
//! for name resolution but allows control over parameters of TCP socket
//! or of the accepting actual connections
//!
//! [tk-pool]: https://crates.io/crates/tk-pool
//! [tk-listen]: https://crates.io/crates/tk-listen
//!
//! # Writing Applications
//!
//! Applications should use `ns-router` crate that supports multiple resolvers,
//! and configuring them on-the-fly.
//!
//! # Writing Connection Pools
//!
//! As said in [Writing Protocols](#writing-protocols) section a single
//! connection pool should use `T: Stream<Item=Address>` for as a name
//! source, this allows good flexibility (also see [tk-pool])
//!
//! But in case you need kinda connection pool to a lot of different names
//! and services, this is the good case for accepting `Resolver` trait itself.
//! (Still, most of the time actual application should supply
//! `ns_router::Router`)
//!
extern crate futures;
extern crate rand;
extern crate void;
extern crate quick_error;
pub use Address;
pub use IpList;
pub use Error;
pub use Name;
pub use ;