Skip to main content

libnss_host4/
err.rs

1pub type NssRes<T> = Result<T, NssErr>;
2
3/// Contains the return information passed by this plugin
4/// through the NSS API.
5///
6/// Some common constants are defined, but feel free to
7/// construct your own as well.
8#[derive(Debug, PartialEq, Eq)]
9pub struct NssErr {
10    /// A standard libc error.
11    c_err: i32,
12    nss: NssStatus,
13    dns: HostStatus,
14}
15
16impl NssErr {
17    /// The command succeeded. No error.
18    pub const SUCCESS: Self = Self {
19        c_err: 0,
20        nss: NssStatus::Success,
21        dns: HostStatus::Success,
22    };
23
24    /// The plugin completed successfully and found no matches for the hostname.
25    pub const NO_RESULT: Self = Self {
26        c_err: 0,
27        nss: NssStatus::NotFound,
28        dns: HostStatus::NoData,
29    };
30
31    /// For example, a hostname is not valid UTF-8, which is expected
32    /// by this library.
33    pub const INVALID_INPUT: Self = Self {
34        c_err: libc::EINVAL,
35        nss: NssStatus::Unavailable,
36        dns: HostStatus::NoRecovery,
37    };
38
39    /// This is a suitable return type for total plugin failure. For example,
40    /// if you're relying on unix sockets to communicate with a DNS server and
41    /// there are failures talking to the server.
42    pub const PLUGIN_FAILED: Self = Self {
43        // IO is somewhat questionable here. Feel free to overwrite it
44        // with something more appropriate for your context.
45        c_err: libc::EIO,
46        nss: NssStatus::Unavailable,
47        dns: HostStatus::NoRecovery,
48    };
49
50    /// The buffer containing requests results was too small. Retrying
51    /// with a larger buffer may succeed.
52    pub(crate) const BUF_TOO_SMALL: Self = Self {
53        c_err: libc::EAGAIN,
54        nss: NssStatus::TryAgain,
55        dns: HostStatus::TryAgain,
56    };
57
58    /// Writes error state to return pointers and yields the appropriate
59    /// NSS exit code for this error.
60    pub(crate) fn bail(self, errnop: &mut libc::c_int, h_errnop: &mut libc::c_int) -> libc::c_int {
61        *errnop = self.c_err;
62        *h_errnop = self.dns as i32;
63        self.nss as i32
64    }
65}
66
67/// Return status of an NSS function call.
68///
69/// Defined here:
70/// <https://github.com/lattera/glibc/blob/895ef79e04a953cac1493863bcae29ad85657ee1/nss/nss.h#L30-L38>
71#[derive(Debug, PartialEq, Eq)]
72pub enum NssStatus {
73    /// This service is temporarily unusable. For example, the given address
74    /// buffer is too small or the backing DNS service is overloaded.
75    TryAgain = -2,
76
77    /// Plugin failure. For example, IPC or connectivity to some backing
78    /// DNS service failed.
79    Unavailable,
80
81    /// The query completed successfully without returning any matching hosts.
82    /// Pairs with [`HostStatus::HostNotFound`].
83    NotFound,
84
85    /// Request succeeded. Caller should check PAT list.
86    Success,
87    //
88    // Don't use `RETURN`? nss-mdns never does, and some cursory searching
89    // suggests plugins should not return this value.
90    // Return,
91}
92
93/// The NSS Host lookup errno. Further explains the
94/// standard C errno.
95///
96/// Defined here. Comments copied verbatim.
97///
98/// <https://github.com/lattera/glibc/blob/895ef79e04a953cac1493863bcae29ad85657ee1/resolv/netdb.h#L62-L75>
99#[derive(Debug, PartialEq, Eq)]
100pub enum HostStatus {
101    /// See errno.
102    Internal = -1,
103
104    /// No problem
105    Success,
106
107    /// Authoritative Answer Host not found.
108    HostNotFound,
109
110    /// Non-Authoritative Host not found or SERVERFAIL.
111    TryAgain,
112
113    /// Non recoverable errors, FORMERR, REFUSED, NOTIMP.
114    NoRecovery,
115
116    /// Valid name, no data record of requested type.
117    NoData,
118}