proxygen
folly::AsyncSSLSocket Class Reference

#include <AsyncSSLSocket.h>

Inheritance diagram for folly::AsyncSSLSocket:
folly::AsyncSocket folly::AsyncTransportWrapper folly::AsyncTransport folly::AsyncReader folly::AsyncWriter folly::DelayedDestruction folly::AsyncSocketBase folly::DelayedDestructionBase folly::MockAsyncSSLSocket folly::test::MockAsyncSSLSocket

Classes

class  DefaultOpenSSLAsyncFinishCallback
 
class  HandshakeCB
 
class  Timeout
 

Public Types

enum  SSLStateEnum {
  STATE_UNINIT, STATE_UNENCRYPTED, STATE_ACCEPTING, STATE_CACHE_LOOKUP,
  STATE_ASYNC_PENDING, STATE_CONNECTING, STATE_ESTABLISHED, STATE_REMOTE_CLOSED,
  STATE_CLOSING, STATE_CONNECTING_CLOSING, STATE_CLOSED, STATE_ERROR
}
 
typedef std::unique_ptr< AsyncSSLSocket, DestructorUniquePtr
 
using X509_deleter = folly::static_function_deleter< X509,&X509_free >
 
- Public Types inherited from folly::AsyncSocket
enum  StateEnum : uint8_t {
  StateEnum::UNINIT, StateEnum::CONNECTING, StateEnum::ESTABLISHED, StateEnum::CLOSED,
  StateEnum::ERROR, StateEnum::FAST_OPEN
}
 
typedef std::unique_ptr< AsyncSocket, DestructorUniquePtr
 
typedef std::map< OptionKey, int > OptionMap
 
- Public Types inherited from folly::AsyncTransportWrapper
using UniquePtr = std::unique_ptr< AsyncTransportWrapper, Destructor >
 
using ReadCallback = AsyncReader::ReadCallback
 
using WriteCallback = AsyncWriter::WriteCallback
 
- Public Types inherited from folly::AsyncTransport
typedef std::unique_ptr< AsyncTransport, DestructorUniquePtr
 

Public Member Functions

 AsyncSSLSocket (const std::shared_ptr< folly::SSLContext > &ctx, EventBase *evb, bool deferSecurityNegotiation=false)
 
 AsyncSSLSocket (const std::shared_ptr< folly::SSLContext > &ctx, EventBase *evb, int fd, bool server=true, bool deferSecurityNegotiation=false)
 
 AsyncSSLSocket (const std::shared_ptr< folly::SSLContext > &ctx, AsyncSocket::UniquePtr oldAsyncSocket, bool server=true, bool deferSecurityNegotiation=false)
 
void closeNow () override
 
void shutdownWrite () override
 
void shutdownWriteNow () override
 
bool good () const override
 
bool connecting () const override
 
std::string getApplicationProtocol () const noexceptoverride
 
std::string getSecurityProtocol () const override
 
void setEorTracking (bool track) override
 
size_t getRawBytesWritten () const override
 
size_t getRawBytesReceived () const override
 
void enableClientHelloParsing ()
 
virtual void sslAccept (HandshakeCB *callback, std::chrono::milliseconds timeout=std::chrono::milliseconds::zero(), const folly::SSLContext::SSLVerifyPeerEnum &verifyPeer=folly::SSLContext::SSLVerifyPeerEnum::USE_CTX)
 
void restartSSLAccept ()
 
void connect (ConnectCallback *callback, const folly::SocketAddress &address, int timeout=0, const OptionMap &options=emptyOptionMap, const folly::SocketAddress &bindAddr=anyAddress()) noexceptoverride
 
virtual void connect (ConnectCallback *callback, const folly::SocketAddress &address, std::chrono::milliseconds connectTimeout, std::chrono::milliseconds totalConnectTimeout, const OptionMap &options=emptyOptionMap, const folly::SocketAddress &bindAddr=anyAddress()) noexcept
 
virtual void sslConn (HandshakeCB *callback, std::chrono::milliseconds timeout=std::chrono::milliseconds::zero(), const folly::SSLContext::SSLVerifyPeerEnum &verifyPeer=folly::SSLContext::SSLVerifyPeerEnum::USE_CTX)
 
SSLStateEnum getSSLState () const
 
SSL_SESSION * getSSLSession ()
 
const SSL * getSSL () const
 
void setSSLSession (SSL_SESSION *session, bool takeOwnership=false)
 
virtual void getSelectedNextProtocol (const unsigned char **protoName, unsigned *protoLen) const
 
virtual bool getSelectedNextProtocolNoThrow (const unsigned char **protoName, unsigned *protoLen) const
 
virtual bool getSSLSessionReused () const
 
bool sessionIDResumed () const
 
void setSessionIDResumed (bool resumed)
 
virtual const char * getNegotiatedCipherName () const
 
const char * getSSLServerName () const
 
const char * getSSLServerNameNoThrow () const
 
int getSSLVersion () const
 
const char * getSSLCertSigAlgName () const
 
int getSSLCertSize () const
 
const X509 * getSelfCert () const override
 
void attachEventBase (EventBase *eventBase) override
 
void detachEventBase () override
 
bool isDetachable () const override
 
virtual void attachTimeoutManager (TimeoutManager *manager)
 
virtual void detachTimeoutManager ()
 
const std::shared_ptr< folly::SSLContext > & getSSLContext () const
 
void timeoutExpired (std::chrono::milliseconds timeout) noexcept
 
void getSSLClientCiphers (std::string &clientCiphers, bool convertToString=true) const
 
std::string getSSLClientComprMethods () const
 
std::string getSSLClientExts () const
 
std::string getSSLClientSigAlgs () const
 
std::string getSSLClientSupportedVersions () const
 
std::string getSSLAlertsReceived () const
 
void setSSLCertVerificationAlert (std::string alert)
 
std::string getSSLCertVerificationAlert () const
 
void getSSLSharedCiphers (std::string &sharedCiphers) const
 
void getSSLServerCiphers (std::string &serverCiphers) const
 
bool needsPeerVerification () const
 
void resetClientHelloParsing (SSL *ssl)
 
ssl::ClientHelloInfogetClientHelloInfo () const
 
virtual std::chrono::nanoseconds getHandshakeTime () const
 
void setMinWriteSize (size_t minWriteSize)
 
size_t getMinWriteSize () const
 
void setReadCB (ReadCallback *callback) override
 
void setBufferMovableEnabled (bool enabled)
 
const AsyncTransportCertificategetPeerCertificate () const override
 
const AsyncTransportCertificategetSelfCertificate () const override
 
ssl::X509UniquePtr getPeerCert () const override
 
void forceCacheAddrOnFailure (bool force)
 
const std::stringgetSessionKey () const
 
void setSessionKey (std::string sessionKey)
 
void setCertCacheHit (bool hit)
 
bool getCertCacheHit () const
 
bool sessionResumptionAttempted () const
 
std::chrono::milliseconds getTotalConnectTimeout () const
 
void setAsyncOperationFinishCallback (std::unique_ptr< ReadCallback > cb)
 
- Public Member Functions inherited from folly::AsyncSocket
 AsyncSocket ()
 
 AsyncSocket (EventBase *evb)
 
void setShutdownSocketSet (const std::weak_ptr< ShutdownSocketSet > &wSS)
 
 AsyncSocket (EventBase *evb, const folly::SocketAddress &address, uint32_t connectTimeout=0)
 
 AsyncSocket (EventBase *evb, const std::string &ip, uint16_t port, uint32_t connectTimeout=0)
 
 AsyncSocket (EventBase *evb, int fd, uint32_t zeroCopyBufId=0)
 
 AsyncSocket (AsyncSocket::UniquePtr)
 
void destroy () override
 
EventBasegetEventBase () const override
 
virtual int getFd () const
 
virtual int detachFd ()
 
void connect (ConnectCallback *callback, const std::string &ip, uint16_t port, int timeout=0, const OptionMap &options=emptyOptionMap) noexcept
 
void cancelConnect ()
 
void setSendTimeout (uint32_t milliseconds) override
 
uint32_t getSendTimeout () const override
 
void setMaxReadsPerEvent (uint16_t maxReads)
 
uint16_t getMaxReadsPerEvent () const
 
virtual void setErrMessageCB (ErrMessageCallback *callback)
 
virtual ErrMessageCallbackgetErrMessageCallback () const
 
virtual void setSendMsgParamCB (SendMsgParamsCallback *callback)
 
virtual SendMsgParamsCallbackgetSendMsgParamsCB () const
 
ReadCallbackgetReadCallback () const override
 
bool setZeroCopy (bool enable)
 
bool getZeroCopy () const
 
uint32_t getZeroCopyBufId () const
 
size_t getZeroCopyReenableThreshold () const
 
void setZeroCopyReenableThreshold (size_t threshold)
 
void write (WriteCallback *callback, const void *buf, size_t bytes, WriteFlags flags=WriteFlags::NONE) override
 
void writev (WriteCallback *callback, const iovec *vec, size_t count, WriteFlags flags=WriteFlags::NONE) override
 
void writeChain (WriteCallback *callback, std::unique_ptr< folly::IOBuf > &&buf, WriteFlags flags=WriteFlags::NONE) override
 
virtual void writeRequest (WriteRequest *req)
 
void writeRequestReady ()
 
void close () override
 
void closeWithReset () override
 
bool readable () const override
 
bool writable () const override
 
bool isPending () const override
 
virtual bool hangup () const
 
bool error () const override
 
void getLocalAddress (folly::SocketAddress *address) const override
 
void getPeerAddress (folly::SocketAddress *address) const override
 
bool isEorTrackingEnabled () const override
 
virtual bool isClosedByPeer () const
 
virtual bool isClosedBySelf () const
 
size_t getAppBytesWritten () const override
 
size_t getAppBytesReceived () const override
 
std::chrono::nanoseconds getConnectTime () const
 
std::chrono::milliseconds getConnectTimeout () const
 
std::chrono::steady_clock::time_point getConnectStartTime () const
 
std::chrono::steady_clock::time_point getConnectEndTime () const
 
bool getTFOAttempted () const
 
bool getTFOFinished () const
 
bool getTFOSucceded () const
 
int setNoDelay (bool noDelay)
 
void setCloseOnExec ()
 
int setCongestionFlavor (const std::string &cname)
 
int setQuickAck (bool quickack)
 
int setSendBufSize (size_t bufsize)
 
int setRecvBufSize (size_t bufsize)
 
int setTCPProfile (int profd)
 
template<typename T >
int getSockOpt (int level, int optname, T *optval, socklen_t *optlen)
 
template<typename T >
int setSockOpt (int level, int optname, const T *optval)
 
virtual int getSockOptVirtual (int level, int optname, void *optval, socklen_t *optlen)
 
virtual int setSockOptVirtual (int level, int optname, void const *optval, socklen_t optlen)
 
virtual void setPreReceivedData (std::unique_ptr< IOBuf > data)
 
void enableTFO ()
 
void disableTransparentTls ()
 
void disableTSocks ()
 
void setBufferCallback (BufferCallback *cb)
 
void setEvbChangedCallback (std::unique_ptr< EvbChangeCallback > cb)
 
void cacheAddresses ()
 
bool isZeroCopyWriteInProgress () const noexcept
 
bool processZeroCopyWriteInProgress () noexcept
 
void setPeerCertificate (std::unique_ptr< const AsyncTransportCertificate > cert)
 
void setSelfCertificate (std::unique_ptr< const AsyncTransportCertificate > cert)
 
- Public Member Functions inherited from folly::AsyncTransportWrapper
virtual const AsyncTransportWrappergetWrappedTransport () const
 
template<class T >
const TgetUnderlyingTransport () const
 
template<class T >
TgetUnderlyingTransport ()
 
- Public Member Functions inherited from folly::AsyncTransport
SocketAddress getLocalAddress () const
 
void getAddress (SocketAddress *address) const override
 
SocketAddress getPeerAddress () const
 
virtual bool isReplaySafe () const
 
virtual void setReplaySafetyCallback (ReplaySafetyCallback *callback)
 
- Public Member Functions inherited from folly::DelayedDestruction
bool getDestroyPending () const
 
- Public Member Functions inherited from folly::DelayedDestructionBase
virtual ~DelayedDestructionBase ()=default
 
- Public Member Functions inherited from folly::AsyncSocketBase
virtual ~AsyncSocketBase ()=default
 

Static Public Member Functions

static std::shared_ptr< AsyncSSLSocketnewSocket (const std::shared_ptr< folly::SSLContext > &ctx, EventBase *evb, int fd, bool server=true, bool deferSecurityNegotiation=false)
 
static std::shared_ptr< AsyncSSLSocketnewSocket (const std::shared_ptr< folly::SSLContext > &ctx, EventBase *evb, bool deferSecurityNegotiation=false)
 
static int getSSLExDataIndex ()
 
static AsyncSSLSocketgetFromSSL (const SSL *ssl)
 
static int bioWrite (BIO *b, const char *in, int inl)
 
static int bioRead (BIO *b, char *out, int outl)
 
static void clientHelloParsingCallback (int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg)
 
static const char * getSSLServerNameFromSSL (SSL *ssl)
 
- Static Public Member Functions inherited from folly::AsyncSocket
static std::shared_ptr< AsyncSocketnewSocket (EventBase *evb)
 
static std::shared_ptr< AsyncSocketnewSocket (EventBase *evb, const folly::SocketAddress &address, uint32_t connectTimeout=0)
 
static std::shared_ptr< AsyncSocketnewSocket (EventBase *evb, const std::string &ip, uint16_t port, uint32_t connectTimeout=0)
 
static std::shared_ptr< AsyncSocketnewSocket (EventBase *evb, int fd)
 
static const folly::SocketAddressanyAddress ()
 

Protected Member Functions

 ~AsyncSSLSocket () override
 
void prepareReadBuffer (void **buf, size_t *buflen) override
 
void handleRead () noexceptoverride
 
void handleWrite () noexceptoverride
 
void handleAccept () noexcept
 
void handleConnect () noexceptoverride
 
void invalidState (HandshakeCB *callback)
 
bool willBlock (int ret, int *sslErrorOut, unsigned long *errErrorOut) noexcept
 
void checkForImmediateRead () noexceptoverride
 
void handleInitialReadWrite () noexceptoverride
 
WriteResult interpretSSLError (int rc, int error)
 
ReadResult performRead (void **buf, size_t *buflen, size_t *offset) override
 
WriteResult performWrite (const iovec *vec, uint32_t count, WriteFlags flags, uint32_t *countWritten, uint32_t *partialWritten) override
 
ssize_t performWriteIovec (const iovec *vec, uint32_t count, WriteFlags flags, uint32_t *countWritten, uint32_t *partialWritten)
 
virtual int sslWriteImpl (SSL *ssl, const void *buf, int n)
 
void applyVerificationOptions (const ssl::SSLUniquePtr &ssl)
 
bool setupSSLBio ()
 
int eorAwareSSLWrite (const ssl::SSLUniquePtr &ssl, const void *buf, int n, bool eor)
 
void failHandshake (const char *fn, const AsyncSocketException &ex)
 
void invokeHandshakeErr (const AsyncSocketException &ex)
 
void invokeHandshakeCB ()
 
void invokeConnectErr (const AsyncSocketException &ex) override
 
void invokeConnectSuccess () override
 
void scheduleConnectTimeout () override
 
void startSSLConnect ()
 
- Protected Member Functions inherited from folly::AsyncSocket
 ~AsyncSocket () override
 
void init ()
 
void scheduleImmediateRead () noexcept
 
void scheduleInitialReadWrite () noexcept
 
void ioReady (uint16_t events) noexcept
 
virtual size_t handleErrMessages () noexcept
 
void timeoutExpired () noexcept
 
void writeChainImpl (WriteCallback *callback, iovec *vec, size_t count, std::unique_ptr< folly::IOBuf > &&buf, WriteFlags flags)
 
void writeImpl (WriteCallback *callback, const iovec *vec, size_t count, std::unique_ptr< folly::IOBuf > &&buf, WriteFlags flags=WriteFlags::NONE)
 
AsyncSocket::WriteResult sendSocketMessage (int fd, struct msghdr *msg, int msg_flags)
 
virtual ssize_t tfoSendMsg (int fd, struct msghdr *msg, int msg_flags)
 
int socketConnect (const struct sockaddr *addr, socklen_t len)
 
void registerForConnectEvents ()
 
bool updateEventRegistration ()
 
bool updateEventRegistration (uint16_t enable, uint16_t disable)
 
void doClose ()
 
void startFail ()
 
void finishFail ()
 
void finishFail (const AsyncSocketException &ex)
 
void invokeAllErrors (const AsyncSocketException &ex)
 
void fail (const char *fn, const AsyncSocketException &ex)
 
void failConnect (const char *fn, const AsyncSocketException &ex)
 
void failRead (const char *fn, const AsyncSocketException &ex)
 
void failErrMessageRead (const char *fn, const AsyncSocketException &ex)
 
void failWrite (const char *fn, WriteCallback *callback, size_t bytesWritten, const AsyncSocketException &ex)
 
void failWrite (const char *fn, const AsyncSocketException &ex)
 
void failAllWrites (const AsyncSocketException &ex)
 
void invalidState (ConnectCallback *callback)
 
void invalidState (ErrMessageCallback *callback)
 
void invalidState (ReadCallback *callback)
 
void invalidState (WriteCallback *callback)
 
std::string withAddr (const std::string &s)
 
void cacheLocalAddress () const
 
void cachePeerAddress () const
 
bool isZeroCopyRequest (WriteFlags flags)
 
bool isZeroCopyMsg (const cmsghdr &cmsg) const
 
void processZeroCopyMsg (const cmsghdr &cmsg)
 
uint32_t getNextZeroCopyBufId ()
 
void adjustZeroCopyFlags (folly::WriteFlags &flags)
 
void addZeroCopyBuf (std::unique_ptr< folly::IOBuf > &&buf)
 
void addZeroCopyBuf (folly::IOBuf *ptr)
 
void setZeroCopyBuf (std::unique_ptr< folly::IOBuf > &&buf)
 
bool containsZeroCopyBuf (folly::IOBuf *ptr)
 
void releaseZeroCopyBuf (uint32_t id)
 
- Protected Member Functions inherited from folly::AsyncTransport
 ~AsyncTransport () override=default
 
- Protected Member Functions inherited from folly::DelayedDestruction
 ~DelayedDestruction () override=default
 
 DelayedDestruction ()
 
- Protected Member Functions inherited from folly::DelayedDestructionBase
 DelayedDestructionBase ()
 
uint32_t getDestructorGuardCount () const
 
- Protected Member Functions inherited from folly::AsyncReader
virtual ~AsyncReader ()=default
 
- Protected Member Functions inherited from folly::AsyncWriter
virtual ~AsyncWriter ()=default
 

Static Protected Member Functions

static void sslInfoCallback (const SSL *ssl, int type, int val)
 
static int sslVerifyCallback (int preverifyOk, X509_STORE_CTX *ctx)
 

Protected Attributes

bool corkCurrentWrite_ {false}
 
bool server_ {false}
 
bool handshakeComplete_ {false}
 
bool renegotiateAttempted_ {false}
 
SSLStateEnum sslState_ {STATE_UNINIT}
 
std::shared_ptr< folly::SSLContextctx_
 
HandshakeCBhandshakeCallback_ {nullptr}
 
ssl::SSLUniquePtr ssl_
 
SSL_SESSION * sslSession_ {nullptr}
 
Timeout handshakeTimeout_
 
Timeout connectionTimeout_
 
size_t appEorByteNo_ {0}
 
