This is another small case of Juniper-specific handling in the ESP code. The ONCP protocol needs to tell the server to explicitly enable or disable the ESP tunnel. I don't really understand why the separate oncp_control_queue is needed, since these control packets only get sent when dtls_state != DTLS_CONNECTED and therefore they would always automatically get sent via the ONCP tunnel instead of the ESP tunnel anyway. Signed-off-by: Daniel Lenski <dlenski at gmail.com> --- esp.c | 8 ++++---- library.c | 2 +- oncp.c | 15 ++++++++++++++- openconnect-internal.h | 2 +- 4 files changed, 20 insertions(+), 7 deletions(-) diff --git a/esp.c b/esp.c index 5cea3fb..4557b79 100644 --- a/esp.c +++ b/esp.c @@ -192,7 +192,6 @@ int esp_mainloop(struct openconnect_info *vpninfo, int *timeout) 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; @@ -234,8 +233,8 @@ int esp_mainloop(struct openconnect_info *vpninfo, int *timeout) case KA_DPD_DEAD: vpn_progress(vpninfo, PRG_ERR, _("ESP detected dead peer\n")); - queue_esp_control(vpninfo, 0); - esp_close(vpninfo); + if (vpninfo->proto->udp_close) + vpninfo->proto->udp_close(vpninfo); if (vpninfo->proto->udp_send_probes) vpninfo->proto->udp_send_probes(vpninfo); return 1; @@ -310,5 +309,6 @@ void esp_shutdown(struct openconnect_info *vpninfo) destroy_esp_ciphers(&vpninfo->esp_in[0]); destroy_esp_ciphers(&vpninfo->esp_in[1]); destroy_esp_ciphers(&vpninfo->esp_out); - esp_close(vpninfo); + if (vpninfo->proto->udp_close) + vpninfo->proto->udp_close(vpninfo); } diff --git a/library.c b/library.c index b0d635b..4826c66 100644 --- a/library.c +++ b/library.c @@ -136,7 +136,7 @@ const struct vpn_proto openconnect_protos[] = { #ifdef HAVE_ESP .udp_setup = esp_setup, .udp_mainloop = esp_mainloop, - .udp_close = esp_close, + .udp_close = oncp_esp_close, .udp_shutdown = esp_shutdown, .udp_send_probes = oncp_esp_send_probes, .udp_catch_probe = oncp_esp_catch_probe, diff --git a/oncp.c b/oncp.c index bc01a3f..dbfb1ef 100644 --- a/oncp.c +++ b/oncp.c @@ -452,7 +452,7 @@ static const struct pkt esp_enable_pkt = { .len = 13 }; -int queue_esp_control(struct openconnect_info *vpninfo, int enable) +static int queue_esp_control(struct openconnect_info *vpninfo, int enable) { struct pkt *new = malloc(sizeof(*new) + 13); if (!new) @@ -931,6 +931,12 @@ int oncp_mainloop(struct openconnect_info *vpninfo, int *timeout) if (vpninfo->ssl_fd == -1) goto do_reconnect; + /* Queue the ESP enable message. We will start sending packets + via ESP once the enable message has been *sent* over the + TCP channel. */ + if (vpninfo->dtls_state == DTLS_CONNECTING) + queue_esp_control(vpninfo, 1); + /* FIXME: The poll() handling here is fairly simplistic. Actually, if the SSL connection stalls it could return a WANT_WRITE error on _either_ of the SSL_read() or SSL_write() calls. In that case, @@ -1303,6 +1309,13 @@ int oncp_bye(struct openconnect_info *vpninfo, const char *reason) } #ifdef HAVE_ESP +void oncp_esp_close(struct openconnect_info *vpninfo) +{ + /* Tell server to stop sending on ESP channel */ + queue_esp_control(vpninfo, 0); + esp_close(vpninfo); +} + int oncp_esp_send_probes(struct openconnect_info *vpninfo) { struct pkt *pkt; diff --git a/openconnect-internal.h b/openconnect-internal.h index e96610b..9890ff6 100644 --- a/openconnect-internal.h +++ b/openconnect-internal.h @@ -853,10 +853,10 @@ int oncp_obtain_cookie(struct openconnect_info *vpninfo); void oncp_common_headers(struct openconnect_info *vpninfo, struct oc_text_buf *buf); /* oncp.c */ -int queue_esp_control(struct openconnect_info *vpninfo, int enable); int oncp_connect(struct openconnect_info *vpninfo); int oncp_mainloop(struct openconnect_info *vpninfo, int *timeout); int oncp_bye(struct openconnect_info *vpninfo, const char *reason); +void oncp_esp_close(struct openconnect_info *vpninfo); int oncp_esp_send_probes(struct openconnect_info *vpninfo); int oncp_esp_catch_probe(struct openconnect_info *vpninfo, struct pkt *pkt); -- 2.7.4