From 747f9cb34ff50b74142eb52f8a0de8827fe78eda Mon Sep 17 00:00:00 2001 From: Nikos Mavrogiannopoulos Date: Wed, 2 Apr 2014 16:01:56 +0200 Subject: [PATCH] When connecting the UDP socket use the address of the TCP socket to bind on. --- dtls.c | 70 +++++++++++++++++++++++++++++++++++++----------------------------- 1 file changed, 39 insertions(+), 31 deletions(-) diff --git a/dtls.c b/dtls.c index 48d7b5b..42c576f 100644 --- a/dtls.c +++ b/dtls.c @@ -461,6 +461,15 @@ void dtls_shutdown(struct openconnect_info *vpninfo) int connect_dtls_socket(struct openconnect_info *vpninfo) { int dtls_fd, ret, sndbuf; + union { + struct sockaddr_in in; + struct sockaddr_in6 in6; + } dtls_bind_addr; +#ifdef __linux__ + socklen_t dtls_bind_addrlen; +#else + int dtls_bind_addrlen; +#endif /* Sanity check for the removal of new_dtls_{fd,ssl} */ if (vpninfo->dtls_fd != -1) { @@ -500,40 +509,39 @@ int connect_dtls_socket(struct openconnect_info *vpninfo) sndbuf = vpninfo->ip_info.mtu * 2; setsockopt(dtls_fd, SOL_SOCKET, SO_SNDBUF, (void *)&sndbuf, sizeof(sndbuf)); - if (vpninfo->dtls_local_port) { - union { - struct sockaddr_in in; - struct sockaddr_in6 in6; - } dtls_bind_addr; - int dtls_bind_addrlen; + dtls_bind_addrlen = sizeof(dtls_bind_addr); + if (getsockname(vpninfo->ssl_fd, (struct sockaddr*)&dtls_bind_addr, &dtls_bind_addrlen)==-1) { + vpn_progress(vpninfo, PRG_ERR, + _("Could not bind to the same interface as TLS\n")); memset(&dtls_bind_addr, 0, sizeof(dtls_bind_addr)); + } - if (vpninfo->peer_addr->sa_family == AF_INET) { - struct sockaddr_in *addr = &dtls_bind_addr.in; - dtls_bind_addrlen = sizeof(*addr); - addr->sin_family = AF_INET; - addr->sin_addr.s_addr = INADDR_ANY; - addr->sin_port = htons(vpninfo->dtls_local_port); - } else if (vpninfo->peer_addr->sa_family == AF_INET6) { - struct sockaddr_in6 *addr = &dtls_bind_addr.in6; - dtls_bind_addrlen = sizeof(*addr); - addr->sin6_family = AF_INET6; - addr->sin6_addr = in6addr_any; - addr->sin6_port = htons(vpninfo->dtls_local_port); - } else { - vpn_progress(vpninfo, PRG_ERR, - _("Unknown protocol family %d. Cannot do DTLS\n"), - vpninfo->peer_addr->sa_family); - vpninfo->dtls_attempt_period = 0; - closesocket(dtls_fd); - return -EINVAL; - } + if (vpninfo->peer_addr->sa_family == AF_INET) { + struct sockaddr_in *addr = &dtls_bind_addr.in; + dtls_bind_addrlen = sizeof(*addr); - if (bind(dtls_fd, (struct sockaddr *)&dtls_bind_addr, dtls_bind_addrlen)) { - perror(_("Bind UDP socket for DTLS")); - closesocket(dtls_fd); - return -EINVAL; - } + addr->sin_family = AF_INET; + addr->sin_addr.s_addr = INADDR_ANY; + addr->sin_port = htons(vpninfo->dtls_local_port); + } else if (vpninfo->peer_addr->sa_family == AF_INET6) { + struct sockaddr_in6 *addr = &dtls_bind_addr.in6; + dtls_bind_addrlen = sizeof(*addr); + addr->sin6_family = AF_INET6; + addr->sin6_addr = in6addr_any; + addr->sin6_port = htons(vpninfo->dtls_local_port); + } else { + vpn_progress(vpninfo, PRG_ERR, + _("Unknown protocol family %d. Cannot do DTLS\n"), + vpninfo->peer_addr->sa_family); + vpninfo->dtls_attempt_period = 0; + closesocket(dtls_fd); + return -EINVAL; + } + + if (bind(dtls_fd, (struct sockaddr *)&dtls_bind_addr, dtls_bind_addrlen)) { + perror(_("Bind UDP socket for DTLS")); + closesocket(dtls_fd); + return -EINVAL; } if (connect(dtls_fd, vpninfo->dtls_addr, vpninfo->peer_addrlen)) { -- 1.9.0