size_t minWriteSize_ {1500}
 
size_t minEorRawByteNo_ {0}
 
std::string sessionKey_
 
folly::SSLContext::SSLVerifyPeerEnum verifyPeer_
 
bool parseClientHello_ {false}
 
bool cacheAddrOnFailure_ {false}
 
bool bufferMovableEnabled_ {false}
 
bool certCacheHit_ {false}
 
std::unique_ptr< ssl::ClientHelloInfoclientHelloInfo_
 
std::vector< std::pair< char, StringPiece > > alertsReceived_
 
std::chrono::steady_clock::time_point handshakeStartTime_
 
std::chrono::steady_clock::time_point handshakeEndTime_
 
std::chrono::milliseconds handshakeConnectTimeout_ {0}
 
std::chrono::milliseconds totalConnectTimeout_ {0}
 
std::string sslVerificationAlert_
 
bool sessionResumptionAttempted_ {false}
 
bool sessionIDResumed_ {false}
 
std::unique_ptr< ReadCallbackasyncOperationFinishCallback_
 
- Protected Attributes inherited from folly::AsyncSocket
uint32_t zeroCopyBufId_ {0}
 
std::unordered_map< uint32_t, folly::IOBuf * > idZeroCopyBufPtrMap_
 
std::unordered_map< folly::IOBuf *, IOBufInfoidZeroCopyBufInfoMap_
 
StateEnum state_
 StateEnum describing current state. More...
 
uint8_t shutdownFlags_
 Shutdown state (ShutdownFlags) More...
 
uint16_t eventFlags_
 EventBase::HandlerFlags settings. More...
 
int fd_
 The socket file descriptor. More...
 
folly::SocketAddress addr_
 The address we tried to connect to. More...
 
folly::SocketAddress localAddr_
 The address we are connecting from. More...
 
uint32_t sendTimeout_
 The send timeout, in milliseconds. More...
 
uint16_t maxReadsPerEvent_
 Max reads per event loop iteration. More...
 
bool isBufferMovable_ {false}
 
int8_t readErr_ {READ_NO_ERROR}
 The read error encountered, if any. More...
 
EventBaseeventBase_
 The EventBase. More...
 
WriteTimeout writeTimeout_
 A timeout for connect and write. More...
 
IoHandler ioHandler_
 A EventHandler to monitor the fd. More...
 
ImmediateReadCB immediateReadHandler_
 LoopCallback for checking read. More...
 
ConnectCallbackconnectCallback_
 ConnectCallback. More...
 
ErrMessageCallbackerrMessageCallback_
 TimestampCallback. More...
 
SendMsgParamsCallbacksendMsgParamCallback_
 < Callback for retrieving More...
 
ReadCallbackreadCallback_
 ReadCallback. More...
 
WriteRequestwriteReqHead_
 Chain of WriteRequests. More...
 
WriteRequestwriteReqTail_
 End of WriteRequest chain. More...
 
std::weak_ptr< ShutdownSocketSetwShutdownSocketSet_
 
size_t appBytesReceived_
 Num of bytes received from socket. More...
 
size_t appBytesWritten_
 Num of bytes written to socket. More...
 
std::unique_ptr< IOBufpreReceivedData_
 
std::chrono::steady_clock::time_point connectStartTime_
 
std::chrono::steady_clock::time_point connectEndTime_
 
std::chrono::milliseconds connectTimeout_ {0}
 
std::unique_ptr< EvbChangeCallbackevbChangeCb_ {nullptr}
 
BufferCallbackbufferCallback_ {nullptr}
 
bool tfoEnabled_ {false}
 
bool tfoAttempted_ {false}
 
bool tfoFinished_ {false}
 
bool noTransparentTls_ {false}
 
bool noTSocks_ {false}
 
bool trackEor_ {false}
 
bool zeroCopyEnabled_ {false}
 
bool zeroCopyVal_ {false}
 
size_t zeroCopyReenableThreshold_ {0}
 
size_t zeroCopyReenableCounter_ {0}
 
std::unique_ptr< const AsyncTransportCertificatepeerCertData_
 
std::unique_ptr< const AsyncTransportCertificateselfCertData_
 

Private Member Functions

void handleReturnFromSSLAccept (int ret)
 
void init ()
 

Additional Inherited Members

- Static Public Attributes inherited from folly::AsyncSocket
static const OptionMap emptyOptionMap
 
- Protected Types inherited from folly::AsyncSocket
enum  ReadResultEnum { READ_EOF = 0, READ_ERROR = -1, READ_BLOCKING = -2, READ_NO_ERROR = -3 }
 
enum  WriteResultEnum { WRITE_ERROR = -1 }
 
enum  ShutdownFlags { SHUT_WRITE_PENDING = 0x01, SHUT_WRITE = 0x02, SHUT_READ = 0x04 }
 

Detailed Description

A class for performing asynchronous I/O on an SSL connection.

AsyncSSLSocket allows users to asynchronously wait for data on an SSL connection, and to asynchronously send data.

The APIs for reading and writing are intentionally asymmetric. Waiting for data to read is a persistent API: a callback is installed, and is notified whenever new data is available. It continues to be notified of new events until it is uninstalled.

AsyncSSLSocket does not provide read timeout functionality, because it typically cannot determine when the timeout should be active. Generally, a timeout should only be enabled when processing is blocked waiting on data from the remote endpoint. For server connections, the timeout should not be active if the server is currently processing one or more outstanding requests for this connection. For client connections, the timeout should not be active if there are no requests pending on the connection. Additionally, if a client has multiple pending requests, it will ususally want a separate timeout for each request, rather than a single read timeout.

The write API is fairly intuitive: a user can request to send a block of data, and a callback will be informed once the entire block has been transferred to the kernel, or on error. AsyncSSLSocket does provide a send timeout, since most callers want to give up if the remote end stops responding and no further progress can be made sending the data.

Definition at line 70 of file AsyncSSLSocket.h.

Member Typedef Documentation

Definition at line 72 of file AsyncSSLSocket.h.

Definition at line 73 of file AsyncSSLSocket.h.

Member Enumeration Documentation

Enumerator
STATE_UNINIT 
STATE_UNENCRYPTED 
STATE_ACCEPTING 
STATE_CACHE_LOOKUP 
STATE_ASYNC_PENDING 
STATE_CONNECTING 
STATE_ESTABLISHED 
STATE_REMOTE_CLOSED 
STATE_CLOSING 

remote end closed; we can still write

close() called, but waiting on writes to complete

STATE_CONNECTING_CLOSING 

close() called with pending writes, before connect() has completed

STATE_CLOSED 
STATE_ERROR 

Definition at line 428 of file AsyncSSLSocket.h.

Constructor & Destructor Documentation

folly::AsyncSSLSocket::AsyncSSLSocket ( const std::shared_ptr< folly::SSLContext > &  ctx,
EventBase evb,
bool  deferSecurityNegotiation = false 
)

Create a client AsyncSSLSocket

Definition at line 222 of file AsyncSSLSocket.cpp.

References init(), sslState_, and STATE_UNENCRYPTED.

Referenced by AsyncSSLSocket(), and newSocket().

226  : AsyncSocket(evb),
227  ctx_(ctx),
228  handshakeTimeout_(this, evb),
229  connectionTimeout_(this, evb) {
230  init();
231  if (deferSecurityNegotiation) {
233  }
234 }
std::shared_ptr< folly::SSLContext > ctx_
folly::AsyncSSLSocket::AsyncSSLSocket ( const std::shared_ptr< folly::SSLContext > &  ctx,
EventBase evb,
int  fd,
bool  server = true,
bool  deferSecurityNegotiation = false 
)

Create a server/client AsyncSSLSocket from an already connected socket file descriptor.

Note that while AsyncSSLSocket enables TCP_NODELAY for sockets it creates when connecting, it does not change the socket options when given an existing file descriptor. If callers want TCP_NODELAY enabled when using this version of the constructor, they need to explicitly call setNoDelay(true) after the constructor returns.

Parameters
ctxSSL context for this connection.
evbEventBase that will manage this socket.
fdFile descriptor to take over (should be a connected socket).
serverIs socket in server mode?
deferSecurityNegotiationunencrypted data can be sent before sslConn/Accept

Create a server/client AsyncSSLSocket

Definition at line 239 of file AsyncSSLSocket.cpp.

References ctx_, init(), folly::AsyncSocket::noTransparentTls_, sslInfoCallback(), sslState_, and STATE_UNENCRYPTED.

245  : AsyncSocket(evb, fd),
246  server_(server),
247  ctx_(ctx),
248  handshakeTimeout_(this, evb),
249  connectionTimeout_(this, evb) {
250  noTransparentTls_ = true;
251  init();
252  if (server) {
253  SSL_CTX_set_info_callback(
254  ctx_->getSSLCtx(), AsyncSSLSocket::sslInfoCallback);
255  }
256  if (deferSecurityNegotiation) {
258  }
259 }
std::shared_ptr< folly::SSLContext > ctx_
static void sslInfoCallback(const SSL *ssl, int type, int val)
folly::AsyncSSLSocket::AsyncSSLSocket ( const std::shared_ptr< folly::SSLContext > &  ctx,
AsyncSocket::UniquePtr  oldAsyncSocket,
bool  server = true,
bool  deferSecurityNegotiation = false 
)

Create a server/client AsyncSSLSocket from an already connected AsyncSocket.

Definition at line 261 of file AsyncSSLSocket.cpp.

References AsyncSSLSocket(), ctx_, init(), folly::AsyncSocket::noTransparentTls_, sslInfoCallback(), sslState_, STATE_UNENCRYPTED, and string.

266  : AsyncSocket(std::move(oldAsyncSocket)),
267  server_(server),
268  ctx_(ctx),
271  noTransparentTls_ = true;
272  init();
273  if (server) {
274  SSL_CTX_set_info_callback(
275  ctx_->getSSLCtx(), AsyncSSLSocket::sslInfoCallback);
276  }
277  if (deferSecurityNegotiation) {
279  }
280 }
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
std::shared_ptr< folly::SSLContext > ctx_
EventBase * getEventBase() const override
Definition: AsyncSocket.h:328
static void sslInfoCallback(const SSL *ssl, int type, int val)
folly::AsyncSSLSocket::~AsyncSSLSocket ( )
overrideprotected

Protected destructor.

Users of AsyncSSLSocket must never delete it directly. Instead, invoke destroy() instead. (See the documentation in DelayedDestruction.h for more details.)

Definition at line 311 of file AsyncSSLSocket.cpp.

References folly::AsyncSocket::eventBase_, folly::AsyncSocket::eventFlags_, folly::AsyncSocket::fd_, sslState_, and folly::AsyncSocket::state_.

Referenced by setAsyncOperationFinishCallback().

311  {
312  VLOG(3) << "actual destruction of AsyncSSLSocket(this=" << this
313  << ", evb=" << eventBase_ << ", fd=" << fd_
314  << ", state=" << int(state_) << ", sslState=" << sslState_
315  << ", events=" << eventFlags_ << ")";
316 }
EventBase * eventBase_
The EventBase.
Definition: AsyncSocket.h:1240
uint16_t eventFlags_
EventBase::HandlerFlags settings.
Definition: AsyncSocket.h:1228
StateEnum state_
StateEnum describing current state.
Definition: AsyncSocket.h:1226
int fd_
The socket file descriptor.
Definition: AsyncSocket.h:1229

Member Function Documentation

void folly::AsyncSSLSocket::applyVerificationOptions ( const ssl::SSLUniquePtr ssl)
protected

Apply verification options passed to sslConn/sslAccept or those set in the underlying SSLContext object.

Parameters
sslpointer to the SSL object on which verification options will be applied. If verifyPeer_ was explicitly set either via sslConn/sslAccept, those options override the settings in the underlying SSLContext.

Definition at line 720 of file AsyncSSLSocket.cpp.

References ctx_, folly::SSLContext::getVerificationMode(), sslVerifyCallback(), and verifyPeer_.

Referenced by handleAccept(), sslConn(), and sslWriteImpl().

