From: Woo Xie Date: Thu, 11 Jun 2015 20:25:03 +0000 (-0700) Subject: refactor the interpretation of SSL errors into a function X-Git-Tag: v0.47.0~37 X-Git-Url: http://plrg.eecs.uci.edu/git/?p=folly.git;a=commitdiff_plain;h=42111d8713cb17e524e097a49f93c9084c084a45 refactor the interpretation of SSL errors into a function Summary: This fucntion will be re-used for different SSL write functions in future. Reviewed By: @djwatson Differential Revision: D2117529 --- diff --git a/folly/io/async/AsyncSSLSocket.cpp b/folly/io/async/AsyncSSLSocket.cpp index 0489b6a4..447f2543 100644 --- a/folly/io/async/AsyncSSLSocket.cpp +++ b/folly/io/async/AsyncSSLSocket.cpp @@ -1181,6 +1181,44 @@ void AsyncSSLSocket::handleWrite() noexcept { AsyncSocket::handleWrite(); } +int AsyncSSLSocket::interpretSSLError(int rc, int error) { + if (error == SSL_ERROR_WANT_READ) { + // TODO: Even though we are attempting to write data, SSL_write() may + // need to read data if renegotiation is being performed. We currently + // don't support this and just fail the write. + LOG(ERROR) << "AsyncSSLSocket(fd=" << fd_ << ", state=" << int(state_) + << ", sslState=" << sslState_ << ", events=" << eventFlags_ + << "): " << "unsupported SSL renegotiation during write", + errno = ERR_PACK(ERR_LIB_USER, TASYNCSSLSOCKET_F_PERFORM_WRITE, + SSL_INVALID_RENEGOTIATION); + ERR_clear_error(); + return -1; + } else { + // TODO: Fix this code so that it can return a proper error message + // to the callback, rather than relying on AsyncSocket code which + // can't handle SSL errors. + long lastError = ERR_get_error(); + VLOG(3) << "ERROR: AsyncSSLSocket(fd=" << fd_ << ", state=" << int(state_) + << ", sslState=" << sslState_ << ", events=" << eventFlags_ << "): " + << "SSL error: " << error << ", errno: " << errno + << ", func: " << ERR_func_error_string(lastError) + << ", reason: " << ERR_reason_error_string(lastError); + if (error != SSL_ERROR_SYSCALL) { + if ((unsigned long)lastError < 0x8000) { + errno = ENOSYS; + } else { + errno = lastError; + } + } + ERR_clear_error(); + if (!zero_return(error, rc)) { + return -1; + } else { + return 0; + } + } +} + ssize_t AsyncSSLSocket::performWrite(const iovec* vec, uint32_t count, WriteFlags flags, @@ -1192,7 +1230,8 @@ ssize_t AsyncSSLSocket::performWrite(const iovec* vec, } if (sslState_ != STATE_ESTABLISHED) { LOG(ERROR) << "AsyncSSLSocket(fd=" << fd_ << ", state=" << int(state_) - << ", sslState=" << sslState_ << ", events=" << eventFlags_ << "): " + << ", sslState=" << sslState_ + << ", events=" << eventFlags_ << "): " << "TODO: AsyncSSLSocket currently does not support calling " << "write() before the handshake has fully completed"; errno = ERR_PACK(ERR_LIB_USER, TASYNCSSLSOCKET_F_PERFORM_WRITE, @@ -1286,40 +1325,11 @@ ssize_t AsyncSSLSocket::performWrite(const iovec* vec, // The caller will register for write event if not already. *partialWritten = offset; return totalWritten; - } else if (error == SSL_ERROR_WANT_READ) { - // TODO: Even though we are attempting to write data, SSL_write() may - // need to read data if renegotiation is being performed. We currently - // don't support this and just fail the write. - LOG(ERROR) << "AsyncSSLSocket(fd=" << fd_ << ", state=" << int(state_) - << ", sslState=" << sslState_ << ", events=" << eventFlags_ << "): " - << "unsupported SSL renegotiation during write", - errno = ERR_PACK(ERR_LIB_USER, TASYNCSSLSOCKET_F_PERFORM_WRITE, - SSL_INVALID_RENEGOTIATION); - ERR_clear_error(); - return -1; - } else { - // TODO: Fix this code so that it can return a proper error message - // to the callback, rather than relying on AsyncSocket code which - // can't handle SSL errors. - long lastError = ERR_get_error(); - VLOG(3) << - "ERROR: AsyncSSLSocket(fd=" << fd_ << ", state=" << int(state_) - << ", sslState=" << sslState_ << ", events=" << eventFlags_ << "): " - << "SSL error: " << error << ", errno: " << errno - << ", func: " << ERR_func_error_string(lastError) - << ", reason: " << ERR_reason_error_string(lastError); - if (error != SSL_ERROR_SYSCALL) { - if ((unsigned long)lastError < 0x8000) { - errno = ENOSYS; - } else { - errno = lastError; - } - } - ERR_clear_error(); - if (!zero_return(error, bytes)) { - return -1; - } // else fall through to below to correctly record totalWritten } + int rc = interpretSSLError(bytes, error); + if (rc < 0) { + return rc; + } // else fall through to below to correctly record totalWritten } totalWritten += bytes; diff --git a/folly/io/async/AsyncSSLSocket.h b/folly/io/async/AsyncSSLSocket.h index 393b8765..b72205de 100644 --- a/folly/io/async/AsyncSSLSocket.h +++ b/folly/io/async/AsyncSSLSocket.h @@ -686,6 +686,7 @@ class AsyncSSLSocket : public virtual AsyncSocket { // AsyncSocket calls this at the wrong time for SSL void handleInitialReadWrite() noexcept override {} + int interpretSSLError(int rc, int error); ssize_t performRead(void* buf, size_t buflen) override; ssize_t performWrite(const iovec* vec, uint32_t count, WriteFlags flags, uint32_t* countWritten, uint32_t* partialWritten)