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#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/* Inline functions */
249
250static inline bool
252{
253 return (level & M_DEBUG_LEVEL) <= x_debug_level;
254}
255
257static inline bool
259{
260 return check_debug_level(flags) && dont_mute(flags);
261}
262
263/* Call if we forked */
264void msg_forked(void);
265
266/* syslog output */
267
268void open_syslog(const char *pgmname, bool stdio_to_null);
269
270void close_syslog(void);
271
272/* log file output */
273void redirect_stdout_stderr(const char *file, bool append);
274
275#ifdef _WIN32
276/* get original stderr fd, even if redirected by --log/--log-append */
277int get_orig_stderr(void);
278
279#endif
280
281/* exit program */
282void openvpn_exit(const int status);
283
284/* exit program on out of memory error */
285void out_of_memory(void);
286
287/*
288 * Check the return status of read/write routines.
289 */
290
291struct link_socket;
292struct tuntap;
293
294extern unsigned int x_cs_info_level;
295extern unsigned int x_cs_verbose_level;
296extern unsigned int x_cs_err_delay_ms;
297
298void reset_check_status(void);
299
300void set_check_status(unsigned int info_level, unsigned int verbose_level);
301
302void x_check_status(ssize_t status, const char *description, struct link_socket *sock,
303 struct tuntap *tt);
304
305static inline void
306check_status(ssize_t status, const char *description, struct link_socket *sock, struct tuntap *tt)
307{
309 {
310 x_check_status(status, description, sock, tt);
311 }
312}
313
314static inline void
315set_check_status_error_delay(unsigned int milliseconds)
316{
317 x_cs_err_delay_ms = milliseconds;
318}
319
320/*
321 * In multiclient mode, put a client-specific prefix
322 * before each message.
323 *
324 * TODO: x_msg_prefix should be thread-local
325 */
326
327extern const char *x_msg_prefix;
328
329static inline void
330msg_set_prefix(const char *prefix)
331{
332 x_msg_prefix = prefix;
333}
334
335static inline const char *
337{
338 return x_msg_prefix;
339}
340
341/*
342 * Allow MSG to be redirected through a virtual_output object
343 */
344
345struct virtual_output;
346
347extern const struct virtual_output *x_msg_virtual_output;
348
349static inline void
351{
353}
354
355static inline const struct virtual_output *
360
361/*
362 * Return true if this is a system error
363 * which can be safely ignored.
364 */
365static inline bool
366ignore_sys_error(const int err, bool crt_error)
367{
368#ifdef _WIN32
369 if (!crt_error && ((err == WSAEWOULDBLOCK || err == WSAEINVAL)))
370 {
371 return true;
372 }
373#else
374 crt_error = true;
375#endif
376
377 /* I/O operation pending */
378 if (crt_error && (err == EAGAIN))
379 {
380 return true;
381 }
382
383#if 0 /* if enabled, suppress ENOBUFS errors */
384#ifdef ENOBUFS
385 /* No buffer space available */
386 if (err == ENOBUFS)
387 {
388 return true;
389 }
390#endif
391#endif
392
393 return false;
394}
395
397static inline msglvl_t
399{
400 return err & M_FATAL ? (err ^ M_FATAL) | M_NONFATAL : err;
401}
402
403static inline int
405{
406 int err = 0;
407 *crt_error = false;
408#ifdef _WIN32
409 err = GetLastError();
410 if (err == ERROR_SUCCESS)
411 {
412 /* error is likely C runtime */
413 *crt_error = true;
414 err = errno;
415 }
416#else /* ifdef _WIN32 */
417 *crt_error = true;
418 err = errno;
419#endif
420 return err;
421}
422
423#include "errlevel.h"
424
425#endif /* ifndef ERROR_H */
static SERVICE_STATUS status
Definition interactive.c:51
void x_check_status(ssize_t status, const char *description, struct link_socket *sock, struct tuntap *tt)
Definition error.c:624
void error_reset(void)
Definition error.c:155
const struct virtual_output * x_msg_virtual_output
Definition error.c:693
static bool check_debug_level(msglvl_t level)
Definition error.h:251
static void msg_set_prefix(const char *prefix)
Definition error.h:330
void out_of_memory(void)
Definition error.c:435
msglvl_t get_debug_level(void)
Definition error.c:131
void errors_to_stderr(void)
Definition error.c:179
void open_syslog(const char *pgmname, bool stdio_to_null)
Definition error.c:442
void close_syslog(void)
Definition error.c:467
static msglvl_t nonfatal(const msglvl_t err)
Convert fatal errors to nonfatal, don't touch other errors.
Definition error.h:398
unsigned int x_cs_info_level
Definition error.c:597
#define M_DEBUG_LEVEL
Definition error.h:88
void x_msg(const msglvl_t flags, const char *format,...)
Definition error.c:212
void assert_failed(const char *filename, int line, const char *condition) __attribute__((__noreturn__))
Definition error.c:417
msglvl_t x_debug_level
Definition error.c:48
static void msg_set_virtual_output(const struct virtual_output *vo)
Definition error.h:350
static const char * msg_get_prefix(void)
Definition error.h:336
const char * strerror_win32(DWORD errnum, struct gc_arena *gc)
Definition error.c:768
void msg_forked(void)
Definition error.c:95
static bool msg_test(msglvl_t flags)
Return true if flags represent an enabled, not muted log level.
Definition error.h:258
const char * x_msg_prefix
Definition error.c:687
int x_msg_line_num
Definition error.c:209
#define M_FATAL
Definition error.h:90
bool dont_mute(msglvl_t flags)
Check muting filter.
Definition error.c:383
static void set_check_status_error_delay(unsigned int milliseconds)
Definition error.h:315
int get_orig_stderr(void)
Definition error.c:484
static void check_status(ssize_t status, const char *description, struct link_socket *sock, struct tuntap *tt)
Definition error.h:306
void redirect_stdout_stderr(const char *file, bool append)
Definition error.c:491
#define M_NONFATAL
Definition error.h:91
bool set_mute_cutoff(const int cutoff)
Definition error.c:117
static bool ignore_sys_error(const int err, bool crt_error)
Definition error.h:366
void set_check_status(unsigned int info_level, unsigned int verbose_level)
Definition error.c:609
static int openvpn_errno_maybe_crt(bool *crt_error)
Definition error.h:404
unsigned int x_cs_verbose_level
Definition error.c:598
void openvpn_exit(const int status)
Definition error.c:700
unsigned int msglvl_t
Definition error.h:77
void reset_check_status(void)
Definition error.c:602
void x_msg_va(const msglvl_t flags, const char *format, va_list arglist)
Definition error.c:233
int get_mute_cutoff(void)
Definition error.c:137
void set_suppress_timestamps(bool suppressed)
Definition error.c:143
void set_machine_readable_output(bool parsable)
Definition error.c:149
FILE * msg_fp(const msglvl_t flags)
Definition error.c:188
static const struct virtual_output * msg_get_virtual_output(void)
Definition error.h:356
bool set_debug_level(const int level, const unsigned int flags)
Definition error.c:101
const char * msg_flags_string(const msglvl_t flags, struct gc_arena *gc)
Definition error.c:739
unsigned int x_cs_err_delay_ms
Definition error.c:599
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