720  {
721  // apply the settings specified in verifyPeer_
722  if (verifyPeer_ == SSLContext::SSLVerifyPeerEnum::USE_CTX) {
723  if (ctx_->needsPeerVerification()) {
724  SSL_set_verify(
725  ssl.get(),
726  ctx_->getVerificationMode(),
728  }
729  } else {
730  if (verifyPeer_ == SSLContext::SSLVerifyPeerEnum::VERIFY ||
731  verifyPeer_ == SSLContext::SSLVerifyPeerEnum::VERIFY_REQ_CLIENT_CERT) {
732  SSL_set_verify(
733  ssl.get(),
736  }
737  }
738 }
virtual int getVerificationMode()
Definition: SSLContext.cpp:185
static int sslVerifyCallback(int preverifyOk, X509_STORE_CTX *ctx)
folly::SSLContext::SSLVerifyPeerEnum verifyPeer_
std::shared_ptr< folly::SSLContext > ctx_
void folly::AsyncSSLSocket::attachEventBase ( EventBase eventBase)
inlineoverridevirtual

Attach the transport to a EventBase.

This may only be called if the transport is not currently attached to a EventBase (by an earlier call to detachEventBase()).

This method must be invoked in the EventBase's thread.

Reimplemented from folly::AsyncSocket.

Definition at line 569 of file AsyncSSLSocket.h.

References folly::AsyncTimeout::attachEventBase(), folly::AsyncSocket::attachEventBase(), connectionTimeout_, and handshakeTimeout_.

Referenced by folly::EvbAndContext::attach().

569  {
570  AsyncSocket::attachEventBase(eventBase);
573  }
void attachEventBase(EventBase *eventBase) override
void attachEventBase(EventBase *eventBase, InternalEnum internal=InternalEnum::NORMAL)
virtual void folly::AsyncSSLSocket::attachTimeoutManager ( TimeoutManager manager)
inlinevirtual

Definition at line 585 of file AsyncSSLSocket.h.

References folly::AsyncTimeout::attachTimeoutManager(), and handshakeTimeout_.

585  {
587  }
void attachTimeoutManager(TimeoutManager *timeoutManager, InternalEnum internal=InternalEnum::NORMAL)
int folly::AsyncSSLSocket::bioRead ( BIO *  b,
char *  out,
int  outl 
)
static

Definition at line 1751 of file AsyncSSLSocket.cpp.

References folly::IOBufQueue::append(), folly::ssl::OpenSSLUtils::getBioAppData(), folly::ssl::OpenSSLUtils::getBioFd(), folly::ssl::OpenSSLUtils::getBioShouldRetryWrite(), folly::IOBufQueue::move(), folly::gen::move, folly::io::detail::CursorBase< Derived, BufType >::pullAtMost(), folly::netops::recv(), and folly::IOBufQueue::trimStart().

Referenced by getSSLContext().

1751  {
1752  if (!out) {
1753  return 0;
1754  }
1755  BIO_clear_retry_flags(b);
1756 
1757  auto appData = OpenSSLUtils::getBioAppData(b);
1758  CHECK(appData);
1759  auto sslSock = reinterpret_cast<AsyncSSLSocket*>(appData);
1760 
1761  if (sslSock->preReceivedData_ && !sslSock->preReceivedData_->empty()) {
1762  VLOG(5) << "AsyncSSLSocket::bioRead() this=" << sslSock
1763  << ", reading pre-received data";
1764 
1765  Cursor cursor(sslSock->preReceivedData_.get());
1766  auto len = cursor.pullAtMost(out, outl);
1767 
1768  IOBufQueue queue;
1769  queue.append(std::move(sslSock->preReceivedData_));
1770  queue.trimStart(len);
1771  sslSock->preReceivedData_ = queue.move();
1772  return static_cast<int>(len);
1773  } else {
1774  auto result = int(recv(OpenSSLUtils::getBioFd(b, nullptr), out, outl, 0));
1775  if (result <= 0 && OpenSSLUtils::getBioShouldRetryWrite(result)) {
1776  BIO_set_retry_read(b);
1777  }
1778  return result;
1779  }
1780 }
char b
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
static void * getBioAppData(BIO *b)
size_t pullAtMost(void *buf, size_t len)
Definition: Cursor.h:407
static int getBioFd(BIO *b, int *fd)
static int getBioShouldRetryWrite(int ret)
AsyncSSLSocket(const std::shared_ptr< folly::SSLContext > &ctx, EventBase *evb, bool deferSecurityNegotiation=false)
ssize_t recv(NetworkSocket s, void *buf, size_t len, int flags)
Definition: NetOps.cpp:180
int folly::AsyncSSLSocket::bioWrite ( BIO *  b,
const char *  in,
int  inl 
)
static

Definition at line 1701 of file AsyncSSLSocket.cpp.

References folly::CORK, folly::EOR, folly::ssl::OpenSSLUtils::getBioAppData(), folly::ssl::OpenSSLUtils::getBioFd(), folly::ssl::OpenSSLUtils::getBioShouldRetryWrite(), folly::AsyncSocket::SendMsgParamsCallback::maxAncillaryDataSize, and folly::NONE.

Referenced by getSSLContext().

1701  {
1702  struct msghdr msg;
1703  struct iovec iov;
1704  AsyncSSLSocket* tsslSock;
1705 
1706  iov.iov_base = const_cast<char*>(in);
1707  iov.iov_len = size_t(inl);
1708  memset(&msg, 0, sizeof(msg));
1709  msg.msg_iov = &iov;
1710  msg.msg_iovlen = 1;
1711 
1712  auto appData = OpenSSLUtils::getBioAppData(b);
1713  CHECK(appData);
1714 
1715  tsslSock = reinterpret_cast<AsyncSSLSocket*>(appData);
1716  CHECK(tsslSock);
1717 
1719  if (tsslSock->isEorTrackingEnabled() && tsslSock->minEorRawByteNo_ &&
1720  tsslSock->minEorRawByteNo_ <= BIO_number_written(b) + inl) {
1721  flags |= WriteFlags::EOR;
1722  }
1723 
1724  if (tsslSock->corkCurrentWrite_) {
1725  flags |= WriteFlags::CORK;
1726  }
1727 
1728  int msg_flags = tsslSock->getSendMsgParamsCB()->getFlags(
1729  flags, false /*zeroCopyEnabled*/);
1730  msg.msg_controllen =
1731  tsslSock->getSendMsgParamsCB()->getAncillaryDataSize(flags);
1732  CHECK_GE(
1734  msg.msg_controllen);
1735  if (msg.msg_controllen != 0) {
1736  msg.msg_control = reinterpret_cast<char*>(alloca(msg.msg_controllen));
1737  tsslSock->getSendMsgParamsCB()->getAncillaryData(flags, msg.msg_control);
1738  }
1739 
1740  auto result = tsslSock->sendSocketMessage(
1741  OpenSSLUtils::getBioFd(b, nullptr), &msg, msg_flags);
1742  BIO_clear_retry_flags(b);
1743  if (!result.exception && result.writeReturn <= 0) {
1744  if (OpenSSLUtils::getBioShouldRetryWrite(int(result.writeReturn))) {
1745  BIO_set_retry_write(b);
1746  }
1747  }
1748  return int(result.writeReturn);
1749 }
flags
Definition: http_parser.h:127
char b
static void * getBioAppData(BIO *b)
static int getBioFd(BIO *b, int *fd)
static int getBioShouldRetryWrite(int ret)
AsyncSSLSocket(const std::shared_ptr< folly::SSLContext > &ctx, EventBase *evb, bool deferSecurityNegotiation=false)
void folly::AsyncSSLSocket::checkForImmediateRead ( )
overrideprotectedvirtualnoexcept

Reimplemented from folly::AsyncSocket.

Definition at line 1073 of file AsyncSSLSocket.cpp.

References folly::AsyncSocket::checkForImmediateRead(), folly::AsyncSocket::handleRead(), and ssl_.

Referenced by setAsyncOperationFinishCallback(), and sslAccept().

1073  {
1074  // openssl may have buffered data that it read from the socket already.
1075  // In this case we have to process it immediately, rather than waiting for
1076  // the socket to become readable again.
1077  if (ssl_ != nullptr && SSL_pending(ssl_.get()) > 0) {
1079  } else {
1081  }
1082 }
ssl::SSLUniquePtr ssl_
virtual void handleRead() noexcept
virtual void checkForImmediateRead() noexcept
void folly::AsyncSSLSocket::clientHelloParsingCallback ( int  write_p,
int  version,
int  content_type,
const void *  buf,
size_t  len,
SSL *  ssl,
void *  arg 
)
static

Definition at line 1807 of file AsyncSSLSocket.cpp.

References clientHelloInfo_, folly::IOBuf::copyBuffer(), i, resetClientHelloParsing(), folly::ssl::SIGNATURE_ALGORITHMS, folly::ssl::SUPPORTED_VERSIONS, uint16_t, uint32_t, uint8_t, and folly::IOBuf::wrapBuffer().

Referenced by getSSLContext(), and handleAccept().

1814  {
1815  AsyncSSLSocket* sock = static_cast<AsyncSSLSocket*>(arg);
1816  if (written != 0) {
1817  sock->resetClientHelloParsing(ssl);
1818  return;
1819  }
1820  if (contentType != SSL3_RT_HANDSHAKE) {
1821  return;
1822  }
1823  if (len == 0) {
1824  return;
1825  }
1826 
1827  auto& clientHelloBuf = sock->clientHelloInfo_->clientHelloBuf_;
1828  clientHelloBuf.append(IOBuf::wrapBuffer(buf, len));
1829  try {
1830  Cursor cursor(clientHelloBuf.front());
1831  if (cursor.read<uint8_t>() != SSL3_MT_CLIENT_HELLO) {
1832  sock->resetClientHelloParsing(ssl);
1833  return;
1834  }
1835 
1836  if (cursor.totalLength() < 3) {
1837  clientHelloBuf.trimEnd(len);
1838  clientHelloBuf.append(IOBuf::copyBuffer(buf, len));
1839  return;
1840  }
1841 
1842  uint32_t messageLength = cursor.read<uint8_t>();
1843  messageLength <<= 8;
1844  messageLength |= cursor.read<uint8_t>();
1845  messageLength <<= 8;
1846  messageLength |= cursor.read<uint8_t>();
1847  if (cursor.totalLength() < messageLength) {
1848  clientHelloBuf.trimEnd(len);
1849  clientHelloBuf.append(IOBuf::copyBuffer(buf, len));
1850  return;
1851  }
1852 
1853  sock->clientHelloInfo_->clientHelloMajorVersion_ = cursor.read<uint8_t>();
1854  sock->clientHelloInfo_->clientHelloMinorVersion_ = cursor.read<uint8_t>();
1855 
1856  cursor.skip(4); // gmt_unix_time
1857  cursor.skip(28); // random_bytes
1858 
1859  cursor.skip(cursor.read<uint8_t>()); // session_id
1860 
1861  uint16_t cipherSuitesLength = cursor.readBE<uint16_t>();
1862  for (int i = 0; i < cipherSuitesLength; i += 2) {
1863  sock->clientHelloInfo_->clientHelloCipherSuites_.push_back(
1864  cursor.readBE<uint16_t>());
1865  }
1866 
1867  uint8_t compressionMethodsLength = cursor.read<uint8_t>();
1868  for (int i = 0; i < compressionMethodsLength; ++i) {
1869  sock->clientHelloInfo_->clientHelloCompressionMethods_.push_back(
1870  cursor.readBE<uint8_t>());
1871  }
1872 
1873  if (cursor.totalLength() > 0) {
1874  uint16_t extensionsLength = cursor.readBE<uint16_t>();
1875  while (extensionsLength) {
1876  ssl::TLSExtension extensionType =
1877  static_cast<ssl::TLSExtension>(cursor.readBE<uint16_t>());
1878  sock->clientHelloInfo_->clientHelloExtensions_.push_back(extensionType);
1879  extensionsLength -= 2;
1880  uint16_t extensionDataLength = cursor.readBE<uint16_t>();
1881  extensionsLength -= 2;
1882  extensionsLength -= extensionDataLength;
1883 
1884  if (extensionType == ssl::TLSExtension::SIGNATURE_ALGORITHMS) {
1885  cursor.skip(2);
1886  extensionDataLength -= 2;
1887  while (extensionDataLength) {
1888  ssl::HashAlgorithm hashAlg =
1889  static_cast<ssl::HashAlgorithm>(cursor.readBE<uint8_t>());
1890  ssl::SignatureAlgorithm sigAlg =
1891  static_cast<ssl::SignatureAlgorithm>(cursor.readBE<uint8_t>());
1892  extensionDataLength -= 2;
1893  sock->clientHelloInfo_->clientHelloSigAlgs_.emplace_back(
1894  hashAlg, sigAlg);
1895  }
1896  } else if (extensionType == ssl::TLSExtension::SUPPORTED_VERSIONS) {
1897  cursor.skip(1);
1898  extensionDataLength -= 1;
1899  while (extensionDataLength) {
1900  sock->clientHelloInfo_->clientHelloSupportedVersions_.push_back(
1901  cursor.readBE<uint16_t>());
1902  extensionDataLength -= 2;
1903  }
1904  } else {
1905  cursor.skip(extensionDataLength);
1906  }
1907  }
1908  }
1909  } catch (std::out_of_range&) {
1910  // we'll use what we found and cleanup below.
1911  VLOG(4) << "AsyncSSLSocket::clientHelloParsingCallback(): "
1912  << "buffer finished unexpectedly."
1913  << " AsyncSSLSocket socket=" << sock;
1914  }
1915 
1916  sock->resetClientHelloParsing(ssl);
1917 }
static std::unique_ptr< IOBuf > wrapBuffer(const void *buf, std::size_t capacity)
Definition: IOBuf.cpp:353
AsyncSSLSocket(const std::shared_ptr< folly::SSLContext > &ctx, EventBase *evb, bool deferSecurityNegotiation=false)
static std::unique_ptr< IOBuf > copyBuffer(const void *buf, std::size_t size, std::size_t headroom=0, std::size_t minTailroom=0)
Definition: IOBuf.h:1587
void folly::AsyncSSLSocket::closeNow ( )
overridevirtual

TODO: implement support for SSL renegotiation.

This involves proper handling of the SSL_ERROR_WANT_READ/WRITE code as a result of SSL_write/read(), instead of returning an error. In that case, the READ/WRITE event should be registered, and a flag (e.g., writeBlockedOnRead) should be set to indiciate the condition. In the next invocation of read/write callback, if the flag is on, performWrite()/performRead() should be called in addition to the normal call to performRead()/performWrite(), and the flag should be reset.

Reimplemented from folly::AsyncSocket.

Definition at line 327 of file AsyncSSLSocket.cpp.

References folly::AsyncTimeout::cancelTimeout(), folly::AsyncSocket::closeNow(), folly::AsyncSocketException::END_OF_FILE, folly::AsyncSocket::fd_, handshakeTimeout_, invokeHandshakeErr(), folly::AsyncTimeout::isScheduled(), ssl_, sslSession_, sslState_, and STATE_CLOSED.

Referenced by folly::test::MockAsyncSSLSocket::connect(), SSLCacheClient::handshakeSuc(), newSocket(), shutdownWriteNow(), and folly::TEST().

327  {
328  // Close the SSL connection.
329  if (ssl_ != nullptr && fd_ != -1) {
330  int rc = SSL_shutdown(ssl_.get());
331  if (rc == 0) {
332  rc = SSL_shutdown(ssl_.get());
333  }
334  if (rc < 0) {
335  ERR_clear_error();
336  }
337  }
338 
339  if (sslSession_ != nullptr) {
340  SSL_SESSION_free(sslSession_);
341  sslSession_ = nullptr;
342  }
343 
345 
348  }
349 
350  DestructorGuard dg(this);
351 
352  invokeHandshakeErr(AsyncSocketException(
353  AsyncSocketException::END_OF_FILE, "SSL connection closed locally"));
354 
355  // Close the socket.
357 }
void invokeHandshakeErr(const AsyncSocketException &ex)
ssl::SSLUniquePtr ssl_
SSL_SESSION * sslSession_
void closeNow() override
int fd_
The socket file descriptor.
Definition: AsyncSocket.h:1229
bool isScheduled() const
void folly::AsyncSSLSocket::connect ( ConnectCallback callback,
const folly::SocketAddress address,
int  timeout = 0,
const OptionMap options = emptyOptionMap,
const folly::SocketAddress bindAddr = anyAddress() 
)
overridevirtualnoexcept

Connect to the given address, invoking callback when complete or on error

Note timeout applies to TCP + SSL connection time

Reimplemented from folly::AsyncSocket.

Reimplemented in folly::test::MockAsyncSSLSocket.

Definition at line 682 of file AsyncSSLSocket.cpp.

References folly::detail::timeout.

Referenced by getSecurityProtocol().

687  {
688  auto timeoutChrono = std::chrono::milliseconds(timeout);
689  connect(callback, address, timeoutChrono, timeoutChrono, options, bindAddr);
690 }
void connect(ConnectCallback *callback, const folly::SocketAddress &address, int timeout=0, const OptionMap &options=emptyOptionMap, const folly::SocketAddress &bindAddr=anyAddress()) noexceptoverride
void folly::AsyncSSLSocket::connect ( ConnectCallback callback,
const folly::SocketAddress address,
std::chrono::milliseconds  connectTimeout,
std::chrono::milliseconds  totalConnectTimeout,
const OptionMap options = emptyOptionMap,
const folly::SocketAddress bindAddr = anyAddress() 
)
virtualnoexcept

A variant of connect that allows the caller to specify the timeout for the regular connect and the ssl connect separately. connectTimeout is specified as the time to establish a TCP connection. totalConnectTimeout defines the time it takes from starting the TCP connection to the time the ssl connection is established. The reason the timeout is defined this way is because user's rarely need to specify the SSL timeout independently of the connect timeout. It allows us to bound the time for a connect and SSL connection in a finer grained manner than if timeout was just defined independently for SSL.

Definition at line 692 of file AsyncSSLSocket.cpp.

References folly::AsyncSocket::connect(), folly::AsyncSocket::noTransparentTls_, server_, sslState_, folly::AsyncSocket::state_, STATE_UNENCRYPTED, STATE_UNINIT, totalConnectTimeout_, and folly::AsyncSocket::UNINIT.

698  {
699  assert(!server_);
700  assert(state_ == StateEnum::UNINIT);
702  noTransparentTls_ = true;
703  totalConnectTimeout_ = totalConnectTimeout;
704  if (sslState_ != STATE_UNENCRYPTED) {
705  callback = new AsyncSSLSocketConnector(this, callback, totalConnectTimeout);
706  }
708  callback, address, int(connectTimeout.count()), options, bindAddr);
709 }
virtual void connect(ConnectCallback *callback, const folly::SocketAddress &address, int timeout=0, const OptionMap &options=emptyOptionMap, const folly::SocketAddress &bindAddr=anyAddress()) noexcept
std::chrono::milliseconds totalConnectTimeout_
StateEnum state_
StateEnum describing current state.
Definition: AsyncSocket.h:1226
bool folly::AsyncSSLSocket::connecting ( ) const
overridevirtual

Determine if transport is connected to the endpoint

Returns
false iff the transport is connected, otherwise true

Reimplemented from folly::AsyncSocket.

Definition at line 386 of file AsyncSSLSocket.cpp.

References folly::AsyncSocket::connecting(), folly::AsyncSocket::good(), server_, sslState_, STATE_CONNECTING, and STATE_UNINIT.

Referenced by newSocket().

void folly::AsyncSSLSocket::detachEventBase ( )
inlineoverridevirtual

Detach the transport from its EventBase.

This may only be called when the transport is idle and has no reads or writes pending. Once detached, the transport may not be used again until it is re-attached to a EventBase by calling attachEventBase().

This method must be called from the current EventBase's thread.

Reimplemented from folly::AsyncSocket.

Definition at line 575 of file AsyncSSLSocket.h.

References connectionTimeout_, folly::AsyncTimeout::detachEventBase(), folly::AsyncSocket::detachEventBase(), and handshakeTimeout_.

virtual void folly::AsyncSSLSocket::detachTimeoutManager ( )
inlinevirtual
void folly::AsyncSSLSocket::enableClientHelloParsing ( )

Definition at line 1796 of file AsyncSSLSocket.cpp.

References clientHelloInfo_, and parseClientHello_.

Referenced by getSecurityProtocol().

1796  {
1797  parseClientHello_ = true;
1798  clientHelloInfo_ = std::make_unique<ssl::ClientHelloInfo>();
1799 }
std::unique_ptr< ssl::ClientHelloInfo > clientHelloInfo_
int folly::AsyncSSLSocket::eorAwareSSLWrite ( const ssl::SSLUniquePtr ssl,
const void *  buf,
int  n,
bool  eor 
)
protected

A SSL_write wrapper that understand EOR

Parameters
sslSSL pointer
bufBuffer to be written
nNumber of bytes to be written
eorDoes the last byte (buf[n-1]) have the app-last-byte?
Returns
: The number of app bytes successfully written to the socket

Definition at line 1651 of file AsyncSSLSocket.cpp.

References folly::AsyncSocket::appBytesWritten_, appEorByteNo_, getRawBytesWritten(), folly::AsyncSocket::isEorTrackingEnabled(), minEorRawByteNo_, and sslWriteImpl().

Referenced by performWrite(), and sslWriteImpl().

1655  {
1656  if (eor && isEorTrackingEnabled()) {
1657  if (appEorByteNo_) {
1658  // cannot track for more than one app byte EOR
1659  CHECK(appEorByteNo_ == appBytesWritten_ + n);
1660  } else {
1662  }
1663 
1664  // 1. It is fine to keep updating minEorRawByteNo_.
1665  // 2. It is _min_ in the sense that SSL record will add some overhead.
1667  }
1668 
1669  n = sslWriteImpl(ssl.get(), buf, n);
1670  if (n > 0) {
1671  appBytesWritten_ += n;
1672  if (appEorByteNo_) {
1674  minEorRawByteNo_ = 0;
1675  }
1677  appEorByteNo_ = 0;
1678  } else {
1680  }
1681  }
1682  }
1683  return n;
1684 }
size_t getRawBytesWritten() const override
bool isEorTrackingEnabled() const override
Definition: AsyncSocket.h:559
size_t appBytesWritten_
Num of bytes written to socket.
Definition: AsyncSocket.h:1254
virtual int sslWriteImpl(SSL *ssl, const void *buf, int n)
void folly::AsyncSSLSocket::forceCacheAddrOnFailure ( bool  force)
inline

Force AsyncSSLSocket object to cache local and peer socket addresses. If called with "true" before connect() this function forces full local and remote socket addresses to be cached in the socket object and available through getLocalAddress()/getPeerAddress() methods even after the socket is closed.

Definition at line 765 of file AsyncSSLSocket.h.

References cacheAddrOnFailure_.

765  {
766  cacheAddrOnFailure_ = force;
767  }
std::string folly::AsyncSSLSocket::getApplicationProtocol ( ) const
overridevirtualnoexcept

Return the application protocol being used by the underlying transport protocol. This is useful for transports which are used to tunnel other protocols.

Reimplemented from folly::AsyncTransport.

Definition at line 394 of file AsyncSSLSocket.cpp.

References getSelectedNextProtocolNoThrow(), and string.

Referenced by newSocket().

394  {
395  const unsigned char* protoName = nullptr;
396  unsigned protoLength;
397  if (getSelectedNextProtocolNoThrow(&protoName, &protoLength)) {
398  return std::string(reinterpret_cast<const char*>(protoName), protoLength);
399  }
400  return "";
401 }
virtual bool getSelectedNextProtocolNoThrow(const unsigned char **protoName, unsigned *protoLen) const
const char * string
Definition: Conv.cpp:212
bool folly::AsyncSSLSocket::getCertCacheHit ( ) const
inline

Definition at line 781 of file AsyncSSLSocket.h.

References certCacheHit_.

781  {
782  return certCacheHit_;
783  }
ssl::ClientHelloInfo* folly::AsyncSSLSocket::getClientHelloInfo ( ) const
inline

Definition at line 716 of file AsyncSSLSocket.h.

References clientHelloInfo_.

Referenced by wangle::SSLContextManager::addSSLContextConfig().

716  {
717  return clientHelloInfo_.get();
718  }
std::unique_ptr< ssl::ClientHelloInfo > clientHelloInfo_
AsyncSSLSocket * folly::AsyncSSLSocket::getFromSSL ( const SSL *  ssl)
static

Definition at line 645 of file AsyncSSLSocket.cpp.

References getSSLExDataIndex().

Referenced by wangle::SSLContextManager::addSSLContextConfig(), wangle::SSLSessionCacheManager::getSession(), folly::TestSSLAsyncCacheServer::getSessionCallback(), wangle::SSLSessionCallbacks::getSessionKeyFromSSL(), getSSLContext(), folly::SNIServer::serverNameCallback(), sslInfoCallback(), and sslVerifyCallback().

645  {
646  return static_cast<AsyncSSLSocket*>(
647  SSL_get_ex_data(ssl, getSSLExDataIndex()));
648 }
AsyncSSLSocket(const std::shared_ptr< folly::SSLContext > &ctx, EventBase *evb, bool deferSecurityNegotiation=false)
static int getSSLExDataIndex()
virtual std::chrono::nanoseconds folly::AsyncSSLSocket::getHandshakeTime ( ) const
inlinevirtual

Returns the time taken to complete a handshake.

Definition at line 723 of file AsyncSSLSocket.h.

References handshakeEndTime_, and handshakeStartTime_.

723  {
725  }
std::chrono::steady_clock::time_point handshakeEndTime_
std::chrono::steady_clock::time_point handshakeStartTime_
size_t folly::AsyncSSLSocket::getMinWriteSize ( ) const
inline

Definition at line 731 of file AsyncSSLSocket.h.

References getPeerCertificate(), getSelfCertificate(), minWriteSize_, setBufferMovableEnabled(), and setReadCB().

731  {
732  return minWriteSize_;
733  }
const char * folly::AsyncSSLSocket::getNegotiatedCipherName ( ) const
virtual

Get the negociated cipher name for this SSL connection. Returns the cipher used or the constant value "NONE" when no SSL session has been established.

Definition at line 882 of file AsyncSSLSocket.cpp.

References ssl_.

Referenced by proxygen::HTTPConnector::connectSuccess(), wangle::SSLAcceptorHandshakeHelper::fillSSLTransportInfoFields(), and setSessionIDResumed().

882  {
883  return (ssl_ != nullptr) ? SSL_get_cipher_name(ssl_.get()) : nullptr;
884 }
ssl::SSLUniquePtr ssl_
ssl::X509UniquePtr folly::AsyncSSLSocket::getPeerCert ( ) const
inlineoverridevirtual

Returns the peer certificate, or nullptr if no peer certificate received.

Reimplemented from folly::AsyncTransport.

Definition at line 750 of file AsyncSSLSocket.h.

References getPeerCertificate().

