From 033a3342eaad216ad03efe1bd35e74a8c68b9a61 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Sat, 12 May 2012 11:12:45 -0700 Subject: [PATCH] Add cancellation handling to proxy I/O functions Signed-off-by: David Woodhouse --- http.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++--- ssl.c | 5 +++-- 2 files changed, 49 insertions(+), 5 deletions(-) diff --git a/http.c b/http.c index 8374f3e..42afd47 100644 --- a/http.c +++ b/http.c @@ -899,9 +899,31 @@ static int proxy_write(struct openconnect_info *vpninfo, int fd, unsigned char *buf, size_t len) { size_t count; - + for (count = 0; count < len; ) { - int i = write(fd, buf + count, len - count); + fd_set rd_set, wr_set; + int maxfd = fd; + int i; + + FD_ZERO(&wr_set); + FD_ZERO(&rd_set); + FD_SET(fd, &wr_set); + if (vpninfo->cancel_fd != -1) { + FD_SET(vpninfo->cancel_fd, &rd_set); + if (vpninfo->cancel_fd > 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)) + return -EINTR; + + /* Not that this should ever be able to happen... */ + if (!FD_ISSET(fd, &wr_set)) + continue; + + i = write(fd, buf + count, len - count); if (i < 0) return -errno; @@ -916,7 +938,28 @@ static int proxy_read(struct openconnect_info *vpninfo, int fd, size_t count; for (count = 0; count < len; ) { - int i = read(fd, buf + count, len - count); + fd_set rd_set; + int maxfd = fd; + int i; + + FD_ZERO(&rd_set); + FD_SET(fd, &rd_set); + if (vpninfo->cancel_fd != -1) { + FD_SET(vpninfo->cancel_fd, &rd_set); + if (vpninfo->cancel_fd > fd) + maxfd = vpninfo->cancel_fd; + } + + select(maxfd + 1, &rd_set, NULL, NULL, NULL); + if (vpninfo->cancel_fd != -1 && + FD_ISSET(vpninfo->cancel_fd, &rd_set)) + return -EINTR; + + /* Not that this should ever be able to happen... */ + if (!FD_ISSET(fd, &rd_set)) + continue; + + i = read(fd, buf + count, len - count); if (i < 0) return -errno; diff --git a/ssl.c b/ssl.c index d4096b8..08175b6 100644 --- a/ssl.c +++ b/ssl.c @@ -1062,8 +1062,6 @@ int openconnect_open_https(struct openconnect_info *vpninfo) } } fcntl(ssl_sock, F_SETFD, FD_CLOEXEC); - /* Stick it back in blocking mode for now... */ - fcntl(ssl_sock, F_SETFL, fcntl(ssl_sock, F_GETFL) & ~O_NONBLOCK); if (vpninfo->proxy) { err = process_proxy(vpninfo, ssl_sock); @@ -1073,6 +1071,9 @@ int openconnect_open_https(struct openconnect_info *vpninfo) } } + /* Stick it back in blocking mode for now... */ + fcntl(ssl_sock, F_SETFL, fcntl(ssl_sock, F_GETFL) & ~O_NONBLOCK); + ssl3_method = TLSv1_client_method(); if (!vpninfo->https_ctx) { vpninfo->https_ctx = SSL_CTX_new(ssl3_method); -- 2.7.4