/*
- * Copyright 2017 Facebook, Inc.
+ * Copyright 2014-present Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
#include <fcntl.h>
#include <sys/types.h>
#include <chrono>
+#include <memory>
-#include <folly/Bits.h>
+#include <folly/Format.h>
#include <folly/SocketAddress.h>
#include <folly/SpinLock.h>
#include <folly/io/Cursor.h>
#include <folly/io/IOBuf.h>
+#include <folly/lang/Bits.h>
#include <folly/portability/OpenSSL.h>
using folly::SocketAddress;
return instance;
}
-void* initsslBioMethod(void) {
+void* initsslBioMethod() {
auto sslBioMethod = getSSLBioMethod();
// override the bwrite method for MSG_EOR support
OpenSSLUtils::setCustomBioWriteMethod(sslBioMethod, AsyncSSLSocket::bioWrite);
return nullptr;
}
-} // anonymous namespace
+} // namespace
namespace folly {
return 0;
}
BIO* next = BIO_next(b);
- while (next != NULL) {
+ while (next != nullptr) {
b = next;
next = BIO_next(b);
}
std::chrono::milliseconds timeout,
const SSLContext::SSLVerifyPeerEnum& verifyPeer) {
DestructorGuard dg(this);
- assert(eventBase_->isInEventBaseThread());
+ eventBase_->dcheckIsInEventBaseThread();
verifyPeer_ = verifyPeer;
// Make sure we're in the uninitialized state
- if (!server_ || (sslState_ != STATE_UNINIT &&
- sslState_ != STATE_UNENCRYPTED) ||
+ if (!server_ ||
+ (sslState_ != STATE_UNINIT && sslState_ != STATE_UNENCRYPTED) ||
handshakeCallback_ != nullptr) {
return invalidState(callback);
}
// Cache local and remote socket addresses to keep them available
// after socket file descriptor is closed.
- if (cacheAddrOnFailure_ && -1 != getFd()) {
- cacheLocalPeerAddr();
+ if (cacheAddrOnFailure_) {
+ cacheAddresses();
}
handshakeStartTime_ = std::chrono::steady_clock::now();
// In order to call attachSSLContext, detachSSLContext must have been
// previously called.
// We need to update the initial_ctx if necessary
- auto sslCtx = ctx->getSSLCtx();
- SSL_CTX_up_ref(sslCtx);
-
// The 'initial_ctx' inside an SSL* points to the context that it was created
// with, which is also where session callbacks and servername callbacks
// happen.
// NOTE: this will only work if we have access to ssl_ internals, so it may
// not work on
// OpenSSL version >= 1.1.0
+ auto sslCtx = ctx->getSSLCtx();
OpenSSLUtils::setSSLInitialCtx(ssl_, sslCtx);
// Detach sets the socket's context to the dummy context. Thus we must acquire
// this lock.
}
}
-void AsyncSSLSocket::cacheLocalPeerAddr() {
- SocketAddress address;
- try {
- getLocalAddress(&address);
- getPeerAddress(&address);
- } catch (const std::system_error& e) {
- // The handle can be still valid while the connection is already closed.
- if (e.code() != std::error_code(ENOTCONN, std::system_category())) {
- throw;
- }
- }
-}
-
void AsyncSSLSocket::connect(
ConnectCallback* callback,
const folly::SocketAddress& address,
const folly::SocketAddress& bindAddr) noexcept {
assert(!server_);
assert(state_ == StateEnum::UNINIT);
- assert(sslState_ == STATE_UNINIT);
+ assert(sslState_ == STATE_UNINIT || sslState_ == STATE_UNENCRYPTED);
noTransparentTls_ = true;
totalConnectTimeout_ = totalConnectTimeout;
- AsyncSSLSocketConnector* connector =
- new AsyncSSLSocketConnector(this, callback, totalConnectTimeout.count());
+ if (sslState_ != STATE_UNENCRYPTED) {
+ callback = new AsyncSSLSocketConnector(
+ this, callback, int(totalConnectTimeout.count()));
+ }
AsyncSocket::connect(
- connector, address, connectTimeout.count(), options, bindAddr);
+ callback, address, int(connectTimeout.count()), options, bindAddr);
}
bool AsyncSSLSocket::needsPeerVerification() const {
std::chrono::milliseconds timeout,
const SSLContext::SSLVerifyPeerEnum& verifyPeer) {
DestructorGuard dg(this);
- assert(eventBase_->isInEventBaseThread());
+ eventBase_->dcheckIsInEventBaseThread();
// Cache local and remote socket addresses to keep them available
// after socket file descriptor is closed.
- if (cacheAddrOnFailure_ && -1 != getFd()) {
- cacheLocalPeerAddr();
+ if (cacheAddrOnFailure_) {
+ cacheAddresses();
}
verifyPeer_ = verifyPeer;
// The timeout (if set) keeps running here
return true;
#endif
- } else if ((0
+ } else if ((false
#ifdef SSL_ERROR_WANT_RSA_ASYNC_PENDING
- || error == SSL_ERROR_WANT_RSA_ASYNC_PENDING
+ || error == SSL_ERROR_WANT_RSA_ASYNC_PENDING
#endif
#ifdef SSL_ERROR_WANT_ECDSA_ASYNC_PENDING
- || error == SSL_ERROR_WANT_ECDSA_ASYNC_PENDING
+ || error == SSL_ERROR_WANT_ECDSA_ASYNC_PENDING
#endif
- )) {
+ )) {
// Our custom openssl function has kicked off an async request to do
// rsa/ecdsa private key operation. When that call returns, a callback will
// be invoked that will re-call handleAccept.
flags |= WriteFlags::CORK;
}
- int msg_flags = tsslSock->getSendMsgParamsCB()->getFlags(flags);
+ int msg_flags = tsslSock->getSendMsgParamsCB()->getFlags(
+ flags, false /*zeroCopyEnabled*/);
msg.msg_controllen =
tsslSock->getSendMsgParamsCB()->getAncillaryDataSize(flags);
CHECK_GE(AsyncSocket::SendMsgParamsCallback::maxAncillaryDataSize,
queue.append(std::move(sslSock->preReceivedData_));
queue.trimStart(len);
sslSock->preReceivedData_ = queue.move();
- return len;
+ return static_cast<int>(len);
} else {
- auto result = recv(OpenSSLUtils::getBioFd(b, nullptr), out, outl, 0);
+ auto result = int(recv(OpenSSLUtils::getBioFd(b, nullptr), out, outl, 0));
if (result <= 0 && OpenSSLUtils::getBioShouldRetryWrite(result)) {
BIO_set_retry_read(b);
}
void AsyncSSLSocket::enableClientHelloParsing() {
parseClientHello_ = true;
- clientHelloInfo_.reset(new ssl::ClientHelloInfo());
+ clientHelloInfo_ = std::make_unique<ssl::ClientHelloInfo>();
}
void AsyncSSLSocket::resetClientHelloParsing(SSL *ssl) {
}
}
-} // namespace
+} // namespace folly