750  {
751  auto peerCert = getPeerCertificate();
752  if (!peerCert) {
753  return nullptr;
754  }
755  return peerCert->getX509();
756  }
const AsyncTransportCertificate * getPeerCertificate() const override
const AsyncTransportCertificate * folly::AsyncSSLSocket::getPeerCertificate ( ) const
overridevirtual

Get the peer certificate information if any

Reimplemented from folly::AsyncSocket.

Definition at line 935 of file AsyncSSLSocket.cpp.

References folly::gen::move, folly::AsyncSocket::peerCertData_, and ssl_.

Referenced by getMinWriteSize(), and getPeerCert().

935  {
936  if (peerCertData_) {
937  return peerCertData_.get();
938  }
939  if (ssl_ != nullptr) {
940  auto peerX509 = SSL_get_peer_certificate(ssl_.get());
941  if (peerX509) {
942  // already up ref'd
943  folly::ssl::X509UniquePtr peer(peerX509);
944  peerCertData_ = std::make_unique<AsyncSSLCertificate>(std::move(peer));
945  }
946  }
947  return peerCertData_.get();
948 }
std::unique_ptr< X509, X509Deleter > X509UniquePtr
std::unique_ptr< const AsyncTransportCertificate > peerCertData_
Definition: AsyncSocket.h:1282
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
ssl::SSLUniquePtr ssl_
size_t folly::AsyncSSLSocket::getRawBytesReceived ( ) const
overridevirtual

Reimplemented from folly::AsyncSocket.

Definition at line 429 of file AsyncSSLSocket.cpp.

References b, and ssl_.

Referenced by wangle::SSLAcceptorHandshakeHelper::fillSSLTransportInfoFields(), and getSecurityProtocol().

429  {
430  BIO* b;
431  if (!ssl_ || !(b = SSL_get_rbio(ssl_.get()))) {
432  return 0;
433  }
434 
435  return BIO_number_read(b);
436 }
char b
ssl::SSLUniquePtr ssl_
size_t folly::AsyncSSLSocket::getRawBytesWritten ( ) const
overridevirtual

Reimplemented from folly::AsyncSocket.

Definition at line 411 of file AsyncSSLSocket.cpp.

References b, cpp.ast::next(), and ssl_.

Referenced by eorAwareSSLWrite(), wangle::SSLAcceptorHandshakeHelper::fillSSLTransportInfoFields(), and getSecurityProtocol().

411  {
412  // The bio(s) in the write path are in a chain
413  // each bio flushes to the next and finally written into the socket
414  // to get the rawBytesWritten on the socket,
415  // get the write bytes of the last bio
416  BIO* b;
417  if (!ssl_ || !(b = SSL_get_wbio(ssl_.get()))) {
418  return 0;
419  }
420  BIO* next = BIO_next(b);
421  while (next != nullptr) {
422  b = next;
423  next = BIO_next(b);
424  }
425 
426  return BIO_number_written(b);
427 }
char b
ssl::SSLUniquePtr ssl_
def next(obj)
Definition: ast.py:58
void folly::AsyncSSLSocket::getSelectedNextProtocol ( const unsigned char **  protoName,
unsigned *  protoLen 
) const
virtual

Get the name of the protocol selected by the client during Application Layer Protocol Negotiation (ALPN)

Throw an exception if openssl does not support NPN

Parameters
protoNameName of the protocol (not guaranteed to be null terminated); will be set to nullptr if the client did not negotiate a protocol. Note: the AsyncSSLSocket retains ownership of this string.
protoNameLenLength of the name.
protoTypeWhether this was an NPN or ALPN negotiation

Definition at line 853 of file AsyncSSLSocket.cpp.

References getSelectedNextProtocolNoThrow(), and folly::AsyncSocketException::NOT_SUPPORTED.

Referenced by folly::test::MockAsyncSSLSocket::connect(), getSSLState(), and CurlService::CurlClient::sslHandshakeFollowup().

855  {
856  if (!getSelectedNextProtocolNoThrow(protoName, protoLen)) {
857  throw AsyncSocketException(
858  AsyncSocketException::NOT_SUPPORTED, "ALPN not supported");
859  }
860 }
virtual bool getSelectedNextProtocolNoThrow(const unsigned char **protoName, unsigned *protoLen) const
bool folly::AsyncSSLSocket::getSelectedNextProtocolNoThrow ( const unsigned char **  protoName,
unsigned *  protoLen 
) const
virtual

Get the name of the protocol selected by the client during Next Protocol Negotiation (NPN) or Application Layer Protocol Negotiation (ALPN)

Parameters
protoNameName of the protocol (not guaranteed to be null terminated); will be set to nullptr if the client did not negotiate a protocol. Note: the AsyncSSLSocket retains ownership of this string.
protoNameLenLength of the name.
protoTypeWhether this was an NPN or ALPN negotiation
Returns
false if openssl does not support NPN

Definition at line 862 of file AsyncSSLSocket.cpp.

References ssl_.

Referenced by folly::test::MockAsyncSSLSocket::connect(), getApplicationProtocol(), getSelectedNextProtocol(), and getSSLState().

864  {
865  *protoName = nullptr;
866  *protoLen = 0;
867 #if FOLLY_OPENSSL_HAS_ALPN
868  SSL_get0_alpn_selected(ssl_.get(), protoName, protoLen);
869  return true;
870 #else
871  return false;
872 #endif
873 }
ssl::SSLUniquePtr ssl_
const X509 * folly::AsyncSSLSocket::getSelfCert ( ) const
overridevirtual

Get the certificate used for this SSL connection. May be null

Reimplemented from folly::AsyncTransport.

Definition at line 967 of file AsyncSSLSocket.cpp.

References ssl_.

Referenced by setSessionIDResumed().

967  {
968  return (ssl_ != nullptr) ? SSL_get_certificate(ssl_.get()) : nullptr;
969 }
ssl::SSLUniquePtr ssl_
const AsyncTransportCertificate * folly::AsyncSSLSocket::getSelfCertificate ( ) const
overridevirtual

Get the certificate information of this transport, if any

Reimplemented from folly::AsyncSocket.

Definition at line 950 of file AsyncSSLSocket.cpp.

References folly::gen::move, folly::AsyncSocket::selfCertData_, and ssl_.

Referenced by getMinWriteSize().

950  {
951  if (selfCertData_) {
952  return selfCertData_.get();
953  }
954  if (ssl_ != nullptr) {
955  auto selfX509 = SSL_get_certificate(ssl_.get());
956  if (selfX509) {
957  // need to upref
958  X509_up_ref(selfX509);
959  folly::ssl::X509UniquePtr peer(selfX509);
960  selfCertData_ = std::make_unique<AsyncSSLCertificate>(std::move(peer));
961  }
962  }
963  return selfCertData_.get();
964 }
std::unique_ptr< X509, X509Deleter > X509UniquePtr
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
ssl::SSLUniquePtr ssl_
std::unique_ptr< const AsyncTransportCertificate > selfCertData_
Definition: AsyncSocket.h:1284
const std::string& folly::AsyncSSLSocket::getSessionKey ( ) const
inline

Definition at line 769 of file AsyncSSLSocket.h.

References sessionKey_.

769  {
770  return sessionKey_;
771  }
const SSL * folly::AsyncSSLSocket::getSSL ( ) const

Get a handle to the SSL struct.

Definition at line 837 of file AsyncSSLSocket.cpp.

References ssl_.

Referenced by getSSLState().

837  {
838  return ssl_.get();
839 }
ssl::SSLUniquePtr ssl_
std::string folly::AsyncSSLSocket::getSSLAlertsReceived ( ) const

Definition at line 2004 of file AsyncSSLSocket.cpp.

References alertsReceived_, and string.

Referenced by getSSLContext().

2004  {
2005  std::string ret;
2006 
2007  for (const auto& alert : alertsReceived_) {
2008  if (!ret.empty()) {
2009  ret.append(",");
2010  }
2011  ret.append(folly::to<std::string>(alert.first, ": ", alert.second));
2012  }
2013 
2014  return ret;
2015 }
std::vector< std::pair< char, StringPiece > > alertsReceived_
const char * string
Definition: Conv.cpp:212
const char * folly::AsyncSSLSocket::getSSLCertSigAlgName ( ) const

Get the signature algorithm used in the cert that is used for this connection.

Definition at line 915 of file AsyncSSLSocket.cpp.

References ssl_.

Referenced by wangle::SSLAcceptorHandshakeHelper::fillSSLTransportInfoFields(), and setSessionIDResumed().

915  {
916  X509* cert = (ssl_ != nullptr) ? SSL_get_certificate(ssl_.get()) : nullptr;
917  if (cert) {
918  int nid = X509_get_signature_nid(cert);
919  return OBJ_nid2ln(nid);
920  }
921  return nullptr;
922 }
ssl::SSLUniquePtr ssl_
int folly::AsyncSSLSocket::getSSLCertSize ( ) const

Get the certificate size used for this SSL connection.

Definition at line 924 of file AsyncSSLSocket.cpp.

References ssl_.

Referenced by wangle::SSLAcceptorHandshakeHelper::fillSSLTransportInfoFields(), and setSessionIDResumed().

924  {
925  int certSize = 0;
926  X509* cert = (ssl_ != nullptr) ? SSL_get_certificate(ssl_.get()) : nullptr;
927  if (cert) {
928  EVP_PKEY* key = X509_get_pubkey(cert);
929  certSize = EVP_PKEY_bits(key);
930  EVP_PKEY_free(key);
931  }
932  return certSize;
933 }
ssl::SSLUniquePtr ssl_
std::string folly::AsyncSSLSocket::getSSLCertVerificationAlert ( ) const

Definition at line 2021 of file AsyncSSLSocket.cpp.

References sslVerificationAlert_.

Referenced by getSSLContext().

2021  {
2022  return sslVerificationAlert_;
2023 }
std::string sslVerificationAlert_
void folly::AsyncSSLSocket::getSSLClientCiphers ( std::string clientCiphers,
bool  convertToString = true 
) const

Get the list of supported ciphers sent by the client in the client's preference order.

Definition at line 1919 of file AsyncSSLSocket.cpp.

References clientHelloInfo_, folly::gen::first, folly::ssl::OpenSSLUtils::getCipherName(), folly::hexlify(), folly::gen::move, name, parseClientHello_, string, and uint8_t.

Referenced by wangle::SSLAcceptorHandshakeHelper::fillSSLTransportInfoFields(), and getSSLContext().

1921  {
1922  std::string ciphers;
1923 
1924  if (parseClientHello_ == false ||
1925  clientHelloInfo_->clientHelloCipherSuites_.empty()) {
1926  clientCiphers = "";
1927  return;
1928  }
1929 
1930  bool first = true;
1931  for (auto originalCipherCode : clientHelloInfo_->clientHelloCipherSuites_) {
1932  if (first) {
1933  first = false;
1934  } else {
1935  ciphers += ":";
1936  }
1937 
1938  bool nameFound = convertToString;
1939 
1940  if (convertToString) {
1941  const auto& name = OpenSSLUtils::getCipherName(originalCipherCode);
1942  if (name.empty()) {
1943  nameFound = false;
1944  } else {
1945  ciphers += name;
1946  }
1947  }
1948 
1949  if (!nameFound) {
1951  std::array<uint8_t, 2>{
1952  {static_cast<uint8_t>((originalCipherCode >> 8) & 0xffL),
1953  static_cast<uint8_t>(originalCipherCode & 0x00ffL)}},
1954  ciphers,
1955  /* append to ciphers = */ true);
1956  }
1957  }
1958 
1959  clientCiphers = std::move(ciphers);
1960 }
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
const char * name
Definition: http_parser.c:437
std::unique_ptr< ssl::ClientHelloInfo > clientHelloInfo_
const char * string
Definition: Conv.cpp:212
bool hexlify(const InputString &input, OutputString &output, bool append_output)
Definition: String-inl.h:596
static const std::string & getCipherName(uint16_t cipherCode)
constexpr detail::First first
Definition: Base-inl.h:2553
std::string folly::AsyncSSLSocket::getSSLClientComprMethods ( ) const

Get the list of compression methods sent by the client in TLS Hello.

Definition at line 1962 of file AsyncSSLSocket.cpp.

References clientHelloInfo_, folly::join(), and parseClientHello_.

Referenced by wangle::SSLAcceptorHandshakeHelper::fillSSLTransportInfoFields(), and getSSLContext().

1962  {
1963  if (!parseClientHello_) {
1964  return "";
1965  }
1966  return folly::join(":", clientHelloInfo_->clientHelloCompressionMethods_);
1967 }
std::unique_ptr< ssl::ClientHelloInfo > clientHelloInfo_
void join(const Delim &delimiter, Iterator begin, Iterator end, String &output)
Definition: String-inl.h:498
std::string folly::AsyncSSLSocket::getSSLClientExts ( ) const

Get the list of TLS extensions sent by the client in the TLS Hello.

Definition at line 1969 of file AsyncSSLSocket.cpp.

References clientHelloInfo_, folly::join(), and parseClientHello_.

Referenced by wangle::SSLAcceptorHandshakeHelper::fillSSLTransportInfoFields(), and getSSLContext().

1969  {
1970  if (!parseClientHello_) {
1971  return "";
1972  }
1973  return folly::join(":", clientHelloInfo_->clientHelloExtensions_);
1974 }
std::unique_ptr< ssl::ClientHelloInfo > clientHelloInfo_
void join(const Delim &delimiter, Iterator begin, Iterator end, String &output)
Definition: String-inl.h:498
std::string folly::AsyncSSLSocket::getSSLClientSigAlgs ( ) const

Definition at line 1976 of file AsyncSSLSocket.cpp.

References clientHelloInfo_, i, parseClientHello_, and string.

Referenced by wangle::SSLAcceptorHandshakeHelper::fillSSLTransportInfoFields(), and getSSLContext().

1976  {
1977  if (!parseClientHello_) {
1978  return "";
1979  }
1980 
1981  std::string sigAlgs;
1982  sigAlgs.reserve(clientHelloInfo_->clientHelloSigAlgs_.size() * 4);
1983  for (size_t i = 0; i < clientHelloInfo_->clientHelloSigAlgs_.size(); i++) {
1984  if (i) {
1985  sigAlgs.push_back(':');
1986  }
1987  sigAlgs.append(
1988  folly::to<std::string>(clientHelloInfo_->clientHelloSigAlgs_[i].first));
1989  sigAlgs.push_back(',');
1990  sigAlgs.append(folly::to<std::string>(
1991  clientHelloInfo_->clientHelloSigAlgs_[i].second));
1992  }
1993 
1994  return sigAlgs;
1995 }
std::unique_ptr< ssl::ClientHelloInfo > clientHelloInfo_
const char * string
Definition: Conv.cpp:212
std::string folly::AsyncSSLSocket::getSSLClientSupportedVersions ( ) const

Get the list of versions in the supported versions extension (used to negotiate TLS 1.3).

Definition at line 1997 of file AsyncSSLSocket.cpp.

References clientHelloInfo_, folly::join(), and parseClientHello_.

Referenced by wangle::SSLAcceptorHandshakeHelper::fillSSLTransportInfoFields(), and getSSLContext().

1997  {
1998  if (!parseClientHello_) {
1999  return "";
2000  }
2001  return folly::join(":", clientHelloInfo_->clientHelloSupportedVersions_);
2002 }
std::unique_ptr< ssl::ClientHelloInfo > clientHelloInfo_
void join(const Delim &delimiter, Iterator begin, Iterator end, String &output)
Definition: String-inl.h:498
const std::shared_ptr<folly::SSLContext>& folly::AsyncSSLSocket::getSSLContext ( ) const
inline
int folly::AsyncSSLSocket::getSSLExDataIndex ( )
static

Definition at line 639 of file AsyncSSLSocket.cpp.

Referenced by getFromSSL(), getSSLContext(), handleAccept(), and sslConn().

639  {
640  static auto index = SSL_get_ex_new_index(
641  0, (void*)"AsyncSSLSocket data index", nullptr, nullptr, nullptr);
642  return index;
643 }
void folly::AsyncSSLSocket::getSSLServerCiphers ( std::string serverCiphers) const

Get the list of ciphers supported by the server in the server's preference order.

Definition at line 2032 of file AsyncSSLSocket.cpp.

References cipher, i, and ssl_.

Referenced by wangle::SSLAcceptorHandshakeHelper::fillSSLTransportInfoFields(), and getSSLContext().

2032  {
2033  serverCiphers = SSL_get_cipher_list(ssl_.get(), 0);
2034  int i = 1;
2035  const char* cipher;
2036  while ((cipher = SSL_get_cipher_list(ssl_.get(), i)) != nullptr) {
2037  serverCiphers.append(":");
2038  serverCiphers.append(cipher);
2039  i++;
2040  }
2041 }
ssl::SSLUniquePtr ssl_
CipherSuite cipher
const char * folly::AsyncSSLSocket::getSSLServerName ( ) const

Get the server name for this SSL connection. Returns the server name used or the constant value "NONE" when no SSL session has been established. If openssl has no SNI support, throw TTransportException.

Definition at line 898 of file AsyncSSLSocket.cpp.

References getSSLServerNameFromSSL(), folly::AsyncSocketException::NOT_SUPPORTED, and ssl_.

Referenced by wangle::SSLAcceptorHandshakeHelper::fillSSLTransportInfoFields(), and setSessionIDResumed().

898  {
899 #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
900  return getSSLServerNameFromSSL(ssl_.get());
901 #else
902  throw AsyncSocketException(
903  AsyncSocketException::NOT_SUPPORTED, "SNI not supported");
904 #endif
905 }
static const char * getSSLServerNameFromSSL(SSL *ssl)
ssl::SSLUniquePtr ssl_
const char * folly::AsyncSSLSocket::getSSLServerNameFromSSL ( SSL *  ssl)
static

Definition at line 887 of file AsyncSSLSocket.cpp.

Referenced by getSSLContext(), getSSLServerName(), getSSLServerNameNoThrow(), and wangle::SSLSessionCallbacks::newSessionCallback().

887  {
888  if (ssl == nullptr) {
889  return nullptr;
890  }
891 #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
892  return SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
893 #else
894  return nullptr;
895 #endif
896 }
const char * folly::AsyncSSLSocket::getSSLServerNameNoThrow ( ) const

Get the server name for this SSL connection. Returns the server name used or the constant value "NONE" when no SSL session has been established. If openssl has no SNI support, return "NONE"

Definition at line 907 of file AsyncSSLSocket.cpp.

References getSSLServerNameFromSSL(), and ssl_.

Referenced by setSessionIDResumed().

907  {
908  return getSSLServerNameFromSSL(ssl_.get());
909 }
static const char * getSSLServerNameFromSSL(SSL *ssl)
ssl::SSLUniquePtr ssl_
SSL_SESSION * folly::AsyncSSLSocket::getSSLSession ( )

Get a handle to the negotiated SSL session. This increments the session refcount and must be deallocated by the caller.

Definition at line 829 of file AsyncSSLSocket.cpp.

References ssl_, sslSession_, sslState_, and STATE_ESTABLISHED.

Referenced by wangle::ClientBootstrap< Pipeline >::ConnectCallback::connectSuccess(), getSSLState(), and SSLCacheClient::handshakeSuc().

829  {
830  if (ssl_ != nullptr && sslState_ == STATE_ESTABLISHED) {
831  return SSL_get1_session(ssl_.get());
832  }
833 
834  return sslSession_;
835 }
ssl::SSLUniquePtr ssl_
SSL_SESSION * sslSession_
bool folly::AsyncSSLSocket::getSSLSessionReused ( ) const
virtual

Determine if the session specified during setSSLSession was reused or if the server rejected it and issued a new session.

