Close ssl_sock before returning error in connect_https_socket()
[platform/upstream/openconnect.git] / cstp.c
diff --git a/cstp.c b/cstp.c
index bb15e9c..dacb2ae 100644 (file)
--- a/cstp.c
+++ b/cstp.c
@@ -302,6 +302,9 @@ static int start_cstp_connection(struct openconnect_info *vpninfo)
 
                if (!new_option->option || !new_option->value) {
                        vpn_progress(vpninfo, PRG_ERR, _("No memory for options\n"));
+                       free(new_option->option);
+                       free(new_option->value);
+                       free(new_option);
                        return -ENOMEM;
                }
 
@@ -803,11 +806,25 @@ int cstp_mainloop(struct openconnect_info *vpninfo, int *timeout)
                ret = cstp_write(vpninfo,
                                 vpninfo->current_ssl_pkt->hdr,
                                 vpninfo->current_ssl_pkt->len + 8);
-               
                if (ret < 0)
                        goto do_reconnect;
-               else if (!ret && ka_stalled_dpd_time(&vpninfo->ssl_times, timeout))
-                       goto peer_dead;
+               else if (!ret) {
+                       /* -EAGAIN: cstp_write() will have added the SSL fd to
+                          ->select_wfds if appropriate, so we can just return
+                          and wait. Unless it's been stalled for so long that
+                          DPD kicks in and we kill the connection. */
+                       switch (ka_stalled_action(&vpninfo->ssl_times, timeout)) {
+                       case KA_DPD_DEAD:
+                               goto peer_dead;
+                       case KA_REKEY:
+                               goto do_rekey;
+                       case KA_NONE:
+                               return work_done;
+                       default:
+                               /* This should never happen */
+                               ;
+                       }
+               }
 
                if (ret != vpninfo->current_ssl_pkt->len + 8) {
                        vpn_progress(vpninfo, PRG_ERR,
@@ -835,6 +852,7 @@ int cstp_mainloop(struct openconnect_info *vpninfo, int *timeout)
 
        switch (keepalive_action(&vpninfo->ssl_times, timeout)) {
        case KA_REKEY:
+       do_rekey:
                /* Not that this will ever happen; we don't even process
                   the setting when we're asked for it. */
                vpn_progress(vpninfo, PRG_INFO, _("CSTP rekey due\n"));