diff --git a/http.c b/http.c index 02662999..62d36944 100644 --- a/http.c +++ b/http.c @@ -835,20 +835,15 @@ static int do_https_request(struct openconnect_info *vpninfo, const char *method { struct oc_text_buf *buf; int result, buflen; + int rq_retry; - retry: + redirected: vpninfo->redirect_type = REDIR_TYPE_NONE; if (*form_buf) { free(*form_buf); *form_buf = NULL; } - if (openconnect_open_https(vpninfo)) { - vpn_progress(vpninfo, PRG_ERR, - _("Failed to open HTTPS connection to %s\n"), - vpninfo->hostname); - return -EINVAL; - } /* * It would be nice to use cURL for this, but we really need to guarantee @@ -884,7 +879,27 @@ static int do_https_request(struct openconnect_info *vpninfo, const char *method if (buf_error(buf)) return buf_free(buf); + retry: + if (openconnect_https_connected(vpninfo)) { + /* The session is already connected. If we get a failure on + * *sending* the request, try it again immediately with a new + * connection. */ + rq_retry = 1; + } else { + rq_retry = 0; + if (openconnect_open_https(vpninfo)) { + vpn_progress(vpninfo, PRG_ERR, + _("Failed to open HTTPS connection to %s\n"), + vpninfo->hostname); + return -EINVAL; + } + } + result = openconnect_SSL_write(vpninfo, buf->data, buf->pos); + if (rq_retry && result < 0) { + openconnect_close_https(vpninfo, 0); + goto retry; + } buf_free(buf); if (result < 0) return result; @@ -900,7 +915,7 @@ static int do_https_request(struct openconnect_info *vpninfo, const char *method if (result == 0) { if (!fetch_redirect) return 0; - goto retry; + goto redirected; } goto out; } diff --git a/openconnect-internal.h b/openconnect-internal.h index 51172af0..c116a324 100644 --- a/openconnect-internal.h +++ b/openconnect-internal.h @@ -410,6 +410,11 @@ int openconnect_sha1(unsigned char *result, void *data, int len); int openconnect_random(void *bytes, int len); int openconnect_local_cert_md5(struct openconnect_info *vpninfo, char *buf); +#if defined(OPENCONNECT_OPENSSL) +#define openconnect_https_connected(_v) ((_v)->https_ssl) +#elif defined (OPENCONNECT_GNUTLS) +#define openconnect_https_connected(_v) ((_v)->https_sess) +#endif /* mainloop.c */ int vpn_add_pollfd(struct openconnect_info *vpninfo, int fd, short events);