Definition at line 875 of file AsyncSSLSocket.cpp.

References ssl_, sslState_, and STATE_ESTABLISHED.

Referenced by wangle::ClientBootstrap< Pipeline >::ConnectCallback::connectSuccess(), wangle::SSLUtil::getResumeState(), getSSLState(), and SSLCacheClient::handshakeSuc().

875  {
876  if (ssl_ != nullptr && sslState_ == STATE_ESTABLISHED) {
877  return SSL_session_reused(ssl_.get());
878  }
879  return false;
880 }
ssl::SSLUniquePtr ssl_
void folly::AsyncSSLSocket::getSSLSharedCiphers ( std::string sharedCiphers) const

Get the list of shared ciphers between the server and the client. Works well for only SSLv2, not so good for SSLv3 or TLSv1.

Definition at line 2025 of file AsyncSSLSocket.cpp.

References ssl_.

Referenced by getSSLContext().

2025  {
2026  char ciphersBuffer[1024];
2027  ciphersBuffer[0] = '\0';
2028  SSL_get_shared_ciphers(ssl_.get(), ciphersBuffer, sizeof(ciphersBuffer) - 1);
2029  sharedCiphers = ciphersBuffer;
2030 }
ssl::SSLUniquePtr ssl_
SSLStateEnum folly::AsyncSSLSocket::getSSLState ( ) const
inline
int folly::AsyncSSLSocket::getSSLVersion ( ) const

Get the SSL version for this connection. Possible return values are SSL2_VERSION, SSL3_VERSION, TLS1_VERSION, with hexa representations 0x200, 0x300, 0x301, or 0 if no SSL session has been established.

Definition at line 911 of file AsyncSSLSocket.cpp.

References ssl_.

Referenced by proxygen::HTTPConnector::connectSuccess(), wangle::SSLAcceptorHandshakeHelper::fillSSLTransportInfoFields(), and setSessionIDResumed().

911  {
912  return (ssl_ != nullptr) ? SSL_version(ssl_.get()) : 0;
913 }
ssl::SSLUniquePtr ssl_
std::chrono::milliseconds folly::AsyncSSLSocket::getTotalConnectTimeout ( ) const
inline

If the SSL socket was used to connect as well as establish an SSL connection, this gives the total timeout for the connect + SSL connection that was set.

Definition at line 795 of file AsyncSSLSocket.h.

References totalConnectTimeout_.

795  {
796  return totalConnectTimeout_;
797  }
std::chrono::milliseconds totalConnectTimeout_
bool folly::AsyncSSLSocket::good ( ) const
overridevirtual

Determine if transport is open and ready to read or write.

Note that this function returns false on EOF; you must also call error() to distinguish between an EOF and an error.

Returns
true iff the transport is open and ready, false otherwise.

Reimplemented from folly::AsyncSocket.

Definition at line 374 of file AsyncSSLSocket.cpp.

References folly::AsyncSocket::good(), sslState_, STATE_ACCEPTING, STATE_CONNECTING, STATE_ESTABLISHED, STATE_UNENCRYPTED, and STATE_UNINIT.

Referenced by folly::test::MockAsyncSSLSocket::connect(), and newSocket().

void folly::AsyncSSLSocket::handleAccept ( )
protectednoexcept

Definition at line 1108 of file AsyncSSLSocket.cpp.

References applyVerificationOptions(), clientHelloParsingCallback(), ctx_, folly::AsyncSocket::ESTABLISHED, folly::AsyncSocket::eventFlags_, failHandshake(), folly::AsyncSocket::fd_, getSSLExDataIndex(), handleReturnFromSSLAccept(), folly::AsyncSocketException::INTERNAL_ERROR, folly::EventHandler::NONE, parseClientHello_, folly::EventHandler::READ, server_, setupSSLBio(), ssl_, sslState_, folly::AsyncSocket::state_, STATE_ACCEPTING, STATE_ERROR, folly::AsyncSocket::updateEventRegistration(), and folly::EventHandler::WRITE.

Referenced by handleRead(), handleWrite(), restartSSLAccept(), and setAsyncOperationFinishCallback().

1108  {
1109  VLOG(3) << "AsyncSSLSocket::handleAccept() this=" << this << ", fd=" << fd_
1110  << ", state=" << int(state_) << ", "
1111  << "sslState=" << sslState_ << ", events=" << eventFlags_;
1112  assert(server_);
1114  if (!ssl_) {
1115  /* lazily create the SSL structure */
1116  try {
1117  ssl_.reset(ctx_->createSSL());
1118  } catch (std::exception& e) {
1120  AsyncSocketException ex(
1122  "error calling SSLContext::createSSL()");
1123  LOG(ERROR) << "AsyncSSLSocket::handleAccept(this=" << this
1124  << ", fd=" << fd_ << "): " << e.what();
1125  return failHandshake(__func__, ex);
1126  }
1127 
1128  if (!setupSSLBio()) {
1130  AsyncSocketException ex(
1131  AsyncSocketException::INTERNAL_ERROR, "error creating write bio");
1132  return failHandshake(__func__, ex);
1133  }
1134 
1135  SSL_set_ex_data(ssl_.get(), getSSLExDataIndex(), this);
1136 
1138  }
1139 
1140  if (server_ && parseClientHello_) {
1141  SSL_set_msg_callback(
1143  SSL_set_msg_callback_arg(ssl_.get(), this);
1144  }
1145 
1146  DCHECK(ctx_->sslAcceptRunner());
1149  DelayedDestruction::DestructorGuard dg(this);
1150  ctx_->sslAcceptRunner()->run(
1151  [this, dg]() { return SSL_accept(ssl_.get()); },
1152  [this, dg](int ret) { handleReturnFromSSLAccept(ret); });
1153 }
void applyVerificationOptions(const ssl::SSLUniquePtr &ssl)
ssl::SSLUniquePtr ssl_
bool updateEventRegistration()
std::shared_ptr< folly::SSLContext > ctx_
uint16_t eventFlags_
EventBase::HandlerFlags settings.
Definition: AsyncSocket.h:1228
void handleReturnFromSSLAccept(int ret)
static void clientHelloParsingCallback(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg)
StateEnum state_
StateEnum describing current state.
Definition: AsyncSocket.h:1226
int fd_
The socket file descriptor.
Definition: AsyncSocket.h:1229
void failHandshake(const char *fn, const AsyncSocketException &ex)
static int getSSLExDataIndex()
void folly::AsyncSSLSocket::handleConnect ( )
overrideprotectedvirtualnoexcept

Reimplemented from folly::AsyncSocket.

Definition at line 1209 of file AsyncSSLSocket.cpp.

References folly::AsyncTimeout::cancelTimeout(), folly::AsyncSocket::CONNECTING, folly::AsyncSocket::ESTABLISHED, folly::AsyncSocket::eventBase_, folly::AsyncSocket::eventFlags_, failHandshake(), folly::AsyncSocket::FAST_OPEN, folly::AsyncSocket::fd_, folly::AsyncSocket::handleConnect(), folly::AsyncSocket::handleInitialReadWrite(), handshakeComplete_, handshakeTimeout_, invokeHandshakeCB(), folly::AsyncTimeout::isScheduled(), folly::EventHandler::READ, server_, ssl_, sslState_, folly::AsyncSocket::state_, STATE_CONNECTING, STATE_ERROR, STATE_ESTABLISHED, folly::AsyncSocket::updateEventRegistration(), willBlock(), and folly::EventHandler::WRITE.

Referenced by handleRead(), handleWrite(), setAsyncOperationFinishCallback(), and startSSLConnect().

1209  {
1210  VLOG(3) << "AsyncSSLSocket::handleConnect() this=" << this << ", fd=" << fd_
1211  << ", state=" << int(state_) << ", "
1212  << "sslState=" << sslState_ << ", events=" << eventFlags_;
1213  assert(!server_);
1215  return AsyncSocket::handleConnect();
1216  }
1217 
1218  assert(
1221  assert(ssl_);
1222 
1223  auto originalState = state_;
1224  int ret = SSL_connect(ssl_.get());
1225  if (ret <= 0) {
1226  int sslError;
1227  unsigned long errError;
1228  int errnoCopy = errno;
1229  if (willBlock(ret, &sslError, &errError)) {
1230  // We fell back to connecting state due to TFO
1231  if (state_ == StateEnum::CONNECTING) {
1232  DCHECK_EQ(StateEnum::FAST_OPEN, originalState);
1235  }
1236  }
1237  return;
1238  } else {
1240  SSLException ex(sslError, errError, ret, errnoCopy);
1241  return failHandshake(__func__, ex);
1242  }
1243  }
1244 
1245  handshakeComplete_ = true;
1247 
1248  // Move into STATE_ESTABLISHED in the normal case that we are in
1249  // STATE_CONNECTING.
1251 
1252  VLOG(3) << "AsyncSSLSocket " << this << ": "
1253  << "fd " << fd_ << " successfully connected; "
1254  << "state=" << int(state_) << ", sslState=" << sslState_
1255  << ", events=" << eventFlags_;
1256 
1257  // Remember the EventBase we are attached to, before we start invoking any
1258  // callbacks (since the callbacks may call detachEventBase()).
1259  EventBase* originalEventBase = eventBase_;
1260 
1261  // Call the handshake callback.
1263 
1264  // Note that the connect callback may have changed our state.
1265  // (set or unset the read callback, called write(), closed the socket, etc.)
1266  // The following code needs to handle these situations correctly.
1267  //
1268  // If the socket has been closed, readCallback_ and writeReqHead_ will
1269  // always be nullptr, so that will prevent us from trying to read or write.
1270  //
1271  // The main thing to check for is if eventBase_ is still originalEventBase.
1272  // If not, we have been detached from this event base, so we shouldn't
1273  // perform any more operations.
1274  if (eventBase_ != originalEventBase) {
1275  return;
1276  }
1277 
1279 }
bool willBlock(int ret, int *sslErrorOut, unsigned long *errErrorOut) noexcept
ssl::SSLUniquePtr ssl_
virtual void handleConnect() noexcept
EventBase * eventBase_
The EventBase.
Definition: AsyncSocket.h:1240
bool updateEventRegistration()
uint16_t eventFlags_
EventBase::HandlerFlags settings.
Definition: AsyncSocket.h:1228
StateEnum state_
StateEnum describing current state.
Definition: AsyncSocket.h:1226
int fd_
The socket file descriptor.
Definition: AsyncSocket.h:1229
bool isScheduled() const
void failHandshake(const char *fn, const AsyncSocketException &ex)
virtual void handleInitialReadWrite() noexcept
void folly::AsyncSSLSocket::handleInitialReadWrite ( )
inlineoverrideprotectedvirtualnoexcept
void folly::AsyncSSLSocket::handleRead ( )
overrideprotectedvirtualnoexcept

Reimplemented from folly::AsyncSocket.

Definition at line 1357 of file AsyncSSLSocket.cpp.

References folly::AsyncSocket::ESTABLISHED, folly::AsyncSocket::eventFlags_, folly::AsyncSocket::fd_, handleAccept(), handleConnect(), folly::AsyncSocket::handleRead(), server_, sslState_, folly::AsyncSocket::state_, STATE_ACCEPTING, and STATE_CONNECTING.

Referenced by setAsyncOperationFinishCallback().

1357  {
1358  VLOG(5) << "AsyncSSLSocket::handleRead() this=" << this << ", fd=" << fd_
1359  << ", state=" << int(state_) << ", "
1360  << "sslState=" << sslState_ << ", events=" << eventFlags_;
1362  return AsyncSocket::handleRead();
1363  }
1364 
1365  if (sslState_ == STATE_ACCEPTING) {
1366  assert(server_);
1367  handleAccept();
1368  return;
1369  } else if (sslState_ == STATE_CONNECTING) {
1370  assert(!server_);
1371  handleConnect();
1372  return;
1373  }
1374 
1375  // Normal read
1377 }
virtual void handleRead() noexcept
uint16_t eventFlags_
EventBase::HandlerFlags settings.
Definition: AsyncSocket.h:1228
void handleConnect() noexceptoverride
StateEnum state_
StateEnum describing current state.
Definition: AsyncSocket.h:1226
int fd_
The socket file descriptor.
Definition: AsyncSocket.h:1229
void handleAccept() noexcept
void folly::AsyncSSLSocket::handleReturnFromSSLAccept ( int  ret)
private

Handle the return from invoking SSL_accept

Definition at line 1155 of file AsyncSSLSocket.cpp.

References folly::AsyncSocket::eventBase_, folly::AsyncSocket::eventFlags_, failHandshake(), folly::AsyncSocket::fd_, folly::AsyncSocket::handleInitialReadWrite(), handshakeComplete_, invokeHandshakeCB(), folly::EventHandler::READ, sslState_, folly::AsyncSocket::state_, STATE_ACCEPTING, STATE_ERROR, STATE_ESTABLISHED, folly::AsyncSocket::updateEventRegistration(), willBlock(), and folly::EventHandler::WRITE.

Referenced by handleAccept(), and setAsyncOperationFinishCallback().

1155  {
1156  if (sslState_ != STATE_ACCEPTING) {
1157  return;
1158  }
1159 
1160  if (ret <= 0) {
1161  VLOG(3) << "SSL_accept returned: " << ret;
1162  int sslError;
1163  unsigned long errError;
1164  int errnoCopy = errno;
1165  if (willBlock(ret, &sslError, &errError)) {
1166  return;
1167  } else {
1169  SSLException ex(sslError, errError, ret, errnoCopy);
1170  return failHandshake(__func__, ex);
1171  }
1172  }
1173 
1174  handshakeComplete_ = true;
1176 
1177  // Move into STATE_ESTABLISHED in the normal case that we are in
1178  // STATE_ACCEPTING.
1180 
1181  VLOG(3) << "AsyncSSLSocket " << this << ": fd " << fd_
1182  << " successfully accepted; state=" << int(state_)
1183  << ", sslState=" << sslState_ << ", events=" << eventFlags_;
1184 
1185  // Remember the EventBase we are attached to, before we start invoking any
1186  // callbacks (since the callbacks may call detachEventBase()).
1187  EventBase* originalEventBase = eventBase_;
1188 
1189  // Call the accept callback.
1191 
1192  // Note that the accept callback may have changed our state.
1193  // (set or unset the read callback, called write(), closed the socket, etc.)
1194  // The following code needs to handle these situations correctly.
1195  //
1196  // If the socket has been closed, readCallback_ and writeReqHead_ will
1197  // always be nullptr, so that will prevent us from trying to read or write.
1198  //
1199  // The main thing to check for is if eventBase_ is still originalEventBase.
1200  // If not, we have been detached from this event base, so we shouldn't
1201  // perform any more operations.
1202  if (eventBase_ != originalEventBase) {
1203  return;
1204  }
1205 
1207 }
bool willBlock(int ret, int *sslErrorOut, unsigned long *errErrorOut) noexcept
EventBase * eventBase_
The EventBase.
Definition: AsyncSocket.h:1240
bool updateEventRegistration()
uint16_t eventFlags_
EventBase::HandlerFlags settings.
Definition: AsyncSocket.h:1228
StateEnum state_
StateEnum describing current state.
Definition: AsyncSocket.h:1226
int fd_
The socket file descriptor.
Definition: AsyncSocket.h:1229
void failHandshake(const char *fn, const AsyncSocketException &ex)
virtual void handleInitialReadWrite() noexcept
void folly::AsyncSSLSocket::handleWrite ( )
overrideprotectedvirtualnoexcept

This function attempts to write as much data as possible, until no more data can be written.

  • If it sends all available data, it unregisters for write events, and stops the writeTimeout_.
  • If not all of the data can be sent immediately, it reschedules writeTimeout_ (if a non-zero timeout is set), and ensures the handler is registered for write events.

Reimplemented from folly::AsyncSocket.

Definition at line 1449 of file AsyncSSLSocket.cpp.

References folly::AsyncSocket::ESTABLISHED, folly::AsyncSocket::eventFlags_, folly::AsyncSocket::fd_, handleAccept(), handleConnect(), folly::AsyncSocket::handleWrite(), server_, sslState_, folly::AsyncSocket::state_, STATE_ACCEPTING, and STATE_CONNECTING.

Referenced by setAsyncOperationFinishCallback().

1449  {
1450  VLOG(5) << "AsyncSSLSocket::handleWrite() this=" << this << ", fd=" << fd_
1451  << ", state=" << int(state_) << ", "
1452  << "sslState=" << sslState_ << ", events=" << eventFlags_;
1454  return AsyncSocket::handleWrite();
1455  }
1456 
1457  if (sslState_ == STATE_ACCEPTING) {
1458  assert(server_);
1459  handleAccept();
1460  return;
1461  }
1462 
1463  if (sslState_ == STATE_CONNECTING) {
1464  assert(!server_);
1465  handleConnect();
1466  return;
1467  }
1468 
1469  // Normal write
1471 }
uint16_t eventFlags_
EventBase::HandlerFlags settings.
Definition: AsyncSocket.h:1228
virtual void handleWrite() noexcept
void handleConnect() noexceptoverride
StateEnum state_
StateEnum describing current state.
Definition: AsyncSocket.h:1226
int fd_
The socket file descriptor.
Definition: AsyncSocket.h:1229
void handleAccept() noexcept
void folly::AsyncSSLSocket::init ( )
private

Definition at line 318 of file AsyncSSLSocket.cpp.

References ctx_.

Referenced by AsyncSSLSocket(), and setAsyncOperationFinishCallback().

318  {
319  // Do this here to ensure we initialize this once before any use of
320  // AsyncSSLSocket instances and not as part of library load.
321  static const auto sslBioMethodInitializer = initsslBioMethod();
322  (void)sslBioMethodInitializer;
323 
324  setup_SSL_CTX(ctx_->getSSLCtx());
325 }
std::shared_ptr< folly::SSLContext > ctx_
AsyncSocket::WriteResult folly::AsyncSSLSocket::interpretSSLError ( int  rc,
int  error 
)
protected

Definition at line 1473 of file AsyncSSLSocket.cpp.

References folly::AsyncSocket::eventFlags_, folly::AsyncSocket::fd_, folly::INVALID_RENEGOTIATION, sslState_, folly::AsyncSocket::state_, and folly::AsyncSocket::WRITE_ERROR.

Referenced by handleInitialReadWrite(), and performWrite().

1473  {
1474  if (error == SSL_ERROR_WANT_READ) {
1475  // Even though we are attempting to write data, SSL_write() may
1476  // need to read data if renegotiation is being performed. We currently
1477  // don't support this and just fail the write.
1478  LOG(ERROR) << "AsyncSSLSocket(fd=" << fd_ << ", state=" << int(state_)
1479  << ", sslState=" << sslState_ << ", events=" << eventFlags_
1480  << "): "
1481  << "unsupported SSL renegotiation during write";
1482  return WriteResult(
1483  WRITE_ERROR,
1484  std::make_unique<SSLException>(SSLError::INVALID_RENEGOTIATION));
1485  } else {
1486  if (zero_return(error, rc)) {
1487  return WriteResult(0);
1488  }
1489  auto errError = ERR_get_error();
1490  VLOG(3) << "ERROR: AsyncSSLSocket(fd=" << fd_ << ", state=" << int(state_)
1491  << ", sslState=" << sslState_ << ", events=" << eventFlags_ << "): "
1492  << "SSL error: " << error << ", errno: " << errno
1493  << ", func: " << ERR_func_error_string(errError)
1494  << ", reason: " << ERR_reason_error_string(errError);
1495  return WriteResult(
1496  WRITE_ERROR,
1497  std::make_unique<SSLException>(error, errError, rc, errno));
1498  }
1499 }
bool error() const override
uint16_t eventFlags_
EventBase::HandlerFlags settings.
Definition: AsyncSocket.h:1228
StateEnum state_
StateEnum describing current state.
Definition: AsyncSocket.h:1226
int fd_
The socket file descriptor.
Definition: AsyncSocket.h:1229
void folly::AsyncSSLSocket::invalidState ( HandshakeCB callback)
protected

