mirror of
https://gitlab.com/openconnect/ocserv.git
synced 2026-10-13 18:12:03 +08:00
Added the mobile-dpd configuration option.
This option allows setting a different DPD value for mobile clients to allow them going to sleep for longer time.
This commit is contained in:
@@ -57,6 +57,7 @@ static struct cfg_options available_options[] = {
|
||||
{ .name = "udp-port", .type = OPTION_NUMERIC, .mandatory = 0 },
|
||||
{ .name = "keepalive", .type = OPTION_NUMERIC, .mandatory = 0 },
|
||||
{ .name = "dpd", .type = OPTION_NUMERIC, .mandatory = 0 },
|
||||
{ .name = "mobile-dpd", .type = OPTION_NUMERIC, .mandatory = 0 },
|
||||
{ .name = "rate-limit-ms", .type = OPTION_NUMERIC, .mandatory = 0 },
|
||||
{ .name = "ocsp-response", .type = OPTION_STRING, .mandatory = 0 },
|
||||
{ .name = "server-cert", .type = OPTION_STRING, .mandatory = 1 },
|
||||
@@ -322,6 +323,7 @@ unsigned force_cert_auth;
|
||||
READ_NUMERIC("udp-port", config->udp_port);
|
||||
READ_NUMERIC("keepalive", config->keepalive);
|
||||
READ_NUMERIC("dpd", config->dpd);
|
||||
READ_NUMERIC("mobile-dpd", config->mobile_dpd);
|
||||
READ_NUMERIC("rate-limit-ms", config->rate_limit_ms);
|
||||
|
||||
READ_STRING("ocsp-response", config->ocsp_response);
|
||||
|
||||
+9
-1
@@ -110,9 +110,17 @@ udp-port = 3333
|
||||
# Keepalive in seconds
|
||||
keepalive = 32400
|
||||
|
||||
# Dead peer detection in seconds
|
||||
# Dead peer detection in seconds. Set to zero
|
||||
# to disable.
|
||||
dpd = 240
|
||||
|
||||
# Dead peer detection for mobile clients. The needs to
|
||||
# be much higher (or even disabled by setting to zero),
|
||||
# to prevent such clients being awaken too often by the DPD
|
||||
# messages, and save battery.
|
||||
# (clients that send the X-AnyConnect-Identifier-DeviceType)
|
||||
mobile-dpd = 1800
|
||||
|
||||
# MTU discovery (DPD must be enabled)
|
||||
try-mtu-discovery = false
|
||||
|
||||
|
||||
@@ -202,6 +202,7 @@ struct cfg_st {
|
||||
unsigned auth_timeout; /* timeout of HTTP auth */
|
||||
unsigned keepalive;
|
||||
unsigned dpd;
|
||||
unsigned mobile_dpd;
|
||||
unsigned foreground;
|
||||
unsigned debug;
|
||||
unsigned max_clients;
|
||||
|
||||
+40
-34
@@ -172,16 +172,6 @@ int url_cb(http_parser * parser, const char *at, size_t length)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define STR_HDR_COOKIE "Cookie"
|
||||
#define STR_HDR_USER_AGENT "User-Agent"
|
||||
#define STR_HDR_CONNECTION "Connection"
|
||||
#define STR_HDR_MS "X-DTLS-Master-Secret"
|
||||
#define STR_HDR_CS "X-DTLS-CipherSuite"
|
||||
#define STR_HDR_DMTU "X-DTLS-MTU"
|
||||
#define STR_HDR_CMTU "X-CSTP-MTU"
|
||||
#define STR_HDR_ATYPE "X-CSTP-Address-Type"
|
||||
#define STR_HDR_HOST "X-CSTP-Hostname"
|
||||
#define STR_HDR_FULL_IPV6 "X-CSTP-Full-IPv6-Capability"
|
||||
|
||||
#define CS_ESALSA20 "OC-DTLS1_2-ESALSA20-SHA"
|
||||
#define CS_SALSA20 "OC-DTLS1_2-SALSA20-SHA"
|
||||
@@ -290,6 +280,9 @@ static void value_check(struct worker_st *ws, struct http_req_st *req)
|
||||
memcpy(req->hostname, value, value_length);
|
||||
req->hostname[value_length] = 0;
|
||||
break;
|
||||
case HEADER_DEVICE_TYPE:
|
||||
req->is_mobile = 1;
|
||||
break;
|
||||
case HEADER_USER_AGENT:
|
||||
if (value_length + 1 > MAX_AGENT_NAME) {
|
||||
req->user_agent[0] = 0;
|
||||
@@ -413,6 +406,7 @@ int header_field_cb(http_parser * parser, const char *at, size_t length)
|
||||
|
||||
static void header_check(struct http_req_st *req)
|
||||
{
|
||||
/* FIXME: move this mess to a table */
|
||||
if (req->header.length == sizeof(STR_HDR_COOKIE) - 1 &&
|
||||
strncmp((char *)req->header.data, STR_HDR_COOKIE,
|
||||
req->header.length) == 0) {
|
||||
@@ -437,6 +431,10 @@ static void header_check(struct http_req_st *req)
|
||||
strncmp((char *)req->header.data, STR_HDR_CS,
|
||||
req->header.length) == 0) {
|
||||
req->next_header = HEADER_DTLS_CIPHERSUITE;
|
||||
} else if (req->header.length == sizeof(STR_HDR_DEVICE_TYPE) - 1 &&
|
||||
strncmp((char *)req->header.data, STR_HDR_DEVICE_TYPE,
|
||||
req->header.length) == 0) {
|
||||
req->next_header = HEADER_DEVICE_TYPE;
|
||||
} else if (req->header.length == sizeof(STR_HDR_ATYPE) - 1 &&
|
||||
strncmp((char *)req->header.data, STR_HDR_ATYPE,
|
||||
req->header.length) == 0) {
|
||||
@@ -898,7 +896,7 @@ void mtu_ok(worker_st * ws)
|
||||
}
|
||||
|
||||
static
|
||||
int periodic_check(worker_st * ws, unsigned mtu_overhead, time_t now)
|
||||
int periodic_check(worker_st * ws, unsigned mtu_overhead, time_t now, unsigned dpd)
|
||||
{
|
||||
socklen_t sl;
|
||||
int max, e, ret;
|
||||
@@ -907,22 +905,23 @@ int periodic_check(worker_st * ws, unsigned mtu_overhead, time_t now)
|
||||
return 0;
|
||||
|
||||
/* check DPD. Otherwise exit */
|
||||
if (ws->udp_state == UP_ACTIVE
|
||||
&& now - ws->last_msg_udp > DPD_TRIES * ws->config->dpd) {
|
||||
if (ws->udp_state == UP_ACTIVE &&
|
||||
now - ws->last_msg_udp > DPD_TRIES * dpd &&
|
||||
dpd > 0) {
|
||||
oclog(ws, LOG_ERR,
|
||||
"have not received UDP any message or DPD for long (%d secs)",
|
||||
(int)(now - ws->last_msg_udp));
|
||||
"have not received UDP any message or DPD for long (%d secs, DPD is %d)",
|
||||
(int)(now - ws->last_msg_udp), dpd);
|
||||
|
||||
ws->buffer[0] = AC_PKT_DPD_OUT;
|
||||
tls_send(ws->dtls_session, ws->buffer, 1);
|
||||
|
||||
if (now - ws->last_msg_udp > DPD_MAX_TRIES * ws->config->dpd) {
|
||||
if (now - ws->last_msg_udp > DPD_MAX_TRIES * dpd) {
|
||||
oclog(ws, LOG_ERR,
|
||||
"have not received UDP message or DPD for very long; disabling UDP port");
|
||||
ws->udp_state = UP_INACTIVE;
|
||||
}
|
||||
}
|
||||
if (now - ws->last_msg_tcp > DPD_TRIES * ws->config->dpd) {
|
||||
if (dpd > 0 && now - ws->last_msg_tcp > DPD_TRIES * dpd) {
|
||||
oclog(ws, LOG_ERR,
|
||||
"have not received TCP DPD for long (%d secs)",
|
||||
(int)(now - ws->last_msg_tcp));
|
||||
@@ -937,7 +936,7 @@ int periodic_check(worker_st * ws, unsigned mtu_overhead, time_t now)
|
||||
|
||||
tls_send(ws->session, ws->buffer, 8);
|
||||
|
||||
if (now - ws->last_msg_tcp > DPD_MAX_TRIES * ws->config->dpd) {
|
||||
if (now - ws->last_msg_tcp > DPD_MAX_TRIES * dpd) {
|
||||
oclog(ws, LOG_ERR,
|
||||
"have not received TCP DPD for very long; tearing down connection");
|
||||
return -1;
|
||||
@@ -1018,7 +1017,8 @@ static int connect_handler(worker_st * ws)
|
||||
{
|
||||
struct http_req_st *req = &ws->req;
|
||||
fd_set rfds;
|
||||
int l, e, max, ret, overhead;
|
||||
int l, e, max, ret, overhead, t;
|
||||
int dpd;
|
||||
unsigned tls_retry, dtls_mtu, cstp_mtu;
|
||||
char *p;
|
||||
#ifdef HAVE_PSELECT
|
||||
@@ -1030,7 +1030,6 @@ static int connect_handler(worker_st * ws)
|
||||
time_t udp_recv_time = 0, now;
|
||||
struct timespec tnow;
|
||||
unsigned mtu_overhead = 0, ip6;
|
||||
int sndbuf;
|
||||
socklen_t sl;
|
||||
bandwidth_st b_tx;
|
||||
bandwidth_st b_rx;
|
||||
@@ -1110,8 +1109,16 @@ static int connect_handler(worker_st * ws)
|
||||
ret = tls_puts(ws->session, "X-CSTP-Version: 1\r\n");
|
||||
SEND_ERR(ret);
|
||||
|
||||
ret = tls_printf(ws->session, "X-CSTP-DPD: %u\r\n", ws->config->dpd);
|
||||
if (req->is_mobile)
|
||||
dpd = ws->config->mobile_dpd;
|
||||
else
|
||||
dpd = ws->config->dpd;
|
||||
|
||||
oclog(ws, LOG_DEBUG, "suggesting DPD of %d secs", dpd);
|
||||
if (dpd > 0) {
|
||||
ret = tls_printf(ws->session, "X-CSTP-DPD: %u\r\n", dpd);
|
||||
SEND_ERR(ret);
|
||||
}
|
||||
|
||||
if (ws->config->default_domain) {
|
||||
ret =
|
||||
@@ -1310,14 +1317,14 @@ static int connect_handler(worker_st * ws)
|
||||
|
||||
/* set TCP socket options */
|
||||
if (ws->config->output_buffer > 0) {
|
||||
sndbuf = ws->conn_mtu * ws->config->output_buffer;
|
||||
t = ws->conn_mtu * ws->config->output_buffer;
|
||||
ret =
|
||||
setsockopt(ws->conn_fd, SOL_SOCKET, SO_SNDBUF, &sndbuf,
|
||||
sizeof(sndbuf));
|
||||
setsockopt(ws->conn_fd, SOL_SOCKET, SO_SNDBUF, &t,
|
||||
sizeof(t));
|
||||
if (ret == -1)
|
||||
oclog(ws, LOG_DEBUG,
|
||||
"setsockopt(TCP, SO_SNDBUF) to %u, failed.",
|
||||
sndbuf);
|
||||
t);
|
||||
}
|
||||
|
||||
set_net_priority(ws, ws->conn_fd, ws->config->net_priority);
|
||||
@@ -1334,10 +1341,10 @@ static int connect_handler(worker_st * ws)
|
||||
ws->buffer);
|
||||
SEND_ERR(ret);
|
||||
|
||||
ret =
|
||||
tls_printf(ws->session, "X-DTLS-DPD: %u\r\n",
|
||||
ws->config->dpd);
|
||||
if (dpd > 0) {
|
||||
ret = tls_printf(ws->session, "X-DTLS-DPD: %u\r\n", dpd);
|
||||
SEND_ERR(ret);
|
||||
}
|
||||
|
||||
ret =
|
||||
tls_printf(ws->session, "X-DTLS-Port: %u\r\n",
|
||||
@@ -1397,13 +1404,12 @@ static int connect_handler(worker_st * ws)
|
||||
oclog(ws, LOG_DEBUG, "suggesting DTLS MTU %u", dtls_mtu);
|
||||
|
||||
if (ws->config->output_buffer > 0) {
|
||||
sndbuf = MIN(2048, dtls_mtu * ws->config->output_buffer);
|
||||
setsockopt(ws->udp_fd, SOL_SOCKET, SO_SNDBUF, &sndbuf,
|
||||
sizeof(sndbuf));
|
||||
t = MIN(2048, dtls_mtu * ws->config->output_buffer);
|
||||
setsockopt(ws->udp_fd, SOL_SOCKET, SO_SNDBUF, &t,
|
||||
sizeof(t));
|
||||
if (ret == -1)
|
||||
oclog(ws, LOG_DEBUG,
|
||||
"setsockopt(UDP, SO_SNDBUF) to %u, failed.",
|
||||
sndbuf);
|
||||
"setsockopt(UDP, SO_SNDBUF) to %u, failed.", t);
|
||||
}
|
||||
|
||||
set_net_priority(ws, ws->udp_fd, ws->config->net_priority);
|
||||
@@ -1517,7 +1523,7 @@ static int connect_handler(worker_st * ws)
|
||||
gettime(&tnow);
|
||||
now = tnow.tv_sec;
|
||||
|
||||
if (periodic_check(ws, mtu_overhead, now) < 0)
|
||||
if (periodic_check(ws, mtu_overhead, now, dpd) < 0)
|
||||
goto exit;
|
||||
|
||||
if (FD_ISSET(ws->tun_fd, &rfds)) {
|
||||
|
||||
@@ -42,6 +42,18 @@ typedef enum {
|
||||
UP_ACTIVE
|
||||
} udp_port_state_t;
|
||||
|
||||
#define STR_HDR_COOKIE "Cookie"
|
||||
#define STR_HDR_USER_AGENT "User-Agent"
|
||||
#define STR_HDR_CONNECTION "Connection"
|
||||
#define STR_HDR_MS "X-DTLS-Master-Secret"
|
||||
#define STR_HDR_CS "X-DTLS-CipherSuite"
|
||||
#define STR_HDR_DMTU "X-DTLS-MTU"
|
||||
#define STR_HDR_CMTU "X-CSTP-MTU"
|
||||
#define STR_HDR_ATYPE "X-CSTP-Address-Type"
|
||||
#define STR_HDR_HOST "X-CSTP-Hostname"
|
||||
#define STR_HDR_FULL_IPV6 "X-CSTP-Full-IPv6-Capability"
|
||||
#define STR_HDR_DEVICE_TYPE "X-AnyConnect-Identifier-DeviceType"
|
||||
|
||||
enum {
|
||||
HEADER_COOKIE = 1,
|
||||
HEADER_MASTER_SECRET,
|
||||
@@ -49,6 +61,7 @@ enum {
|
||||
HEADER_CSTP_MTU,
|
||||
HEADER_CSTP_ATYPE,
|
||||
HEADER_DTLS_MTU,
|
||||
HEADER_DEVICE_TYPE,
|
||||
HEADER_DTLS_CIPHERSUITE,
|
||||
HEADER_CONNECTION,
|
||||
HEADER_FULL_IPV6,
|
||||
@@ -94,6 +107,8 @@ struct http_req_st {
|
||||
uint8_t sid_cookie[SID_SIZE];
|
||||
unsigned int sid_cookie_set;
|
||||
|
||||
unsigned int is_mobile;
|
||||
|
||||
unsigned char master_secret[TLS_MASTER_SIZE];
|
||||
unsigned int master_secret_set;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user