OpenVPN
error.c
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#ifdef HAVE_CONFIG_H
24#include "config.h"
25#endif
26
27#include "syshead.h"
28
29#include "error.h"
30#include "buffer.h"
31#include "init.h"
32#include "misc.h"
33#include "win32.h"
34#include "socket.h"
35#include "tun.h"
36#include "otime.h"
37#include "status.h"
38#include "integer.h"
39#include "ps.h"
40
41#if SYSLOG_CAPABILITY
42#ifndef LOG_OPENVPN
43#define LOG_OPENVPN LOG_DAEMON
44#endif
45#endif
46
47/* Globals */
49
50/* Mute state */
51static int mute_cutoff; /* GLOBAL */
52static int mute_count; /* GLOBAL */
53static msglvl_t mute_category; /* GLOBAL */
54
55/*
56 * Output mode priorities are as follows:
57 *
58 * (1) --log-x overrides everything
59 * (2) syslog is used if --daemon is defined and not --log-x
60 * (3) if OPENVPN_DEBUG_COMMAND_LINE is defined, output
61 * to constant logfile name.
62 * (4) Output to stdout.
63 */
64
65/* If true, indicates that stdin/stdout/stderr
66 * have been redirected due to --log */
67static bool std_redir; /* GLOBAL */
68
69/* Should messages be written to the syslog? */
70static bool use_syslog; /* GLOBAL */
71
72/* Should stdout/stderr be be parsable and always be prefixed with time
73 * and message flags */
74static bool machine_readable_output; /* GLOBAL */
75
76/* Should timestamps be included on messages to stdout/stderr? */
77static bool suppress_timestamps; /* GLOBAL */
78
79/* The program name passed to syslog */
80#if SYSLOG_CAPABILITY
81static char *pgmname_syslog; /* GLOBAL */
82#endif
83
84/* If non-null, messages should be written here (used for debugging only) */
85static FILE *msgfp; /* GLOBAL */
86
87/* If true, we forked from main OpenVPN process */
88static bool forked; /* GLOBAL */
89
90/* our default output targets */
91static FILE *default_out; /* GLOBAL */
92static FILE *default_err; /* GLOBAL */
93
94void
96{
97 forked = true;
98}
99
100#if defined(__GNUC__) || defined(__clang__)
101#pragma GCC diagnostic push
102#pragma GCC diagnostic ignored "-Wsign-compare"
103#endif
104
105bool
106set_debug_level(const int level, const unsigned int flags)
107{
108 if (level >= 0 && level <= M_DEBUG_LEVEL)
109 {
110 x_debug_level = (msglvl_t)level;
111 return true;
112 }
113 else if (flags & SDL_CONSTRAIN)
114 {
116 return true;
117 }
118 return false;
119}
120
121#if defined(__GNUC__) || defined(__clang__)
122#pragma GCC diagnostic pop
123#endif
124
125bool
126set_mute_cutoff(const int cutoff)
127{
128 if (cutoff >= 0)
129 {
130 mute_cutoff = cutoff;
131 return true;
132 }
133 else
134 {
135 return false;
136 }
137}
138
141{
142 return x_debug_level;
143}
144
145int
147{
148 return mute_cutoff;
149}
150
151void
153{
154 suppress_timestamps = suppressed;
155}
156
157void
159{
160 machine_readable_output = parsable;
161}
162
163void
165{
166 use_syslog = std_redir = false;
167 suppress_timestamps = false;
169 x_debug_level = 1;
170 mute_cutoff = 0;
171 mute_count = 0;
172 mute_category = 0;
175
176#ifdef OPENVPN_DEBUG_COMMAND_LINE
177 msgfp = fopen(OPENVPN_DEBUG_FILE, "w");
178 if (!msgfp)
179 {
181 }
182#else
183 msgfp = NULL;
184#endif
185}
186
187void
192
193/*
194 * Return a file to print messages to before syslog is opened.
195 */
196FILE *
197msg_fp(const msglvl_t flags)
198{
199 FILE *fp = msgfp;
200 if (!fp)
201 {
202 fp = (flags & (M_FATAL | M_USAGE_SMALL)) ? default_err : default_out;
203 }
204 if (!fp)
205 {
207 }
208 return fp;
209}
210
211#define SWAP \
212 { \
213 tmp = m1; \
214 m1 = m2; \
215 m2 = tmp; \
216 }
217
218int x_msg_line_num; /* GLOBAL */
219
220void
221x_msg(const msglvl_t flags, const char *format, ...)
222{
223 va_list arglist;
224 va_start(arglist, format);
225 x_msg_va(flags, format, arglist);
226 va_end(arglist);
227}
228
229static const char *
230openvpn_strerror(int err, bool crt_error, struct gc_arena *gc)
231{
232#ifdef _WIN32
233 if (!crt_error)
234 {
235 return strerror_win32(err, gc);
236 }
237#endif
238 return strerror(err);
239}
240
241void
242x_msg_va(const msglvl_t flags, const char *format, va_list arglist)
243{
244 struct gc_arena gc;
245#if SYSLOG_CAPABILITY
246 int level;
247#endif
248 char *m1;
249 char *m2;
250 char *tmp;
251 int e;
252 const char *prefix;
253 const char *prefix_sep;
254
255 void usage_small(void);
256
257 /* the macro has checked this otherwise */
258 if (!msg_test(flags))
259 {
260 return;
261 }
262
263 bool crt_error = false;
264 e = openvpn_errno_maybe_crt(&crt_error);
265
266 /*
267 * Apply muting filter.
268 */
269 /* the macro has checked this otherwise */
270 if (!dont_mute(flags))
271 {
272 return;
273 }
274
275 gc_init(&gc);
276
277 m1 = (char *)gc_malloc(ERR_BUF_SIZE, false, &gc);
278 m2 = (char *)gc_malloc(ERR_BUF_SIZE, false, &gc);
279
280 vsnprintf(m1, ERR_BUF_SIZE, format, arglist);
281 m1[ERR_BUF_SIZE - 1] = 0; /* windows vsnprintf needs this */
282
283 if ((flags & M_ERRNO) && e)
284 {
285 snprintf(m2, ERR_BUF_SIZE, "%s: %s (errno=%d)", m1, openvpn_strerror(e, crt_error, &gc), e);
286 SWAP;
287 }
288
289 if (flags & M_OPTERR)
290 {
291 snprintf(m2, ERR_BUF_SIZE, "Options error: %s", m1);
292 SWAP;
293 }
294
295#if SYSLOG_CAPABILITY
296 if (flags & (M_FATAL | M_NONFATAL | M_USAGE_SMALL))
297 {
298 level = LOG_ERR;
299 }
300 else if (flags & M_WARN)
301 {
302 level = LOG_WARNING;
303 }
304 else
305 {
306 level = LOG_NOTICE;
307 }
308#endif
309
310 /* set up client prefix */
311 if (flags & M_NOIPREFIX)
312 {
313 prefix = NULL;
314 }
315 else
316 {
317 prefix = msg_get_prefix();
318 }
319 prefix_sep = " ";
320 if (!prefix)
321 {
322 prefix_sep = prefix = "";
323 }
324
325 /* virtual output capability used to copy output to management subsystem */
326 if (!forked)
327 {
328 const struct virtual_output *vo = msg_get_virtual_output();
329 if (vo)
330 {
331 snprintf(m2, ERR_BUF_SIZE, "%s%s%s", prefix, prefix_sep, m1);
332 virtual_output_print(vo, flags, m2);
333 }
334 }
335
336 if (!(flags & M_MSG_VIRT_OUT))
337 {
338 if (use_syslog && !std_redir && !forked)
339 {
340#if SYSLOG_CAPABILITY
341 syslog(level, "%s%s%s", prefix, prefix_sep, m1);
342#endif
343 }
344 else
345 {
346 FILE *fp = msg_fp(flags);
347 const bool show_usec = check_debug_level(DEBUG_LEVEL_USEC_TIME);
348
350 {
351 struct timeval tv;
352 gettimeofday(&tv, NULL);
353
354 fprintf(fp, "%" PRIi64 ".%06ld %x %s%s%s%s", (int64_t)tv.tv_sec, (long)tv.tv_usec,
355 flags, prefix, prefix_sep, m1, "\n");
356 }
357 else if ((flags & M_NOPREFIX) || suppress_timestamps)
358 {
359 fprintf(fp, "%s%s%s%s", prefix, prefix_sep, m1, (flags & M_NOLF) ? "" : "\n");
360 }
361 else
362 {
363 fprintf(fp, "%s %s%s%s%s", time_string(0, 0, show_usec, &gc), prefix, prefix_sep,
364 m1, (flags & M_NOLF) ? "" : "\n");
365 }
366 fflush(fp);
368 }
369 }
370
371 if (flags & M_FATAL)
372 {
373 msg(M_INFO, "Exiting due to fatal error");
374 }
375
376 if (flags & M_FATAL)
377 {
378 openvpn_exit(OPENVPN_EXIT_STATUS_ERROR); /* exit point */
379 }
380 if (flags & M_USAGE_SMALL)
381 {
382 usage_small();
383 }
384
385 gc_free(&gc);
386}
387
388/*
389 * Apply muting filter.
390 */
391bool
393{
394 bool ret = true;
395 if (mute_cutoff > 0 && !(flags & M_NOMUTE))
396 {
397 const msglvl_t mute_level = DECODE_MUTE_LEVEL(flags);
398 if (mute_level == mute_category)
399 {
400 if (mute_count == mute_cutoff)
401 {
402 msg(M_INFO | M_NOMUTE, "NOTE: --mute triggered...");
403 }
404 if (++mute_count > mute_cutoff)
405 {
406 ret = false;
407 }
408 }
409 else
410 {
411 const int suppressed = mute_count - mute_cutoff;
412 if (suppressed > 0)
413 {
415 "%d variation(s) on previous %d message(s) suppressed by --mute", suppressed,
417 }
418 mute_count = 1;
419 mute_category = mute_level;
420 }
421 }
422 return ret;
423}
424
425void
426assert_failed(const char *filename, int line, const char *condition)
427{
428 if (condition)
429 {
430 msg(M_FATAL, "Assertion failed at %s:%d (%s)", filename, line, condition);
431 }
432 else
433 {
434 msg(M_FATAL, "Assertion failed at %s:%d", filename, line);
435 }
436 _exit(1);
437}
438
439/*
440 * Fail memory allocation. Don't use msg() because it tries
441 * to allocate memory as part of its operation.
442 */
443void
445{
446 fprintf(stderr, PACKAGE_NAME ": Out of Memory\n");
447 exit(1);
448}
449
450void
451open_syslog(const char *pgmname, bool stdio_to_null)
452{
453#if SYSLOG_CAPABILITY
454 if (!msgfp && !std_redir)
455 {
456 if (!use_syslog)
457 {
458 pgmname_syslog = string_alloc(pgmname ? pgmname : PACKAGE, NULL);
459 openlog(pgmname_syslog, LOG_PID, LOG_OPENVPN);
460 use_syslog = true;
461
462 /* Better idea: somehow pipe stdout/stderr output to msg() */
463 if (stdio_to_null)
464 {
466 }
467 }
468 }
469#else /* if SYSLOG_CAPABILITY */
470 msg(M_WARN,
471 "Warning on use of --daemon: this operating system lacks daemon logging features, therefore when I become a daemon, I won't be able to log status or error messages");
472#endif
473}
474
475void
477{
478#if SYSLOG_CAPABILITY
479 if (use_syslog)
480 {
481 closelog();
482 use_syslog = false;
483 free(pgmname_syslog);
484 pgmname_syslog = NULL;
485 }
486#endif
487}
488
489#ifdef _WIN32
490static int orig_stderr;
491
492int
494{
495 return orig_stderr ? orig_stderr : _fileno(stderr);
496}
497#endif
498
499void
500redirect_stdout_stderr(const char *file, bool append)
501{
502#if defined(_WIN32)
503 if (!std_redir)
504 {
505 struct gc_arena gc = gc_new();
506 HANDLE log_handle;
507 int log_fd;
508
509 SECURITY_ATTRIBUTES saAttr;
510 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
511 saAttr.bInheritHandle = TRUE;
512 saAttr.lpSecurityDescriptor = NULL;
513
514 log_handle = CreateFileW(wide_string(file, &gc), GENERIC_WRITE, FILE_SHARE_READ, &saAttr,
515 append ? OPEN_ALWAYS : CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
516
517 gc_free(&gc);
518
519 if (log_handle == INVALID_HANDLE_VALUE)
520 {
521 msg(M_WARN | M_ERRNO, "Warning: cannot open --log file: %s", file);
522 return;
523 }
524
525 /* append to logfile? */
526 if (append)
527 {
528 if (SetFilePointer(log_handle, 0, NULL, FILE_END) == INVALID_SET_FILE_POINTER)
529 {
530 msg(M_ERR, "Error: cannot seek to end of --log file: %s", file);
531 }
532 }
533
534 /* save original stderr for password prompts */
535 orig_stderr = _dup(_fileno(stderr));
536 if (orig_stderr == -1)
537 {
539 "Warning: cannot duplicate stderr, password prompts will appear in log file instead of console.");
540 orig_stderr = _fileno(stderr);
541 }
542
543 /* direct stdout/stderr to point to log_handle */
544 log_fd = _open_osfhandle((intptr_t)log_handle, _O_TEXT);
545 if (log_fd == -1)
546 {
547 msg(M_ERR, "Error: --log redirect failed due to _open_osfhandle failure");
548 }
549
550 /* open log_handle as FILE stream */
551 ASSERT(msgfp == NULL);
552 msgfp = _fdopen(log_fd, "wt");
553 if (msgfp == NULL)
554 {
555 msg(M_ERR, "Error: --log redirect failed due to _fdopen");
556 }
557
558 /* redirect C-library stdout/stderr to log file */
559 if (_dup2(log_fd, 1) == -1 || _dup2(log_fd, 2) == -1)
560 {
561 msg(M_WARN, "Error: --log redirect of stdout/stderr failed");
562 }
563
564 std_redir = true;
565 }
566#elif defined(HAVE_DUP2)
567 if (!std_redir)
568 {
569 int out = open(file, O_CREAT | O_WRONLY | (append ? O_APPEND : O_TRUNC), S_IRUSR | S_IWUSR);
570
571 if (out < 0)
572 {
573 msg(M_WARN | M_ERRNO, "Warning: Error redirecting stdout/stderr to --log file: %s",
574 file);
575 return;
576 }
577
578 if (dup2(out, 1) == -1)
579 {
580 msg(M_ERR, "--log file redirection error on stdout");
581 }
582 if (dup2(out, 2) == -1)
583 {
584 msg(M_ERR, "--log file redirection error on stderr");
585 }
586
587 if (out > 2)
588 {
589 close(out);
590 }
591
592 std_redir = true;
593 }
594
595#else /* if defined(_WIN32) */
596 msg(M_WARN,
597 "WARNING: The --log option is not supported on this OS because it lacks the dup2 function");
598#endif /* if defined(_WIN32) */
599}
600
601/*
602 * Functions used to check return status
603 * of I/O operations.
604 */
605
606unsigned int x_cs_info_level; /* GLOBAL */
607unsigned int x_cs_verbose_level; /* GLOBAL */
608unsigned int x_cs_err_delay_ms; /* GLOBAL */
609
610void
612{
613 x_cs_info_level = 0;
615}
616
617void
618set_check_status(unsigned int info_level, unsigned int verbose_level)
619{
620 x_cs_info_level = info_level;
621 x_cs_verbose_level = verbose_level;
622}
623
624#if defined(__GNUC__) || defined(__clang__)
625#pragma GCC diagnostic push
626#pragma GCC diagnostic ignored "-Wsign-compare"
627#endif
628
629/*
630 * Called after most socket or tun/tap operations, via the inline
631 * function check_status().
632 *
633 * Decide if we should print an error message, and see if we can
634 * extract any useful info from the error, such as a Path MTU hint
635 * from the OS.
636 */
637void
638x_check_status(ssize_t status, const char *description, struct link_socket *sock, struct tuntap *tt)
639{
640 const char *extended_msg = NULL;
641
642 bool crt_error = false;
643 int my_errno = openvpn_errno_maybe_crt(&crt_error);
644
645 msg(x_cs_verbose_level, "%s %s returned %zd",
646 sock ? proto2ascii(sock->info.proto, sock->info.af, true) : "", description, status);
647
648 if (status < 0)
649 {
650 struct gc_arena gc = gc_new();
651#if EXTENDED_SOCKET_ERROR_CAPABILITY
652 /* get extended socket error message and possible PMTU hint from OS */
653 if (sock)
654 {
655 int mtu;
656 extended_msg = format_extended_socket_error(sock->sd, &mtu, &gc);
657 if (mtu > 0 && sock->mtu != mtu)
658 {
659 sock->mtu = mtu;
660 sock->info.mtu_changed = true;
661 }
662 }
663#endif /* EXTENDED_SOCKET_ERROR_CAPABILITY */
664
665#ifdef _WIN32
666 /* get possible driver error from TAP-Windows driver */
667 if (tuntap_defined(tt))
668 {
669 extended_msg = tap_win_getinfo(tt, &gc);
670 }
671#endif
672
673 if (!ignore_sys_error(my_errno, crt_error))
674 {
675 if (extended_msg)
676 {
677 msg(x_cs_info_level, "%s %s [%s]: %s (fd=" SOCKET_PRINTF ",code=%d)", description,
678 sock ? proto2ascii(sock->info.proto, sock->info.af, true) : "", extended_msg,
679 openvpn_strerror(my_errno, crt_error, &gc), sock ? sock->sd : -1, my_errno);
680 }
681 else
682 {
683 msg(x_cs_info_level, "%s %s: %s (fd=" SOCKET_PRINTF ",code=%d)", description,
684 sock ? proto2ascii(sock->info.proto, sock->info.af, true) : "",
685 openvpn_strerror(my_errno, crt_error, &gc), sock ? sock->sd : -1, my_errno);
686 }
687
689 {
691 }
692 }
693 gc_free(&gc);
694 }
695}
696
697#if defined(__GNUC__) || defined(__clang__)
698#pragma GCC diagnostic pop
699#endif
700
701/*
702 * In multiclient mode, put a client-specific prefix
703 * before each message.
704 */
705const char *x_msg_prefix; /* GLOBAL */
706
707/*
708 * Allow MSG to be redirected through a virtual_output object
709 */
710
711const struct virtual_output *x_msg_virtual_output; /* GLOBAL */
712
713/*
714 * Exiting.
715 */
716
717void
719{
720 if (!forked)
721 {
722 tun_abort();
723
724#ifdef _WIN32
725 uninit_win32();
726#endif
728
729 close_syslog();
730
731#ifdef ENABLE_PLUGIN
732 plugin_abort();
733#endif
734
735#if PORT_SHARE
736 if (port_share)
737 {
738 port_share_abort(port_share);
739 }
740#endif
741
742#ifdef ABORT_ON_ERROR
744 {
745 abort();
746 }
747#endif
748 }
749
750 exit(status);
751}
752
753/*
754 * Translate msg flags into a string
755 */
756const char *
758{
759 struct buffer out = alloc_buf_gc(16, gc);
760 if (flags == M_INFO)
761 {
762 buf_printf(&out, "I");
763 }
764 if (flags & M_FATAL)
765 {
766 buf_printf(&out, "F");
767 }
768 if (flags & M_NONFATAL)
769 {
770 buf_printf(&out, "N");
771 }
772 if (flags & M_WARN)
773 {
774 buf_printf(&out, "W");
775 }
776 if (flags & M_DEBUG)
777 {
778 buf_printf(&out, "D");
779 }
780 return BSTR(&out);
781}
782
783#ifdef _WIN32
784
785const char *
787{
788 /*
789 * This code can be omitted, though often the Windows
790 * WSA error messages are less informative than the
791 * Posix equivalents.
792 */
793#if 1
794 switch (errnum)
795 {
796 /*
797 * When the TAP-Windows driver returns STATUS_UNSUCCESSFUL, this code
798 * gets returned to user space.
799 */
801 return "General failure (ERROR_GEN_FAILURE)";
802
803 case ERROR_IO_PENDING:
804 return "I/O Operation in progress (ERROR_IO_PENDING)";
805
807 return "I/O Operation in progress (WSA_IO_INCOMPLETE)";
808
809 case WSAEINTR:
810 return "Interrupted system call (WSAEINTR)";
811
812 case WSAEBADF:
813 return "Bad file number (WSAEBADF)";
814
815 case WSAEACCES:
816 return "Permission denied (WSAEACCES)";
817
818 case WSAEFAULT:
819 return "Bad address (WSAEFAULT)";
820
821 case WSAEINVAL:
822 return "Invalid argument (WSAEINVAL)";
823
824 case WSAEMFILE:
825 return "Too many open files (WSAEMFILE)";
826
827 case WSAEWOULDBLOCK:
828 return "Operation would block (WSAEWOULDBLOCK)";
829
830 case WSAEINPROGRESS:
831 return "Operation now in progress (WSAEINPROGRESS)";
832
833 case WSAEALREADY:
834 return "Operation already in progress (WSAEALREADY)";
835
836 case WSAEDESTADDRREQ:
837 return "Destination address required (WSAEDESTADDRREQ)";
838
839 case WSAEMSGSIZE:
840 return "Message too long (WSAEMSGSIZE)";
841
842 case WSAEPROTOTYPE:
843 return "Protocol wrong type for socket (WSAEPROTOTYPE)";
844
845 case WSAENOPROTOOPT:
846 return "Bad protocol option (WSAENOPROTOOPT)";
847
849 return "Protocol not supported (WSAEPROTONOSUPPORT)";
850
852 return "Socket type not supported (WSAESOCKTNOSUPPORT)";
853
854 case WSAEOPNOTSUPP:
855 return "Operation not supported on socket (WSAEOPNOTSUPP)";
856
857 case WSAEPFNOSUPPORT:
858 return "Protocol family not supported (WSAEPFNOSUPPORT)";
859
860 case WSAEAFNOSUPPORT:
861 return "Address family not supported by protocol family (WSAEAFNOSUPPORT)";
862
863 case WSAEADDRINUSE:
864 return "Address already in use (WSAEADDRINUSE)";
865
866 case WSAENETDOWN:
867 return "Network is down (WSAENETDOWN)";
868
869 case WSAENETUNREACH:
870 return "Network is unreachable (WSAENETUNREACH)";
871
872 case WSAENETRESET:
873 return "Net dropped connection or reset (WSAENETRESET)";
874
875 case WSAECONNABORTED:
876 return "Software caused connection abort (WSAECONNABORTED)";
877
878 case WSAECONNRESET:
879 return "Connection reset by peer (WSAECONNRESET)";
880
881 case WSAENOBUFS:
882 return "No buffer space available (WSAENOBUFS)";
883
884 case WSAEISCONN:
885 return "Socket is already connected (WSAEISCONN)";
886
887 case WSAENOTCONN:
888 return "Socket is not connected (WSAENOTCONN)";
889
890 case WSAETIMEDOUT:
891 return "Connection timed out (WSAETIMEDOUT)";
892
893 case WSAECONNREFUSED:
894 return "Connection refused (WSAECONNREFUSED)";
895
896 case WSAELOOP:
897 return "Too many levels of symbolic links (WSAELOOP)";
898
899 case WSAENAMETOOLONG:
900 return "File name too long (WSAENAMETOOLONG)";
901
902 case WSAEHOSTDOWN:
903 return "Host is down (WSAEHOSTDOWN)";
904
905 case WSAEHOSTUNREACH:
906 return "No Route to Host (WSAEHOSTUNREACH)";
907
908 case WSAENOTEMPTY:
909 return "Directory not empty (WSAENOTEMPTY)";
910
911 case WSAEPROCLIM:
912 return "Too many processes (WSAEPROCLIM)";
913
914 case WSAEUSERS:
915 return "Too many users (WSAEUSERS)";
916
917 case WSAEDQUOT:
918 return "Disc Quota Exceeded (WSAEDQUOT)";
919
920 case WSAESTALE:
921 return "Stale NFS file handle (WSAESTALE)";
922
923 case WSASYSNOTREADY:
924 return "Network SubSystem is unavailable (WSASYSNOTREADY)";
925
927 return "WINSOCK DLL Version out of range (WSAVERNOTSUPPORTED)";
928
930 return "Successful WSASTARTUP not yet performed (WSANOTINITIALISED)";
931
932 case WSAEREMOTE:
933 return "Too many levels of remote in path (WSAEREMOTE)";
934
936 return "Host not found (WSAHOST_NOT_FOUND)";
937
938 default:
939 break;
940 }
941#endif /* if 1 */
942
943 /* format a windows error message */
944 {
945 wchar_t wmessage[256];
946 char *message = NULL;
947 struct buffer out = alloc_buf_gc(256, gc);
948 const DWORD status =
952 if (status)
953 {
955 }
956 if (!status || !message)
957 {
958 buf_printf(&out, "[Unknown Win32 Error]");
959 }
960 else
961 {
962 char *cp;
963 for (cp = message; *cp != '\0'; ++cp)
964 {
965 if (*cp == '\n' || *cp == '\r')
966 {
967 *cp = ' ';
968 }
969 }
970
971 buf_printf(&out, "%s", message);
972 }
973
974 return BSTR(&out);
975 }
976}
977
978#endif /* ifdef _WIN32 */
bool buf_printf(struct buffer *buf, const char *format,...)
Definition buffer.c:241
void * gc_malloc(size_t size, bool clear, struct gc_arena *a)
Definition buffer.c:341
struct buffer alloc_buf_gc(size_t size, struct gc_arena *gc)
Definition buffer.c:89
char * string_alloc(const char *str, struct gc_arena *gc)
Definition buffer.c:653
#define BSTR(buf)
Definition buffer.h:129
static void gc_init(struct gc_arena *a)
Definition buffer.h:1028
static void gc_free(struct gc_arena *a)
Definition buffer.h:1049
static struct gc_arena gc_new(void)
Definition buffer.h:1041
#define DEBUG_LEVEL_USEC_TIME
Definition errlevel.h:32
#define M_INFO
Definition errlevel.h:54
void remove_pid_file(void)
Definition init.c:5020
void tun_abort(void)
Definition init.c:2145
static int constrain_int(int x, int min, int max)
Definition integer.h:118
static SERVICE_STATUS status
Definition interactive.c:51
void set_std_files_to_null(bool stdin_only)
Definition misc.c:55
#define SIZE(x)
Definition basic.h:29
void x_check_status(ssize_t status, const char *description, struct link_socket *sock, struct tuntap *tt)
Definition error.c:638
static FILE * msgfp
Definition error.c:85
void error_reset(void)
Definition error.c:164
const struct virtual_output * x_msg_virtual_output
Definition error.c:711
void out_of_memory(void)
Definition error.c:444
msglvl_t get_debug_level(void)
Definition error.c:140
void errors_to_stderr(void)
Definition error.c:188
void open_syslog(const char *pgmname, bool stdio_to_null)
Definition error.c:451
void close_syslog(void)
Definition error.c:476
static FILE * default_err
Definition error.c:92
unsigned int x_cs_info_level
Definition error.c:606
void x_msg(const msglvl_t flags, const char *format,...)
Definition error.c:221
static bool forked
Definition error.c:88
msglvl_t x_debug_level
Definition error.c:48
const char * strerror_win32(DWORD errnum, struct gc_arena *gc)
Definition error.c:786
void msg_forked(void)
Definition error.c:95
const char * x_msg_prefix
Definition error.c:705
int x_msg_line_num
Definition error.c:218
bool dont_mute(msglvl_t flags)
Check muting filter.
Definition error.c:392
static int orig_stderr
Definition error.c:490
int get_orig_stderr(void)
Definition error.c:493
static FILE * default_out
Definition error.c:91
static bool use_syslog
Definition error.c:70
void redirect_stdout_stderr(const char *file, bool append)
Definition error.c:500
void assert_failed(const char *filename, int line, const char *condition)
Definition error.c:426
static int mute_cutoff
Definition error.c:51
bool set_mute_cutoff(const int cutoff)
Definition error.c:126
#define SWAP
Definition error.c:211
void set_check_status(unsigned int info_level, unsigned int verbose_level)
Definition error.c:618
static msglvl_t mute_category
Definition error.c:53
unsigned int x_cs_verbose_level
Definition error.c:607
void openvpn_exit(const int status)
Definition error.c:718
void reset_check_status(void)
Definition error.c:611
static bool machine_readable_output
Definition error.c:74
void x_msg_va(const msglvl_t flags, const char *format, va_list arglist)
Definition error.c:242
static bool std_redir
Definition error.c:67
int get_mute_cutoff(void)
Definition error.c:146
void set_suppress_timestamps(bool suppressed)
Definition error.c:152
void set_machine_readable_output(bool parsable)
Definition error.c:158
FILE * msg_fp(const msglvl_t flags)
Definition error.c:197
static const char * openvpn_strerror(int err, bool crt_error, struct gc_arena *gc)
Definition error.c:230
bool set_debug_level(const int level, const unsigned int flags)
Definition error.c:106
static int mute_count
Definition error.c:52
static bool suppress_timestamps
Definition error.c:77
const char * msg_flags_string(const msglvl_t flags, struct gc_arena *gc)
Definition error.c:757
unsigned int x_cs_err_delay_ms
Definition error.c:608
#define M_OPTERR
Definition error.h:101
static bool check_debug_level(msglvl_t level)
Definition error.h:251
#define SDL_CONSTRAIN
Definition error.h:201
#define M_NOIPREFIX
Definition error.h:103
#define OPENVPN_DEBUG_FILE
Definition error.h:66
#define M_NOPREFIX
Definition error.h:98
#define DECODE_MUTE_LEVEL(flags)
Definition error.h:120
#define M_DEBUG_LEVEL
Definition error.h:88
#define ERR_BUF_SIZE
Definition error.h:34
static const char * msg_get_prefix(void)
Definition error.h:336
static bool msg_test(msglvl_t flags)
Return true if flags represent an enabled, not muted log level.
Definition error.h:258
#define M_NOMUTE
Definition error.h:97
#define M_FATAL
Definition error.h:90
#define OPENVPN_EXIT_STATUS_CANNOT_OPEN_DEBUG_FILE
Definition error.h:55
#define OPENVPN_MSG_FP
Definition error.h:45
#define OPENVPN_EXIT_STATUS_ERROR
Definition error.h:53
#define M_NONFATAL
Definition error.h:91
#define M_NOLF
Definition error.h:102
static bool ignore_sys_error(const int err, bool crt_error)
Definition error.h:366
#define M_ERR
Definition error.h:106
#define msg(flags,...)
Definition error.h:152
static int openvpn_errno_maybe_crt(bool *crt_error)
Definition error.h:404
unsigned int msglvl_t
Definition error.h:77
#define ASSERT(x)
Definition error.h:219
#define M_DEBUG
Definition error.h:93
#define M_WARN
Definition error.h:92
#define M_MSG_VIRT_OUT
Definition error.h:100
#define M_USAGE_SMALL
Definition error.h:99
#define M_ERRNO
Definition error.h:95
static const struct virtual_output * msg_get_virtual_output(void)
Definition error.h:356
#define OPENVPN_ERROR_FP
Definition error.h:46
void usage_small(void)
Definition options.c:4846
const char * time_string(time_t t, tv_usec_t usec, bool show_usec, struct gc_arena *gc)
Definition otime.c:104
void platform_sleep_milliseconds(unsigned int n)
Definition platform.c:473
void plugin_abort(void)
Definition plugin.c:888
const char * proto2ascii(int proto, sa_family_t af, bool display_form)
static void virtual_output_print(const struct virtual_output *vo, const unsigned int flags, const char *str)
Definition status.h:39
Wrapper structure for dynamically allocated memory.
Definition buffer.h:60
int len
Length in bytes of the actual content within the allocated memory.
Definition buffer.h:65
Garbage collection arena used to keep track of dynamically allocated memory.
Definition buffer.h:116
Definition tun.h:183
#define SOCKET_PRINTF
Definition syshead.h:444
struct gc_arena gc
Definition test_ssl.c:131
const char * tap_win_getinfo(const struct tuntap *tt, struct gc_arena *gc)
Definition tun.c:6059
static bool tuntap_defined(const struct tuntap *tt)
Definition tun.h:254
char * utf16to8(const wchar_t *utf16, struct gc_arena *gc)
Definition win32-util.c:49
WCHAR * wide_string(const char *utf8, struct gc_arena *gc)
Definition win32-util.c:40
void uninit_win32(void)
Definition win32.c:120