Definition at line 438 of file AsyncSSLSocket.cpp.

References folly::AsyncSocket::eventFlags_, failHandshake(), folly::AsyncSocket::fd_, handshakeCallback_, handshakeEndTime_, handshakeTimeout_, folly::AsyncSocketException::INVALID_STATE, folly::AsyncTimeout::isScheduled(), now(), server_, sslState_, folly::AsyncSocket::state_, and STATE_ERROR.

Referenced by setAsyncOperationFinishCallback(), sslAccept(), and sslConn().

438  {
439  LOG(ERROR) << "AsyncSSLSocket(this=" << this << ", fd=" << fd_
440  << ", state=" << int(state_) << ", sslState=" << sslState_ << ", "
441  << "events=" << eventFlags_ << ", server=" << short(server_)
442  << "): "
443  << "sslAccept/Connect() called in invalid "
444  << "state, handshake callback " << handshakeCallback_
445  << ", new callback " << callback;
446  assert(!handshakeTimeout_.isScheduled());
448 
449  AsyncSocketException ex(
451  "sslAccept() called with socket in invalid state");
452 
454  if (callback) {
455  callback->handshakeErr(this, ex);
456  }
457 
458  failHandshake(__func__, ex);
459 }
std::chrono::steady_clock::time_point now()
uint16_t eventFlags_
EventBase::HandlerFlags settings.
Definition: AsyncSocket.h:1228
std::chrono::steady_clock::time_point handshakeEndTime_
StateEnum state_
StateEnum describing current state.
Definition: AsyncSocket.h:1226
int fd_
The socket file descriptor.
Definition: AsyncSocket.h:1229
HandshakeCB * handshakeCallback_
bool isScheduled() const
void failHandshake(const char *fn, const AsyncSocketException &ex)
void folly::AsyncSSLSocket::invokeConnectErr ( const AsyncSocketException ex)
overrideprotectedvirtual

Reimplemented from folly::AsyncSocket.

Definition at line 1281 of file AsyncSSLSocket.cpp.

References folly::AsyncTimeout::cancelTimeout(), connectionTimeout_, handshakeTimeout_, folly::AsyncSocket::invokeConnectErr(), invokeHandshakeErr(), folly::AsyncTimeout::isScheduled(), and sslState_.

Referenced by sslWriteImpl().

1281  {
1284  if (sslState_ == SSLStateEnum::STATE_CONNECTING) {
1287  }
1288  // If we fell back to connecting state during TFO and the connection
1289  // failed, it would be an SSL failure as well.
1290  invokeHandshakeErr(ex);
1291  }
1292 }
void invokeHandshakeErr(const AsyncSocketException &ex)
bool isScheduled() const
virtual void invokeConnectErr(const AsyncSocketException &ex)
void folly::AsyncSSLSocket::invokeConnectSuccess ( )
overrideprotectedvirtual

Reimplemented from folly::AsyncSocket.

Definition at line 1294 of file AsyncSSLSocket.cpp.

References folly::AsyncTimeout::cancelTimeout(), connectionTimeout_, folly::AsyncSocket::invokeConnectSuccess(), sslState_, startSSLConnect(), and folly::AsyncSocket::tfoAttempted_.

Referenced by sslWriteImpl().

1294  {
1296  if (sslState_ == SSLStateEnum::STATE_CONNECTING) {
1297  assert(tfoAttempted_);
1298  // If we failed TFO, we'd fall back to trying to connect the socket,
1299  // to setup things like timeouts.
1300  startSSLConnect();
1301  }
1302  // still invoke the base class since it re-sets the connect time.
1304 }
virtual void invokeConnectSuccess()
void folly::AsyncSSLSocket::invokeHandshakeCB ( )
protected

Definition at line 670 of file AsyncSSLSocket.cpp.

References folly::AsyncTimeout::cancelTimeout(), handshakeCallback_, handshakeEndTime_, folly::AsyncSSLSocket::HandshakeCB::handshakeSuc(), handshakeTimeout_, folly::AsyncTimeout::isScheduled(), and now().

Referenced by handleConnect(), handleReturnFromSSLAccept(), and sslWriteImpl().

670  {
674  }
675  if (handshakeCallback_) {
676  HandshakeCB* callback = handshakeCallback_;
677  handshakeCallback_ = nullptr;
678  callback->handshakeSuc(this);
679  }
680 }
std::chrono::steady_clock::time_point now()
virtual void handshakeSuc(AsyncSSLSocket *sock) noexcept=0
std::chrono::steady_clock::time_point handshakeEndTime_
HandshakeCB * handshakeCallback_
bool isScheduled() const
void folly::AsyncSSLSocket::invokeHandshakeErr ( const AsyncSocketException ex)
protected

Definition at line 661 of file AsyncSSLSocket.cpp.

References handshakeCallback_, handshakeEndTime_, folly::AsyncSSLSocket::HandshakeCB::handshakeErr(), and now().

Referenced by closeNow(), failHandshake(), invokeConnectErr(), and sslWriteImpl().

661  {
663  if (handshakeCallback_ != nullptr) {
664  HandshakeCB* callback = handshakeCallback_;
665  handshakeCallback_ = nullptr;
666  callback->handshakeErr(this, ex);
667  }
668 }
std::chrono::steady_clock::time_point now()
virtual void handshakeErr(AsyncSSLSocket *sock, const AsyncSocketException &ex) noexcept=0
std::chrono::steady_clock::time_point handshakeEndTime_
HandshakeCB * handshakeCallback_
bool folly::AsyncSSLSocket::isDetachable ( ) const
inlineoverridevirtual

Determine if the transport can be detached.

This method must be called from the current EventBase's thread.

Reimplemented from folly::AsyncSocket.

Definition at line 581 of file AsyncSSLSocket.h.

References handshakeTimeout_, folly::AsyncSocket::isDetachable(), and folly::AsyncTimeout::isScheduled().

581  {
583  }
bool isScheduled() const
bool isDetachable() const override
bool folly::AsyncSSLSocket::needsPeerVerification ( ) const

Method to check if peer verfication is set.

Returns
true if peer verification is required.

Definition at line 711 of file AsyncSSLSocket.cpp.

References ctx_, and verifyPeer_.

Referenced by getSSLContext().

711  {
712  if (verifyPeer_ == SSLContext::SSLVerifyPeerEnum::USE_CTX) {
713  return ctx_->needsPeerVerification();
714  }
715  return (
716  verifyPeer_ == SSLContext::SSLVerifyPeerEnum::VERIFY ||
717  verifyPeer_ == SSLContext::SSLVerifyPeerEnum::VERIFY_REQ_CLIENT_CERT);
718 }
folly::SSLContext::SSLVerifyPeerEnum verifyPeer_
std::shared_ptr< folly::SSLContext > ctx_
static std::shared_ptr<AsyncSSLSocket> folly::AsyncSSLSocket::newSocket ( const std::shared_ptr< folly::SSLContext > &  ctx,
EventBase evb,
int  fd,
bool  server = true,
bool  deferSecurityNegotiation = false 
)
inlinestatic

Helper function to create a server/client shared_ptr<AsyncSSLSocket>.

Definition at line 239 of file AsyncSSLSocket.h.

References AsyncSSLSocket().

Referenced by wangle::ClientBootstrap< DefaultPipeline >::connect(), folly::SSLClient::connect(), folly::SSLServerAcceptCallbackBase::connectionAccepted(), folly::EvbAndContext::createSocket(), and newSocket().

244  {
245  return std::shared_ptr<AsyncSSLSocket>(
246  new AsyncSSLSocket(ctx, evb, fd, server, deferSecurityNegotiation),
247  Destructor());
248  }
AsyncSSLSocket(const std::shared_ptr< folly::SSLContext > &ctx, EventBase *evb, bool deferSecurityNegotiation=false)
static std::shared_ptr<AsyncSSLSocket> folly::AsyncSSLSocket::newSocket ( const std::shared_ptr< folly::SSLContext > &  ctx,
EventBase evb,
bool  deferSecurityNegotiation = false 
)
inlinestatic

Helper function to create a client shared_ptr<AsyncSSLSocket>.

Definition at line 253 of file AsyncSSLSocket.h.

References AsyncSSLSocket(), closeNow(), connecting(), getApplicationProtocol(), good(), newSocket(), folly::pushmi::__adl::noexcept(), shutdownWrite(), shutdownWriteNow(), and string.

256  {
257  return std::shared_ptr<AsyncSSLSocket>(
258  new AsyncSSLSocket(ctx, evb, deferSecurityNegotiation), Destructor());
259  }
AsyncSSLSocket(const std::shared_ptr< folly::SSLContext > &ctx, EventBase *evb, bool deferSecurityNegotiation=false)
AsyncSocket::ReadResult folly::AsyncSSLSocket::performRead ( void **  buf,
size_t *  buflen,
size_t *  offset 
)
overrideprotectedvirtual

Attempt to read from the socket.

Parameters
bufThe buffer to read data into.
buflenThe length of the buffer.
Returns
Returns a read result. See read result for details.

Reimplemented from folly::AsyncSocket.

Definition at line 1380 of file AsyncSSLSocket.cpp.

References folly::AsyncSocket::appBytesReceived_, folly::CLIENT_RENEGOTIATION, folly::AsyncSocket::eventFlags_, folly::AsyncSocket::fd_, folly::INVALID_RENEGOTIATION, folly::AsyncSocket::isBufferMovable_, folly::AsyncSocket::performRead(), folly::AsyncSocket::READ_BLOCKING, folly::AsyncSocket::READ_ERROR, renegotiateAttempted_, server_, ssl_, sslState_, folly::AsyncSocket::state_, and STATE_UNENCRYPTED.

Referenced by handleInitialReadWrite().

1380  {
1381  VLOG(4) << "AsyncSSLSocket::performRead() this=" << this << ", buf=" << *buf
1382  << ", buflen=" << *buflen;
1383 
1384  if (sslState_ == STATE_UNENCRYPTED) {
1385  return AsyncSocket::performRead(buf, buflen, offset);
1386  }
1387 
1388  int bytes = 0;
1389  if (!isBufferMovable_) {
1390  bytes = SSL_read(ssl_.get(), *buf, int(*buflen));
1391  }
1392 #ifdef SSL_MODE_MOVE_BUFFER_OWNERSHIP
1393  else {
1394  bytes = SSL_read_buf(ssl_.get(), buf, (int*)offset, (int*)buflen);
1395  }
1396 #endif
1397 
1398  if (server_ && renegotiateAttempted_) {
1399  LOG(ERROR) << "AsyncSSLSocket(fd=" << fd_ << ", state=" << int(state_)
1400  << ", sslstate=" << sslState_ << ", events=" << eventFlags_
1401  << "): client intitiated SSL renegotiation not permitted";
1402  return ReadResult(
1403  READ_ERROR,
1404  std::make_unique<SSLException>(SSLError::CLIENT_RENEGOTIATION));
1405  }
1406  if (bytes <= 0) {
1407  int error = SSL_get_error(ssl_.get(), bytes);
1408  if (error == SSL_ERROR_WANT_READ) {
1409  // The caller will register for read event if not already.
1410  if (errno == EWOULDBLOCK || errno == EAGAIN) {
1411  return ReadResult(READ_BLOCKING);
1412  } else {
1413  return ReadResult(READ_ERROR);
1414  }
1415  } else if (error == SSL_ERROR_WANT_WRITE) {
1416  // TODO: Even though we are attempting to read data, SSL_read() may
1417  // need to write data if renegotiation is being performed. We currently
1418  // don't support this and just fail the read.
1419  LOG(ERROR) << "AsyncSSLSocket(fd=" << fd_ << ", state=" << int(state_)
1420  << ", sslState=" << sslState_ << ", events=" << eventFlags_
1421  << "): unsupported SSL renegotiation during read";
1422  return ReadResult(
1423  READ_ERROR,
1424  std::make_unique<SSLException>(SSLError::INVALID_RENEGOTIATION));
1425  } else {
1426  if (zero_return(error, bytes)) {
1427  return ReadResult(bytes);
1428  }
1429  auto errError = ERR_get_error();
1430  VLOG(6) << "AsyncSSLSocket(fd=" << fd_ << ", "
1431  << "state=" << state_ << ", "
1432  << "sslState=" << sslState_ << ", "
1433  << "events=" << std::hex << eventFlags_ << "): "
1434  << "bytes: " << bytes << ", "
1435  << "error: " << error << ", "
1436  << "errno: " << errno << ", "
1437  << "func: " << ERR_func_error_string(errError) << ", "
1438  << "reason: " << ERR_reason_error_string(errError);
1439  return ReadResult(
1440  READ_ERROR,
1441  std::make_unique<SSLException>(error, errError, bytes, errno));
1442  }
1443  } else {
1444  appBytesReceived_ += bytes;
1445  return ReadResult(bytes);
1446  }
1447 }
ssl::SSLUniquePtr ssl_
bool error() const override
size_t appBytesReceived_
Num of bytes received from socket.
Definition: AsyncSocket.h:1253
uint16_t eventFlags_
EventBase::HandlerFlags settings.
Definition: AsyncSocket.h:1228
virtual ReadResult performRead(void **buf, size_t *buflen, size_t *offset)
StateEnum state_
StateEnum describing current state.
Definition: AsyncSocket.h:1226
int fd_
The socket file descriptor.
Definition: AsyncSocket.h:1229
AsyncSocket::WriteResult folly::AsyncSSLSocket::performWrite ( const iovec *  vec,
uint32_t  count,
WriteFlags  flags,
uint32_t countWritten,
uint32_t partialWritten 
)
overrideprotectedvirtual

Attempt to write to the socket.

Parameters
vecThe iovec array pointing to the buffers to write.
countThe length of the iovec array.
flagsSet of write flags.
countWrittenOn return, the value pointed to by this parameter will contain the number of iovec entries that were fully written.
partialWrittenOn return, the value pointed to by this parameter will contain the number of bytes written in the partially written iovec entry.
Returns
Returns a WriteResult. See WriteResult for more details.

Reimplemented from folly::AsyncSocket.

Definition at line 1501 of file AsyncSSLSocket.cpp.

References folly::CORK, corkCurrentWrite_, count, folly::EARLY_WRITE, folly::EOR, eorAwareSSLWrite(), folly::AsyncSocket::eventFlags_, folly::AsyncSocket::fd_, i, interpretSSLError(), folly::isSet(), min, minWriteSize_, folly::AsyncSocket::performWrite(), SCOPE_EXIT, ssl_, sslState_, folly::AsyncSocket::state_, STATE_ESTABLISHED, STATE_UNENCRYPTED, uint32_t, and folly::AsyncSocket::WRITE_ERROR.

Referenced by handleInitialReadWrite().

1506  {
1507  if (sslState_ == STATE_UNENCRYPTED) {
1509  vec, count, flags, countWritten, partialWritten);
1510  }
1511  if (sslState_ != STATE_ESTABLISHED) {
1512  LOG(ERROR) << "AsyncSSLSocket(fd=" << fd_ << ", state=" << int(state_)
1513  << ", sslState=" << sslState_ << ", events=" << eventFlags_
1514  << "): "
1515  << "TODO: AsyncSSLSocket currently does not support calling "
1516  << "write() before the handshake has fully completed";
1517  return WriteResult(
1518  WRITE_ERROR, std::make_unique<SSLException>(SSLError::EARLY_WRITE));
1519  }
1520 
1521  // Declare a buffer used to hold small write requests. It could point to a
1522  // memory block either on stack or on heap. If it is on heap, we release it
1523  // manually when scope exits
1524  char* combinedBuf{nullptr};
1525  SCOPE_EXIT {
1526  // Note, always keep this check consistent with what we do below
1527  if (combinedBuf != nullptr && minWriteSize_ > MAX_STACK_BUF_SIZE) {
1528  delete[] combinedBuf;
1529  }
1530  };
1531 
1532  *countWritten = 0;
1533  *partialWritten = 0;
1534  ssize_t totalWritten = 0;
1535  size_t bytesStolenFromNextBuffer = 0;
1536  for (uint32_t i = 0; i < count; i++) {
1537  const iovec* v = vec + i;
1538  size_t offset = bytesStolenFromNextBuffer;
1539  bytesStolenFromNextBuffer = 0;
1540  size_t len = v->iov_len - offset;
1541  const void* buf;
1542  if (len == 0) {
1543  (*countWritten)++;
1544  continue;
1545  }
1546  buf = ((const char*)v->iov_base) + offset;
1547 
1548  ssize_t bytes;
1549  uint32_t buffersStolen = 0;
1550  auto sslWriteBuf = buf;
1551  if ((len < minWriteSize_) && ((i + 1) < count)) {
1552  // Combine this buffer with part or all of the next buffers in
1553  // order to avoid really small-grained calls to SSL_write().
1554  // Each call to SSL_write() produces a separate record in
1555  // the egress SSL stream, and we've found that some low-end
1556  // mobile clients can't handle receiving an HTTP response
1557  // header and the first part of the response body in two
1558  // separate SSL records (even if those two records are in
1559  // the same TCP packet).
1560 
1561  if (combinedBuf == nullptr) {
1562  if (minWriteSize_ > MAX_STACK_BUF_SIZE) {
1563  // Allocate the buffer on heap
1564  combinedBuf = new char[minWriteSize_];
1565  } else {
1566  // Allocate the buffer on stack
1567  combinedBuf = (char*)alloca(minWriteSize_);
1568  }
1569  }
1570  assert(combinedBuf != nullptr);
1571  sslWriteBuf = combinedBuf;
1572 
1573  memcpy(combinedBuf, buf, len);
1574  do {
1575  // INVARIANT: i + buffersStolen == complete chunks serialized
1576  uint32_t nextIndex = i + buffersStolen + 1;
1577  bytesStolenFromNextBuffer =
1578  std::min(vec[nextIndex].iov_len, minWriteSize_ - len);
1579  if (bytesStolenFromNextBuffer > 0) {
1580  assert(vec[nextIndex].iov_base != nullptr);
1581  ::memcpy(
1582  combinedBuf + len,
1583  vec[nextIndex].iov_base,
1584  bytesStolenFromNextBuffer);
1585  }
1586  len += bytesStolenFromNextBuffer;
1587  if (bytesStolenFromNextBuffer < vec[nextIndex].iov_len) {
1588  // couldn't steal the whole buffer
1589  break;
1590  } else {
1591  bytesStolenFromNextBuffer = 0;
1592  buffersStolen++;
1593  }
1594  } while ((i + buffersStolen + 1) < count && (len < minWriteSize_));
1595  }
1596 
1597  // Advance any empty buffers immediately after.
1598  if (bytesStolenFromNextBuffer == 0) {
1599  while ((i + buffersStolen + 1) < count &&
1600  vec[i + buffersStolen + 1].iov_len == 0) {
1601  buffersStolen++;
1602  }
1603  }
1604 
1606  isSet(flags, WriteFlags::CORK) || (i + buffersStolen + 1 < count);
1607  bytes = eorAwareSSLWrite(
1608  ssl_,
1609  sslWriteBuf,
1610  int(len),
1611  (isSet(flags, WriteFlags::EOR) && i + buffersStolen + 1 == count));
1612 
1613  if (bytes <= 0) {
1614  int error = SSL_get_error(ssl_.get(), int(bytes));
1615  if (error == SSL_ERROR_WANT_WRITE) {
1616  // The caller will register for write event if not already.
1617  *partialWritten = uint32_t(offset);
1618  return WriteResult(totalWritten);
1619  }
1620  auto writeResult = interpretSSLError(int(bytes), error);
1621  if (writeResult.writeReturn < 0) {
1622  return writeResult;
1623  } // else fall through to below to correctly record totalWritten
1624  }
1625 
1626  totalWritten += bytes;
1627 
1628  if (bytes == (ssize_t)len) {
1629  // The full iovec is written.
1630  (*countWritten) += 1 + buffersStolen;
1631  i += buffersStolen;
1632  // continue
1633  } else {
1634  bytes += offset; // adjust bytes to account for all of v
1635  while (bytes >= (ssize_t)v->iov_len) {
1636  // We combined this buf with part or all of the next one, and
1637  // we managed to write all of this buf but not all of the bytes
1638  // from the next one that we'd hoped to write.
1639  bytes -= v->iov_len;
1640  (*countWritten)++;
1641  v = &(vec[++i]);
1642  }
1643  *partialWritten = uint32_t(bytes);
1644  return WriteResult(totalWritten);
1645  }
1646  }
1647 
1648  return WriteResult(totalWritten);
1649 }
flags
Definition: http_parser.h:127
WriteResult interpretSSLError(int rc, int error)
virtual WriteResult performWrite(const iovec *vec, uint32_t count, WriteFlags flags, uint32_t *countWritten, uint32_t *partialWritten)
ssl::SSLUniquePtr ssl_
#define SCOPE_EXIT
Definition: ScopeGuard.h:274
bool error() const override
bool isSet(WriteFlags a, WriteFlags b)
LogLevel min
Definition: LogLevel.cpp:30
uint16_t eventFlags_
EventBase::HandlerFlags settings.
Definition: AsyncSocket.h:1228
Definition: Traits.h:588
int * count
StateEnum state_
StateEnum describing current state.
Definition: AsyncSocket.h:1226
int fd_
The socket file descriptor.
Definition: AsyncSocket.h:1229
int eorAwareSSLWrite(const ssl::SSLUniquePtr &ssl, const void *buf, int n, bool eor)
ssize_t folly::AsyncSSLSocket::performWriteIovec ( const iovec *  vec,
uint32_t  count,
WriteFlags  flags,
uint32_t countWritten,
uint32_t partialWritten 
)
protected

