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);