OpenVPN
error.h
Go to the documentation of this file.
1/*
2 * OpenVPN -- An application to securely tunnel IP networks
3 * over a single TCP/UDP port, with support for SSL/TLS-based
4 * session authentication and key exchange,
5 * packet encryption, packet authentication, and
6 * packet compression.
7 *
8 * Copyright (C) 2002-2025 OpenVPN Inc <sales@openvpn.net>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2
12 * as published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, see <https://www.gnu.org/licenses/>.
21 */
22
23#ifndef ERROR_H
24#define ERROR_H
25
26#include "basic.h"
27#include "syshead.h"
28
29#include <assert.h>
30
31/* #define ABORT_ON_ERROR */
32
33#if defined(ENABLE_PKCS11) || defined(ENABLE_MANAGEMENT)
34#define ERR_BUF_SIZE 10240
35#else
36#define ERR_BUF_SIZE 1280
37#endif
38
39struct gc_arena;
40
41/*
42 * Where should messages be printed before syslog is opened?
43 * Not used if OPENVPN_DEBUG_COMMAND_LINE is defined.
44 */
45#define OPENVPN_MSG_FP stdout
46#define OPENVPN_ERROR_FP stderr
47
48/*
49 * Exit status codes
50 */
51
52#define OPENVPN_EXIT_STATUS_GOOD 0
53#define OPENVPN_EXIT_STATUS_ERROR 1
54#define OPENVPN_EXIT_STATUS_USAGE 1
55#define OPENVPN_EXIT_STATUS_CANNOT_OPEN_DEBUG_FILE 1
56
57/*
58 * Special command line debugging mode.
59 * If OPENVPN_DEBUG_COMMAND_LINE
60 * is defined, contents of argc/argv will
61 * be dumped to OPENVPN_DEBUG_FILE as well
62 * as all other OpenVPN messages.
63 */
64
65/* #define OPENVPN_DEBUG_COMMAND_LINE */
66#define OPENVPN_DEBUG_FILE PACKAGE ".log"
67
68/* String and Error functions */
69
70#ifdef _WIN32
71#define openvpn_errno() GetLastError()
72const char *strerror_win32(DWORD errnum, struct gc_arena *gc);
73#else
74#define openvpn_errno() errno
75#endif
76
77typedef unsigned int msglvl_t;
78
79/*
80 * These globals should not be accessed directly,
81 * but rather through macros or inline functions defined below.
82 */
84extern int x_msg_line_num;
85
86/* msg() flags */
87
88#define M_DEBUG_LEVEL (0x0Fu) /* debug level mask */
89
90#define M_FATAL (1u << 4) /* exit program */
91#define M_NONFATAL (1u << 5) /* non-fatal error */
92#define M_WARN (1u << 6) /* call syslog with LOG_WARNING */
93#define M_DEBUG (1u << 7)
94
95#define M_ERRNO (1u << 8) /* show errno description */
96
97#define M_NOMUTE (1u << 11) /* don't do mute processing */
98#define M_NOPREFIX (1u << 12) /* don't show date/time prefix */
99#define M_USAGE_SMALL (1u << 13) /* fatal options error, call usage_small */
100#define M_MSG_VIRT_OUT (1u << 14) /* output message through msg_status_output callback */
101#define M_OPTERR (1u << 15) /* print "Options error:" prefix */
102#define M_NOLF (1u << 16) /* don't print new line */
103#define M_NOIPREFIX (1u << 17) /* don't print instance prefix */
104
105/* flag combinations which are frequently used */
106#define M_ERR (M_FATAL | M_ERRNO)
107#define M_USAGE (M_USAGE_SMALL | M_NOPREFIX | M_OPTERR)
108#define M_CLIENT (M_MSG_VIRT_OUT | M_NOMUTE | M_NOIPREFIX)
109
110/*
111 * Mute levels are designed to avoid large numbers of
112 * mostly similar messages clogging the log file.
113 *
114 * A mute level of 0 is always printed.
115 */
116#define MUTE_LEVEL_SHIFT 24
117#define MUTE_LEVEL_MASK 0xFFu
118
119#define ENCODE_MUTE_LEVEL(mute_level) (((mute_level) & MUTE_LEVEL_MASK) << MUTE_LEVEL_SHIFT)
120#define DECODE_MUTE_LEVEL(flags) (((flags) >> MUTE_LEVEL_SHIFT) & MUTE_LEVEL_MASK)
121
122/*
123 * log_level: verbosity level n (--verb n) must be >= log_level to print.
124 * mute_level: don't print more than n (--mute n) consecutive messages at
125 * a given mute level, or if 0 disable muting and print everything.
126 *
127 * Mask map:
128 * Bits 0-3: log level
129 * Bits 4-23: M_x flags
130 * Bits 24-31: mute level
131 */
132#define LOGLEV(log_level, mute_level, other) ((log_level) | ENCODE_MUTE_LEVEL(mute_level) | other)
133
134/*
135 * If compiler supports variable arguments in macros, define
136 * msg() as a macro for optimization win.
137 */
138
140bool dont_mute(msglvl_t flags);
141
142/* Macro to ensure (and teach static analysis tools) we exit on fatal errors */
143#define EXIT_FATAL(flags) \
144 do \
145 { \
146 if ((flags) & M_FATAL) \
147 { \
148 _exit(1); \
149 } \
150 } while (false)
151
152#define msg(flags, ...) \
153 do \
154 { \
155 if (msg_test(flags)) \
156 { \
157 x_msg((flags), __VA_ARGS__); \
158 } \
159 EXIT_FATAL(flags); \
160 } while (false)
161#ifdef ENABLE_DEBUG
162#define dmsg(flags, ...) \
163 do \
164 { \
165 if (msg_test(flags)) \
166 { \
167 x_msg((flags), __VA_ARGS__); \
168 } \
169 EXIT_FATAL(flags); \
170 } while (false)
171#else
172#define dmsg(flags, ...)
173#endif
174
175void x_msg(const msglvl_t flags, const char *format, ...)
176#ifdef __GNUC__
177#if __USE_MINGW_ANSI_STDIO
178 __attribute__((format(gnu_printf, 2, 3)))
179#else
180 __attribute__((format(__printf__, 2, 3)))
181#endif
182#endif
183 ; /* should be called via msg above */
184
185void x_msg_va(const msglvl_t flags, const char *format, va_list arglist);
186
187/*
188 * Function prototypes
189 */
190
191void error_reset(void);
192
193/* route errors to stderr that would normally go to stdout */
194void errors_to_stderr(void);
195
196void set_suppress_timestamps(bool suppressed);
197
198void set_machine_readable_output(bool parsable);
199
200
201#define SDL_CONSTRAIN (1 << 0)
202bool set_debug_level(const int level, const unsigned int flags);
203
204bool set_mute_cutoff(const int cutoff);
205
207
208int get_mute_cutoff(void);
209
210const char *msg_flags_string(const msglvl_t flags, struct gc_arena *gc);
211
212/*
213 * File to print messages to before syslog is opened.
214 */
215FILE *msg_fp(const msglvl_t flags);
216
217/* Fatal logic errors */
218#ifndef ENABLE_SMALL
219#define ASSERT(x) \
220 do \
221 { \
222 if (!(x)) \
223 { \
224 assert_failed(__FILE__, __LINE__, #x); \
225 } \
226 } while (false)
227#else
228#define ASSERT(x) \
229 do \
230 { \
231 if (!(x)) \
232 { \
233 assert_failed(__FILE__, __LINE__, NULL); \
234 } \
235 } while (false)
236#endif
237
238#ifdef _MSC_VER
239__declspec(noreturn)
240#endif
241void
242assert_failed(const char *filename, int line, const char *condition)
243#ifndef _MSC_VER
244 __attribute__((__noreturn__))
245#endif
246 ;
247
248/* Poor-man's static_assert() for when not supplied by assert.h, taken from
249 * Linux's sys/cdefs.h under GPLv2 */
250#ifndef static_assert
251#define static_assert(expr, diagnostic) \
252 extern int (*__OpenVPN_static_assert_function( \
253 void))[!!sizeof(struct { int __error_if_negative : (expr) ? 2 : -1; })]
254#endif
255
256/* Inline functions */
257
258static inline bool
260{
261 return (level & M_DEBUG_LEVEL) <= x_debug_level;
262}
263
265static inline bool
267{
268 return check_debug_level(flags) && dont_mute(flags);
269}
270
271/* Call if we forked */
272void msg_forked(void);
273
274/* syslog output */
275
276void open_syslog(const char *pgmname, bool stdio_to_null);
277
278void close_syslog(void);
279
280/* log file output */
281void redirect_stdout_stderr(const char *file, bool append);
282
283#ifdef _WIN32
284/* get original stderr fd, even if redirected by --log/--log-append */
285int get_orig_stderr(void);
286
287#endif
288
289/* exit program */
290void openvpn_exit(const int status);
291
292/* exit program on out of memory error */
293void out_of_memory(void);
294
295/*
296 * Check the return status of read/write routines.
297 */
298
299struct link_socket;
300struct tuntap;
301
302extern unsigned int x_cs_info_level;
303extern unsigned int x_cs_verbose_level;
304extern unsigned int x_cs_err_delay_ms;
305
306void reset_check_status(void);
307
308void set_check_status(unsigned int info_level, unsigned int verbose_level);
309
310void x_check_status(int status, const char *description, struct link_socket *sock,
311 struct tuntap *tt);
312
313static inline void
314check_status(int status, const char *description, struct link_socket *sock, struct tuntap *tt)
315{
317 {
318 x_check_status(status, description, sock, tt);
319 }
320}
321
322static inline void
323set_check_status_error_delay(unsigned int milliseconds)
324{
325 x_cs_err_delay_ms = milliseconds;
326}
327
328/*
329 * In multiclient mode, put a client-specific prefix
330 * before each message.
331 *
332 * TODO: x_msg_prefix should be thread-local
333 */
334
335extern const char *x_msg_prefix;
336
337static inline void
338msg_set_prefix(const char *prefix)
339{
340 x_msg_prefix = prefix;
341}
342
343static inline const char *
345{
346 return x_msg_prefix;
347}
348
349/*
350 * Allow MSG to be redirected through a virtual_output object
351 */
352
353struct virtual_output;
354
355extern const struct virtual_output *x_msg_virtual_output;
356
357static inline void
359{
361}
362
363static inline const struct virtual_output *
368
369/*
370 * Return true if this is a system error
371 * which can be safely ignored.
372 */
373static inline bool
374ignore_sys_error(const int err, bool crt_error)
375{
376#ifdef _WIN32
377 if (!crt_error && ((err == WSAEWOULDBLOCK || err == WSAEINVAL)))
378 {
379 return true;
380 }
381#else
382 crt_error = true;
383#endif
384
385 /* I/O operation pending */
386 if (crt_error && (err == EAGAIN))
387 {
388 return true;
389 }
390
391#if 0 /* if enabled, suppress ENOBUFS errors */
392#ifdef ENOBUFS
393 /* No buffer space available */
394 if (err == ENOBUFS)
395 {
396 return true;
397 }
398#endif
399#endif
400
401 return false;
402}
403
405static inline msglvl_t
407{
408 return err & M_FATAL ? (err ^ M_FATAL) | M_NONFATAL : err;
409}
410
411static inline int
413{
414 int err = 0;
415 *crt_error = false;
416#ifdef _WIN32
417 err = GetLastError();
418 if (err == ERROR_SUCCESS)
419 {
420 /* error is likely C runtime */
421 *crt_error = true;
422 err = errno;
423 }
424#else /* ifdef _WIN32 */
425 *crt_error = true;
426 err = errno;
427#endif
428 return err;
429}
430
431#include "errlevel.h"
432
433#endif /* ifndef ERROR_H */
static SERVICE_STATUS status
Definition interactive.c:51
void error_reset(void)
Definition error.c:158
const struct virtual_output * x_msg_virtual_output
Definition error.c:696
static bool check_debug_level(msglvl_t level)
Definition error.h:259
static void msg_set_prefix(const char *prefix)
Definition error.h:338
void out_of_memory(void)
Definition error.c:438
msglvl_t get_debug_level(void)
Definition error.c:134
void errors_to_stderr(void)
Definition error.c:182
void open_syslog(const char *pgmname, bool stdio_to_null)
Definition error.c:445
void close_syslog(void)
Definition error.c:470
static msglvl_t nonfatal(const msglvl_t err)
Convert fatal errors to nonfatal, don't touch other errors.
Definition error.h:406
unsigned int x_cs_info_level
Definition error.c:600
#define M_DEBUG_LEVEL
Definition error.h:88
void x_msg(const msglvl_t flags, const char *format,...)
Definition error.c:215
void assert_failed(const char *filename, int line, const char *condition) __attribute__((__noreturn__))
Definition error.c:420
msglvl_t x_debug_level
Definition error.c:51
static void msg_set_virtual_output(const struct virtual_output *vo)
Definition error.h:358
static const char * msg_get_prefix(void)
Definition error.h:344
const char * strerror_win32(DWORD errnum, struct gc_arena *gc)
Definition error.c:780
void msg_forked(void)
Definition error.c:98
static bool msg_test(msglvl_t flags)
Return true if flags represent an enabled, not muted log level.
Definition error.h:266
const char * x_msg_prefix
Definition error.c:690
int x_msg_line_num
Definition error.c:212
#define M_FATAL
Definition error.h:90
bool dont_mute(msglvl_t flags)
Check muting filter.
Definition error.c:386
void x_check_status(int status, const char *description, struct link_socket *sock, struct tuntap *tt)
Definition error.c:627
static void set_check_status_error_delay(unsigned int milliseconds)
Definition error.h:323
int get_orig_stderr(void)
Definition error.c:487
void redirect_stdout_stderr(const char *file, bool append)
Definition error.c:494
#define M_NONFATAL
Definition error.h:91
bool set_mute_cutoff(const int cutoff)
Definition error.c:120
static bool ignore_sys_error(const int err, bool crt_error)
Definition error.h:374
void set_check_status(unsigned int info_level, unsigned int verbose_level)
Definition error.c:612
static int openvpn_errno_maybe_crt(bool *crt_error)
Definition error.h:412
unsigned int x_cs_verbose_level
Definition error.c:601
void openvpn_exit(const int status)
Definition error.c:703
unsigned int msglvl_t
Definition error.h:77
void reset_check_status(void)
Definition error.c:605
static void check_status(int status, const char *description, struct link_socket *sock, struct tuntap *tt)
Definition error.h:314
void x_msg_va(const msglvl_t flags, const char *format, va_list arglist)
Definition error.c:236
int get_mute_cutoff(void)
Definition error.c:140
void set_suppress_timestamps(bool suppressed)
Definition error.c:146
void set_machine_readable_output(bool parsable)
Definition error.c:152
FILE * msg_fp(const msglvl_t flags)
Definition error.c:191
static const struct virtual_output * msg_get_virtual_output(void)
Definition error.h:364
bool set_debug_level(const int level, const unsigned int flags)
Definition error.c:104
const char * msg_flags_string(const msglvl_t flags, struct gc_arena *gc)
Definition error.c:751
unsigned int x_cs_err_delay_ms
Definition error.c:602
Garbage collection arena used to keep track of dynamically allocated memory.
Definition buffer.h:116
Definition tun.h:183
__attribute__((unused))
Definition test.c:42
struct gc_arena gc
Definition test_ssl.c:131