1 /*  Copyright (C) 2021 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
2 
3     This program is free software: you can redistribute it and/or modify
4     it under the terms of the GNU General Public License as published by
5     the Free Software Foundation, either version 3 of the License, or
6     (at your option) any later version.
7 
8     This program is distributed in the hope that it will be useful,
9     but WITHOUT ANY WARRANTY; without even the implied warranty of
10     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11     GNU General Public License for more details.
12 
13     You should have received a copy of the GNU General Public License
14     along with this program.  If not, see <https://www.gnu.org/licenses/>.
15  */
16 
17 /*!
18  * \file
19  *
20  * \brief Knot error codes.
21  *
22  * \addtogroup libknot
23  * @{
24  */
25 
26 #pragma once
27 
28 #include <errno.h>
29 
30 /*! \brief Error codes used in the library. */
31 enum knot_error {
32 	KNOT_EOK = 0,
33 
34 	/* Directly mapped error codes. */
35 	KNOT_ENOMEM        = -ENOMEM,
36 	KNOT_EINVAL        = -EINVAL,
37 	KNOT_ENOTSUP       = -ENOTSUP,
38 	KNOT_EBUSY         = -EBUSY,
39 	KNOT_EAGAIN        = -EAGAIN,
40 	KNOT_ENOBUFS       = -ENOBUFS,
41 	KNOT_EMFILE        = -EMFILE,
42 	KNOT_ENFILE        = -ENFILE,
43 	KNOT_EACCES        = -EACCES,
44 	KNOT_EISCONN       = -EISCONN,
45 	KNOT_ECONNREFUSED  = -ECONNREFUSED,
46 	KNOT_EALREADY      = -EALREADY,
47 	KNOT_ECONNRESET    = -ECONNRESET,
48 	KNOT_ECONNABORTED  = -ECONNABORTED,
49 	KNOT_ENETRESET     = -ENETRESET,
50 	KNOT_EHOSTUNREACH  = -EHOSTUNREACH,
51 	KNOT_ENETUNREACH   = -ENETUNREACH,
52 	KNOT_EHOSTDOWN     = -EHOSTDOWN,
53 	KNOT_ENETDOWN      = -ENETDOWN,
54 	KNOT_EADDRINUSE    = -EADDRINUSE,
55 	KNOT_ENOENT        = -ENOENT,
56 	KNOT_EEXIST        = -EEXIST,
57 	KNOT_ERANGE        = -ERANGE,
58 	KNOT_EADDRNOTAVAIL = -EADDRNOTAVAIL,
59 	KNOT_ENOTDIR       = -ENOTDIR,
60 
61 	KNOT_ERRNO_ERROR   = -500,
62 
63 	KNOT_ERROR_MIN = -1000,
64 
65 	/* General errors. */
66 	KNOT_ERROR = KNOT_ERROR_MIN,
67 	KNOT_EPARSEFAIL,
68 	KNOT_ESEMCHECK,
69 	KNOT_EUPTODATE,
70 	KNOT_EFEWDATA,
71 	KNOT_ESPACE,
72 	KNOT_EMALF,
73 	KNOT_ENSEC3PAR,
74 	KNOT_ENSEC3CHAIN,
75 	KNOT_EOUTOFZONE,
76 	KNOT_EZONEINVAL,
77 	KNOT_ENOZONE,
78 	KNOT_ENONODE,
79 	KNOT_ENORECORD,
80 	KNOT_EISRECORD,
81 	KNOT_ENOMASTER,
82 	KNOT_EPREREQ,
83 	KNOT_ETTL,
84 	KNOT_ENOXFR,
85 	KNOT_EDENIED,
86 	KNOT_ECONN,
87 	KNOT_ETIMEOUT,
88 	KNOT_ENODIFF,
89 	KNOT_ENOTSIG,
90 	KNOT_ELIMIT,
91 	KNOT_EZONESIZE,
92 	KNOT_EOF,
93 	KNOT_ESYSTEM,
94 	KNOT_EFILE,
95 	KNOT_ESOAINVAL,
96 	KNOT_ETRAIL,
97 	KNOT_EPROCESSING,
98 	KNOT_EPROGRESS,
99 	KNOT_ELOOP,
100 	KNOT_EPROGRAM,
101 	KNOT_EFD,
102 	KNOT_ENOPARAM,
103 	KNOT_EXPARAM,
104 	KNOT_EEMPTYZONE,
105 	KNOT_EUNREACH,
106 
107 	KNOT_GENERAL_ERROR = -900,
108 
109 	/* Control states. */
110 	KNOT_CTL_ESTOP,
111 	KNOT_CTL_EZONE,
112 
113 	/* Network errors. */
114 	KNOT_NET_EADDR,
115 	KNOT_NET_ESOCKET,
116 	KNOT_NET_ECONNECT,
117 	KNOT_NET_ESEND,
118 	KNOT_NET_ERECV,
119 	KNOT_NET_ETIMEOUT,
120 
121 	/* Encoding errors. */
122 	KNOT_BASE64_ESIZE,
123 	KNOT_BASE64_ECHAR,
124 	KNOT_BASE32HEX_ESIZE,
125 	KNOT_BASE32HEX_ECHAR,
126 
127 	/* TSIG errors. */
128 	KNOT_TSIG_EBADSIG,
129 	KNOT_TSIG_EBADKEY,
130 	KNOT_TSIG_EBADTIME,
131 	KNOT_TSIG_EBADTRUNC,
132 
133 	/* DNSSEC errors. */
134 	KNOT_DNSSEC_EMISSINGKEYTYPE,
135 	KNOT_DNSSEC_ENOKEY,
136 	KNOT_DNSSEC_ENOSIG,
137 	KNOT_DNSSEC_ENSEC_BITMAP,
138 	KNOT_DNSSEC_ENSEC_CHAIN,
139 	KNOT_DNSSEC_ENSEC3_OPTOUT,
140 
141 	/* Yparser errors. */
142 	KNOT_YP_ECHAR_TAB,
143 	KNOT_YP_EINVAL_ITEM,
144 	KNOT_YP_EINVAL_ID,
145 	KNOT_YP_EINVAL_DATA,
146 	KNOT_YP_EINVAL_INDENT,
147 	KNOT_YP_ENOTSUP_DATA,
148 	KNOT_YP_ENOTSUP_ID,
149 	KNOT_YP_ENODATA,
150 	KNOT_YP_ENOID,
151 
152 	/* Configuration errors. */
153 	KNOT_CONF_ENOTINIT,
154 	KNOT_CONF_EVERSION,
155 	KNOT_CONF_EREDEFINE,
156 
157 	/* Transaction errors. */
158 	KNOT_TXN_EEXISTS,
159 	KNOT_TXN_ENOTEXISTS,
160 
161 	/* DNSSEC errors. */
162 	KNOT_INVALID_PUBLIC_KEY,
163 	KNOT_INVALID_PRIVATE_KEY,
164 	KNOT_INVALID_KEY_ALGORITHM,
165 	KNOT_INVALID_KEY_SIZE,
166 	KNOT_INVALID_KEY_ID,
167 	KNOT_INVALID_KEY_NAME,
168 	KNOT_NO_PUBLIC_KEY,
169 	KNOT_NO_PRIVATE_KEY,
170 	KNOT_NO_READY_KEY,
171 
172 	KNOT_ERROR_MAX = -501
173 };
174 
175 /*!
176  * \brief Map POSIX errno code to Knot error code.
177  *
178  * \param code       Errno code to transform (set -1 to use the current errno).
179  * \param dflt_error Default return value, if code is unknown.
180  *
181  * \return Mapped errno or the value of dflt_error if unknown.
182  */
knot_map_errno_code_def(int code,int dflt_error)183 inline static int knot_map_errno_code_def(int code, int dflt_error)
184 {
185 	if (code < 0) {
186 		code = errno;
187 	}
188 
189 	typedef struct {
190 		int errno_code;
191 		int libknot_code;
192 	} err_table_t;
193 
194 	#define ERR_ITEM(name) { name, KNOT_##name }
195 	static const err_table_t errno_to_errcode[] = {
196 		ERR_ITEM(ENOMEM),
197 		ERR_ITEM(EINVAL),
198 		ERR_ITEM(ENOTSUP),
199 		ERR_ITEM(EBUSY),
200 		ERR_ITEM(EAGAIN),
201 		ERR_ITEM(ENOBUFS),
202 		ERR_ITEM(EMFILE),
203 		ERR_ITEM(ENFILE),
204 		ERR_ITEM(EACCES),
205 		ERR_ITEM(EISCONN),
206 		ERR_ITEM(ECONNREFUSED),
207 		ERR_ITEM(EALREADY),
208 		ERR_ITEM(ECONNRESET),
209 		ERR_ITEM(ECONNABORTED),
210 		ERR_ITEM(ENETRESET),
211 		ERR_ITEM(EHOSTUNREACH),
212 		ERR_ITEM(ENETUNREACH),
213 		ERR_ITEM(EHOSTDOWN),
214 		ERR_ITEM(ENETDOWN),
215 		ERR_ITEM(EADDRINUSE),
216 		ERR_ITEM(ENOENT),
217 		ERR_ITEM(EEXIST),
218 		ERR_ITEM(ERANGE),
219 		ERR_ITEM(EADDRNOTAVAIL),
220 
221 		/* Terminator - the value isn't used. */
222 		{ 0, KNOT_ERRNO_ERROR }
223 	};
224 	#undef ERR_ITEM
225 
226 	const err_table_t *err = errno_to_errcode;
227 
228 	while (err->errno_code != 0 && err->errno_code != code) {
229 		err++;
230 	}
231 
232 	return err->errno_code != 0 ? err->libknot_code : dflt_error;
233 }
234 
235 /*!
236  * \brief Map POSIX errno code to Knot error code.
237  *
238  * \param code Errno code to transform (set -1 to use the current errno).
239  *
240  * \return Mapped errno or KNOT_ERRNO_ERROR if unknown.
241  */
knot_map_errno_code(int code)242 inline static int knot_map_errno_code(int code)
243 {
244 	return knot_map_errno_code_def(code, KNOT_ERRNO_ERROR);
245 }
246 
247 /*!
248  * \brief Get a POSIX errno mapped to Knot error code.
249  *
250  * \param dflt_error Default return value, if code is unknown.
251  *
252  * \return Mapped errno.
253  */
knot_map_errno_def(int dflt_error)254 inline static int knot_map_errno_def(int dflt_error)
255 {
256 	return knot_map_errno_code_def(-1, dflt_error);
257 }
258 
259 /*!
260  * \brief Get a POSIX errno mapped to Knot error code.
261  *
262  * \return Mapped errno or KNOT_ERRNO_ERROR if unknown.
263  */
knot_map_errno(void)264 inline static int knot_map_errno(void)
265 {
266 	return knot_map_errno_code_def(-1, KNOT_ERRNO_ERROR);
267 }
268 
269 /*! @} */
270