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