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