Referenced by handleInitialReadWrite().

void folly::AsyncSSLSocket::prepareReadBuffer ( void **  buf,
size_t *  buflen 
)
overrideprotectedvirtual

Reimplemented from folly::AsyncSocket.

Definition at line 1346 of file AsyncSSLSocket.cpp.

References folly::AsyncReader::ReadCallback::getReadBuffer(), folly::AsyncSocket::isBufferMovable_, and folly::AsyncSocket::readCallback_.

Referenced by setAsyncOperationFinishCallback().

1346  {
1347  CHECK(readCallback_);
1348  if (isBufferMovable_) {
1349  *buf = nullptr;
1350  *buflen = 0;
1351  } else {
1352  // buf is necessary for SSLSocket without SSL_MODE_MOVE_BUFFER_OWNERSHIP
1353  readCallback_->getReadBuffer(buf, buflen);
1354  }
1355 }
virtual void getReadBuffer(void **bufReturn, size_t *lenReturn)=0
ReadCallback * readCallback_
ReadCallback.
Definition: AsyncSocket.h:1249
void folly::AsyncSSLSocket::resetClientHelloParsing ( SSL *  ssl)

Definition at line 1801 of file AsyncSSLSocket.cpp.

References clientHelloInfo_.

Referenced by clientHelloParsingCallback(), and getSSLContext().

1801  {
1802  SSL_set_msg_callback(ssl, nullptr);
1803  SSL_set_msg_callback_arg(ssl, nullptr);
1804  clientHelloInfo_->clientHelloBuf_.clear();
1805 }
std::unique_ptr< ssl::ClientHelloInfo > clientHelloInfo_
void folly::AsyncSSLSocket::restartSSLAccept ( )

Invoke SSL accept following an asynchronous session cache lookup

Definition at line 1084 of file AsyncSSLSocket.cpp.

References folly::AsyncSocket::eventFlags_, failHandshake(), folly::AsyncSocket::fd_, handleAccept(), sslState_, folly::AsyncSocket::state_, STATE_ACCEPTING, STATE_ASYNC_PENDING, STATE_CACHE_LOOKUP, STATE_CLOSED, STATE_ERROR, and folly::AsyncSocketException::TIMED_OUT.

Referenced by getSecurityProtocol(), folly::TestSSLAsyncCacheServer::getSessionCallback(), and wangle::SSLSessionCacheManager::restartSSLAccept().

1084  {
1085  VLOG(3) << "AsyncSSLSocket::restartSSLAccept() this=" << this
1086  << ", fd=" << fd_ << ", state=" << int(state_) << ", "
1087  << "sslState=" << sslState_ << ", events=" << eventFlags_;
1088  DestructorGuard dg(this);
1089  assert(
1092  if (sslState_ == STATE_CLOSED) {
1093  // I sure hope whoever closed this socket didn't delete it already,
1094  // but this is not strictly speaking an error
1095  return;
1096  }
1097  if (sslState_ == STATE_ERROR) {
1098  // go straight to fail if timeout expired during lookup
1099  AsyncSocketException ex(
1100  AsyncSocketException::TIMED_OUT, "SSL accept timed out");
1101  failHandshake(__func__, ex);
1102  return;
1103  }
1105  this->handleAccept();
1106 }
uint16_t eventFlags_
EventBase::HandlerFlags settings.
Definition: AsyncSocket.h:1228
StateEnum state_
StateEnum describing current state.
Definition: AsyncSocket.h:1226
int fd_
The socket file descriptor.
Definition: AsyncSocket.h:1229
void failHandshake(const char *fn, const AsyncSocketException &ex)
void handleAccept() noexcept
void folly::AsyncSSLSocket::scheduleConnectTimeout ( )
overrideprotectedvirtual

Reimplemented from folly::AsyncSocket.

Definition at line 1306 of file AsyncSSLSocket.cpp.

References folly::AsyncSocket::connectCallback_, connectionTimeout_, folly::AsyncSocket::connectTimeout_, folly::AsyncSocketException::INTERNAL_ERROR, folly::AsyncSocket::scheduleConnectTimeout(), folly::AsyncSSLSocket::Timeout::scheduleTimeout(), sslState_, and folly::AsyncSocket::withAddr().

Referenced by sslWriteImpl().

1306  {
1307  if (sslState_ == SSLStateEnum::STATE_CONNECTING) {
1308  // We fell back from TFO, and need to set the timeouts.
1309  // We will not have a connect callback in this case, thus if the timer
1310  // expires we would have no-one to notify.
1311  // Thus we should reset even the connect timers to point to the handshake
1312  // timeouts.
1313  assert(connectCallback_ == nullptr);
1314  // We use a different connect timeout here than the handshake timeout, so
1315  // that we can disambiguate the 2 timers.
1316  if (connectTimeout_.count() > 0) {
1318  throw AsyncSocketException(
1320  withAddr("failed to schedule AsyncSSLSocket connect timeout"));
1321  }
1322  }
1323  return;
1324  }
1326 }
std::string withAddr(const std::string &s)
std::chrono::milliseconds connectTimeout_
Definition: AsyncSocket.h:1263
virtual void scheduleConnectTimeout()
bool scheduleTimeout(TimeoutManager::timeout_type timeout)
ConnectCallback * connectCallback_
ConnectCallback.
Definition: AsyncSocket.h:1245
bool folly::AsyncSSLSocket::sessionIDResumed ( ) const
inline

true if the session was resumed using session ID

Definition at line 514 of file AsyncSSLSocket.h.

References sessionIDResumed_.

Referenced by wangle::SSLUtil::getResumeState().

514  {
515  return sessionIDResumed_;
516  }
bool folly::AsyncSSLSocket::sessionResumptionAttempted ( ) const
inline

Definition at line 785 of file AsyncSSLSocket.h.

References sessionResumptionAttempted_.

785  {
787  }
void folly::AsyncSSLSocket::setAsyncOperationFinishCallback ( std::unique_ptr< ReadCallback cb)
inline
void folly::AsyncSSLSocket::setBufferMovableEnabled ( bool  enabled)

Tries to enable the buffer movable experimental feature in openssl. This is not guaranteed to succeed in case openssl does not have the experimental feature built in.

Definition at line 1342 of file AsyncSSLSocket.cpp.

References bufferMovableEnabled_.

Referenced by getMinWriteSize().

1342  {
1343  bufferMovableEnabled_ = enabled;
1344 }
void folly::AsyncSSLSocket::setCertCacheHit ( bool  hit)
inline

Definition at line 777 of file AsyncSSLSocket.h.

References certCacheHit_.

777  {
778  certCacheHit_ = hit;
779  }
void folly::AsyncSSLSocket::setEorTracking ( bool  track)
overridevirtual

Reimplemented from folly::AsyncSocket.

Definition at line 403 of file AsyncSSLSocket.cpp.

References appEorByteNo_, folly::AsyncSocket::isEorTrackingEnabled(), minEorRawByteNo_, and folly::AsyncSocket::setEorTracking().

Referenced by getSecurityProtocol().

403  {
404  if (isEorTrackingEnabled() != track) {
406  appEorByteNo_ = 0;
407  minEorRawByteNo_ = 0;
408  }
409 }
void setEorTracking(bool track) override
Definition: AsyncSocket.h:563
bool isEorTrackingEnabled() const override
Definition: AsyncSocket.h:559
void folly::AsyncSSLSocket::setMinWriteSize ( size_t  minWriteSize)
inline

Definition at line 727 of file AsyncSSLSocket.h.

References minWriteSize_.

727  {
728  minWriteSize_ = minWriteSize;
729  }
void folly::AsyncSSLSocket::setReadCB ( ReadCallback callback)
overridevirtual

Reimplemented from folly::AsyncSocket.

Definition at line 1328 of file AsyncSSLSocket.cpp.

References bufferMovableEnabled_, folly::AsyncReader::ReadCallback::isBufferMovable(), folly::AsyncSocket::isBufferMovable_, folly::AsyncSocket::setReadCB(), and ssl_.

Referenced by folly::test::MockAsyncSSLSocket::connect(), and getMinWriteSize().

1328  {
1329 #ifdef SSL_MODE_MOVE_BUFFER_OWNERSHIP
1330  // turn on the buffer movable in openssl
1331  if (bufferMovableEnabled_ && ssl_ != nullptr && !isBufferMovable_ &&
1332  callback != nullptr && callback->isBufferMovable()) {
1333  SSL_set_mode(
1334  ssl_.get(), SSL_get_mode(ssl_.get()) | SSL_MODE_MOVE_BUFFER_OWNERSHIP);
1335  isBufferMovable_ = true;
1336  }
1337 #endif
1338 
1339  AsyncSocket::setReadCB(callback);
1340 }
ssl::SSLUniquePtr ssl_
void setReadCB(ReadCallback *callback) override
void folly::AsyncSSLSocket::setSessionIDResumed ( bool  resumed)
inline
void folly::AsyncSSLSocket::setSessionKey ( std::string  sessionKey)
inline

Definition at line 773 of file AsyncSSLSocket.h.

References folly::gen::move, and sessionKey_.

773  {
774  sessionKey_ = std::move(sessionKey);
775  }
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
void folly::AsyncSSLSocket::setSSLCertVerificationAlert ( std::string  alert)

Definition at line 2017 of file AsyncSSLSocket.cpp.

References folly::gen::move, and sslVerificationAlert_.

Referenced by getSSLContext().

2017  {
2019 }
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
std::string sslVerificationAlert_
void folly::AsyncSSLSocket::setSSLSession ( SSL_SESSION *  session,
bool  takeOwnership = false 
)

Set the SSL session to be used during sslConn. AsyncSSLSocket will hold a reference to the session until it is destroyed or released by the underlying SSL structure.

Parameters
takeOwnershipif true, AsyncSSLSocket will assume the caller's reference count to session.

Definition at line 841 of file AsyncSSLSocket.cpp.

References sslSession_.

Referenced by SSLCacheClient::connectSuccess(), and getSSLState().

841  {
842  if (sslSession_) {
843  SSL_SESSION_free(sslSession_);
844  }
845  sslSession_ = session;
846  if (!takeOwnership && session != nullptr) {
847  // Increment the reference count
848  // This API exists in BoringSSL and OpenSSL 1.1.0
849  SSL_SESSION_up_ref(session);
850  }
851 }
SSL_SESSION * sslSession_
bool folly::AsyncSSLSocket::setupSSLBio ( )
protected

Sets up SSL with a custom write bio which intercepts all writes.

Returns
true, if succeeds and false if there is an error creating the bio.

Definition at line 740 of file AsyncSSLSocket.cpp.

References folly::AsyncSocket::fd_, folly::ssl::OpenSSLUtils::setBioAppData(), folly::ssl::OpenSSLUtils::setBioFd(), and ssl_.

Referenced by handleAccept(), sslConn(), and sslWriteImpl().

740  {
741  auto sslBio = BIO_new(getSSLBioMethod());
742 
743  if (!sslBio) {
744  return false;
745  }
746 
747  OpenSSLUtils::setBioAppData(sslBio, this);
748  OpenSSLUtils::setBioFd(sslBio, fd_, BIO_NOCLOSE);
749  SSL_set_bio(ssl_.get(), sslBio, sslBio);
750  return true;
751 }
ssl::SSLUniquePtr ssl_
static void setBioFd(BIO *b, int fd, int flags)
static void setBioAppData(BIO *b, void *ptr)
int fd_
The socket file descriptor.
Definition: AsyncSocket.h:1229
void folly::AsyncSSLSocket::shutdownWrite ( )
overridevirtual

Perform a half-shutdown of the write side of the transport.

The caller should not make any more calls to write() or writev() after shutdownWrite() is called. Any future write attempts will fail immediately.

Not all transport types support half-shutdown. If the underlying transport does not support half-shutdown, it will fully shutdown both the read and write sides of the transport. (Fully shutting down the socket is better than doing nothing at all, since the caller may rely on the shutdownWrite() call to notify the other end of the connection that no more data can be read.)

If there is pending data still waiting to be written on the transport, the actual shutdown will be delayed until the pending data has been written.

Note: There is no corresponding shutdownRead() equivalent. Simply uninstall the read callback if you wish to stop reading. (On TCP sockets at least, shutting down the read side of the socket is a no-op anyway.)

Reimplemented from folly::AsyncSocket.

Definition at line 359 of file AsyncSSLSocket.cpp.

References folly::AsyncSocket::close().

Referenced by newSocket().

359  {
360  // SSL sockets do not support half-shutdown, so just perform a full shutdown.
361  //
362  // (Performing a full shutdown here is more desirable than doing nothing at
363  // all. The purpose of shutdownWrite() is normally to notify the other end
364  // of the connection that no more data will be sent. If we do nothing, the
365  // other end will never know that no more data is coming, and this may result
366  // in protocol deadlock.)
367  close();
368 }
void close() override
void folly::AsyncSSLSocket::shutdownWriteNow ( )
overridevirtual

Perform a half-shutdown of the write side of the transport.

shutdownWriteNow() is identical to shutdownWrite(), except that it immediately performs the shutdown, rather than waiting for pending writes to complete. Any pending write requests will be immediately failed when shutdownWriteNow() is called.

Reimplemented from folly::AsyncSocket.

Definition at line 370 of file AsyncSSLSocket.cpp.

References closeNow().

Referenced by newSocket().

370  {
371  closeNow();
372 }
void closeNow() override
void folly::AsyncSSLSocket::sslAccept ( HandshakeCB callback,
std::chrono::milliseconds  timeout = std::chrono::milliseconds::zero(),
const folly::SSLContext::SSLVerifyPeerEnum verifyPeer = folly::SSLContext::SSLVerifyPeerEnum::USE_CTX 
)
virtual

Accept an SSL connection on the socket.

The callback will be invoked and uninstalled when an SSL connection has been established on the underlying socket. The value of verifyPeer determines the client verification method. By default, its set to use the value in the underlying context

Parameters
callbackcallback object to invoke on success/failure
timeouttimeout for this function in milliseconds, or 0 for no timeout
verifyPeerSSLVerifyPeerEnum uses the options specified in the context by default, can be set explcitly to override the method in the context

Reimplemented in folly::test::MockAsyncSSLSocket.

Definition at line 461 of file AsyncSSLSocket.cpp.

References folly::AsyncSocket::cacheAddresses(), cacheAddrOnFailure_, checkForImmediateRead(), ctx_, folly::EventBase::dcheckIsInEventBaseThread(), folly::AsyncSocket::eventBase_, folly::AsyncSocket::getFd(), folly::SSLContext::getSSLCtx(), folly::ssl::OpenSSLUtils::getSSLInitialCtx(), folly::gen::guard(), handshakeCallback_, handshakeEndTime_, handshakeStartTime_, handshakeTimeout_, invalidState(), folly::gen::move, now(), folly::EventHandler::READ, folly::AsyncSSLSocket::Timeout::scheduleTimeout(), server_, folly::ssl::OpenSSLUtils::setSSLInitialCtx(), ssl_, folly::portability::ssl::SSL_SESSION_get0_hostname(), sslInfoCallback(), sslState_, STATE_ACCEPTING, STATE_UNENCRYPTED, STATE_UNINIT, string, folly::AsyncSocket::updateEventRegistration(), verifyPeer_, and folly::EventHandler::WRITE.

Referenced by folly::SSLServerAcceptCallback::connAccepted(), folly::SSLServerAsyncCacheAcceptCallback::connAccepted(), folly::HandshakeErrorCallback::connAccepted(), and getSecurityProtocol().

464  {
465  DestructorGuard dg(this);
467  verifyPeer_ = verifyPeer;
468 
469  // Make sure we're in the uninitialized state
470  if (!server_ ||
472  handshakeCallback_ != nullptr) {
473  return invalidState(callback);
474  }
475 
476  // Cache local and remote socket addresses to keep them available
477  // after socket file descriptor is closed.
478  if (cacheAddrOnFailure_) {
479  cacheAddresses();
480  }
481 
483  // Make end time at least >= start time.
485 
487  handshakeCallback_ = callback;
488 
489  if (timeout > std::chrono::milliseconds::zero()) {
491  }
492 
493  /* register for a read operation (waiting for CLIENT HELLO) */
495 
497 }
void checkForImmediateRead() noexceptoverride
folly::SSLContext::SSLVerifyPeerEnum verifyPeer_
std::chrono::steady_clock::time_point now()
EventBase * eventBase_
The EventBase.
Definition: AsyncSocket.h:1240
bool updateEventRegistration()
void dcheckIsInEventBaseThread() const
Definition: EventBase.h:520
std::chrono::steady_clock::time_point handshakeEndTime_
HandshakeCB * handshakeCallback_
void invalidState(HandshakeCB *callback)
std::chrono::steady_clock::time_point handshakeStartTime_
bool scheduleTimeout(TimeoutManager::timeout_type timeout)
void folly::AsyncSSLSocket::sslConn ( HandshakeCB callback,
std::chrono::milliseconds  timeout = std::chrono::milliseconds::zero(),
const folly::SSLContext::SSLVerifyPeerEnum verifyPeer = folly::SSLContext::SSLVerifyPeerEnum::USE_CTX 
)
virtual

