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