From 22118d68d2cfe6e3f48564117f99f26c1aa0e435 Mon Sep 17 00:00:00 2001 From: Benjamin Sergeant Date: Fri, 24 Jan 2020 22:36:23 -0800 Subject: [PATCH] session resume wip, for mac only --- ixwebsocket/IXSocketAppleSSL.cpp | 25 ++++++++++++++----------- ixwebsocket/IXSocketAppleSSL.h | 2 ++ ixwebsocket/IXSocketConnect.cpp | 19 ++++++++++++++++++- ixwebsocket/IXWebSocketHandshake.cpp | 11 +++++++++++ ixwebsocket/IXWebSocketTransport.cpp | 13 ++++++++++++- ixwebsocket/IXWebSocketTransport.h | 2 +- 6 files changed, 58 insertions(+), 14 deletions(-) diff --git a/ixwebsocket/IXSocketAppleSSL.cpp b/ixwebsocket/IXSocketAppleSSL.cpp index ad557583..d8050b09 100644 --- a/ixwebsocket/IXSocketAppleSSL.cpp +++ b/ixwebsocket/IXSocketAppleSSL.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #define socketerrno errno #include @@ -31,12 +32,17 @@ namespace ix , _sslContext(nullptr) , _tlsOptions(tlsOptions) { - ; + _sslContext = SSLCreateContext(kCFAllocatorDefault, kSSLClientSide, kSSLStreamType); + SSLSetIOFuncs( + _sslContext, SocketAppleSSL::readFromSocket, SocketAppleSSL::writeToSocket); } SocketAppleSSL::~SocketAppleSSL() { - SocketAppleSSL::close(); + CFRelease(_sslContext); + _sslContext = nullptr; + + Socket::close(); } std::string SocketAppleSSL::getSSLErrorDescription(OSStatus status) @@ -177,14 +183,16 @@ namespace ix _sockfd = SocketConnect::connect(host, port, errMsg, isCancellationRequested); if (_sockfd == -1) return false; - _sslContext = SSLCreateContext(kCFAllocatorDefault, kSSLClientSide, kSSLStreamType); - - SSLSetIOFuncs( - _sslContext, SocketAppleSSL::readFromSocket, SocketAppleSSL::writeToSocket); SSLSetConnection(_sslContext, (SSLConnectionRef)(long) _sockfd); SSLSetProtocolVersionMin(_sslContext, kTLSProtocol12); SSLSetPeerDomainName(_sslContext, host.c_str(), host.size()); + // Record a peer id, which speed up SSL connection when reconnecting to the same host + std::stringstream ss; + ss << host << ":" << port; + _peerId = ss.str(); + SSLSetPeerID(_sslContext, (void*) _peerId.c_str(), _peerId.size()); + if (_tlsOptions.isPeerVerifyDisabled()) { Boolean option(1); @@ -227,12 +235,7 @@ namespace ix { std::lock_guard lock(_mutex); - if (_sslContext == nullptr) return; - SSLClose(_sslContext); - CFRelease(_sslContext); - _sslContext = nullptr; - Socket::close(); } diff --git a/ixwebsocket/IXSocketAppleSSL.h b/ixwebsocket/IXSocketAppleSSL.h index ef81b09a..b27efb3c 100644 --- a/ixwebsocket/IXSocketAppleSSL.h +++ b/ixwebsocket/IXSocketAppleSSL.h @@ -41,6 +41,8 @@ namespace ix mutable std::mutex _mutex; // AppleSSL routines are not thread-safe SocketTLSOptions _tlsOptions; + + std::string _peerId; }; } // namespace ix diff --git a/ixwebsocket/IXSocketConnect.cpp b/ixwebsocket/IXSocketConnect.cpp index 1d887b7e..cae85398 100644 --- a/ixwebsocket/IXSocketConnect.cpp +++ b/ixwebsocket/IXSocketConnect.cpp @@ -19,10 +19,12 @@ #include #endif +#include + namespace ix { // - // This function can be cancelled every 50 ms + // This function can be cancelled every 10 ms // This is important so that we don't block the main UI thread when shutting down a // connection which is already trying to reconnect, and can be blocked waiting for // ::connect to respond. @@ -44,8 +46,15 @@ namespace ix // block us for too long SocketConnect::configure(fd); + auto start = std::chrono::system_clock::now(); + int res = ::connect(fd, address->ai_addr, address->ai_addrlen); + auto now = std::chrono::system_clock::now(); + auto milliseconds = std::chrono::duration_cast(now - start); + auto ms = milliseconds.count(); + std::cout << "tcp connection completed in " << ms << "ms" << std::endl; + if (res == -1 && !Socket::isWaitNeeded()) { errMsg = strerror(Socket::getErrno()); @@ -98,11 +107,19 @@ namespace ix std::string& errMsg, const CancellationRequest& isCancellationRequested) { + auto start = std::chrono::system_clock::now(); + // // First do DNS resolution // auto dnsLookup = std::make_shared(hostname, port); struct addrinfo* res = dnsLookup->resolve(errMsg, isCancellationRequested); + + auto now = std::chrono::system_clock::now(); + auto milliseconds = std::chrono::duration_cast(now - start); + auto ms = milliseconds.count(); + std::cout << "dns resolution completed in " << ms << "ms" << std::endl; + if (res == nullptr) { return -1; diff --git a/ixwebsocket/IXWebSocketHandshake.cpp b/ixwebsocket/IXWebSocketHandshake.cpp index dac14dac..c712dc9d 100644 --- a/ixwebsocket/IXWebSocketHandshake.cpp +++ b/ixwebsocket/IXWebSocketHandshake.cpp @@ -15,6 +15,9 @@ #include #include +#include +#include + namespace ix { @@ -97,8 +100,16 @@ namespace ix auto isCancellationRequested = makeCancellationRequestWithTimeout(timeoutSecs, _requestInitCancellation); + auto start = std::chrono::system_clock::now(); + std::string errMsg; bool success = _socket->connect(host, port, errMsg, isCancellationRequested); + + auto now = std::chrono::system_clock::now(); + auto milliseconds = std::chrono::duration_cast(now - start); + auto ms = milliseconds.count(); + std::cout << "connection completed in " << ms << "ms" << std::endl; + if (!success) { std::stringstream ss; diff --git a/ixwebsocket/IXWebSocketTransport.cpp b/ixwebsocket/IXWebSocketTransport.cpp index 3b000200..d7964b92 100644 --- a/ixwebsocket/IXWebSocketTransport.cpp +++ b/ixwebsocket/IXWebSocketTransport.cpp @@ -151,7 +151,18 @@ namespace ix std::string errorMsg; bool tls = protocol == "wss"; - _socket = createSocket(tls, -1, errorMsg, _socketTLSOptions); + + if (_host == host) + { + _socket->close(); + } + else + { + _socket = createSocket(tls, -1, errorMsg, _socketTLSOptions); + } + + // Record the host for later + _host = host; if (!_socket) { diff --git a/ixwebsocket/IXWebSocketTransport.h b/ixwebsocket/IXWebSocketTransport.h index 47c1bfee..1aea0705 100644 --- a/ixwebsocket/IXWebSocketTransport.h +++ b/ixwebsocket/IXWebSocketTransport.h @@ -107,7 +107,7 @@ namespace ix size_t bufferedAmount() const; private: - std::string _url; + std::string _host; struct wsheader_type {