From: Tobias Brunner Date: Fri, 28 Aug 2020 09:56:36 +0000 (+0200) Subject: tls-socket: Change how EOF of the underlying socket is handled X-Git-Tag: 5.9.2rc1~23^2~67 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=27360d34076c5d780990d409c468790b9bbbe37c;p=thirdparty%2Fstrongswan.git tls-socket: Change how EOF of the underlying socket is handled With the previous code, there was an issue when replying to TLS 1.3 post-handshake messages. In this case, SUCCESS is eventually returned from build(), however, no actual data has been received so in_done is 0. This was interpreted as EOF, plain_eof was set to TRUE and no further data was read from the socket afterwards. Returning SUCCESS from build() if the exchange is initiated by write_(), as is the case with the finished reply, never was a problem because there the return value of 0 is not interpreted as EOF. --- diff --git a/src/libtls/tls_socket.c b/src/libtls/tls_socket.c index 7745988fb6..8b427dd1a4 100644 --- a/src/libtls/tls_socket.c +++ b/src/libtls/tls_socket.c @@ -101,6 +101,11 @@ struct private_tls_socket_t { * Underlying OS socket */ int fd; + + /** + * Whether the socket returned EOF + */ + bool eof; }; METHOD(tls_application_t, process, status_t, @@ -236,6 +241,7 @@ static bool exchange(private_tls_socket_t *this, bool wr, bool block) } if (in == 0) { /* EOF */ + this->eof = TRUE; return TRUE; } switch (this->tls->process(this->tls, buf, in)) @@ -268,11 +274,20 @@ METHOD(tls_socket_t, read_, ssize_t, } return cache; } + if (this->eof) + { + return 0; + } this->app.in.ptr = buf; this->app.in.len = len; this->app.in_done = 0; if (exchange(this, FALSE, block)) { + if (!this->app.in_done && !this->eof) + { + errno = EWOULDBLOCK; + return -1; + } return this->app.in_done; } return -1; @@ -296,13 +311,13 @@ METHOD(tls_socket_t, splice, bool, { char buf[PLAIN_BUF_SIZE], *pos; ssize_t in, out; - bool old, plain_eof = FALSE, crypto_eof = FALSE; + bool old, crypto_eof = FALSE; struct pollfd pfd[] = { { .fd = this->fd, .events = POLLIN, }, { .fd = rfd, .events = POLLIN, }, }; - while (!plain_eof && !crypto_eof) + while (!this->eof && !crypto_eof) { old = thread_cancelability(TRUE); in = poll(pfd, countof(pfd), -1); @@ -312,14 +327,11 @@ METHOD(tls_socket_t, splice, bool, DBG1(DBG_TLS, "TLS select error: %s", strerror(errno)); return FALSE; } - while (!plain_eof && pfd[0].revents & (POLLIN | POLLHUP | POLLNVAL)) + while (!this->eof && pfd[0].revents & (POLLIN | POLLHUP | POLLNVAL)) { in = read_(this, buf, sizeof(buf), FALSE); switch (in) { - case 0: - plain_eof = TRUE; - break; case -1: if (errno != EWOULDBLOCK) {