[PATCH 5/8] add vpn_proto member functions .udp_send_probes and .udp_catch_probe in preparation for supporting GlobalProtect ESP

Daniel Lenski dlenski at gmail.com
Sat May 20 15:43:26 PDT 2017


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 at gmail.com>
---
 esp.c                  | 35 +++++++++++++++++++++++------------
 library.c              |  2 ++
 openconnect-internal.h |  8 ++++++++
 3 files changed, 33 insertions(+), 12 deletions(-)

diff --git a/esp.c b/esp.c
index 5b038c4..f705aa3 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 7d26ba8..52126cd 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
 	}, {
 		.name = "gp",
diff --git a/openconnect-internal.h b/openconnect-internal.h
index 09d9c6e..a9e2750 100644
--- a/openconnect-internal.h
+++ b/openconnect-internal.h
@@ -286,6 +286,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 {
@@ -920,6 +926,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);
-- 
2.7.4




More information about the openconnect-devel mailing list