diff --git a/library.c b/library.c index 3a8d6cd6..643aa25d 100644 --- a/library.c +++ b/library.c @@ -1080,7 +1080,7 @@ const char *openconnect_get_dtls_cipher(struct openconnect_info *vpninfo) * one is enabled. */ if (vpninfo->dtls_cipher_desc == NULL) { #if defined(OPENCONNECT_GNUTLS) - vpninfo->dtls_cipher_desc = get_gnutls_cipher(vpninfo->dtls_ssl); + vpninfo->dtls_cipher_desc = get_gnutls_cipher(vpninfo->dtls_ssl); #else if (asprintf(&vpninfo->dtls_cipher_desc, "%s-%s", SSL_get_version(vpninfo->dtls_ssl), SSL_get_cipher_name(vpninfo->dtls_ssl)) < 0) diff --git a/main.c b/main.c index 58a7fc0f..f477a4c6 100644 --- a/main.c +++ b/main.c @@ -82,6 +82,7 @@ static int verbose = PRG_INFO; static int timestamp; #ifndef _WIN32 static int background; +static int use_syslog = 0; static FILE *pid_fp = NULL; static char *pidfile = NULL; #endif @@ -757,6 +758,9 @@ static void handle_signal(int sig) cmd = OC_CMD_CANCEL; #endif break; + case SIGUSR1: + cmd = OC_CMD_STATS; + break; case SIGUSR2: default: cmd = OC_CMD_PAUSE; @@ -1391,10 +1395,12 @@ static int autocomplete(int argc, char **argv) static void print_connection_info(struct openconnect_info *vpninfo) { const struct oc_ip_info *ip_info; - const char *ssl_compr, *udp_compr, *dtls_state; + const char *ssl_compr, *udp_compr, *dtls_state, *ssl_state; openconnect_get_ip_info(vpninfo, &ip_info, NULL, NULL); + ssl_state = vpninfo->ssl_fd == -1 ? _("disconnected") : _("connected"); + switch (vpninfo->dtls_state) { case DTLS_NOSECRET: dtls_state = _("unsuccessful"); @@ -1413,11 +1419,12 @@ static void print_connection_info(struct openconnect_info *vpninfo) ssl_compr = openconnect_get_cstp_compression(vpninfo); udp_compr = openconnect_get_dtls_compression(vpninfo); vpn_progress(vpninfo, PRG_INFO, - _("Connected as %s%s%s, using SSL%s%s, with %s%s%s %s\n"), + _("Configured as %s%s%s, with SSL%s%s %s and %s%s%s %s\n"), ip_info->addr?:"", (ip_info->netmask6 && ip_info->addr) ? " + " : "", ip_info->netmask6 ? : "", ssl_compr ? " + " : "", ssl_compr ? : "", + ssl_state, vpninfo->proto->udp_protocol ? : "UDP", udp_compr ? " + " : "", udp_compr ? : "", dtls_state); if (vpninfo->auth_expiration != 0) @@ -1425,6 +1432,39 @@ static void print_connection_info(struct openconnect_info *vpninfo) ctime(&vpninfo->auth_expiration)); } +static void print_connection_stats(void *_vpninfo, const struct oc_stats *stats) +{ + struct openconnect_info *vpninfo = _vpninfo; + int saved_loglevel = vpninfo->verbose; + + /* XX: print even if loglevel would otherwise suppress */ + openconnect_set_loglevel(vpninfo, PRG_INFO); + + print_connection_info(vpninfo); + vpn_progress(vpninfo, PRG_INFO, + _("RX: %ld packets (%ld B); TX: %ld packets (%ld B)\n"), + stats->rx_pkts, stats->rx_bytes, stats->tx_pkts, stats->tx_bytes); + + if (vpninfo->ssl_fd != -1) + vpn_progress(vpninfo, PRG_INFO, _("SSL ciphersuite: %s\n"), openconnect_get_cstp_cipher(vpninfo)); + if (vpninfo->dtls_state == DTLS_CONNECTED) + vpn_progress(vpninfo, PRG_INFO, _("%s ciphersuite: %s\n"), + vpninfo->proto->udp_protocol ? : "UDP", openconnect_get_dtls_cipher(vpninfo)); + if (vpninfo->ssl_times.last_rekey && vpninfo->ssl_times.rekey) + vpn_progress(vpninfo, PRG_INFO, _("Next SSL rekey in %ld seconds\n"), + time(NULL) - vpninfo->ssl_times.last_rekey + vpninfo->ssl_times.rekey); + if (vpninfo->dtls_times.last_rekey && vpninfo->dtls_times.rekey) + vpn_progress(vpninfo, PRG_INFO, _("Next %s rekey in %ld seconds\n"), + vpninfo->proto->udp_protocol ? : "UDP", + time(NULL) - vpninfo->ssl_times.last_rekey + vpninfo->ssl_times.rekey); + if (vpninfo->trojan_interval && vpninfo->last_trojan) + vpn_progress(vpninfo, PRG_INFO, _("Next Trojan invocation in %ld seconds\n"), + time(NULL) - vpninfo->last_trojan + vpninfo->trojan_interval); + + /* XX: restore loglevel */ + openconnect_set_loglevel(vpninfo, saved_loglevel); +} + #ifndef _WIN32 static FILE *background_self(struct openconnect_info *vpninfo, char *pidfile) { FILE *fp = NULL; @@ -1470,7 +1510,14 @@ static void fully_up_cb(void *_vpninfo) { #ifndef _WIN32 if (background) pid_fp = background_self(vpninfo, pidfile); -#endif + +#ifndef __native_client__ + if (use_syslog) { + openlog("openconnect", LOG_PID, LOG_DAEMON); + vpninfo->progress = syslog_progress; + } +#endif /* !__native_client__ */ +#endif /* !_WIN32 */ } int main(int argc, char **argv) @@ -1495,7 +1542,6 @@ int main(int argc, char **argv) #ifndef _WIN32 struct sigaction sa; struct utsname utsbuf; - int use_syslog = 0; #endif #ifdef ENABLE_NLS @@ -1953,6 +1999,7 @@ int main(int argc, char **argv) sigaction(SIGTERM, &sa, NULL); sigaction(SIGINT, &sa, NULL); sigaction(SIGHUP, &sa, NULL); + sigaction(SIGUSR1, &sa, NULL); sigaction(SIGUSR2, &sa, NULL); #endif /* !_WIN32 */ @@ -2031,13 +2078,6 @@ int main(int argc, char **argv) } -#if !defined(_WIN32) && !defined(__native_client__) - if (use_syslog) { - openlog("openconnect", LOG_PID, LOG_DAEMON); - vpninfo->progress = syslog_progress; - } -#endif /* !_WIN32 && !__native_client__ */ - if (!vpninfo->vpnc_script) { vpn_progress(vpninfo, PRG_INFO, _("No --script argument provided; DNS and routing are not configured\n")); @@ -2048,6 +2088,7 @@ int main(int argc, char **argv) openconnect_set_loglevel(vpninfo, verbose); openconnect_set_setup_tun_handler(vpninfo, fully_up_cb); + openconnect_set_stats_handler(vpninfo, print_connection_stats); while (1) { ret = openconnect_mainloop(vpninfo, reconnect_timeout, RECONNECT_INTERVAL_MIN); @@ -2097,7 +2138,10 @@ int main(int argc, char **argv) ret = 1; break; default: - vpn_progress(vpninfo, PRG_ERR, _("Unknown error; exiting.\n")); + if (vpninfo->quit_reason) + vpn_progress(vpninfo, PRG_ERR, "%s; exiting\n", vpninfo->quit_reason); + else + vpn_progress(vpninfo, PRG_ERR, _("Unknown error; exiting.\n")); ret = 1; break; } diff --git a/openconnect.8.in b/openconnect.8.in index 741f4239..55d43a06 100644 --- a/openconnect.8.in +++ b/openconnect.8.in @@ -226,7 +226,7 @@ Use for tunnel interface .TP .B \-l,\-\-syslog -Use syslog for progress messages +After tunnel is brought up, use syslog for further progress messages .TP .B \-\-timestamp Prepend a timestamp to each progress message @@ -607,6 +607,9 @@ disconnects from the gateway and runs the vpnc\-script, but does not log the session off; this allows for reconnection later using .BR \-\-cookie . .TP +.B SIGUSR1 +writes progress message with detailed connection information and statistics. +.TP .B SIGUSR2 forces an immediate disconnection and reconnection; this can be used to quickly recover from LAN IP address changes. diff --git a/www/changelog.xml b/www/changelog.xml index 827cac2d..4e4a9bba 100644 --- a/www/changelog.xml +++ b/www/changelog.xml @@ -22,6 +22,7 @@
  • Add obsolete-server-crypto test (!114)
  • Allow protocols to delay tunnel setup and shutdown (!117)
  • Incomplete, speculative support for GlobalProtect IPv6 (!155; previous work in d6db0ec)
  • +
  • SIGUSR1 causes OpenConnect to log detailed connection information and statistics (!154)

  • OpenConnect v8.10