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-2026 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/* We have DMSG_ALWAYS_AVAILABLE here to able to silence unused warnings for
162 * cppcheck */
163#if !defined(ENABLE_SMALL) || defined(DMSG_ALWAYS_AVAILABLE)
164#define dmsg(flags, ...) \
165 do \
166 { \
167 if (msg_test(flags)) \
168 { \
169 x_msg((flags), __VA_ARGS__); \
170 } \
171 EXIT_FATAL(flags); \
172 } while (false)
173#else
174#define dmsg(flags, ...)
175#endif
176
177void x_msg(const msglvl_t flags, const char *format, ...)
178#ifdef __GNUC__
179#if __USE_MINGW_ANSI_STDIO
180 __attribute__((format(gnu_printf, 2, 3)))
181#else
182 __attribute__((format(__printf__, 2, 3)))
183#endif
184#endif
185 ; /* should be called via msg above */
186
187void x_msg_va(const msglvl_t flags, const char *format, va_list arglist);
188
189/*
190 * Function prototypes
191 */
192
193void error_reset(void);
194
195/* route errors to stderr that would normally go to stdout */
196void errors_to_stderr(void);
197
198void set_suppress_timestamps(bool suppressed);
199
200void set_machine_readable_output(bool parsable);
201
202
203#define SDL_CONSTRAIN (1 << 0)
204bool set_debug_level(const int level, const unsigned int flags);
205
206bool set_mute_cutoff(const int cutoff);
207
209
210int get_mute_cutoff(void);
211
212const char *msg_flags_string(const msglvl_t flags, struct gc_arena *gc);
213
214/*
215 * File to print messages to before syslog is opened.
216 */
217FILE *msg_fp(const msglvl_t flags);
218
219/* Fatal logic errors */
220#ifndef ENABLE_SMALL
221#define ASSERT(x) \
222 do \
223 { \
224 if (!(x)) \
225 { \
226 assert_failed(__FILE__, __LINE__, #x); \
227 } \
228 } while (false)
229#else
230#define ASSERT(x) \
231 do \
232 { \
233 if (!(x)) \
234 { \
235 assert_failed(__FILE__, __LINE__, NULL); \
236 } \
237 } while (false)
238#endif
239
240#ifdef _MSC_VER
241__declspec(noreturn)
242#endif
243void
244assert_failed(const char *filename, int line, const char *condition)
245#ifndef _MSC_VER
246 __attribute__((__noreturn__))
247#endif
248 ;
249
250/* Inline functions */
251
252static inline bool
254{
255 return (level & M_DEBUG_LEVEL) <= x_debug_level;
256}
257
259static inline bool
261{
262 return check_debug_level(flags) && dont_mute(flags);
263}
264
265#if PORT_SHARE
266/* Call if we forked */
267void msg_forked(void);
268#endif
269
270/* syslog output */
271
272void open_syslog(const char *pgmname, bool stdio_to_null);
273
274void close_syslog(void);
275
276/* log file output */
277void redirect_stdout_stderr(const char *file, bool append);
278
279#ifdef _WIN32
280/* get original stderr fd, even if redirected by --log/--log-append */
281int get_orig_stderr(void);
282
283#endif
284
285/* exit program */
286void openvpn_exit(const int status);
287
288/* exit program on out of memory error */
289void out_of_memory(void);
290
291/*
292 * Check the return status of read/write routines.
293 */
294
295struct link_socket;
296struct tuntap;
297
298extern unsigned int x_cs_info_level;
299extern unsigned int x_cs_verbose_level;
300extern unsigned int x_cs_err_delay_ms;
301
302void reset_check_status(void);
303
304void set_check_status(unsigned int info_level, unsigned int verbose_level);
305
306void x_check_status(ssize_t status, const char *description, struct link_socket *sock,
307 struct tuntap *tt);
308
309static inline void
310check_status(ssize_t status, const char *description, struct link_socket *sock, struct tuntap *tt)
311{
313 {
314 x_check_status(status, description, sock, tt);
315 }
316}
317
318static inline void
319set_check_status_error_delay(unsigned int milliseconds)
320{
321 x_cs_err_delay_ms = milliseconds;
322}
323
324/*
325 * In multiclient mode, put a client-specific prefix
326 * before each message.
327 *
328 * TODO: x_msg_prefix should be thread-local
329 */
330
331extern const char *x_msg_prefix;
332
333static inline void
334msg_set_prefix(const char *prefix)
335{
336 x_msg_prefix = prefix;
337}
338
339static inline const char *
341{
342 return x_msg_prefix;
343}
344
345/*
346 * Allow MSG to be redirected through a virtual_output object
347 */
348
349struct virtual_output;
350
351extern const struct virtual_output *x_msg_virtual_output;
352
353static inline void
355{
357}
358
359static inline const struct virtual_output *
364
365/*
366 * Return true if this is a system error
367 * which can be safely ignored.
368 */
369static inline bool
370ignore_sys_error(const int err, bool crt_error)
371{
372#ifdef _WIN32
373 if (!crt_error && ((err == WSAEWOULDBLOCK || err == WSAEINVAL)))
374 {
375 return true;
376 }
377#else
378 crt_error = true;
379#endif
380
381 /* I/O operation pending */
382 if (crt_error && (err == EAGAIN))
383 {
384 return true;
385 }
386
387#if 0 /* if enabled, suppress ENOBUFS errors */
388#ifdef ENOBUFS
389 /* No buffer space available */
390 if (err == ENOBUFS)
391 {
392 return true;
393 }
394#endif
395#endif
396
397 return false;
398}
399
400#if defined(ENABLE_CRYPTO_OPENSSL)
402static inline msglvl_t
404{
405 return (err & M_FATAL) ? (err ^ M_FATAL) | M_NONFATAL : err;
406}
407#endif
408
409static inline int
411{
412 int err = 0;
413#ifdef _WIN32
414 *crt_error = false;
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:52
const struct virtual_output * x_msg_virtual_output
Definition error.c:702
unsigned int x_cs_info_level
Definition error.c:599
msglvl_t x_debug_level
Definition error.c:48
const char * x_msg_prefix
Definition error.c:696
int x_msg_line_num
Definition error.c:211
unsigned int x_cs_verbose_level
Definition error.c:600
unsigned int x_cs_err_delay_ms
Definition error.c:601
void x_check_status(ssize_t status, const char *description, struct link_socket *sock, struct tuntap *tt)
Definition error.c:626
void error_reset(void)
Definition error.c:157
static bool check_debug_level(msglvl_t level)
Definition error.h:253
static void msg_set_prefix(const char *prefix)
Definition error.h:334
void out_of_memory(void)
Definition error.c:437
msglvl_t get_debug_level(void)
Definition error.c:133
void errors_to_stderr(void)
Definition error.c:181
void open_syslog(const char *pgmname, bool stdio_to_null)
Definition error.c:444
void close_syslog(void)
Definition error.c:469
static msglvl_t nonfatal(const msglvl_t err)
Convert fatal errors to nonfatal, don't touch other errors.
Definition error.h:403
#define M_DEBUG_LEVEL
Definition error.h:88
void x_msg(const msglvl_t flags, const char *format,...)
Definition error.c:214
void assert_failed(const char *filename, int line, const char *condition) __attribute__((__noreturn__))
Definition error.c:419
static void msg_set_virtual_output(const struct virtual_output *vo)
Definition error.h:354
static const char * msg_get_prefix(void)
Definition error.h:340
const char * strerror_win32(DWORD errnum, struct gc_arena *gc)
Definition error.c:777
static bool msg_test(msglvl_t flags)
Return true if flags represent an enabled, not muted log level.
Definition error.h:260
#define M_FATAL
Definition error.h:90
bool dont_mute(msglvl_t flags)
Check muting filter.
Definition error.c:385
static void set_check_status_error_delay(unsigned int milliseconds)
Definition error.h:319
int get_orig_stderr(void)
Definition error.c:486
static void check_status(ssize_t status, const char *description, struct link_socket *sock, struct tuntap *tt)
Definition error.h:310
void redirect_stdout_stderr(const char *file, bool append)
Definition error.c:493
#define M_NONFATAL
Definition error.h:91
bool set_mute_cutoff(const int cutoff)
Definition error.c:119
static bool ignore_sys_error(const int err, bool crt_error)
Definition error.h:370
void set_check_status(unsigned int info_level, unsigned int verbose_level)
Definition error.c:611
static int openvpn_errno_maybe_crt(bool *crt_error)
Definition error.h:410
void openvpn_exit(const int status)
Definition error.c:709
unsigned int msglvl_t
Definition error.h:77
void reset_check_status(void)
Definition error.c:604
void x_msg_va(const msglvl_t flags, const char *format, va_list arglist)
Definition error.c:235
int get_mute_cutoff(void)
Definition error.c:139
void set_suppress_timestamps(bool suppressed)
Definition error.c:145
void set_machine_readable_output(bool parsable)
Definition error.c:151
FILE * msg_fp(const msglvl_t flags)
Definition error.c:190
static const struct virtual_output * msg_get_virtual_output(void)
Definition error.h:360
bool set_debug_level(const int level, const unsigned int flags)
Definition error.c:103
const char * msg_flags_string(const msglvl_t flags, struct gc_arena *gc)
Definition error.c:748
Garbage collection arena used to keep track of dynamically allocated memory.
Definition buffer.h:127
Definition tun.h:181
__attribute__((unused))
Definition test.c:42
struct gc_arena gc
Definition test_ssl.c:122