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