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