From 367976ca34fe1d34bccbdc1f3be102a1a075b576 Mon Sep 17 00:00:00 2001 From: Nikos Mavrogiannopoulos Date: Tue, 18 Feb 2014 17:59:03 +0100 Subject: [PATCH] Implemented Idle timeout. When set, a client that does not have any non-control traffic for that period is getting disconnected. --- src/config.c | 2 ++ src/ocserv-args.def | 4 ++++ src/vpn.h | 1 + src/worker-vpn.c | 33 +++++++++++++++++++++++++++++---- src/worker.h | 3 +++ 5 files changed, 39 insertions(+), 4 deletions(-) diff --git a/src/config.c b/src/config.c index 70318c1c..31503777 100644 --- a/src/config.c +++ b/src/config.c @@ -91,6 +91,7 @@ static struct cfg_options available_options[] = { { .name = "cookie-validity", .type = OPTION_NUMERIC, .mandatory = 1 }, { .name = "rekey-time", .type = OPTION_NUMERIC, .mandatory = 0 }, { .name = "auth-timeout", .type = OPTION_NUMERIC, .mandatory = 0 }, + { .name = "idle-timeout", .type = OPTION_NUMERIC, .mandatory = 0 }, { .name = "max-clients", .type = OPTION_NUMERIC, .mandatory = 0 }, { .name = "min-reauth-time", .type = OPTION_NUMERIC, .mandatory = 0 }, { .name = "max-same-clients", .type = OPTION_NUMERIC, .mandatory = 0 }, @@ -392,6 +393,7 @@ unsigned force_cert_auth; } READ_NUMERIC("auth-timeout", config->auth_timeout); + READ_NUMERIC("idle-timeout", config->idle_timeout); READ_NUMERIC("max-clients", config->max_clients); READ_NUMERIC("min-reauth-time", config->min_reauth_time); READ_NUMERIC("max-same-clients", config->max_same_clients); diff --git a/src/ocserv-args.def b/src/ocserv-args.def index 64962e38..0b8bdfda 100644 --- a/src/ocserv-args.def +++ b/src/ocserv-args.def @@ -183,6 +183,10 @@ tls-priorities = "NORMAL:%SERVER_PRECEDENCE:%COMPAT" # to authentication auth-timeout = 40 +# The time (in seconds) that a client is allowed to stay idle (no traffic) +# before being disconnected. Unset to disable. +#idle-timeout = 1200 + # The time (in seconds) that a client is not allowed to reconnect after # a failed authentication attempt. #min-reauth-time = 2 diff --git a/src/vpn.h b/src/vpn.h index 678ff240..26441523 100644 --- a/src/vpn.h +++ b/src/vpn.h @@ -203,6 +203,7 @@ struct cfg_st { time_t rekey_time; /* in seconds */ time_t min_reauth_time; /* after a failed auth, how soon one can reauthenticate -> in seconds */ unsigned auth_timeout; /* timeout of HTTP auth */ + unsigned idle_timeout; /* timeout when idle */ unsigned keepalive; unsigned dpd; unsigned mobile_dpd; diff --git a/src/worker-vpn.c b/src/worker-vpn.c index 31f04b33..0fb2a093 100644 --- a/src/worker-vpn.c +++ b/src/worker-vpn.c @@ -904,6 +904,17 @@ int periodic_check(worker_st * ws, unsigned mtu_overhead, time_t now, unsigned d if (now - ws->last_periodic_check < PERIODIC_CHECK_TIME) return 0; + if (ws->config->idle_timeout > 0) { + if (now - ws->last_nc_msg > ws->config->idle_timeout) { + oclog(ws, LOG_ERR, + "idle timeout reached for process (%d secs)", + (int)(now - ws->last_nc_msg)); + terminate = 1; + goto cleanup; + } + + } + /* check DPD. Otherwise exit */ if (ws->udp_state == UP_ACTIVE && now - ws->last_msg_udp > DPD_TRIES * dpd && @@ -959,6 +970,7 @@ int periodic_check(worker_st * ws, unsigned mtu_overhead, time_t now, unsigned d } } +cleanup: ws->last_periodic_check = now; return 0; @@ -1214,7 +1226,7 @@ static int connect_handler(worker_st * ws) if (req->no_ipv4 != 0 && strchr(ws->vinfo.routes[i], '.') != 0) continue; oclog(ws, LOG_DEBUG, "adding route %s", ws->vinfo.routes[i]); - + if (ip6 != 0 && ws->full_ipv6) { ret = tls_printf(ws->session, "X-CSTP-Split-Include-IP6: %s\r\n", @@ -1253,6 +1265,17 @@ static int connect_handler(worker_st * ws) ws->config->keepalive); SEND_ERR(ret); + if (ws->config->idle_timeout > 0) { + ret = + tls_printf(ws->session, + "X-CSTP-Idle-Timeout: %u\r\n", (unsigned)ws->config->idle_timeout); + } else { + ret = + tls_puts(ws->session, + "X-CSTP-Idle-Timeout: none\r\n"); + } + SEND_ERR(ret); + ret = tls_puts(ws->session, "X-CSTP-Smartcard-Removal-Disconnect: true\r\n"); @@ -1272,7 +1295,6 @@ static int connect_handler(worker_st * ws) } ret = tls_puts(ws->session, "X-CSTP-Session-Timeout: none\r\n" - "X-CSTP-Idle-Timeout: none\r\n" "X-CSTP-Disconnected-Timeout: none\r\n" "X-CSTP-Keep: true\r\n" "X-CSTP-TCP-Keepalive: true\r\n" @@ -1458,7 +1480,7 @@ static int connect_handler(worker_st * ws) /* start dead peer detection */ gettime(&tnow); - ws->last_msg_tcp = ws->last_msg_udp = tnow.tv_sec; + ws->last_msg_tcp = ws->last_msg_udp = ws->last_nc_msg = tnow.tv_sec; bandwidth_init(&b_rx, ws->config->rx_per_sec); bandwidth_init(&b_tx, ws->config->tx_per_sec); @@ -1551,6 +1573,7 @@ static int connect_handler(worker_st * ws) tls_retry = 0; oclog(ws, LOG_TRANSFER_DEBUG, "sending %d byte(s)\n", l); if (ws->udp_state == UP_ACTIVE) { + ws->buffer[7] = AC_PKT_DATA; ret = @@ -1588,6 +1611,7 @@ static int connect_handler(worker_st * ws) l + 8); GNUTLS_FATAL_ERR(ret); } + ws->last_nc_msg = tnow.tv_sec; } } @@ -1595,7 +1619,6 @@ static int connect_handler(worker_st * ws) ret = tls_recv(ws->session, ws->buffer, ws->buffer_size); - oclog(ws, LOG_TRANSFER_DEBUG, "received %d byte(s) (TLS)", ret); GNUTLS_FATAL_ERR(ret); @@ -1606,6 +1629,7 @@ static int connect_handler(worker_st * ws) if (ret > 0) { l = ret; + oclog(ws, LOG_TRANSFER_DEBUG, "received %d byte(s) (TLS)", l); if (bandwidth_update (&b_rx, l - 8, ws->conn_mtu, &tnow) != 0) { @@ -1852,6 +1876,7 @@ static int parse_data(struct worker_st *ws, gnutls_session_t ts, /* the interfac strerror(e)); return -1; } + ws->last_nc_msg = now; break; default: diff --git a/src/worker.h b/src/worker.h index 6c4cddc4..c5a9738f 100644 --- a/src/worker.h +++ b/src/worker.h @@ -150,6 +150,9 @@ typedef struct worker_st { /* for dead peer detection */ time_t last_msg_udp; time_t last_msg_tcp; + + time_t last_nc_msg; /* last message that wasn't control, on any channel */ + time_t last_periodic_check; /* set after authentication */