From 3444f811ae91d77b0bad07ed7b4de61d635bb940 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Thu, 3 Oct 2013 06:18:10 -0700 Subject: [PATCH] Set SO_SNDBUF on DTLS socket and handle -EAGAIN on it The UDP would otherwise get a huge backlog of queued packets, and VoIP over the VPN would become unusable. Signed-off-by: David Woodhouse --- dtls.c | 28 ++++++++++++++++++++++------ www/changelog.xml | 1 + 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/dtls.c b/dtls.c index 47e97d98..3b2dfc06 100644 --- a/dtls.c +++ b/dtls.c @@ -504,7 +504,7 @@ int dtls_try_handshake(struct openconnect_info *vpninfo) int connect_dtls_socket(struct openconnect_info *vpninfo) { - int dtls_fd, ret; + int dtls_fd, ret, sndbuf; if (!vpninfo->dtls_addr) { vpn_progress(vpninfo, PRG_ERR, _("No DTLS address\n")); @@ -532,6 +532,9 @@ int connect_dtls_socket(struct openconnect_info *vpninfo) return -EINVAL; } + sndbuf = vpninfo->actual_mtu * 2; + setsockopt(dtls_fd, SOL_SOCKET, SO_SNDBUF, &sndbuf, sizeof(sndbuf)); + if (vpninfo->dtls_local_port) { union { struct sockaddr_in in; @@ -821,6 +824,7 @@ int dtls_mainloop(struct openconnect_info *vpninfo, int *timeout) } /* Service outgoing packet queue */ + FD_CLR(vpninfo->dtls_fd, &vpninfo->select_wfds); while (vpninfo->outgoing_queue) { struct pkt *this = vpninfo->outgoing_queue; int ret; @@ -836,9 +840,14 @@ int dtls_mainloop(struct openconnect_info *vpninfo, int *timeout) if (ret <= 0) { ret = SSL_get_error(vpninfo->dtls_ssl, ret); - /* If it's a real error, kill the DTLS connection and - requeue the packet to be sent over SSL */ - if (ret != SSL_ERROR_WANT_READ && ret != SSL_ERROR_WANT_WRITE) { + if (ret == SSL_ERROR_WANT_WRITE) { + FD_SET(vpninfo->dtls_fd, &vpninfo->select_wfds); + vpninfo->outgoing_queue = this; + vpninfo->outgoing_qlen++; + + } else if (ret != SSL_ERROR_WANT_READ) { + /* If it's a real error, kill the DTLS connection and + requeue the packet to be sent over SSL */ vpn_progress(vpninfo, PRG_ERR, _("DTLS got write error %d. Falling back to SSL\n"), ret); @@ -846,8 +855,9 @@ int dtls_mainloop(struct openconnect_info *vpninfo, int *timeout) dtls_restart(vpninfo); vpninfo->outgoing_queue = this; vpninfo->outgoing_qlen++; + work_done = 1; } - return 1; + return work_done; } #elif defined(DTLS_GNUTLS) ret = gnutls_record_send(vpninfo->dtls_ssl, &this->hdr[7], this->len + 1); @@ -859,8 +869,14 @@ int dtls_mainloop(struct openconnect_info *vpninfo, int *timeout) dtls_restart(vpninfo); vpninfo->outgoing_queue = this; vpninfo->outgoing_qlen++; + work_done = 1; + } else if (gnutls_record_get_direction(vpninfo->dtls_ssl)) { + FD_SET(vpninfo->dtls_fd, &vpninfo->select_wfds); + vpninfo->outgoing_queue = this; + vpninfo->outgoing_qlen++; } - return 1; + + return work_done; } #endif time(&vpninfo->dtls_times.last_tx); diff --git a/www/changelog.xml b/www/changelog.xml index 55193bee..db2f6e89 100644 --- a/www/changelog.xml +++ b/www/changelog.xml @@ -17,6 +17,7 @@