mirror of
https://gitlab.com/openconnect/ocserv.git
synced 2026-10-13 18:12:03 +08:00
Take into account peer's MTU values after considering the overhead.
This commit is contained in:
+44
-40
@@ -55,6 +55,8 @@
|
|||||||
|
|
||||||
#include <http_parser.h>
|
#include <http_parser.h>
|
||||||
|
|
||||||
|
#define MIN_MTU(ws) (((ws)->vinfo.ipv6!=NULL)?1281:257)
|
||||||
|
|
||||||
/* after that time (secs) of inactivity in the UDP part, connection switches to
|
/* after that time (secs) of inactivity in the UDP part, connection switches to
|
||||||
* TCP (if activity occurs there).
|
* TCP (if activity occurs there).
|
||||||
*/
|
*/
|
||||||
@@ -833,9 +835,9 @@ void mtu_set(worker_st * ws, unsigned mtu)
|
|||||||
ws->conn_mtu = mtu;
|
ws->conn_mtu = mtu;
|
||||||
|
|
||||||
if (ws->dtls_session)
|
if (ws->dtls_session)
|
||||||
gnutls_dtls_set_data_mtu(ws->dtls_session, mtu);
|
gnutls_dtls_set_data_mtu(ws->dtls_session, ws->conn_mtu);
|
||||||
|
|
||||||
mtu_send(ws, mtu);
|
mtu_send(ws, ws->conn_mtu);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* sets the current value of mtu as bad,
|
/* sets the current value of mtu as bad,
|
||||||
@@ -851,9 +853,9 @@ int mtu_not_ok(worker_st * ws)
|
|||||||
if (ws->last_good_mtu >= ws->conn_mtu) {
|
if (ws->last_good_mtu >= ws->conn_mtu) {
|
||||||
ws->last_good_mtu = (2 * (ws->conn_mtu)) / 3;
|
ws->last_good_mtu = (2 * (ws->conn_mtu)) / 3;
|
||||||
|
|
||||||
if (ws->last_good_mtu < 128) {
|
if (ws->last_good_mtu < MIN_MTU(ws)) {
|
||||||
oclog(ws, LOG_INFO,
|
oclog(ws, LOG_INFO,
|
||||||
"could not calculate a valid MTU. Disabling DTLS.");
|
"could not calculate a sufficient MTU. Disabling DTLS.");
|
||||||
ws->udp_state = UP_DISABLED;
|
ws->udp_state = UP_DISABLED;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -1010,7 +1012,6 @@ 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;
|
||||||
struct vpn_st vinfo;
|
|
||||||
unsigned tls_retry, dtls_mtu, cstp_mtu;
|
unsigned tls_retry, dtls_mtu, cstp_mtu;
|
||||||
char *p;
|
char *p;
|
||||||
#ifdef HAVE_PSELECT
|
#ifdef HAVE_PSELECT
|
||||||
@@ -1080,7 +1081,7 @@ static int connect_handler(worker_st * ws)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = get_rt_vpn_info(ws, &vinfo, (char *)ws->buffer, ws->buffer_size);
|
ret = get_rt_vpn_info(ws, &ws->vinfo, (char *)ws->buffer, ws->buffer_size);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
oclog(ws, LOG_ERR,
|
oclog(ws, LOG_ERR,
|
||||||
"no networks are configured; rejecting client");
|
"no networks are configured; rejecting client");
|
||||||
@@ -1120,73 +1121,73 @@ static int connect_handler(worker_st * ws)
|
|||||||
oclog(ws, LOG_DEBUG, "disabling UDP (DTLS) connection");
|
oclog(ws, LOG_DEBUG, "disabling UDP (DTLS) connection");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vinfo.ipv4 && req->no_ipv4 == 0) {
|
if (ws->vinfo.ipv4 && req->no_ipv4 == 0) {
|
||||||
oclog(ws, LOG_DEBUG, "sending IPv4 %s", vinfo.ipv4);
|
oclog(ws, LOG_DEBUG, "sending IPv4 %s", ws->vinfo.ipv4);
|
||||||
ret =
|
ret =
|
||||||
tls_printf(ws->session, "X-CSTP-Address: %s\r\n",
|
tls_printf(ws->session, "X-CSTP-Address: %s\r\n",
|
||||||
vinfo.ipv4);
|
ws->vinfo.ipv4);
|
||||||
SEND_ERR(ret);
|
SEND_ERR(ret);
|
||||||
|
|
||||||
if (vinfo.ipv4_netmask) {
|
if (ws->vinfo.ipv4_netmask) {
|
||||||
ret =
|
ret =
|
||||||
tls_printf(ws->session, "X-CSTP-Netmask: %s\r\n",
|
tls_printf(ws->session, "X-CSTP-Netmask: %s\r\n",
|
||||||
vinfo.ipv4_netmask);
|
ws->vinfo.ipv4_netmask);
|
||||||
SEND_ERR(ret);
|
SEND_ERR(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vinfo.ipv4_dns) {
|
if (ws->vinfo.ipv4_dns) {
|
||||||
ret =
|
ret =
|
||||||
tls_printf(ws->session, "X-CSTP-DNS: %s\r\n",
|
tls_printf(ws->session, "X-CSTP-DNS: %s\r\n",
|
||||||
vinfo.ipv4_dns);
|
ws->vinfo.ipv4_dns);
|
||||||
SEND_ERR(ret);
|
SEND_ERR(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vinfo.ipv4_nbns) {
|
if (ws->vinfo.ipv4_nbns) {
|
||||||
ret =
|
ret =
|
||||||
tls_printf(ws->session, "X-CSTP-NBNS: %s\r\n",
|
tls_printf(ws->session, "X-CSTP-NBNS: %s\r\n",
|
||||||
vinfo.ipv4_nbns);
|
ws->vinfo.ipv4_nbns);
|
||||||
SEND_ERR(ret);
|
SEND_ERR(ret);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vinfo.ipv6 && req->no_ipv6 == 0) {
|
if (ws->vinfo.ipv6 && req->no_ipv6 == 0) {
|
||||||
oclog(ws, LOG_DEBUG, "sending IPv6 %s", vinfo.ipv6);
|
oclog(ws, LOG_DEBUG, "sending IPv6 %s", ws->vinfo.ipv6);
|
||||||
ret =
|
ret =
|
||||||
tls_printf(ws->session, "X-CSTP-Address: %s\r\n",
|
tls_printf(ws->session, "X-CSTP-Address: %s\r\n",
|
||||||
vinfo.ipv6);
|
ws->vinfo.ipv6);
|
||||||
SEND_ERR(ret);
|
SEND_ERR(ret);
|
||||||
|
|
||||||
if (vinfo.ipv6_netmask) {
|
if (ws->vinfo.ipv6_netmask) {
|
||||||
ret =
|
ret =
|
||||||
tls_printf(ws->session, "X-CSTP-Netmask: %s\r\n",
|
tls_printf(ws->session, "X-CSTP-Netmask: %s\r\n",
|
||||||
vinfo.ipv6_netmask);
|
ws->vinfo.ipv6_netmask);
|
||||||
SEND_ERR(ret);
|
SEND_ERR(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vinfo.ipv6_dns) {
|
if (ws->vinfo.ipv6_dns) {
|
||||||
ret =
|
ret =
|
||||||
tls_printf(ws->session, "X-CSTP-DNS: %s\r\n",
|
tls_printf(ws->session, "X-CSTP-DNS: %s\r\n",
|
||||||
vinfo.ipv6_dns);
|
ws->vinfo.ipv6_dns);
|
||||||
SEND_ERR(ret);
|
SEND_ERR(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vinfo.ipv6_nbns) {
|
if (ws->vinfo.ipv6_nbns) {
|
||||||
ret =
|
ret =
|
||||||
tls_printf(ws->session, "X-CSTP-NBNS: %s\r\n",
|
tls_printf(ws->session, "X-CSTP-NBNS: %s\r\n",
|
||||||
vinfo.ipv6_nbns);
|
ws->vinfo.ipv6_nbns);
|
||||||
SEND_ERR(ret);
|
SEND_ERR(ret);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < vinfo.routes_size; i++) {
|
for (i = 0; i < ws->vinfo.routes_size; i++) {
|
||||||
if (req->no_ipv6 != 0 && strchr(vinfo.routes[i], ':') != 0)
|
if (req->no_ipv6 != 0 && strchr(ws->vinfo.routes[i], ':') != 0)
|
||||||
continue;
|
continue;
|
||||||
if (req->no_ipv4 != 0 && strchr(vinfo.routes[i], '.') != 0)
|
if (req->no_ipv4 != 0 && strchr(ws->vinfo.routes[i], '.') != 0)
|
||||||
continue;
|
continue;
|
||||||
oclog(ws, LOG_DEBUG, "adding route %s", vinfo.routes[i]);
|
oclog(ws, LOG_DEBUG, "adding route %s", ws->vinfo.routes[i]);
|
||||||
ret = tls_printf(ws->session,
|
ret = tls_printf(ws->session,
|
||||||
"X-CSTP-Split-Include: %s\r\n",
|
"X-CSTP-Split-Include: %s\r\n",
|
||||||
vinfo.routes[i]);
|
ws->vinfo.routes[i]);
|
||||||
SEND_ERR(ret);
|
SEND_ERR(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1227,14 +1228,14 @@ static int connect_handler(worker_st * ws)
|
|||||||
SEND_ERR(ret);
|
SEND_ERR(ret);
|
||||||
|
|
||||||
if (ws->config->default_mtu > 0) {
|
if (ws->config->default_mtu > 0) {
|
||||||
vinfo.mtu = ws->config->default_mtu;
|
ws->vinfo.mtu = ws->config->default_mtu;
|
||||||
}
|
}
|
||||||
|
|
||||||
mtu_overhead = CSTP_OVERHEAD;
|
mtu_overhead = CSTP_OVERHEAD;
|
||||||
ws->conn_mtu = vinfo.mtu - mtu_overhead;
|
ws->conn_mtu = ws->vinfo.mtu - mtu_overhead;
|
||||||
|
|
||||||
if (req->cstp_mtu > 0) {
|
if (req->cstp_mtu > 0) {
|
||||||
ws->conn_mtu = MIN(ws->conn_mtu, req->cstp_mtu);
|
oclog(ws, LOG_DEBUG, "peer's CSTP MTU is %u (ignored)", req->cstp_mtu);
|
||||||
oclog(ws, LOG_DEBUG, "peer CSTP MTU is %u", req->cstp_mtu);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sl = sizeof(max);
|
sl = sizeof(max);
|
||||||
@@ -1313,19 +1314,22 @@ static int connect_handler(worker_st * ws)
|
|||||||
else
|
else
|
||||||
mtu_overhead = 40 + CSTP_DTLS_OVERHEAD; /* ipv6 */
|
mtu_overhead = 40 + CSTP_DTLS_OVERHEAD; /* ipv6 */
|
||||||
mtu_overhead += 8; /* udp */
|
mtu_overhead += 8; /* udp */
|
||||||
ws->conn_mtu = MIN(ws->conn_mtu, vinfo.mtu - mtu_overhead);
|
ws->conn_mtu = MIN(ws->conn_mtu, ws->vinfo.mtu - mtu_overhead);
|
||||||
|
|
||||||
if (req->dtls_mtu > 0) {
|
|
||||||
ws->conn_mtu = MIN(req->dtls_mtu, ws->conn_mtu);
|
|
||||||
oclog(ws, LOG_INFO,
|
|
||||||
"reducing DTLS MTU to peer's DTLS MTU (%u)",
|
|
||||||
req->dtls_mtu);
|
|
||||||
}
|
|
||||||
|
|
||||||
overhead =
|
overhead =
|
||||||
CSTP_DTLS_OVERHEAD +
|
CSTP_DTLS_OVERHEAD +
|
||||||
tls_get_overhead(ws->req.selected_ciphersuite->gnutls_version,
|
tls_get_overhead(ws->req.selected_ciphersuite->gnutls_version,
|
||||||
ws->req.selected_ciphersuite->gnutls_cipher, ws->req.selected_ciphersuite->gnutls_mac);
|
ws->req.selected_ciphersuite->gnutls_cipher, ws->req.selected_ciphersuite->gnutls_mac);
|
||||||
|
|
||||||
|
if (req->dtls_mtu <= 0)
|
||||||
|
req->dtls_mtu = req->cstp_mtu;
|
||||||
|
if (req->dtls_mtu > 0) {
|
||||||
|
ws->conn_mtu = MIN(req->dtls_mtu+overhead+mtu_overhead, ws->conn_mtu);
|
||||||
|
oclog(ws, LOG_DEBUG,
|
||||||
|
"peer's DTLS MTU is %u (overhead: %u)", req->dtls_mtu, mtu_overhead+overhead);
|
||||||
|
}
|
||||||
|
|
||||||
dtls_mtu = ws->conn_mtu - overhead;
|
dtls_mtu = ws->conn_mtu - overhead;
|
||||||
|
|
||||||
tls_printf(ws->session, "X-DTLS-MTU: %u\r\n", dtls_mtu);
|
tls_printf(ws->session, "X-DTLS-MTU: %u\r\n", dtls_mtu);
|
||||||
|
|||||||
@@ -156,6 +156,9 @@ typedef struct worker_st {
|
|||||||
uint8_t session_id[GNUTLS_MAX_SESSION_ID];
|
uint8_t session_id[GNUTLS_MAX_SESSION_ID];
|
||||||
unsigned cert_auth_ok;
|
unsigned cert_auth_ok;
|
||||||
int tun_fd;
|
int tun_fd;
|
||||||
|
|
||||||
|
/* information on the tun device addresses and network */
|
||||||
|
struct vpn_st vinfo;
|
||||||
|
|
||||||
/* additional data - received per user or per group */
|
/* additional data - received per user or per group */
|
||||||
unsigned routes_size;
|
unsigned routes_size;
|
||||||
|
|||||||
Reference in New Issue
Block a user