Repository: kudu
Updated Branches:
  refs/heads/master 8993716d7 -> 67fcfccd4


tls_socket: support zero-length writes

In some cases, we try to call Write() with a zero-length buffer. This is
allowed with the normal write() or writev() APIs, but OpenSSL uses a '0'
return value to indicate certain types of errors.

This would result in a weird Status like 'NetworkError:
TlsSocket::Write: Success' in cases where we have zero-length sidecars
(e.g empty scan result sets).

This adds a new test with an empty sidecar which triggered the bug, and
fixes TlsSocket::Write to avoid the issue.

Change-Id: Ia4c91722b4c0692384f881a212784d248ec9eeea
Reviewed-on: http://gerrit.cloudera.org:8080/5861
Reviewed-by: Alexey Serbin <aser...@cloudera.com>
Tested-by: Kudu Jenkins


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

Branch: refs/heads/master
Commit: 26a6a51661e4aa5c906ffa990f0c7d70976bf56c
Parents: 8993716
Author: Todd Lipcon <t...@apache.org>
Authored: Wed Feb 1 16:25:07 2017 -0800
Committer: Todd Lipcon <t...@apache.org>
Committed: Thu Feb 2 01:07:27 2017 +0000

----------------------------------------------------------------------
 src/kudu/rpc/rpc-test.cc        | 3 +++
 src/kudu/security/tls_socket.cc | 9 +++++++++
 2 files changed, 12 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/kudu/blob/26a6a516/src/kudu/rpc/rpc-test.cc
----------------------------------------------------------------------
diff --git a/src/kudu/rpc/rpc-test.cc b/src/kudu/rpc/rpc-test.cc
index 9769ffe..e18d07c 100644
--- a/src/kudu/rpc/rpc-test.cc
+++ b/src/kudu/rpc/rpc-test.cc
@@ -285,6 +285,9 @@ TEST_P(TestRpc, TestRpcSidecar) {
   shared_ptr<Messenger> client_messenger(CreateMessenger("Client", 1, 
GetParam()));
   Proxy p(client_messenger, server_addr, 
GenericCalculatorService::static_service_name());
 
+  // Test a zero-length sidecar
+  DoTestSidecar(p, 0, 0);
+
   // Test some small sidecars
   DoTestSidecar(p, 123, 456);
 

http://git-wip-us.apache.org/repos/asf/kudu/blob/26a6a516/src/kudu/security/tls_socket.cc
----------------------------------------------------------------------
diff --git a/src/kudu/security/tls_socket.cc b/src/kudu/security/tls_socket.cc
index 6728133..1eec3dd 100644
--- a/src/kudu/security/tls_socket.cc
+++ b/src/kudu/security/tls_socket.cc
@@ -37,6 +37,15 @@ TlsSocket::~TlsSocket() {
 
 Status TlsSocket::Write(const uint8_t *buf, int32_t amt, int32_t *nwritten) {
   CHECK(ssl_);
+
+  if (PREDICT_FALSE(amt == 0)) {
+    // Writing an empty buffer is a no-op. This happens occasionally, eg in the
+    // case where the response has an empty sidecar. We have to special case
+    // it, because SSL_write can return '0' to indicate certain types of 
errors.
+    *nwritten = 0;
+    return Status::OK();
+  }
+
   ERR_clear_error();
   errno = 0;
   int32_t bytes_written = SSL_write(ssl_.get(), buf, amt);

Reply via email to