/* return true if filename can be opened for read */ bool test_file (const char *filename) { bool ret = false; if (filename) { FILE *fp = platform_fopen (filename, "r"); if (fp) { fclose (fp); ret = true; } else { if( openvpn_errno () == EACCES ) { msg( M_WARN | M_ERRNO, "Could not access file '%s'", filename); } } } dmsg (D_TEST_FILE, "TEST FILE '%s' [%d]", filename ? filename : "UNDEF", ret); return ret; }
/* * Called after most socket or tun/tap operations, via the inline * function check_status(). * * Decide if we should print an error message, and see if we can * extract any useful info from the error, such as a Path MTU hint * from the OS. */ void x_check_status (int status, const char *description, struct link_socket *sock, struct tuntap *tt) { const int my_errno = openvpn_errno (); const char *extended_msg = NULL; msg (x_cs_verbose_level, "%s %s returned %d", sock ? proto2ascii (sock->info.proto, true) : "", description, status); if (status < 0) { struct gc_arena gc = gc_new (); #if EXTENDED_SOCKET_ERROR_CAPABILITY /* get extended socket error message and possible PMTU hint from OS */ if (sock) { int mtu; extended_msg = format_extended_socket_error (sock->sd, &mtu, &gc); if (mtu > 0 && sock->mtu != mtu) { sock->mtu = mtu; sock->info.mtu_changed = true; } } #elif defined(WIN32) /* get possible driver error from TAP-Windows driver */ extended_msg = tap_win_getinfo (tt, &gc); #endif if (!ignore_sys_error (my_errno)) { if (extended_msg) msg (x_cs_info_level, "%s %s [%s]: %s (code=%d)", description, sock ? proto2ascii (sock->info.proto, true) : "", extended_msg, strerror_ts (my_errno, &gc), my_errno); else msg (x_cs_info_level, "%s %s: %s (code=%d)", description, sock ? proto2ascii (sock->info.proto, true) : "", strerror_ts (my_errno, &gc), my_errno); if (x_cs_err_delay_ms) platform_sleep_milliseconds (x_cs_err_delay_ms); } gc_free (&gc); } }
void x_msg_va (const unsigned int flags, const char *format, va_list arglist) { struct gc_arena gc; #if SYSLOG_CAPABILITY int level; #endif char *m1; char *m2; char *tmp; int e; const char *prefix; const char *prefix_sep; void usage_small (void); #ifndef HAVE_VARARG_MACROS /* the macro has checked this otherwise */ if (!MSG_TEST (flags)) return; #endif e = openvpn_errno (); /* * Apply muting filter. */ #ifndef HAVE_VARARG_MACROS /* the macro has checked this otherwise */ if (!dont_mute (flags)) return; #endif gc_init (&gc); m1 = (char *) gc_malloc (ERR_BUF_SIZE, false, &gc); m2 = (char *) gc_malloc (ERR_BUF_SIZE, false, &gc); vsnprintf (m1, ERR_BUF_SIZE, format, arglist); m1[ERR_BUF_SIZE - 1] = 0; /* windows vsnprintf needs this */ if ((flags & M_ERRNO) && e) { openvpn_snprintf (m2, ERR_BUF_SIZE, "%s: %s (errno=%d)", m1, strerror_ts (e, &gc), e); SWAP; } #ifdef ENABLE_CRYPTO #ifdef ENABLE_CRYPTO_OPENSSL if (flags & M_SSL) { int nerrs = 0; int err; while ((err = ERR_get_error ())) { openvpn_snprintf (m2, ERR_BUF_SIZE, "%s: %s", m1, ERR_error_string (err, NULL)); SWAP; ++nerrs; } if (!nerrs) { openvpn_snprintf (m2, ERR_BUF_SIZE, "%s (OpenSSL)", m1); SWAP; } } #endif #endif if (flags & M_OPTERR) { openvpn_snprintf (m2, ERR_BUF_SIZE, "Options error: %s", m1); SWAP; } #if SYSLOG_CAPABILITY if (flags & (M_FATAL|M_NONFATAL|M_USAGE_SMALL)) level = LOG_ERR; else if (flags & M_WARN) level = LOG_WARNING; else level = LOG_NOTICE; #endif /* set up client prefix */ if (flags & M_NOIPREFIX) prefix = NULL; else prefix = msg_get_prefix (); prefix_sep = " "; if (!prefix) prefix_sep = prefix = ""; /* virtual output capability used to copy output to management subsystem */ if (!forked) { const struct virtual_output *vo = msg_get_virtual_output (); if (vo) { openvpn_snprintf (m2, ERR_BUF_SIZE, "%s%s%s", prefix, prefix_sep, m1); virtual_output_print (vo, flags, m2); } } if (!(flags & M_MSG_VIRT_OUT)) { if (use_syslog && !std_redir && !forked) { #if SYSLOG_CAPABILITY syslog (level, "%s%s%s", prefix, prefix_sep, m1); #endif } else { FILE *fp = msg_fp(flags); const bool show_usec = check_debug_level (DEBUG_LEVEL_USEC_TIME); if ((flags & M_NOPREFIX) || suppress_timestamps) { fprintf (fp, "%s%s%s%s", prefix, prefix_sep, m1, (flags&M_NOLF) ? "" : "\n"); } else { fprintf (fp, "%s %s%s%s%s", time_string (0, 0, show_usec, &gc), prefix, prefix_sep, m1, (flags&M_NOLF) ? "" : "\n"); } fflush(fp); ++x_msg_line_num; } } if (flags & M_FATAL) msg (M_INFO, "Exiting due to fatal error"); if (flags & M_FATAL) openvpn_exit (OPENVPN_EXIT_STATUS_ERROR); /* exit point */ if (flags & M_USAGE_SMALL) usage_small (); gc_free (&gc); }
void process_outgoing_link (struct context *c) { struct gc_arena gc = gc_new (); int error_code = 0; perf_push (PERF_PROC_OUT_LINK); if (c->c2.to_link.len > 0 && c->c2.to_link.len <= EXPANDED_SIZE (&c->c2.frame)) { /* * Setup for call to send/sendto which will send * packet to remote over the TCP/UDP port. */ int size = 0; ASSERT (link_socket_actual_defined (c->c2.to_link_addr)); #ifdef ENABLE_DEBUG /* In gremlin-test mode, we may choose to drop this packet */ if (!c->options.gremlin || ask_gremlin (c->options.gremlin)) #endif { /* * Let the traffic shaper know how many bytes * we wrote. */ #ifdef ENABLE_FEATURE_SHAPER if (c->options.shaper) shaper_wrote_bytes (&c->c2.shaper, BLEN (&c->c2.to_link) + datagram_overhead (c->options.ce.proto)); #endif /* * Let the pinger know that we sent a packet. */ if (c->options.ping_send_timeout) event_timeout_reset (&c->c2.ping_send_interval); #if PASSTOS_CAPABILITY /* Set TOS */ link_socket_set_tos (c->c2.link_socket); #endif /* Log packet send */ #ifdef LOG_RW if (c->c2.log_rw) fprintf (stderr, "W"); #endif msg (D_LINK_RW, "%s WRITE [%d] to %s: %s", proto2ascii (c->c2.link_socket->info.proto, c->c2.link_socket->info.af, true), BLEN (&c->c2.to_link), print_link_socket_actual (c->c2.to_link_addr, &gc), PROTO_DUMP (&c->c2.to_link, &gc)); /* Packet send complexified by possible Socks5 usage */ { struct link_socket_actual *to_addr = c->c2.to_link_addr; int size_delta = 0; /* If Socks5 over UDP, prepend header */ socks_preprocess_outgoing_link (c, &to_addr, &size_delta); /* Send packet */ size = link_socket_write (c->c2.link_socket, &c->c2.to_link, to_addr); /* Undo effect of prepend */ link_socket_write_post_size_adjust (&size, size_delta, &c->c2.to_link); } if (size > 0) { c->c2.max_send_size_local = max_int (size, c->c2.max_send_size_local); c->c2.link_write_bytes += size; link_write_bytes_global += size; #ifdef ENABLE_MEMSTATS if (mmap_stats) mmap_stats->link_write_bytes = link_write_bytes_global; #endif #ifdef ENABLE_MANAGEMENT if (management) { management_bytes_out (management, size); #ifdef MANAGEMENT_DEF_AUTH management_bytes_server (management, &c->c2.link_read_bytes, &c->c2.link_write_bytes, &c->c2.mda_context); #endif } #endif } } /* Check return status */ error_code = openvpn_errno(); check_status (size, "write", c->c2.link_socket, NULL); if (size > 0) { /* Did we write a different size packet than we intended? */ if (size != BLEN (&c->c2.to_link)) msg (D_LINK_ERRORS, "TCP/UDP packet was truncated/expanded on write to %s (tried=%d,actual=%d)", print_link_socket_actual (c->c2.to_link_addr, &gc), BLEN (&c->c2.to_link), size); } /* if not a ping/control message, indicate activity regarding --inactive parameter */ if (c->c2.buf.len > 0 ) register_activity (c, size); #ifdef ENABLE_CRYPTO /* for unreachable network and "connecting" state switch to the next host */ if (size < 0 && ENETUNREACH == error_code && c->c2.tls_multi && !tls_initial_packet_received (c->c2.tls_multi) && c->options.mode == MODE_POINT_TO_POINT) { msg (M_INFO, "Network unreachable, restarting"); register_signal (c, SIGUSR1, "network-unreachable"); } #endif } else { if (c->c2.to_link.len > 0) msg (D_LINK_ERRORS, "TCP/UDP packet too large on write to %s (tried=%d,max=%d)", print_link_socket_actual (c->c2.to_link_addr, &gc), c->c2.to_link.len, EXPANDED_SIZE (&c->c2.frame)); } buf_reset (&c->c2.to_link); perf_pop (); gc_free (&gc); }