It looks like we do receive DPD requests occasionally. Handle them
authorDavid Woodhouse <David.Woodhouse@intel.com>
Thu, 2 Oct 2008 11:13:04 +0000 (12:13 +0100)
committerDavid Woodhouse <David.Woodhouse@intel.com>
Thu, 2 Oct 2008 11:13:04 +0000 (12:13 +0100)
anyconnect.h
dtls.c
ssl.c

index da76987..dd949a8 100644 (file)
@@ -77,6 +77,7 @@ struct anyconnect_info {
        SSL_CTX *https_ctx;
        SSL *https_ssl;
        struct keepalive_info ssl_times;
+       int owe_ssl_dpd_response;
        struct pkt *deflate_pkt;
        struct pkt *current_ssl_pkt;
 
diff --git a/dtls.c b/dtls.c
index 30e6905..d99186f 100644 (file)
--- a/dtls.c
+++ b/dtls.c
@@ -268,6 +268,16 @@ int dtls_mainloop(struct anyconnect_info *vpninfo, int *timeout)
                        work_done = 1;
                        break;
 
+               case AC_PKT_DPD_OUT:
+                       if (verbose)
+                               printf("Got DTLS DPD request\n");
+
+                       /* FIXME: What if the packet doesn't get through? */
+                       magic_pkt = AC_PKT_DPD_RESP;
+                       if (SSL_write(vpninfo->dtls_ssl, &magic_pkt, 1) != 1)
+                               fprintf(stderr, "Failed to send DPD response. Expect disconnect\n");
+                       continue;
+
                case AC_PKT_DPD_RESP:
                        if (verbose)
                                printf("Got DTLS DPD response\n");
diff --git a/ssl.c b/ssl.c
index 7801e03..01983d3 100644 (file)
--- a/ssl.c
+++ b/ssl.c
@@ -537,6 +537,10 @@ static struct pkt dpd_pkt = {
        .hdr = { 'S', 'T', 'F', 1, 0, 0, AC_PKT_DPD_OUT, 0 },
 };
 
+static struct pkt dpd_resp_pkt = {
+       .hdr = { 'S', 'T', 'F', 1, 0, 0, AC_PKT_DPD_RESP, 0 },
+};
+
 int ssl_mainloop(struct anyconnect_info *vpninfo, int *timeout)
 {
        unsigned char buf[16384];
@@ -567,6 +571,12 @@ int ssl_mainloop(struct anyconnect_info *vpninfo, int *timeout)
                }
                vpninfo->ssl_times.last_rx = time(NULL);
                switch(buf[6]) {
+               case AC_PKT_DPD_OUT:
+                       if (verbose)
+                               printf("Got CSTP DPD request\n");
+                       vpninfo->owe_ssl_dpd_response = 1;
+                       continue;
+
                case AC_PKT_DPD_RESP:
                        if (verbose)
                                printf("Got CSTP DPD response\n");
@@ -627,7 +637,6 @@ int ssl_mainloop(struct anyconnect_info *vpninfo, int *timeout)
                        case SSL_ERROR_WANT_WRITE:
                                /* Waiting for the socket to become writable -- it's
                                   probably stalled, and/or the buffers are full */
-                               printf("SSL want write\n");
                                vpninfo->pfds[vpninfo->ssl_pfd].events |= POLLOUT;
                        case SSL_ERROR_WANT_READ:
                                if (ka_stalled_dpd_time(&vpninfo->ssl_times, timeout)) {
@@ -651,12 +660,19 @@ int ssl_mainloop(struct anyconnect_info *vpninfo, int *timeout)
                /* Don't free the 'special' packets */
                if (vpninfo->current_ssl_pkt != vpninfo->deflate_pkt &&
                    vpninfo->current_ssl_pkt != &dpd_pkt &&
+                   vpninfo->current_ssl_pkt != &dpd_resp_pkt &&
                    vpninfo->current_ssl_pkt != &keepalive_pkt)
                        free(vpninfo->current_ssl_pkt);
 
                vpninfo->current_ssl_pkt = NULL;
        }
 
+       if (vpninfo->owe_ssl_dpd_response) {
+               vpninfo->owe_ssl_dpd_response = 0;
+               vpninfo->current_ssl_pkt = &dpd_resp_pkt;
+               goto handle_outgoing;
+       }
+
        if (verbose)
                printf("Process CSTP keepalive...\n");
        switch (keepalive_action(&vpninfo->ssl_times, timeout)) {