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