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
use std::net::{IpAddr, Ipv6Addr, SocketAddr};

use futures::{future, Future};

use Error;
use service::locator::Locator;

/// Cloud name resolution for services.
///
/// Used before service connection establishing to determine where to connect, i.e where a service
/// with the given name is located.
/// For common usage the most reasonable choice is a [`Resolver`][resolver] implementation that
/// uses [`Locator`][locator] for name resolution.
///
/// [locator]: struct.Locator.html
/// [resolver]: struct.Resolver.html
pub trait Resolve {
    type Future: Future<Item=Vec<SocketAddr>, Error=Error>;

    /// Resolves a service name into the network endpoints.
    fn resolve(&mut self, name: &str) -> Self::Future;
}

/// A no-op resolver, that always returns preliminarily specified endpoints.
///
/// Used primarily while resolving a `Locator` itself, but can be also used, when you're sure about
/// service's location.
///
/// The default value returns the default `Locator` endpoints, i.e `["::", 10053]` assuming that
/// IPv6 is enabled.
#[derive(Clone, Debug)]
pub struct FixedResolver {
    addrs: Vec<SocketAddr>,
}

impl FixedResolver {
    /// Constructs a fixed resolver, which will always resolve any service name into the specified
    /// endpoints.
    pub fn new(addrs: Vec<SocketAddr>) -> Self {
        FixedResolver {
            addrs: addrs,
        }
    }
}

impl Default for FixedResolver {
    fn default() -> Self {
        FixedResolver {
            // TODO: Replace with dual-stack endpoints. Test.
            addrs: vec![SocketAddr::new(IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)), 10053)],
        }
    }
}

impl Resolve for FixedResolver {
    type Future = future::FutureResult<Vec<SocketAddr>, Error>;

    fn resolve(&mut self, _name: &str) -> Self::Future {
        future::ok(self.addrs.clone())
    }
}

/// A `Resolver` that user the `Locator` for name resolution.
#[derive(Debug)]
pub struct Resolver {
    locator: Locator,
}

impl Resolver {
    /// Constructs a new `Resolver` using the specified `Locator` for name resolution.
    pub fn new(locator: Locator) -> Self {
        Self {
            locator: locator,
        }
    }
}

impl Resolve for Resolver {
    type Future = Box<Future<Item=Vec<SocketAddr>, Error=Error>>;

    fn resolve(&mut self, name: &str) -> Self::Future {
        box self.locator.resolve(name).map(|info| info.endpoints().into())
    }
}