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}