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
77/*
78 * These globals should not be accessed directly,
79 * but rather through macros or inline functions defined below.
80 */
81extern unsigned int x_debug_level;
82extern int x_msg_line_num;
83
84/* msg() flags */
85
86#define M_DEBUG_LEVEL (0x0F) /* debug level mask */
87
88#define M_FATAL (1 << 4) /* exit program */
89#define M_NONFATAL (1 << 5) /* non-fatal error */
90#define M_WARN (1 << 6) /* call syslog with LOG_WARNING */
91#define M_DEBUG (1 << 7)
92
93#define M_ERRNO (1 << 8) /* show errno description */
94
95#define M_NOMUTE (1 << 11) /* don't do mute processing */
96#define M_NOPREFIX (1 << 12) /* don't show date/time prefix */
97#define M_USAGE_SMALL (1 << 13) /* fatal options error, call usage_small */
98#define M_MSG_VIRT_OUT (1 << 14) /* output message through msg_status_output callback */
99#define M_OPTERR (1 << 15) /* print "Options error:" prefix */
100#define M_NOLF (1 << 16) /* don't print new line */
101#define M_NOIPREFIX (1 << 17) /* don't print instance prefix */
102
103/* flag combinations which are frequently used */
104#define M_ERR (M_FATAL | M_ERRNO)
105#define M_USAGE (M_USAGE_SMALL | M_NOPREFIX | M_OPTERR)
106#define M_CLIENT (M_MSG_VIRT_OUT | M_NOMUTE | M_NOIPREFIX)
107
108/*
109 * Mute levels are designed to avoid large numbers of
110 * mostly similar messages clogging the log file.
111 *
112 * A mute level of 0 is always printed.
113 */
114#define MUTE_LEVEL_SHIFT 24
115#define MUTE_LEVEL_MASK 0xFF
116
117#define ENCODE_MUTE_LEVEL(mute_level) (((mute_level) & MUTE_LEVEL_MASK) << MUTE_LEVEL_SHIFT)
118#define DECODE_MUTE_LEVEL(flags) (((flags) >> MUTE_LEVEL_SHIFT) & MUTE_LEVEL_MASK)
119
120/*
121 * log_level: verbosity level n (--verb n) must be >= log_level to print.
122 * mute_level: don't print more than n (--mute n) consecutive messages at
123 * a given mute level, or if 0 disable muting and print everything.
124 *
125 * Mask map:
126 * Bits 0-3: log level
127 * Bits 4-23: M_x flags
128 * Bits 24-31: mute level
129 */
130#define LOGLEV(log_level, mute_level, other) ((log_level) | ENCODE_MUTE_LEVEL(mute_level) | other)
131
132/*
133 * If compiler supports variable arguments in macros, define
134 * msg() as a macro for optimization win.
135 */
136
138bool dont_mute(unsigned int flags);
139
140/* Macro to ensure (and teach static analysis tools) we exit on fatal errors */
141#define EXIT_FATAL(flags) \
142 do \
143 { \
144 if ((flags) & M_FATAL) \
145 { \
146 _exit(1); \
147 } \
148 } while (false)
149
150#define msg(flags, ...) \
151 do \
152 { \
153 if (msg_test(flags)) \
154 { \
155 x_msg((flags), __VA_ARGS__); \
156 } \
157 EXIT_FATAL(flags); \
158 } while (false)
159#ifdef ENABLE_DEBUG
160#define dmsg(flags, ...) \
161 do \
162 { \
163 if (msg_test(flags)) \
164 { \
165 x_msg((flags), __VA_ARGS__); \
166 } \
167 EXIT_FATAL(flags); \
168 } while (false)
169#else
170#define dmsg(flags, ...)
171#endif
172
173void x_msg(const unsigned int flags, const char *format, ...)
174#ifdef __GNUC__
175#if __USE_MINGW_ANSI_STDIO
176 __attribute__((format(gnu_printf, 2, 3)))
177#else
178 __attribute__((format(__printf__, 2, 3)))
179#endif
180#endif
181 ; /* should be called via msg above */
182
183void x_msg_va(const unsigned int flags, const char *format, va_list arglist);
184
185/*
186 * Function prototypes
187 */
188
189void error_reset(void);
190
191/* route errors to stderr that would normally go to stdout */
192void errors_to_stderr(void);
193
194void set_suppress_timestamps(bool suppressed);
195
196void set_machine_readable_output(bool parsable);
197
198
199#define SDL_CONSTRAIN (1 << 0)
200bool set_debug_level(const int level, const unsigned int flags);
201
202bool set_mute_cutoff(const int cutoff);
203
204int get_debug_level(void);
205
206int get_mute_cutoff(void);
207
208const char *msg_flags_string(const unsigned int flags, struct gc_arena *gc);
209
210/*
211 * File to print messages to before syslog is opened.
212 */
213FILE *msg_fp(const unsigned int flags);
214
215/* Fatal logic errors */
216#ifndef ENABLE_SMALL
217#define ASSERT(x) \
218 do \
219 { \
220 if (!(x)) \
221 { \
222 assert_failed(__FILE__, __LINE__, #x); \
223 } \
224 } while (false)
225#else
226#define ASSERT(x) \
227 do \
228 { \
229 if (!(x)) \
230 { \
231 assert_failed(__FILE__, __LINE__, NULL); \
232 } \
233 } while (false)
234#endif
235
236#ifdef _MSC_VER
237__declspec(noreturn)
238#endif
239void
240assert_failed(const char *filename, int line, const char *condition)
241#ifndef _MSC_VER
242 __attribute__((__noreturn__))
243#endif
244 ;
245
246/* Poor-man's static_assert() for when not supplied by assert.h, taken from
247 * Linux's sys/cdefs.h under GPLv2 */
248#ifndef static_assert
249#define static_assert(expr, diagnostic) \
250 extern int (*__OpenVPN_static_assert_function( \
251 void))[!!sizeof(struct { int __error_if_negative : (expr) ? 2 : -1; })]
252#endif
253
254/* Inline functions */
255
256static inline bool
257check_debug_level(unsigned int level)
258{
259 return (level & M_DEBUG_LEVEL) <= x_debug_level;
260}
261
263static inline bool
264msg_test(unsigned int flags)
265{
266 return check_debug_level(flags) && dont_mute(flags);
267}
268
269/* Call if we forked */
270void msg_forked(void);
271
272/* syslog output */
273
274void open_syslog(const char *pgmname, bool stdio_to_null);
275
276void close_syslog(void);
277
278/* log file output */
279void redirect_stdout_stderr(const char *file, bool append);
280
281#ifdef _WIN32
282/* get original stderr fd, even if redirected by --log/--log-append */
283int get_orig_stderr(void);
284
285#endif
286
287/* exit program */
288void openvpn_exit(const int status);
289
290/* exit program on out of memory error */
291void out_of_memory(void);
292
293/*
294 * Check the return status of read/write routines.
295 */
296
297struct link_socket;
298struct tuntap;
299
300extern unsigned int x_cs_info_level;
301extern unsigned int x_cs_verbose_level;
302extern unsigned int x_cs_err_delay_ms;
303
304void reset_check_status(void);
305
306void set_check_status(unsigned int info_level, unsigned int verbose_level);
307
308void x_check_status(int status, const char *description, struct link_socket *sock,
309 struct tuntap *tt);
310
311static inline void
312check_status(int status, const char *description, struct link_socket *sock, struct tuntap *tt)
313{
315 {
316 x_check_status(status, description, sock, tt);
317 }
318}
319
320static inline void
321set_check_status_error_delay(unsigned int milliseconds)
322{
323 x_cs_err_delay_ms = milliseconds;
324}
325
326/*
327 * In multiclient mode, put a client-specific prefix
328 * before each message.
329 *
330 * TODO: x_msg_prefix should be thread-local
331 */
332
333extern const char *x_msg_prefix;
334
335static inline void
336msg_set_prefix(const char *prefix)
337{
338 x_msg_prefix = prefix;
339}
340
341static inline const char *
343{
344 return x_msg_prefix;
345}
346
347/*
348 * Allow MSG to be redirected through a virtual_output object
349 */
350
351struct virtual_output;
352
353extern const struct virtual_output *x_msg_virtual_output;
354
355static inline void
357{
359}
360
361static inline const struct virtual_output *
366
367/*
368 * Return true if this is a system error
369 * which can be safely ignored.
370 */
371static inline bool
372ignore_sys_error(const int err, bool crt_error)
373{
374#ifdef _WIN32
375 if (!crt_error && ((err == WSAEWOULDBLOCK || err == WSAEINVAL)))
376 {
377 return true;
378 }
379#else
380 crt_error = true;
381#endif
382
383 /* I/O operation pending */
384 if (crt_error && (err == EAGAIN))
385 {
386 return true;
387 }
388
389#if 0 /* if enabled, suppress ENOBUFS errors */
390#ifdef ENOBUFS
391 /* No buffer space available */
392 if (err == ENOBUFS)
393 {
394 return true;
395 }
396#endif
397#endif
398
399 return false;
400}
401
403static inline unsigned int
404nonfatal(const unsigned int err)
405{
406 return err & M_FATAL ? (err ^ M_FATAL) | M_NONFATAL : err;
407}
408
409static inline int
411{
412 int err = 0;
413 *crt_error = false;
414#ifdef _WIN32
415 err = GetLastError();
416 if (err == ERROR_SUCCESS)
417 {
418 /* error is likely C runtime */
419 *crt_error = true;
420 err = errno;
421 }
422#else /* ifdef _WIN32 */
423 *crt_error = true;
424 err = errno;
425#endif
426 return err;
427}
428
429#include "errlevel.h"
430
431#endif /* ifndef ERROR_H */
static SERVICE_STATUS status
Definition interactive.c:51
static bool msg_test(unsigned int flags)
Return true if flags represent an enabled, not muted log level.
Definition error.h:264
void error_reset(void)
Definition error.c:160
unsigned int x_debug_level
Definition error.c:51
const struct virtual_output * x_msg_virtual_output
Definition error.c:698
static void msg_set_prefix(const char *prefix)
Definition error.h:336
void out_of_memory(void)
Definition error.c:440
void errors_to_stderr(void)
Definition error.c:184
void open_syslog(const char *pgmname, bool stdio_to_null)
Definition error.c:447
static unsigned int nonfatal(const unsigned int err)
Convert fatal errors to nonfatal, don't touch other errors.
Definition error.h:404
void close_syslog(void)
Definition error.c:472
unsigned int x_cs_info_level
Definition error.c:602
#define M_DEBUG_LEVEL
Definition error.h:86
void assert_failed(const char *filename, int line, const char *condition) __attribute__((__noreturn__))
Definition error.c:422
static void msg_set_virtual_output(const struct virtual_output *vo)
Definition error.h:356
static const char * msg_get_prefix(void)
Definition error.h:342
bool dont_mute(unsigned int flags)
Check muting filter.
Definition error.c:388
const char * strerror_win32(DWORD errnum, struct gc_arena *gc)
Definition error.c:782
void msg_forked(void)
Definition error.c:98
const char * x_msg_prefix
Definition error.c:692
int x_msg_line_num
Definition error.c:214
#define M_FATAL
Definition error.h:88
void x_check_status(int status, const char *description, struct link_socket *sock, struct tuntap *tt)
Definition error.c:629
void x_msg(const unsigned int flags, const char *format,...)
Definition error.c:217
int get_debug_level(void)
Definition error.c:136
static bool check_debug_level(unsigned int level)
Definition error.h:257
static void set_check_status_error_delay(unsigned int milliseconds)
Definition error.h:321
int get_orig_stderr(void)
Definition error.c:489
void redirect_stdout_stderr(const char *file, bool append)
Definition error.c:496
void x_msg_va(const unsigned int flags, const char *format, va_list arglist)
Definition error.c:238
#define M_NONFATAL
Definition error.h:89
bool set_mute_cutoff(const int cutoff)
Definition error.c:122
static bool ignore_sys_error(const int err, bool crt_error)
Definition error.h:372
const char * msg_flags_string(const unsigned int flags, struct gc_arena *gc)
Definition error.c:753
void set_check_status(unsigned int info_level, unsigned int verbose_level)
Definition error.c:614
static int openvpn_errno_maybe_crt(bool *crt_error)
Definition error.h:410
unsigned int x_cs_verbose_level
Definition error.c:603
FILE * msg_fp(const unsigned int flags)
Definition error.c:193
void openvpn_exit(const int status)
Definition error.c:705
void reset_check_status(void)
Definition error.c:607
static void check_status(int status, const char *description, struct link_socket *sock, struct tuntap *tt)
Definition error.h:312
int get_mute_cutoff(void)
Definition error.c:142
void set_suppress_timestamps(bool suppressed)
Definition error.c:148
void set_machine_readable_output(bool parsable)
Definition error.c:154
static const struct virtual_output * msg_get_virtual_output(void)
Definition error.h:362
bool set_debug_level(const int level, const unsigned int flags)
Definition error.c:104
unsigned int x_cs_err_delay_ms
Definition error.c:604
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:154