kudu-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From t...@apache.org
Subject [2/3] kudu git commit: tls_socket: fix handling of syscall errors
Date Wed, 15 Feb 2017 18:54:56 GMT
tls_socket: fix handling of syscall errors

This prevents a case where we'd see an error like 'TlsSocket::Recv: Success'
when trying to read from a TLS socket which got abruptly shut down by the
remote side.

Change-Id: I9a0a63f861d71bd3186567ff98148476795530ab
Reviewed-on: http://gerrit.cloudera.org:8080/5954
Tested-by: Kudu Jenkins
Reviewed-by: Dan Burkert <danburkert@apache.org>


Project: http://git-wip-us.apache.org/repos/asf/kudu/repo
Commit: http://git-wip-us.apache.org/repos/asf/kudu/commit/4a5ab736
Tree: http://git-wip-us.apache.org/repos/asf/kudu/tree/4a5ab736
Diff: http://git-wip-us.apache.org/repos/asf/kudu/diff/4a5ab736

Branch: refs/heads/master
Commit: 4a5ab7368c9c3be39779d44f6bf701b1a925ce09
Parents: 91c93d3
Author: Todd Lipcon <todd@apache.org>
Authored: Thu Feb 9 00:30:08 2017 -0800
Committer: Todd Lipcon <todd@apache.org>
Committed: Wed Feb 15 18:24:51 2017 +0000

----------------------------------------------------------------------
 src/kudu/security/tls_socket.cc | 29 ++++++++++++++++++++++++++---
 1 file changed, 26 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/kudu/blob/4a5ab736/src/kudu/security/tls_socket.cc
----------------------------------------------------------------------
diff --git a/src/kudu/security/tls_socket.cc b/src/kudu/security/tls_socket.cc
index b510906..77f633f 100644
--- a/src/kudu/security/tls_socket.cc
+++ b/src/kudu/security/tls_socket.cc
@@ -24,6 +24,7 @@
 #include "kudu/gutil/basictypes.h"
 #include "kudu/security/cert.h"
 #include "kudu/security/openssl_util.h"
+#include "kudu/util/errno.h"
 
 namespace kudu {
 namespace security {
@@ -58,7 +59,8 @@ Status TlsSocket::Write(const uint8_t *buf, int32_t amt, int32_t *nwritten)
{
       *nwritten = 0;
       return Status::OK();
     }
-    return Status::NetworkError("TlsSocket::Write", GetSSLErrorDescription(error_code));
+    return Status::NetworkError("failed to write to TLS socket",
+                                GetSSLErrorDescription(error_code));
   }
   *nwritten = bytes_written;
   return Status::OK();
@@ -84,12 +86,16 @@ Status TlsSocket::Writev(const struct ::iovec *iov, int iov_len, int32_t
*nwritt
 }
 
 Status TlsSocket::Recv(uint8_t *buf, int32_t amt, int32_t *nread) {
+  const char* kErrString = "failed to read from TLS socket";
+
   CHECK(ssl_);
   ERR_clear_error();
+  errno = 0;
   int32_t bytes_read = SSL_read(ssl_.get(), buf, amt);
+  int save_errno = errno;
   if (bytes_read <= 0) {
     if (bytes_read == 0 && SSL_get_shutdown(ssl_.get()) == SSL_RECEIVED_SHUTDOWN)
{
-      return Status::NetworkError("TlsSocket::Recv", "received remote shutdown", ESHUTDOWN);
+      return Status::NetworkError(kErrString, ErrnoToString(ESHUTDOWN), ESHUTDOWN);
     }
     auto error_code = SSL_get_error(ssl_.get(), bytes_read);
     if (error_code == SSL_ERROR_WANT_READ) {
@@ -97,7 +103,24 @@ Status TlsSocket::Recv(uint8_t *buf, int32_t amt, int32_t *nread) {
       *nread = 0;
       return Status::OK();
     }
-    return Status::NetworkError("TlsSocket::Recv", GetSSLErrorDescription(error_code));
+    if (error_code == SSL_ERROR_SYSCALL && ERR_peek_error() == 0) {
+      // From the OpenSSL docs:
+      //   Some I/O error occurred.  The OpenSSL error queue may contain more
+      //   information on the error.  If the error queue is empty (i.e.
+      //   ERR_get_error() returns 0), ret can be used to find out more about
+      //   the error: If ret == 0, an EOF was observed that violates the pro-
+      //   tocol.  If ret == -1, the underlying BIO reported an I/O error (for
+      //   socket I/O on Unix systems, consult errno for details).
+      if (bytes_read == 0) {
+        // "EOF was observed that violates the protocol" (eg the other end disconnected)
+        return Status::NetworkError(kErrString, ErrnoToString(ECONNRESET), ECONNRESET);
+      }
+      if (bytes_read == -1 && save_errno != 0) {
+        return Status::NetworkError(kErrString, ErrnoToString(save_errno), save_errno);
+      }
+      return Status::NetworkError(kErrString, "unknown ERROR_SYSCALL");
+    }
+    return Status::NetworkError(kErrString, GetSSLErrorDescription(error_code));
   }
   *nread = bytes_read;
   return Status::OK();


Mime
View raw message