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 <dlen...@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


_______________________________________________
openconnect-devel mailing list
openconnect-devel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/openconnect-devel

Reply via email to