Skip to main content

libnss_host4/
err.rs

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