Set custom ssl bio read method.
authorKyle Nekritz <knekritz@fb.com>
Mon, 9 Jan 2017 19:51:33 +0000 (11:51 -0800)
committerFacebook Github Bot <facebook-github-bot@users.noreply.github.com>
Mon, 9 Jan 2017 20:03:13 +0000 (12:03 -0800)
Summary: Similar to the bio write method. This should be essentially a no-op, bioRead has the same functionality as the openssl version. This is needed in the next diff.

Reviewed By: siyengar

Differential Revision: D4325622

fbshipit-source-id: a90b9ec06bee920a1a73551a3ea4c77e1ee0ab08

folly/io/async/AsyncSSLSocket.cpp
folly/io/async/AsyncSSLSocket.h

index 20cc963055fe4784c758c5e509f9ec87a434707d..70a4640e27e72339e8c1b804f559c54de6e4d1aa 100644 (file)
@@ -176,15 +176,16 @@ void setup_SSL_CTX(SSL_CTX *ctx) {
 
 }
 
-BIO_METHOD sslWriteBioMethod;
+BIO_METHOD sslBioMethod;
 
-void* initsslWriteBioMethod(void) {
-  memcpy(&sslWriteBioMethod, BIO_s_socket(), sizeof(sslWriteBioMethod));
+void* initsslBioMethod(void) {
+  memcpy(&sslBioMethod, BIO_s_socket(), sizeof(sslBioMethod));
   // override the bwrite method for MSG_EOR support
   OpenSSLUtils::setCustomBioWriteMethod(
-      &sslWriteBioMethod, AsyncSSLSocket::bioWrite);
+      &sslBioMethod, AsyncSSLSocket::bioWrite);
+  OpenSSLUtils::setCustomBioReadMethod(&sslBioMethod, AsyncSSLSocket::bioRead);
 
-  // Note that the sslWriteBioMethod.type and sslWriteBioMethod.name are not
+  // Note that the sslBioMethod.type and sslBioMethod.name are not
   // set here. openssl code seems to be checking ".type == BIO_TYPE_SOCKET" and
   // then have specific handlings. The sslWriteBioWrite should be compatible
   // with the one in openssl.
@@ -270,8 +271,8 @@ AsyncSSLSocket::~AsyncSSLSocket() {
 void AsyncSSLSocket::init() {
   // Do this here to ensure we initialize this once before any use of
   // AsyncSSLSocket instances and not as part of library load.
-  static const auto sslWriteBioMethodInitializer = initsslWriteBioMethod();
-  (void)sslWriteBioMethodInitializer;
+  static const auto sslBioMethodInitializer = initsslBioMethod();
+  (void)sslBioMethodInitializer;
 
   setup_SSL_CTX(ctx_->getSSLCtx());
 }
@@ -670,15 +671,15 @@ void AsyncSSLSocket::applyVerificationOptions(SSL * ssl) {
 }
 
 bool AsyncSSLSocket::setupSSLBio() {
-  auto wb = BIO_new(&sslWriteBioMethod);
+  auto sslBio = BIO_new(&sslBioMethod);
 
-  if (!wb) {
+  if (!sslBio) {
     return false;
   }
 
-  OpenSSLUtils::setBioAppData(wb, this);
-  OpenSSLUtils::setBioFd(wb, fd_, BIO_NOCLOSE);
-  SSL_set_bio(ssl_, wb, wb);
+  OpenSSLUtils::setBioAppData(sslBio, this);
+  OpenSSLUtils::setBioFd(sslBio, fd_, BIO_NOCLOSE);
+  SSL_set_bio(ssl_, sslBio, sslBio);
   return true;
 }
 
@@ -1605,6 +1606,18 @@ int AsyncSSLSocket::bioWrite(BIO* b, const char* in, int inl) {
   return int(result.writeReturn);
 }
 
+int AsyncSSLSocket::bioRead(BIO* b, char* out, int outl) {
+  if (!out) {
+    return 0;
+  }
+  auto result = recv(OpenSSLUtils::getBioFd(b, nullptr), out, outl, 0);
+  BIO_clear_retry_flags(b);
+  if (result <= 0 && OpenSSLUtils::getBioShouldRetryWrite(result)) {
+    BIO_set_retry_read(b);
+  }
+  return result;
+}
+
 int AsyncSSLSocket::sslVerifyCallback(
     int preverifyOk,
     X509_STORE_CTX* x509Ctx) {
index c8406a92ca37187ab47723f9510097e422b7e489..0d106214a2587c4cb16a78f5ff4214b4d3a5ec2a 100644 (file)
@@ -589,6 +589,7 @@ class AsyncSSLSocket : public virtual AsyncSocket {
   static int getSSLExDataIndex();
   static AsyncSSLSocket* getFromSSL(const SSL *ssl);
   static int bioWrite(BIO* b, const char* in, int inl);
+  static int bioRead(BIO* b, char* out, int outl);
   void resetClientHelloParsing(SSL *ssl);
   static void clientHelloParsingCallback(int write_p, int version,
       int content_type, const void *buf, size_t len, SSL *ssl, void *arg);