Преглед изворни кода

openconnect: made server IP resolving on reconnection conditional

Signed-off-by: Nikos Mavrogiannopoulos <nmav@gnutls.org>
Nikos Mavrogiannopoulos пре 10 година
родитељ
комит
be753f0208
2 измењених фајлова са 147 додато и 8 уклоњено
  1. 1
    1
      net/openconnect/Makefile
  2. 146
    7
      net/openconnect/patches/001-always-resolve-ips.patch

+ 1
- 1
net/openconnect/Makefile Прегледај датотеку

@@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk
9 9
 
10 10
 PKG_NAME:=openconnect
11 11
 PKG_VERSION:=7.00
12
-PKG_RELEASE:=1
12
+PKG_RELEASE:=2
13 13
 
14 14
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
15 15
 PKG_SOURCE_URL:=ftp://ftp.infradead.org/pub/openconnect/

+ 146
- 7
net/openconnect/patches/001-always-resolve-ips.patch Прегледај датотеку

@@ -1,22 +1,161 @@
1 1
 diff --git a/cstp.c b/cstp.c
2
-index b1235ef..05c3444 100644
2
+index b1235ef..f955b82 100644
3 3
 --- a/cstp.c
4 4
 +++ b/cstp.c
5
-@@ -591,6 +591,8 @@ static int cstp_reconnect(struct openconnect_info *vpninfo)
5
+@@ -570,7 +570,10 @@ int openconnect_make_cstp_connection(struct openconnect_info *vpninfo)
6
+ 	return ret;
7
+ }
8
+ 
9
+-static int cstp_reconnect(struct openconnect_info *vpninfo)
10
++/* When dead peer is set, this function will re-attempt resolving
11
++ * the peer in case its IP changed.
12
++ */
13
++static int cstp_reconnect(struct openconnect_info *vpninfo, unsigned dead_peer)
14
+ {
15
+ 	int ret;
16
+ 	int timeout;
17
+@@ -591,6 +594,16 @@ static int cstp_reconnect(struct openconnect_info *vpninfo)
6 18
  	timeout = vpninfo->reconnect_timeout;
7 19
  	interval = vpninfo->reconnect_interval;
8 20
  
9
-+	free(vpninfo->peer_addr); 
10
-+	vpninfo->peer_addr = NULL;
21
++	/* handle cases with dynamic DNS by forcing a new resolve.
22
++	 * The original IP is saved to retry as fallback if resolving
23
++	 * fails.
24
++	 */
25
++	if (dead_peer && vpninfo->first_peer_addr == NULL) {
26
++		vpninfo->first_peer_addr = vpninfo->peer_addr;
27
++		vpninfo->first_peer_addrlen = vpninfo->peer_addrlen;
28
++		vpninfo->peer_addr = NULL;
29
++	}
30
++
11 31
  	while ((ret = openconnect_make_cstp_connection(vpninfo))) {
12 32
  		if (timeout <= 0)
13 33
  			return ret;
14
-@@ -611,6 +613,8 @@ static int cstp_reconnect(struct openconnect_info *vpninfo)
34
+@@ -611,6 +624,11 @@ static int cstp_reconnect(struct openconnect_info *vpninfo)
15 35
  		interval += vpninfo->reconnect_interval;
16 36
  		if (interval > RECONNECT_INTERVAL_MAX)
17 37
  			interval = RECONNECT_INTERVAL_MAX;
18
-+		free(vpninfo->peer_addr); 
19
-+		vpninfo->peer_addr = NULL;
38
++
39
++		if (dead_peer && vpninfo->first_peer_addr != NULL) {
40
++			free(vpninfo->peer_addr);
41
++			vpninfo->peer_addr = NULL;
42
++		}
20 43
  	}
21 44
  	script_config_tun(vpninfo, "reconnect");
22 45
  	return 0;
46
+@@ -903,8 +921,15 @@ int cstp_mainloop(struct openconnect_info *vpninfo, int *timeout)
47
+ 		/* Not that this will ever happen; we don't even process
48
+ 		   the setting when we're asked for it. */
49
+ 		vpn_progress(vpninfo, PRG_INFO, _("CSTP rekey due\n"));
50
+-		if (vpninfo->ssl_times.rekey_method == REKEY_TUNNEL)
51
+-			goto do_reconnect;
52
++		if (vpninfo->ssl_times.rekey_method == REKEY_TUNNEL) {
53
++			ret = cstp_reconnect(vpninfo, 0);
54
++			if (ret) {
55
++				vpn_progress(vpninfo, PRG_ERR, _("Reconnect failed\n"));
56
++				vpninfo->quit_reason = "CSTP reconnect failed";
57
++				return ret;
58
++			}
59
++			goto do_dtls_reconnect;
60
++		}
61
+ 		else if (vpninfo->ssl_times.rekey_method == REKEY_SSL) {
62
+ 			ret = cstp_handshake(vpninfo, 0);
63
+ 			if (ret) {
64
+@@ -922,7 +947,7 @@ int cstp_mainloop(struct openconnect_info *vpninfo, int *timeout)
65
+ 		vpn_progress(vpninfo, PRG_ERR,
66
+ 			     _("CSTP Dead Peer Detection detected dead peer!\n"));
67
+ 	do_reconnect:
68
+-		ret = cstp_reconnect(vpninfo);
69
++		ret = cstp_reconnect(vpninfo, 1);
70
+ 		if (ret) {
71
+ 			vpn_progress(vpninfo, PRG_ERR, _("Reconnect failed\n"));
72
+ 			vpninfo->quit_reason = "CSTP reconnect failed";
73
+diff --git a/library.c b/library.c
74
+index f5d3dc9..7c8d5ec 100644
75
+--- a/library.c
76
++++ b/library.c
77
+@@ -178,6 +178,7 @@ void openconnect_vpninfo_free(struct openconnect_info *vpninfo)
78
+ 		CloseHandle(vpninfo->dtls_event);
79
+ #endif
80
+ 	free(vpninfo->peer_addr);
81
++	free(vpninfo->first_peer_addr);
82
+ 	free_optlist(vpninfo->csd_env);
83
+ 	free_optlist(vpninfo->script_env);
84
+ 	free_optlist(vpninfo->cookies);
85
+@@ -291,6 +292,8 @@ int openconnect_set_hostname(struct openconnect_info *vpninfo,
86
+ 	vpninfo->unique_hostname = NULL;
87
+ 	free(vpninfo->peer_addr);
88
+ 	vpninfo->peer_addr = NULL;
89
++	free(vpninfo->first_peer_addr);
90
++	vpninfo->first_peer_addr = NULL;
91
+ 
92
+ 	return 0;
93
+ }
94
+diff --git a/openconnect-internal.h b/openconnect-internal.h
95
+index 1bc79e5..cafbb3c 100644
96
+--- a/openconnect-internal.h
97
++++ b/openconnect-internal.h
98
+@@ -424,6 +424,9 @@ struct openconnect_info {
99
+ 	struct sockaddr *peer_addr;
100
+ 	struct sockaddr *dtls_addr;
101
+ 
102
++	struct sockaddr *first_peer_addr;
103
++	socklen_t first_peer_addrlen;
104
++
105
+ 	int dtls_local_port;
106
+ 
107
+ 	int deflate;
108
+diff --git a/ssl.c b/ssl.c
109
+index b50652d..e341871 100644
110
+--- a/ssl.c
111
++++ b/ssl.c
112
+@@ -110,6 +110,7 @@ int connect_https_socket(struct openconnect_info *vpninfo)
113
+ {
114
+ 	int ssl_sock = -1;
115
+ 	int err;
116
++	unsigned retry_old_ip = 0;
117
+ 
118
+ 	if (!vpninfo->port)
119
+ 		vpninfo->port = 443;
120
+@@ -230,6 +231,8 @@ int connect_https_socket(struct openconnect_info *vpninfo)
121
+ 			if (hints.ai_flags & AI_NUMERICHOST)
122
+ 				free(hostname);
123
+ 			ssl_sock = -EINVAL;
124
++			if (vpninfo->first_peer_addr != NULL)
125
++				retry_old_ip = 1;
126
+ 			goto out;
127
+ 		}
128
+ 		if (hints.ai_flags & AI_NUMERICHOST)
129
+@@ -291,7 +294,10 @@ int connect_https_socket(struct openconnect_info *vpninfo)
130
+ 		}
131
+ 		freeaddrinfo(result);
132
+ 
133
++
134
+ 		if (ssl_sock < 0) {
135
++			if (vpninfo->first_peer_addr != NULL)
136
++				retry_old_ip = 1;
137
+ 			vpn_progress(vpninfo, PRG_ERR,
138
+ 				     _("Failed to connect to host %s\n"),
139
+ 				     vpninfo->proxy?:vpninfo->hostname);
140
+@@ -314,6 +320,21 @@ int connect_https_socket(struct openconnect_info *vpninfo)
141
+ 		}
142
+ 	}
143
+  out:
144
++	if (retry_old_ip != 0 && vpninfo->first_peer_addr != NULL) {
145
++		vpn_progress(vpninfo, PRG_ERR,
146
++			     _("Retrying connection to host %s with original IP\n"),
147
++				     vpninfo->proxy?:vpninfo->hostname);
148
++
149
++		retry_old_ip = 0;
150
++		if (vpninfo->first_peer_addrlen > vpninfo->peer_addrlen || vpninfo->peer_addr == NULL)
151
++			realloc_inplace(vpninfo->peer_addr, vpninfo->first_peer_addrlen);
152
++
153
++		if (vpninfo->peer_addr != NULL) {
154
++			memcpy(vpninfo->peer_addr, vpninfo->first_peer_addr, vpninfo->first_peer_addrlen);
155
++			goto reconnect;
156
++		}
157
++	}
158
++
159
+ 	/* If proxy processing returned -EAGAIN to reconnect before attempting
160
+ 	   further auth, and we failed to reconnect, we have to clean up here. */
161
+ 	cleanup_proxy_auth(vpninfo);