Reconnection problem on roam

David Woodhouse dwmw2 at infradead.org
Sat Dec 5 19:30:07 EST 2009


On Sun, 2009-12-06 at 00:18 +0000, David Woodhouse wrote:
> On Fri, 2009-12-04 at 13:19 -0500, Colin Zheng wrote:
> > 
> > CSTP Dead Peer Detection detected dead peer!
> > getaddrinfo failed: Temporary failure in name resolution
> > sleep 10s, remaining timeout 300s
> > getaddrinfo failed: Temporary failure in name resolution
> > sleep 20s, remaining timeout 290s 
> 
> Ah. It's trying to reconnect... but it's doing a DNS lookup to find the
> address of the server again. That's not so cunning.
> 
> Can you confirm that it works properly if you specify the IP address of
> the server on the command line, instead of the DNS name?

If so, does this patch also fix it?

diff --git a/ssl.c b/ssl.c
index 88214f9..6d51146 100644
--- a/ssl.c
+++ b/ssl.c
@@ -476,52 +476,67 @@ int openconnect_open_https(struct openconnect_info *vpninfo)
 	BIO *https_bio;
 	int ssl_sock = -1;
 	int err;
-	struct addrinfo hints, *result, *rp;
-
-	memset(&hints, 0, sizeof(struct addrinfo));
-	hints.ai_family = AF_UNSPEC;
-	hints.ai_socktype = SOCK_STREAM;
-	hints.ai_flags = AI_PASSIVE | AI_NUMERICSERV;
-	hints.ai_protocol = 0;
-	hints.ai_canonname = NULL;
-	hints.ai_addr = NULL;
-	hints.ai_next = NULL;
-
-	err = getaddrinfo(vpninfo->hostname, "443", &hints, &result);
-	if (err) {
-		vpninfo->progress(vpninfo, PRG_ERR, "getaddrinfo failed: %s\n", gai_strerror(err));
-		return -EINVAL;
-	}
 
-	vpninfo->progress(vpninfo, PRG_INFO,
-			  "Attempting to connect to %s\n", vpninfo->hostname);
-
-	for (rp = result; rp ; rp = rp->ai_next) {
-		ssl_sock = socket(rp->ai_family, rp->ai_socktype,
-				  rp->ai_protocol);
-		if (ssl_sock < 0)
-			continue;
-		if (connect(ssl_sock, rp->ai_addr, rp->ai_addrlen) >= 0) {
-			/* Store the peer address we actually used, so that DTLS can
-			   use it again later */
-			vpninfo->peer_addr = malloc(rp->ai_addrlen);
-			if (!vpninfo->peer_addr) {
-				vpninfo->progress(vpninfo, PRG_ERR, "Failed to allocate sockaddr storage\n");
-				close(ssl_sock);
-				return -ENOMEM;
-			}
-			vpninfo->peer_addrlen = rp->ai_addrlen;
-			memcpy(vpninfo->peer_addr, rp->ai_addr, rp->ai_addrlen);
-			break;
+	if (vpninfo->peer_addr) {
+		ssl_sock = socket(vpninfo->peer_addr->sa_family, SOCK_STREAM, IPPROTO_IP);
+		if (ssl_sock < 0) {
+		reconn_err:
+			vpninfo->progress(vpninfo, PRG_ERR, "Failed to reconnect to host %s\n", vpninfo->hostname);
+			return -EINVAL;
 		}
-		close(ssl_sock);
-		ssl_sock = -1;
-	}
-	freeaddrinfo(result);
+		if (connect(ssl_sock, vpninfo->peer_addr, vpninfo->peer_addrlen))
+			goto reconn_err;
 
-	if (ssl_sock < 0) {
-		vpninfo->progress(vpninfo, PRG_ERR, "Failed to connect to host %s\n", vpninfo->hostname);
-		return -EINVAL;
+		
+		
+	} else {
+		struct addrinfo hints, *result, *rp;
+
+		memset(&hints, 0, sizeof(struct addrinfo));
+		hints.ai_family = AF_UNSPEC;
+		hints.ai_socktype = SOCK_STREAM;
+		hints.ai_flags = AI_PASSIVE | AI_NUMERICSERV;
+		hints.ai_protocol = 0;
+		hints.ai_canonname = NULL;
+		hints.ai_addr = NULL;
+		hints.ai_next = NULL;
+
+		err = getaddrinfo(vpninfo->hostname, "443", &hints, &result);
+		if (err) {
+			vpninfo->progress(vpninfo, PRG_ERR, "getaddrinfo failed: %s\n", gai_strerror(err));
+			return -EINVAL;
+		}
+
+		vpninfo->progress(vpninfo, PRG_INFO,
+				  "Attempting to connect to %s\n", vpninfo->hostname);
+
+		for (rp = result; rp ; rp = rp->ai_next) {
+			ssl_sock = socket(rp->ai_family, rp->ai_socktype,
+					  rp->ai_protocol);
+			if (ssl_sock < 0)
+				continue;
+			if (connect(ssl_sock, rp->ai_addr, rp->ai_addrlen) >= 0) {
+				/* Store the peer address we actually used, so that DTLS can
+				   use it again later */
+				vpninfo->peer_addr = malloc(rp->ai_addrlen);
+				if (!vpninfo->peer_addr) {
+					vpninfo->progress(vpninfo, PRG_ERR, "Failed to allocate sockaddr storage\n");
+					close(ssl_sock);
+					return -ENOMEM;
+				}
+				vpninfo->peer_addrlen = rp->ai_addrlen;
+				memcpy(vpninfo->peer_addr, rp->ai_addr, rp->ai_addrlen);
+				break;
+			}
+			close(ssl_sock);
+			ssl_sock = -1;
+		}
+		freeaddrinfo(result);
+		
+		if (ssl_sock < 0) {
+			vpninfo->progress(vpninfo, PRG_ERR, "Failed to connect to host %s\n", vpninfo->hostname);
+			return -EINVAL;
+		}
 	}
 	fcntl(ssl_sock, F_SETFD, FD_CLOEXEC);
 


-- 
dwmw2




More information about the openconnect-devel mailing list