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