From: Daniel Lenski <dlenski@gmail.com>
Date: Sat, 20 May 2017 22:43:26 +0000 (-0700)
Subject: add vpn_proto member functions .udp_send_probes and .udp_catch_probe in preparation... 
X-Git-Tag: v8.00~133
X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=5cd81d7524552f0ac315f0bd86c65dbdabcbebbf;p=users%2Fdwmw2%2Fopenconnect.git

add vpn_proto member functions .udp_send_probes and .udp_catch_probe in preparation for supporting GlobalProtect ESP

The existing Juniper ESP code can be almost entirely reused for
GlobalProtect ESP, except for the Juniper-specific code for sending and
recognizing the probe packets used for ESP initiation and DPD.

The Juniper-specific code is moved into functions names esp_send_probes
(sends Juniper probe packets) and esp_catch_probe (recognizes Juniper probe
packet responses), which are called via vpn_proto member functions.

Signed-off-by: Daniel Lenski <dlenski@gmail.com>
Signed-off-by: David Woodhouse <dwmw2@infradead.org>
---

diff --git a/esp.c b/esp.c
index 5b038c45..f705aa3e 100644
--- a/esp.c
+++ b/esp.c
@@ -71,7 +71,7 @@ int print_esp_keys(struct openconnect_info *vpninfo, const char *name, struct es
 	return 0;
 }
 
-static int esp_send_probes(struct openconnect_info *vpninfo)
+int esp_send_probes(struct openconnect_info *vpninfo)
 {
 	struct pkt *pkt;
 	int pktlen;
@@ -112,6 +112,11 @@ static int esp_send_probes(struct openconnect_info *vpninfo)
 	return 0;
 };
 
+int esp_catch_probe(struct openconnect_info *vpninfo, struct pkt *pkt)
+{
+	return (pkt->len == 1 && pkt->data[0] == 0);
+}
+
 int esp_setup(struct openconnect_info *vpninfo, int dtls_attempt_period)
 {
 	if (vpninfo->dtls_state == DTLS_DISABLED ||
@@ -129,7 +134,8 @@ int esp_setup(struct openconnect_info *vpninfo, int dtls_attempt_period)
 	print_esp_keys(vpninfo, _("outgoing"), &vpninfo->esp_out);
 
 	vpn_progress(vpninfo, PRG_DEBUG, _("Send ESP probes\n"));
-	esp_send_probes(vpninfo);
+	if (vpninfo->proto->udp_send_probes)
+		vpninfo->proto->udp_send_probes(vpninfo);
 
 	return 0;
 }
@@ -146,7 +152,8 @@ int esp_mainloop(struct openconnect_info *vpninfo, int *timeout)
 		int when = vpninfo->new_dtls_started + vpninfo->dtls_attempt_period - time(NULL);
 		if (when <= 0 || vpninfo->dtls_need_reconnect) {
 			vpn_progress(vpninfo, PRG_DEBUG, _("Send ESP probes\n"));
-			esp_send_probes(vpninfo);
+			if (vpninfo->proto->udp_send_probes)
+				vpninfo->proto->udp_send_probes(vpninfo);
 			when = vpninfo->dtls_attempt_period;
 		}
 		if (*timeout > when * 1000)
@@ -226,14 +233,16 @@ int esp_mainloop(struct openconnect_info *vpninfo, int *timeout)
 		}
 		vpninfo->dtls_times.last_rx = time(NULL);
 
-		if (pkt->len  == 1 && pkt->data[0] == 0) {
-			if (vpninfo->dtls_state == DTLS_SLEEPING) {
-				vpn_progress(vpninfo, PRG_INFO,
-					     _("ESP session established with server\n"));
-				queue_esp_control(vpninfo, 1);
-				vpninfo->dtls_state = DTLS_CONNECTING;
+		if (vpninfo->proto->udp_catch_probe) {
+			if (vpninfo->proto->udp_catch_probe(vpninfo, pkt)) {
+				if (vpninfo->dtls_state == DTLS_SLEEPING) {
+					vpn_progress(vpninfo, PRG_INFO,
+						     _("ESP session established with server\n"));
+					queue_esp_control(vpninfo, 1);
+					vpninfo->dtls_state = DTLS_CONNECTING;
+				}
+				continue;
 			}
-			continue;
 		}
 		if (pkt->data[len - 1] == 0x05) {
 			struct pkt *newpkt = malloc(sizeof(*pkt) + vpninfo->ip_info.mtu + vpninfo->pkt_trailer);
@@ -273,12 +282,14 @@ int esp_mainloop(struct openconnect_info *vpninfo, int *timeout)
 		vpn_progress(vpninfo, PRG_ERR, _("ESP detected dead peer\n"));
 		queue_esp_control(vpninfo, 0);
 		esp_close(vpninfo);
-		esp_send_probes(vpninfo);
+		if (vpninfo->proto->udp_send_probes)
+			vpninfo->proto->udp_send_probes(vpninfo);
 		return 1;
 
 	case KA_DPD:
 		vpn_progress(vpninfo, PRG_DEBUG, _("Send ESP probes for DPD\n"));
-		esp_send_probes(vpninfo);
+		if (vpninfo->proto->udp_send_probes)
+			vpninfo->proto->udp_send_probes(vpninfo);
 		work_done = 1;
 		break;
 
diff --git a/library.c b/library.c
index 41e164a2..daa1f01d 100644
--- a/library.c
+++ b/library.c
@@ -138,6 +138,8 @@ const struct vpn_proto openconnect_protos[] = {
 		.udp_mainloop = esp_mainloop,
 		.udp_close = esp_close,
 		.udp_shutdown = esp_shutdown,
+		.udp_send_probes = esp_send_probes,
+		.udp_catch_probe = esp_catch_probe,
 #endif
 	},
 	{ /* NULL */ }
diff --git a/openconnect-internal.h b/openconnect-internal.h
index f8f92492..933f78c2 100644
--- a/openconnect-internal.h
+++ b/openconnect-internal.h
@@ -282,6 +282,12 @@ struct vpn_proto {
 
 	/* Close and destroy the (UDP) session */
 	void (*udp_shutdown)(struct openconnect_info *vpninfo);
+
+	/* Send probe packets to start or maintain the (UDP) session */
+	int (*udp_send_probes)(struct openconnect_info *vpninfo);
+
+	/* Catch probe packet confirming the (UDP) session */
+	int (*udp_catch_probe)(struct openconnect_info *vpninfo, struct pkt *p);
 };
 
 struct pkt_q {
@@ -895,6 +901,8 @@ int esp_mainloop(struct openconnect_info *vpninfo, int *timeout);
 void esp_close(struct openconnect_info *vpninfo);
 void esp_shutdown(struct openconnect_info *vpninfo);
 int print_esp_keys(struct openconnect_info *vpninfo, const char *name, struct esp *esp);
+int esp_send_probes(struct openconnect_info *vpninfo);
+int esp_catch_probe(struct openconnect_info *vpninfo, struct pkt *pkt);
 
 /* {gnutls,openssl}-esp.c */
 int setup_esp_keys(struct openconnect_info *vpninfo);