Initiate an SSL connection on the socket The callback will be invoked and uninstalled when an SSL connection has been establshed on the underlying socket. The verification option verifyPeer is applied if it's passed explicitly. If it's not, the options in SSLContext set on the underlying SSLContext are applied.

Parameters
callbackcallback object to invoke on success/failure
timeouttimeout for this function in milliseconds, or 0 for no timeout
verifyPeerSSLVerifyPeerEnum uses the options specified in the context by default, can be set explcitly to override the method in the context. If verification is turned on sets SSL_VERIFY_PEER and invokes HandshakeCB::handshakeVer().

Reimplemented in folly::test::MockAsyncSSLSocket.

Definition at line 753 of file AsyncSSLSocket.cpp.

References applyVerificationOptions(), folly::AsyncSocket::cacheAddresses(), cacheAddrOnFailure_, ctx_, folly::EventBase::dcheckIsInEventBaseThread(), folly::AsyncSocket::eventBase_, failHandshake(), folly::AsyncSocket::fd_, getSSLExDataIndex(), handshakeCallback_, handshakeConnectTimeout_, folly::AsyncSocketException::INTERNAL_ERROR, invalidState(), server_, sessionResumptionAttempted_, setupSSLBio(), ssl_, sslSession_, sslState_, startSSLConnect(), STATE_CONNECTING, STATE_ERROR, STATE_UNENCRYPTED, STATE_UNINIT, and verifyPeer_.

Referenced by SSLCacheClient::connectSuccess(), and getSecurityProtocol().

756  {
757  DestructorGuard dg(this);
759 
760  // Cache local and remote socket addresses to keep them available
761  // after socket file descriptor is closed.
762  if (cacheAddrOnFailure_) {
763  cacheAddresses();
764  }
765 
766  verifyPeer_ = verifyPeer;
767 
768  // Make sure we're in the uninitialized state
769  if (server_ ||
771  handshakeCallback_ != nullptr) {
772  return invalidState(callback);
773  }
774 
776  handshakeCallback_ = callback;
777 
778  try {
779  ssl_.reset(ctx_->createSSL());
780  } catch (std::exception& e) {
782  AsyncSocketException ex(
784  "error calling SSLContext::createSSL()");
785  LOG(ERROR) << "AsyncSSLSocket::sslConn(this=" << this << ", fd=" << fd_
786  << "): " << e.what();
787  return failHandshake(__func__, ex);
788  }
789 
790  if (!setupSSLBio()) {
792  AsyncSocketException ex(
793  AsyncSocketException::INTERNAL_ERROR, "error creating SSL bio");
794  return failHandshake(__func__, ex);
795  }
796 
798 
799  if (sslSession_ != nullptr) {
801  SSL_set_session(ssl_.get(), sslSession_);
802  SSL_SESSION_free(sslSession_);
803  sslSession_ = nullptr;
804  }
805 #if FOLLY_OPENSSL_HAS_SNI
806  if (tlsextHostname_.size()) {
807  SSL_set_tlsext_host_name(ssl_.get(), tlsextHostname_.c_str());
808  }
809 #endif
810 
811  SSL_set_ex_data(ssl_.get(), getSSLExDataIndex(), this);
812 
814  startSSLConnect();
815 }
void applyVerificationOptions(const ssl::SSLUniquePtr &ssl)
folly::SSLContext::SSLVerifyPeerEnum verifyPeer_
ssl::SSLUniquePtr ssl_
std::chrono::milliseconds handshakeConnectTimeout_
SSL_SESSION * sslSession_
EventBase * eventBase_
The EventBase.
Definition: AsyncSocket.h:1240
std::shared_ptr< folly::SSLContext > ctx_
void dcheckIsInEventBaseThread() const
Definition: EventBase.h:520
int fd_
The socket file descriptor.
Definition: AsyncSocket.h:1229
HandshakeCB * handshakeCallback_
void failHandshake(const char *fn, const AsyncSocketException &ex)
void invalidState(HandshakeCB *callback)
static int getSSLExDataIndex()
void folly::AsyncSSLSocket::sslInfoCallback ( const SSL *  ssl,
int  type,
int  val 
)
staticprotected

Definition at line 1686 of file AsyncSSLSocket.cpp.

References alertsReceived_, getFromSSL(), handshakeComplete_, renegotiateAttempted_, and type.

Referenced by AsyncSSLSocket(), sslAccept(), and sslWriteImpl().

1686  {
1687  AsyncSSLSocket* sslSocket = AsyncSSLSocket::getFromSSL(ssl);
1688  if (sslSocket->handshakeComplete_ && (where & SSL_CB_HANDSHAKE_START)) {
1689  sslSocket->renegotiateAttempted_ = true;
1690  }
1691  if (where & SSL_CB_READ_ALERT) {
1692  const char* type = SSL_alert_type_string(ret);
1693  if (type) {
1694  const char* desc = SSL_alert_desc_string(ret);
1695  sslSocket->alertsReceived_.emplace_back(
1696  *type, StringPiece(desc, std::strlen(desc)));
1697  }
1698  }
1699 }
PskType type
AsyncSSLSocket(const std::shared_ptr< folly::SSLContext > &ctx, EventBase *evb, bool deferSecurityNegotiation=false)
Range< const char * > StringPiece
static AsyncSSLSocket * getFromSSL(const SSL *ssl)
int folly::AsyncSSLSocket::sslVerifyCallback ( int  preverifyOk,
X509_STORE_CTX *  ctx 
)
staticprotected

Definition at line 1782 of file AsyncSSLSocket.cpp.

References getFromSSL().

Referenced by applyVerificationOptions().

1784  {
1785  SSL* ssl = (SSL*)X509_STORE_CTX_get_ex_data(
1786  x509Ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
1788 
1789  VLOG(3) << "AsyncSSLSocket::sslVerifyCallback() this=" << self << ", "
1790  << "fd=" << self->fd_ << ", preverifyOk=" << preverifyOk;
1791  return (self->handshakeCallback_)
1792  ? self->handshakeCallback_->handshakeVer(self, preverifyOk, x509Ctx)
1793  : preverifyOk;
1794 }
AsyncSSLSocket(const std::shared_ptr< folly::SSLContext > &ctx, EventBase *evb, bool deferSecurityNegotiation=false)
static AsyncSSLSocket * getFromSSL(const SSL *ssl)
virtual int folly::AsyncSSLSocket::sslWriteImpl ( SSL *  ssl,
const void *  buf,
int  n 
)
inlineprotectedvirtual
void folly::AsyncSSLSocket::startSSLConnect ( )
protected

Definition at line 819 of file AsyncSSLSocket.cpp.

References handleConnect(), handshakeConnectTimeout_, handshakeEndTime_, handshakeStartTime_, handshakeTimeout_, now(), and folly::AsyncSSLSocket::Timeout::scheduleTimeout().

Referenced by invokeConnectSuccess(), sslConn(), and sslWriteImpl().

819  {
821  // Make end time at least >= start time.
823  if (handshakeConnectTimeout_ > std::chrono::milliseconds::zero()) {
825  }
826  handleConnect();
827 }
std::chrono::steady_clock::time_point now()
std::chrono::milliseconds handshakeConnectTimeout_
void handleConnect() noexceptoverride
std::chrono::steady_clock::time_point handshakeEndTime_
std::chrono::steady_clock::time_point handshakeStartTime_
bool scheduleTimeout(TimeoutManager::timeout_type timeout)
void folly::AsyncSSLSocket::timeoutExpired ( std::chrono::milliseconds  timeout)
noexcept

Definition at line 609 of file AsyncSSLSocket.cpp.

References folly::AsyncSocket::CONNECTING, folly::AsyncSocket::ESTABLISHED, failHandshake(), folly::sformat(), sslState_, folly::AsyncSocket::state_, STATE_ACCEPTING, STATE_ASYNC_PENDING, STATE_CACHE_LOOKUP, STATE_CONNECTING, STATE_ERROR, folly::AsyncSocketException::TIMED_OUT, and folly::detail::timeout.

610  {
614  // We are expecting a callback in restartSSLAccept. The cache lookup
615  // and rsa-call necessarily have pointers to this ssl socket, so delay
616  // the cleanup until he calls us back.
617  } else if (state_ == StateEnum::CONNECTING) {
618  assert(sslState_ == STATE_CONNECTING);
619  DestructorGuard dg(this);
620  AsyncSocketException ex(
622  "Fallback connect timed out during TFO");
623  failHandshake(__func__, ex);
624  } else {
625  assert(
628  DestructorGuard dg(this);
629  AsyncSocketException ex(
632  "SSL {} timed out after {}ms",
633  (sslState_ == STATE_CONNECTING) ? "connect" : "accept",
634  timeout.count()));
635  failHandshake(__func__, ex);
636  }
637 }
std::string sformat(StringPiece fmt, Args &&...args)
Definition: Format.h:280
StateEnum state_
StateEnum describing current state.
Definition: AsyncSocket.h:1226
void failHandshake(const char *fn, const AsyncSocketException &ex)
bool folly::AsyncSSLSocket::willBlock ( int  ret,
int *  sslErrorOut,
unsigned long *  errErrorOut 
)
protectednoexcept

Definition at line 971 of file AsyncSSLSocket.cpp.

References asyncOperationFinishCallback_, folly::AsyncSocket::eventBase_, folly::AsyncSocket::eventFlags_, folly::AsyncSocket::fd_, folly::gen::move, folly::AsyncPipeReader::newReader(), folly::EventHandler::NONE, folly::EventHandler::READ, ssl_, sslState_, folly::AsyncSocket::state_, STATE_ASYNC_PENDING, STATE_CACHE_LOOKUP, folly::AsyncSocket::updateEventRegistration(), and folly::EventHandler::WRITE.

Referenced by handleConnect(), handleReturnFromSSLAccept(), and setAsyncOperationFinishCallback().

974  {
975  *errErrorOut = 0;
976  int error = *sslErrorOut = SSL_get_error(ssl_.get(), ret);
977  if (error == SSL_ERROR_WANT_READ) {
978  // Register for read event if not already.
980  return true;
981  } else if (error == SSL_ERROR_WANT_WRITE) {
982  VLOG(3) << "AsyncSSLSocket(fd=" << fd_ << ", state=" << int(state_)
983  << ", sslState=" << sslState_ << ", events=" << eventFlags_ << "): "
984  << "SSL_ERROR_WANT_WRITE";
985  // Register for write event if not already.
987  return true;
988 #ifdef SSL_ERROR_WANT_SESS_CACHE_LOOKUP
989  } else if (error == SSL_ERROR_WANT_SESS_CACHE_LOOKUP) {
990  // We will block but we can't register our own socket. The callback that
991  // triggered this code will re-call handleAccept at the appropriate time.
992 
993  // We can only get here if the linked libssl.so has support for this feature
994  // as well, otherwise SSL_get_error cannot return our error code.
996 
997  // Unregister for all events while blocked here
1000 
1001  // The timeout (if set) keeps running here
1002  return true;
1003 #endif
1004  } else if ((false
1005 #ifdef SSL_ERROR_WANT_RSA_ASYNC_PENDING
1006  || error == SSL_ERROR_WANT_RSA_ASYNC_PENDING
1007 #endif
1008 #ifdef SSL_ERROR_WANT_ECDSA_ASYNC_PENDING
1009  || error == SSL_ERROR_WANT_ECDSA_ASYNC_PENDING
1010 #endif
1011 #ifdef SSL_ERROR_WANT_ASYNC // OpenSSL 1.1.0 Async API
1012  || error == SSL_ERROR_WANT_ASYNC
1013 #endif
1014  )) {
1015  // Our custom openssl function has kicked off an async request to do
1016  // rsa/ecdsa private key operation. When that call returns, a callback will
1017  // be invoked that will re-call handleAccept.
1019 
1020  // Unregister for all events while blocked here
1023 
1024 #ifdef SSL_ERROR_WANT_ASYNC
1025  if (error == SSL_ERROR_WANT_ASYNC) {
1026  size_t numfds;
1027  if (SSL_get_all_async_fds(ssl_.get(), NULL, &numfds) <= 0) {
1028  VLOG(4) << "SSL_ERROR_WANT_ASYNC but no async FDs set!";
1029  return false;
1030  }
1031  if (numfds != 1) {
1032  VLOG(4) << "SSL_ERROR_WANT_ASYNC expected exactly 1 async fd, got "
1033  << numfds;
1034  return false;
1035  }
1036  OSSL_ASYNC_FD ofd; // This should just be an int in POSIX
1037  if (SSL_get_all_async_fds(ssl_.get(), &ofd, &numfds) <= 0) {
1038  VLOG(4) << "SSL_ERROR_WANT_ASYNC cant get async fd";
1039  return false;
1040  }
1041 
1042  auto asyncPipeReader = AsyncPipeReader::newReader(eventBase_, ofd);
1043  auto asyncPipeReaderPtr = asyncPipeReader.get();
1046  new DefaultOpenSSLAsyncFinishCallback(
1047  std::move(asyncPipeReader), this, DestructorGuard(this)));
1048  }
1049  asyncPipeReaderPtr->setReadCB(asyncOperationFinishCallback_.get());
1050  }
1051 #endif
1052 
1053  // The timeout (if set) keeps running here
1054  return true;
1055  } else {
1056  unsigned long lastError = *errErrorOut = ERR_get_error();
1057  VLOG(6) << "AsyncSSLSocket(fd=" << fd_ << ", "
1058  << "state=" << state_ << ", "
1059  << "sslState=" << sslState_ << ", "
1060  << "events=" << std::hex << eventFlags_ << "): "
1061  << "SSL error: " << error << ", "
1062  << "errno: " << errno << ", "
1063  << "ret: " << ret << ", "
1064  << "read: " << BIO_number_read(SSL_get_rbio(ssl_.get())) << ", "
1065  << "written: " << BIO_number_written(SSL_get_wbio(ssl_.get()))
1066  << ", "
1067  << "func: " << ERR_func_error_string(lastError) << ", "
1068  << "reason: " << ERR_reason_error_string(lastError);
1069  return false;
1070  }
1071 }
std::unique_ptr< ReadCallback > asyncOperationFinishCallback_
static UniquePtr newReader(Args &&...args)
Definition: AsyncPipe.h:43
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
ssl::SSLUniquePtr ssl_
EventBase * eventBase_
The EventBase.
Definition: AsyncSocket.h:1240
bool updateEventRegistration()
bool error() const override
uint16_t eventFlags_
EventBase::HandlerFlags settings.
Definition: AsyncSocket.h:1228
StateEnum state_
StateEnum describing current state.
Definition: AsyncSocket.h:1226
int fd_
The socket file descriptor.
Definition: AsyncSocket.h:1229

Member Data Documentation

std::vector<std::pair<char, StringPiece> > folly::AsyncSSLSocket::alertsReceived_
protected

Definition at line 954 of file AsyncSSLSocket.h.

Referenced by getSSLAlertsReceived(), and sslInfoCallback().

size_t folly::AsyncSSLSocket::appEorByteNo_ {0}
protected

Definition at line 926 of file AsyncSSLSocket.h.

Referenced by eorAwareSSLWrite(), and setEorTracking().

std::unique_ptr<ReadCallback> folly::AsyncSSLSocket::asyncOperationFinishCallback_
protected

Definition at line 968 of file AsyncSSLSocket.h.

Referenced by setAsyncOperationFinishCallback(), and willBlock().

bool folly::AsyncSSLSocket::bufferMovableEnabled_ {false}
protected

Definition at line 951 of file AsyncSSLSocket.h.

Referenced by setBufferMovableEnabled(), and setReadCB().

bool folly::AsyncSSLSocket::cacheAddrOnFailure_ {false}
protected

Definition at line 950 of file AsyncSSLSocket.h.

Referenced by forceCacheAddrOnFailure(), sslAccept(), and sslConn().

bool folly::AsyncSSLSocket::certCacheHit_ {false}
protected

Definition at line 952 of file AsyncSSLSocket.h.

Referenced by getCertCacheHit(), and setCertCacheHit().

Timeout folly::AsyncSSLSocket::connectionTimeout_
protected
bool folly::AsyncSSLSocket::corkCurrentWrite_ {false}
protected

Definition at line 906 of file AsyncSSLSocket.h.

Referenced by performWrite().

std::shared_ptr<folly::SSLContext> folly::AsyncSSLSocket::ctx_
protected
bool folly::AsyncSSLSocket::handshakeComplete_ {false}
protected

Definition at line 913 of file AsyncSSLSocket.h.

Referenced by handleConnect(), handleReturnFromSSLAccept(), and sslInfoCallback().

std::chrono::milliseconds folly::AsyncSSLSocket::handshakeConnectTimeout_ {0}
protected

Definition at line 959 of file AsyncSSLSocket.h.

Referenced by sslConn(), and startSSLConnect().

std::chrono::steady_clock::time_point folly::AsyncSSLSocket::handshakeEndTime_
protected
std::chrono::steady_clock::time_point folly::AsyncSSLSocket::handshakeStartTime_
protected

Definition at line 957 of file AsyncSSLSocket.h.

Referenced by getHandshakeTime(), sslAccept(), and startSSLConnect().

size_t folly::AsyncSSLSocket::minEorRawByteNo_ {0}
protected

Definition at line 934 of file AsyncSSLSocket.h.

Referenced by eorAwareSSLWrite(), and setEorTracking().

size_t folly::AsyncSSLSocket::minWriteSize_ {1500}
protected

Definition at line 930 of file AsyncSSLSocket.h.

Referenced by getMinWriteSize(), performWrite(), and setMinWriteSize().

bool folly::AsyncSSLSocket::parseClientHello_ {false}
protected
bool folly::AsyncSSLSocket::renegotiateAttempted_ {false}
protected

Definition at line 914 of file AsyncSSLSocket.h.

Referenced by performRead(), and sslInfoCallback().

bool folly::AsyncSSLSocket::server_ {false}
protected
bool folly::AsyncSSLSocket::sessionIDResumed_ {false}
protected

Definition at line 966 of file AsyncSSLSocket.h.

Referenced by sessionIDResumed(), and setSessionIDResumed().

std::string folly::AsyncSSLSocket::sessionKey_
protected

Definition at line 941 of file AsyncSSLSocket.h.

Referenced by getSessionKey(), and setSessionKey().

bool folly::AsyncSSLSocket::sessionResumptionAttempted_ {false}
protected

Definition at line 964 of file AsyncSSLSocket.h.

Referenced by sessionResumptionAttempted(), and sslConn().

SSL_SESSION* folly::AsyncSSLSocket::sslSession_ {nullptr}
protected

Definition at line 920 of file AsyncSSLSocket.h.

Referenced by closeNow(), getSSLSession(), setSSLSession(), and sslConn().

std::string folly::AsyncSSLSocket::sslVerificationAlert_
protected

Definition at line 962 of file AsyncSSLSocket.h.

Referenced by getSSLCertVerificationAlert(), and setSSLCertVerificationAlert().

std::chrono::milliseconds folly::AsyncSSLSocket::totalConnectTimeout_ {0}
protected

Definition at line 960 of file AsyncSSLSocket.h.

Referenced by connect(), and getTotalConnectTimeout().

folly::SSLContext::SSLVerifyPeerEnum folly::AsyncSSLSocket::verifyPeer_
protected
Initial value:
{
folly::SSLContext::SSLVerifyPeerEnum::USE_CTX}

Definition at line 943 of file AsyncSSLSocket.h.

Referenced by applyVerificationOptions(), needsPeerVerification(), sslAccept(), and sslConn().


The documentation for this class was generated from the following files: