On Thu, 2012-05-31 at 11:44 +0200, Bernhard Schmidt wrote: > we're currently testing OpenConnect 3.20 against our new shiny ASA Beta > which finally does IPv6 transport. However, when we do use that, we have > MTU problems on the link. The official AnyConnect client works fine. It'd be very interesting to know where the Cisco client gets its numbers from. How does this compare? diff --git a/cstp.c b/cstp.c index dbc24b9..5910940 100644 --- a/cstp.c +++ b/cstp.c @@ -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> @@ -86,6 +89,48 @@ static int __attribute__ ((format (printf, 3, 4))) return ret; } +static void calculate_mtu(struct openconnect_info *vpninfo, int *base_mtu, int *mtu) +{ +#ifdef TCP_MAXSEG + int mss; + socklen_t mss_size = sizeof(mss); +#endif +#ifdef TCP_INFO + struct tcp_info ti; + socklen_t ti_size = sizeof(ti); +#endif + if (vpninfo->mtu) { + /* User override */ + *base_mtu = 0; + *mtu = vpninfo->mtu; + } +#ifdef TCP_INFO + else 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); + *base_mtu = ti.tcpi_pmtu; + if (ti.tcpi_rcv_mss < ti.tcpi_snd_mss) + *mtu = ti.tcpi_rcv_mss; + else + *mtu = ti.tcpi_snd_mss; + } +#endif +#ifdef TCP_MAXSEG + else if (!getsockopt(vpninfo->ssl_fd, SOL_TCP, TCP_MAXSEG, &mss, &mss_size)) { + vpn_progress(vpninfo, PRG_TRACE, _("TCP_MAXSEG %d\n"), mss); + *mtu = mss; + /* Erm, how do we sanely find the base MTU? */ + *base_mtu = 1500; + } +#endif + else { + /* Default */ + *base_mtu = 0; + *mtu = 1406; + } +} + static int start_cstp_connection(struct openconnect_info *vpninfo) { char buf[65536]; @@ -100,6 +145,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; @@ -132,6 +178,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); @@ -141,7 +189,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: "); diff --git a/main.c b/main.c index 6f7f86c..9f52ed1 100644 --- a/main.c +++ b/main.c @@ -412,7 +412,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; -- dwmw2 -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/x-pkcs7-signature Size: 6171 bytes Desc: not available URL: <http://lists.infradead.org/pipermail/openconnect-devel/attachments/20120608/00ab415f/attachment.bin>