Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Set X-CSTP-Base-MTU: for new servers
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
  • Loading branch information
David Woodhouse authored and David Woodhouse committed Jun 8, 2012
1 parent e68dc3d commit e2c36e3
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 4 deletions.
68 changes: 67 additions & 1 deletion cstp.c
Expand Up @@ -32,6 +32,9 @@
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <netinet/tcp.h>
#include <sys/types.h>
#include <sys/socket.h>

#include <openssl/ssl.h>
#include <openssl/err.h>
Expand Down Expand Up @@ -86,6 +89,64 @@ static int __attribute__ ((format (printf, 3, 4)))
return ret;
}

/* Calculate MTU to request. Old servers simply use the X-CSTP-MTU: header,
* which represents the tunnel MTU, while new servers do calculations on the
* X-CSTP-Base-MTU: header which represents the cleartext MTU between client
* and server.
*
* If possible, the legacy MTU value should be the TCP MSS less 5 bytes of
* TLS and 8 bytes of CSTP overhead. We can get the MSS from either the
* TCP_INFO or TCP_MAXSEG sockopts.
*
* The base MTU comes from the TCP_INFO sockopt under Linux, but I don't know
* how to work it out on other systems. So leave it blank and do things the
* legacy way there. Contributions welcome...
*
* If we don't even have TCP_MAXSEG, then default to sending a legacy MTU of
* 1406 which is what we always used to do.
*/
static void calculate_mtu(struct openconnect_info *vpninfo, int *base_mtu, int *mtu)
{
*mtu = vpninfo->mtu;
*base_mtu = vpninfo->basemtu;

#ifdef TCP_INFO
if (!*mtu || !*base_mtu) {
struct tcp_info ti;
socklen_t ti_size = sizeof(ti);

if (!getsockopt(vpninfo->ssl_fd, SOL_TCP, TCP_INFO,
&ti, &ti_size)) {
vpn_progress(vpninfo, PRG_TRACE,
_("TCP_INFO rcv mss %d, snd mss %d, adv mss %d, pmtu %d\n"),
ti.tcpi_rcv_mss, ti.tcpi_snd_mss, ti.tcpi_advmss, ti.tcpi_pmtu);
if (!*base_mtu) *base_mtu = ti.tcpi_pmtu;
if (!*mtu) {
if (ti.tcpi_rcv_mss < ti.tcpi_snd_mss)
*mtu = ti.tcpi_rcv_mss - 13;
else
*mtu = ti.tcpi_snd_mss - 13;
}
}
}
#endif
#ifdef TCP_MAXSEG
if (!*mtu) {
int mss;
socklen_t mss_size = sizeof(mss);
if (!getsockopt(vpninfo->ssl_fd, SOL_TCP, TCP_MAXSEG,
&mss, &mss_size)) {
vpn_progress(vpninfo, PRG_TRACE, _("TCP_MAXSEG %d\n"), mss);
*mtu = mss - 13;
}
}
#endif
if (!*mtu) {
/* Default */
*mtu = 1406;
}
}

static int start_cstp_connection(struct openconnect_info *vpninfo)
{
char buf[65536];
Expand All @@ -100,6 +161,7 @@ static int start_cstp_connection(struct openconnect_info *vpninfo)
const char *old_addr6 = vpninfo->vpn_addr6;
const char *old_netmask6 = vpninfo->vpn_netmask6;
struct split_include *inc;
int base_mtu, mtu;

/* Clear old options which will be overwritten */
vpninfo->vpn_addr = vpninfo->vpn_netmask = NULL;
Expand Down Expand Up @@ -132,6 +194,8 @@ static int start_cstp_connection(struct openconnect_info *vpninfo)
}

retry:
calculate_mtu(vpninfo, &base_mtu, &mtu);

buf[0] = 0;
buf_append(buf, sizeof(buf), "CONNECT /CSCOSSLC/tunnel HTTP/1.1\r\n");
buf_append(buf, sizeof(buf), "Host: %s\r\n", vpninfo->hostname);
Expand All @@ -141,7 +205,9 @@ static int start_cstp_connection(struct openconnect_info *vpninfo)
buf_append(buf, sizeof(buf), "X-CSTP-Hostname: %s\r\n", vpninfo->localname);
if (vpninfo->deflate && i < sizeof(buf))
buf_append(buf, sizeof(buf), "X-CSTP-Accept-Encoding: deflate;q=1.0\r\n");
buf_append(buf, sizeof(buf), "X-CSTP-MTU: %d\r\n", vpninfo->mtu);
if (base_mtu)
buf_append(buf, sizeof(buf), "X-CSTP-Base-MTU: %d\r\n", base_mtu);
buf_append(buf, sizeof(buf), "X-CSTP-MTU: %d\r\n", mtu);
buf_append(buf, sizeof(buf), "X-CSTP-Address-Type: %s\r\n",
vpninfo->disable_ipv6?"IPv4":"IPv6,IPv4");
buf_append(buf, sizeof(buf), "X-DTLS-Master-Secret: ");
Expand Down
12 changes: 11 additions & 1 deletion main.c
Expand Up @@ -82,6 +82,7 @@ int non_inter;

