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 = "udp-port", .type = OPTION_NUMERIC, .mandatory = 0 },
|
||||||
{ .name = "keepalive", .type = OPTION_NUMERIC, .mandatory = 0 },
|
{ .name = "keepalive", .type = OPTION_NUMERIC, .mandatory = 0 },
|
||||||
{ .name = "dpd", .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 = "rate-limit-ms", .type = OPTION_NUMERIC, .mandatory = 0 },
|
||||||
{ .name = "ocsp-response", .type = OPTION_STRING, .mandatory = 0 },
|
{ .name = "ocsp-response", .type = OPTION_STRING, .mandatory = 0 },
|
||||||
{ .name = "server-cert", .type = OPTION_STRING, .mandatory = 1 },
|
{ .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("udp-port", config->udp_port);
|
||||||
READ_NUMERIC("keepalive", config->keepalive);
|
READ_NUMERIC("keepalive", config->keepalive);
|
||||||
READ_NUMERIC("dpd", config->dpd);
|
READ_NUMERIC("dpd", config->dpd);
|
||||||
|
READ_NUMERIC("mobile-dpd", config->mobile_dpd);
|
||||||
READ_NUMERIC("rate-limit-ms", config->rate_limit_ms);
|
READ_NUMERIC("rate-limit-ms", config->rate_limit_ms);
|
||||||
|
|
||||||
READ_STRING("ocsp-response", config->ocsp_response);
|
READ_STRING("ocsp-response", config->ocsp_response);
|
||||||
|
|||||||
+9
-1
@@ -110,9 +110,17 @@ udp-port = 3333
|
|||||||
# Keepalive in seconds
|
# Keepalive in seconds
|
||||||
keepalive = 32400
|
keepalive = 32400
|
||||||
|
|
||||||
# Dead peer detection in seconds
|
# Dead peer detection in seconds. Set to zero
|
||||||
|
# to disable.
|
||||||
dpd = 240
|
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)
|
# MTU discovery (DPD must be enabled)
|
||||||
try-mtu-discovery = false
|
try-mtu-discovery = false
|
||||||
|
|
||||||
|
|||||||
@@ -202,6 +202,7 @@ struct cfg_st {
|
|||||||
unsigned auth_timeout; /* timeout of HTTP auth */
|
unsigned auth_timeout; /* timeout of HTTP auth */
|
||||||
unsigned keepalive;
|
unsigned keepalive;
|
||||||
unsigned dpd;
|
unsigned dpd;
|
||||||
|
unsigned mobile_dpd;
|
||||||
unsigned foreground;
|
unsigned foreground;
|
||||||
unsigned debug;
|
unsigned debug;
|
||||||
unsigned max_clients;
|
unsigned max_clients;
|
||||||
|
|||||||
+42
-36
@@ -172,16 +172,6 @@ int url_cb(http_parser * parser, const char *at, size_t length)
|
|||||||
return 0;
|
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_ESALSA20 "OC-DTLS1_2-ESALSA20-SHA"
|
||||||
#define CS_SALSA20 "OC-DTLS1_2-SALSA20-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);
|
memcpy(req->hostname, value, value_length);
|
||||||
req->hostname[value_length] = 0;
|
req->hostname[value_length] = 0;
|
||||||
break;
|
break;
|
||||||
|
case HEADER_DEVICE_TYPE:
|
||||||
|
req->is_mobile = 1;
|
||||||
|
break;
|
||||||
case HEADER_USER_AGENT:
|
case HEADER_USER_AGENT:
|
||||||
if (value_length + 1 > MAX_AGENT_NAME) {
|
if (value_length + 1 > MAX_AGENT_NAME) {
|
||||||
req->user_agent[0] = 0;
|
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)
|
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 &&
|
if (req->header.length == sizeof(STR_HDR_COOKIE) - 1 &&
|
||||||
strncmp((char *)req->header.data, STR_HDR_COOKIE,
|
strncmp((char *)req->header.data, STR_HDR_COOKIE,
|
||||||
req->header.length) == 0) {
|
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,
|
strncmp((char *)req->header.data, STR_HDR_CS,
|
||||||
req->header.length) == 0) {
|
req->header.length) == 0) {
|
||||||
req->next_header = HEADER_DTLS_CIPHERSUITE;
|
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 &&
|
} else if (req->header.length == sizeof(STR_HDR_ATYPE) - 1 &&
|
||||||
strncmp((char *)req->header.data, STR_HDR_ATYPE,
|
strncmp((char *)req->header.data, STR_HDR_ATYPE,
|
||||||
req->header.length) == 0) {
|
req->header.length) == 0) {
|
||||||
@@ -898,7 +896,7 @@ void mtu_ok(worker_st * ws)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static
|
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;
|
socklen_t sl;
|
||||||
int max, e, ret;
|
int max, e, ret;
|
||||||
@@ -907,22 +905,23 @@ int periodic_check(worker_st * ws, unsigned mtu_overhead, time_t now)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* check DPD. Otherwise exit */
|
/* check DPD. Otherwise exit */
|
||||||
if (ws->udp_state == UP_ACTIVE
|
if (ws->udp_state == UP_ACTIVE &&
|
||||||
&& now - ws->last_msg_udp > DPD_TRIES * ws->config->dpd) {
|
now - ws->last_msg_udp > DPD_TRIES * dpd &&
|
||||||
|
dpd > 0) {
|
||||||
oclog(ws, LOG_ERR,
|
oclog(ws, LOG_ERR,
|
||||||
"have not received UDP any message or DPD for long (%d secs)",
|
"have not received UDP any message or DPD for long (%d secs, DPD is %d)",
|
||||||
(int)(now - ws->last_msg_udp));
|
(int)(now - ws->last_msg_udp), dpd);
|
||||||
|
|
||||||
ws->buffer[0] = AC_PKT_DPD_OUT;
|
ws->buffer[0] = AC_PKT_DPD_OUT;
|
||||||
tls_send(ws->dtls_session, ws->buffer, 1);
|
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,
|
oclog(ws, LOG_ERR,
|
||||||
"have not received UDP message or DPD for very long; disabling UDP port");
|
"have not received UDP message or DPD for very long; disabling UDP port");
|
||||||
ws->udp_state = UP_INACTIVE;
|
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,
|
oclog(ws, LOG_ERR,
|
||||||
"have not received TCP DPD for long (%d secs)",
|
"have not received TCP DPD for long (%d secs)",
|
||||||
(int)(now - ws->last_msg_tcp));
|
(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);
|
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,
|
oclog(ws, LOG_ERR,
|
||||||
"have not received TCP DPD for very long; tearing down connection");
|
"have not received TCP DPD for very long; tearing down connection");
|
||||||
return -1;
|
return -1;
|
||||||
@@ -1018,7 +1017,8 @@ static int connect_handler(worker_st * ws)
|
|||||||
{
|
{
|
||||||
struct http_req_st *req = &ws->req;
|
struct http_req_st *req = &ws->req;
|
||||||
fd_set rfds;
|
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;
|
unsigned tls_retry, dtls_mtu, cstp_mtu;
|
||||||
char *p;
|
char *p;
|
||||||
#ifdef HAVE_PSELECT
|
#ifdef HAVE_PSELECT
|
||||||
@@ -1030,7 +1030,6 @@ static int connect_handler(worker_st * ws)
|
|||||||
time_t udp_recv_time = 0, now;
|
time_t udp_recv_time = 0, now;
|
||||||
struct timespec tnow;
|
struct timespec tnow;
|
||||||
unsigned mtu_overhead = 0, ip6;
|
unsigned mtu_overhead = 0, ip6;
|
||||||
int sndbuf;
|
|
||||||
socklen_t sl;
|
socklen_t sl;
|
||||||
bandwidth_st b_tx;
|
bandwidth_st b_tx;
|
||||||
bandwidth_st b_rx;
|
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");
|
ret = tls_puts(ws->session, "X-CSTP-Version: 1\r\n");
|
||||||
SEND_ERR(ret);
|
SEND_ERR(ret);
|
||||||
|
|
||||||
ret = tls_printf(ws->session, "X-CSTP-DPD: %u\r\n", ws->config->dpd);
|
if (req->is_mobile)
|
||||||
SEND_ERR(ret);
|
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) {
|
if (ws->config->default_domain) {
|
||||||
ret =
|
ret =
|
||||||
@@ -1310,14 +1317,14 @@ static int connect_handler(worker_st * ws)
|
|||||||
|
|
||||||
/* set TCP socket options */
|
/* set TCP socket options */
|
||||||
if (ws->config->output_buffer > 0) {
|
if (ws->config->output_buffer > 0) {
|
||||||
sndbuf = ws->conn_mtu * ws->config->output_buffer;
|
t = ws->conn_mtu * ws->config->output_buffer;
|
||||||
ret =
|
ret =
|
||||||
setsockopt(ws->conn_fd, SOL_SOCKET, SO_SNDBUF, &sndbuf,
|
setsockopt(ws->conn_fd, SOL_SOCKET, SO_SNDBUF, &t,
|
||||||
sizeof(sndbuf));
|
sizeof(t));
|
||||||
if (ret == -1)
|
if (ret == -1)
|
||||||
oclog(ws, LOG_DEBUG,
|
oclog(ws, LOG_DEBUG,
|
||||||
"setsockopt(TCP, SO_SNDBUF) to %u, failed.",
|
"setsockopt(TCP, SO_SNDBUF) to %u, failed.",
|
||||||
sndbuf);
|
t);
|
||||||
}
|
}
|
||||||
|
|
||||||
set_net_priority(ws, ws->conn_fd, ws->config->net_priority);
|
set_net_priority(ws, ws->conn_fd, ws->config->net_priority);
|
||||||
@@ -1334,10 +1341,10 @@ static int connect_handler(worker_st * ws)
|
|||||||
ws->buffer);
|
ws->buffer);
|
||||||
SEND_ERR(ret);
|
SEND_ERR(ret);
|
||||||
|
|
||||||
ret =
|
if (dpd > 0) {
|
||||||
tls_printf(ws->session, "X-DTLS-DPD: %u\r\n",
|
ret = tls_printf(ws->session, "X-DTLS-DPD: %u\r\n", dpd);
|
||||||
ws->config->dpd);
|
SEND_ERR(ret);
|
||||||
SEND_ERR(ret);
|
}
|
||||||
|
|
||||||
ret =
|
ret =
|
||||||
tls_printf(ws->session, "X-DTLS-Port: %u\r\n",
|
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);
|
oclog(ws, LOG_DEBUG, "suggesting DTLS MTU %u", dtls_mtu);
|
||||||
|
|
||||||
if (ws->config->output_buffer > 0) {
|
if (ws->config->output_buffer > 0) {
|
||||||
sndbuf = MIN(2048, dtls_mtu * ws->config->output_buffer);
|
t = MIN(2048, dtls_mtu * ws->config->output_buffer);
|
||||||
setsockopt(ws->udp_fd, SOL_SOCKET, SO_SNDBUF, &sndbuf,
|
setsockopt(ws->udp_fd, SOL_SOCKET, SO_SNDBUF, &t,
|
||||||
sizeof(sndbuf));
|
sizeof(t));
|
||||||
if (ret == -1)
|
if (ret == -1)
|
||||||
oclog(ws, LOG_DEBUG,
|
oclog(ws, LOG_DEBUG,
|
||||||
"setsockopt(UDP, SO_SNDBUF) to %u, failed.",
|
"setsockopt(UDP, SO_SNDBUF) to %u, failed.", t);
|
||||||
sndbuf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
set_net_priority(ws, ws->udp_fd, ws->config->net_priority);
|
set_net_priority(ws, ws->udp_fd, ws->config->net_priority);
|
||||||
@@ -1517,7 +1523,7 @@ static int connect_handler(worker_st * ws)
|
|||||||
gettime(&tnow);
|
gettime(&tnow);
|
||||||
now = tnow.tv_sec;
|
now = tnow.tv_sec;
|
||||||
|
|
||||||
if (periodic_check(ws, mtu_overhead, now) < 0)
|
if (periodic_check(ws, mtu_overhead, now, dpd) < 0)
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
if (FD_ISSET(ws->tun_fd, &rfds)) {
|
if (FD_ISSET(ws->tun_fd, &rfds)) {
|
||||||
|
|||||||
@@ -42,6 +42,18 @@ typedef enum {
|
|||||||
UP_ACTIVE
|
UP_ACTIVE
|
||||||
} udp_port_state_t;
|
} 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 {
|
enum {
|
||||||
HEADER_COOKIE = 1,
|
HEADER_COOKIE = 1,
|
||||||
HEADER_MASTER_SECRET,
|
HEADER_MASTER_SECRET,
|
||||||
@@ -49,6 +61,7 @@ enum {
|
|||||||
HEADER_CSTP_MTU,
|
HEADER_CSTP_MTU,
|
||||||
HEADER_CSTP_ATYPE,
|
HEADER_CSTP_ATYPE,
|
||||||
HEADER_DTLS_MTU,
|
HEADER_DTLS_MTU,
|
||||||
|
HEADER_DEVICE_TYPE,
|
||||||
HEADER_DTLS_CIPHERSUITE,
|
HEADER_DTLS_CIPHERSUITE,
|
||||||
HEADER_CONNECTION,
|
HEADER_CONNECTION,
|
||||||
HEADER_FULL_IPV6,
|
HEADER_FULL_IPV6,
|
||||||
@@ -94,6 +107,8 @@ struct http_req_st {
|
|||||||
uint8_t sid_cookie[SID_SIZE];
|
uint8_t sid_cookie[SID_SIZE];
|
||||||
unsigned int sid_cookie_set;
|
unsigned int sid_cookie_set;
|
||||||
|
|
||||||
|
unsigned int is_mobile;
|
||||||
|
|
||||||
unsigned char master_secret[TLS_MASTER_SIZE];
|
unsigned char master_secret[TLS_MASTER_SIZE];
|
||||||
unsigned int master_secret_set;
|
unsigned int master_secret_set;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user