openconnect_SSL_printf(vpninfo, "\r\nX-DTLS-CipherSuite: %s\r\n\r\n",
vpninfo->dtls_ciphers?:"AES256-SHA:AES128-SHA:DES-CBC3-SHA:DES-CBC-SHA");
- fcntl(vpninfo->ssl_fd, F_SETFL, fcntl(vpninfo->ssl_fd, F_GETFL) & ~O_NONBLOCK);
- if (openconnect_SSL_gets(vpninfo, buf, 65536) < 0) {
+ if ((i = openconnect_SSL_gets(vpninfo, buf, 65536) < 0)) {
+ if (i == -EINTR)
+ return i;
vpn_progress(vpninfo, PRG_ERR,
_("Error fetching HTTPS response\n"));
if (!retried) {
while ((i = openconnect_SSL_gets(vpninfo, buf, sizeof(buf)))) {
struct vpn_option *new_option;
- char *colon = strchr(buf, ':');
+ char *colon;
+
+ if (i < 0)
+ return i;
+
+ colon = strchr(buf, ':');
if (!colon)
continue;
BIO_set_nbio(SSL_get_rbio(vpninfo->https_ssl), 1);
BIO_set_nbio(SSL_get_wbio(vpninfo->https_ssl), 1);
- fcntl(vpninfo->ssl_fd, F_SETFL, fcntl(vpninfo->ssl_fd, F_GETFL) | O_NONBLOCK);
if (vpninfo->select_nfds <= vpninfo->ssl_fd)
vpninfo->select_nfds = vpninfo->ssl_fd + 1;
if (len < 2)
return -EINVAL;
- while ( (ret = SSL_read(vpninfo->https_ssl, buf + i, 1)) == 1) {
- if (buf[i] == '\n') {
- buf[i] = 0;
- if (i && buf[i-1] == '\r') {
- buf[i-1] = 0;
- i--;
+ while (1) {
+ ret = SSL_read(vpninfo->https_ssl, buf + i, 1);
+ if (ret == 1) {
+ if (buf[i] == '\n') {
+ buf[i] = 0;
+ if (i && buf[i-1] == '\r') {
+ buf[i-1] = 0;
+ i--;
+ }
+ return i;
}
- return i;
- }
- i++;
+ i++;
- if (i >= len - 1) {
- buf[i] = 0;
- return i;
+ if (i >= len - 1) {
+ buf[i] = 0;
+ return i;
+ }
+ } else {
+ fd_set rd_set, wr_set;
+ int maxfd = vpninfo->ssl_fd;
+
+ FD_ZERO(&rd_set);
+ FD_ZERO(&wr_set);
+
+ ret = SSL_get_error(vpninfo->https_ssl, ret);
+ if (ret == SSL_ERROR_WANT_READ)
+ FD_SET(vpninfo->ssl_fd, &rd_set);
+ else if (ret == SSL_ERROR_WANT_WRITE)
+ FD_SET(vpninfo->ssl_fd, &wr_set);
+ else {
+ vpn_progress(vpninfo, PRG_ERR, _("Failed to read from SSL socket\n"));
+ report_ssl_errors(vpninfo);
+ ret = -EIO;
+ break;
+ }
+ if (vpninfo->cancel_fd != -1) {
+ FD_SET(vpninfo->cancel_fd, &rd_set);
+ if (vpninfo->cancel_fd > vpninfo->ssl_fd)
+ maxfd = vpninfo->cancel_fd;
+ }
+ select(maxfd + 1, &rd_set, &wr_set, NULL, NULL);
+ if (vpninfo->cancel_fd != -1 &&
+ FD_ISSET(vpninfo->cancel_fd, &rd_set)) {
+ vpn_progress(vpninfo, PRG_ERR, _("SSL read cancelled\n"));
+ ret = -EINTR;
+ break;
+ }
}
}
- if (ret == 0) {
- ret = -SSL_get_error(vpninfo->https_ssl, ret);
- }
buf[i] = 0;
return i ?: ret;
}