enum {
OPT_AUTHGROUP = 0x100,
OPT_BASEMTU,
OPT_CAFILE,
OPT_CONFIGFILE,
OPT_COOKIEONLY,
Expand Down Expand Up @@ -130,6 +131,7 @@ static struct option long_options[] = {
OPTION("help", 0, 'h'),
OPTION("interface", 1, 'i'),
OPTION("mtu", 1, 'm'),
OPTION("base-mtu", 1, OPT_BASEMTU),
OPTION("setuid", 1, 'U'),
OPTION("script", 1, 's'),
OPTION("script-tun", 0, 'S'),
Expand Down Expand Up @@ -199,6 +201,7 @@ static void usage(void)
printf(" --csd-user=USER %s\n", _("Drop privileges during CSD execution"));
printf(" --csd-wrapper=SCRIPT %s\n", _("Run SCRIPT instead of CSD binary"));
printf(" -m, --mtu=MTU %s\n", _("Request MTU from server"));
printf(" --base-mtu=MTU %s\n", _("Indicate path MTU to/from server"));
printf(" -p, --key-password=PASS %s\n", _("Set key passphrase or TPM SRK PIN"));
printf(" --key-password-from-fsid %s\n", _("Key passphrase is fsid of file system"));
printf(" -P, --proxy=URL %s\n", _("Set proxy server"));
Expand Down Expand Up @@ -412,7 +415,7 @@ int main(int argc, char **argv)
/* Set up some defaults */
vpninfo->tun_fd = vpninfo->ssl_fd = vpninfo->dtls_fd = vpninfo->new_dtls_fd = -1;
vpninfo->useragent = openconnect_create_useragent("Open AnyConnect VPN Agent");
vpninfo->mtu = 1406;
vpninfo->mtu = 0;
vpninfo->deflate = 1;
vpninfo->dtls_attempt_period = 60;
vpninfo->max_qlen = 10;
Expand Down Expand Up @@ -548,6 +551,13 @@ int main(int argc, char **argv)
vpninfo->mtu = 576;
}
break;
case OPT_BASEMTU:
vpninfo->basemtu = atol(config_arg);
if (vpninfo->basemtu < 576) {
fprintf(stderr, _("MTU %d too small\n"), vpninfo->basemtu);
vpninfo->basemtu = 576;
}
break;
case 'p':
vpninfo->cert_password = strdup(config_arg);
break;
Expand Down
2 changes: 1 addition & 1 deletion openconnect-internal.h
Expand Up @@ -199,7 +199,7 @@ struct openconnect_info {
int script_tun;
char *ifname;

int mtu;
int mtu, basemtu;
const char *banner;
const char *vpn_addr;
const char *vpn_netmask;
Expand Down
10 changes: 9 additions & 1 deletion openconnect.8.in
Expand Up @@ -22,6 +22,7 @@ openconnect \- Connect to Cisco AnyConnect VPN
.OP \-U,\-\-setuid user
.OP \-\-csd\-user user
.OP \-m,\-\-mtu mtu
.OP \-\-basemtu mtu
.OP \-p,\-\-key\-password pass
.OP \-P,\-\-proxy proxyurl
.OP \-\-no\-proxy
Expand Down Expand Up @@ -159,7 +160,14 @@ instead of the CSD (Cisco Secure Desktop) script.
.B \-m,\-\-mtu=MTU
Request
.I MTU
from server
from server as the MTU of the tunnel.
.TP
.B \-\-basemtu=MTU
Indicate
.I MTU
as the path MTU between client and server on the unencrypted network. Newer
servers will automatically calculate the MTU to be used on the tunnel from
this value.
.TP
.B \-p,\-\-key\-password=PASS
Provide passphrase for certificate file, or SRK (System Root Key) PIN for TPM
Expand Down

0 comments on commit e2c36e3

Please sign in to comment.