diff --git a/android/src/main/cpp/sonar.cpp b/android/src/main/cpp/sonar.cpp index ecc15d03b..3bfa8d3a3 100644 --- a/android/src/main/cpp/sonar.cpp +++ b/android/src/main/cpp/sonar.cpp @@ -276,9 +276,9 @@ class JFlipperWebSocket : public facebook::flipper::FlipperSocket { messageHandler_ = std::move(messageHandler); } - virtual bool connect(FlipperConnectionManager* manager) override { + virtual void connect(FlipperConnectionManager* manager) override { if (socket_ != nullptr) { - return true; + return; } std::string connectionURL = endpoint_.secure ? "wss://" : "ws://"; @@ -297,38 +297,9 @@ class JFlipperWebSocket : public facebook::flipper::FlipperSocket { auto secure = endpoint_.secure; - std::promise promise; - auto connected = promise.get_future(); - - connecting_ = true; - socket_ = make_global(JFlipperSocketImpl::create(connectionURL)); socket_->setEventHandler(JFlipperSocketEventHandlerImpl::newObjectCxxArgs( - [this, &promise, eventHandler = eventHandler_](SocketEvent event) { - /** - Only fulfill the promise the first time the event handler is used. - If the open event is received, then set the promise value to true. - For any other event, consider a failure and set to false. - */ - if (this->connecting_) { - this->connecting_ = false; - if (event == SocketEvent::OPEN) { - promise.set_value(true); - } else if (event == SocketEvent::SSL_ERROR) { - try { - promise.set_exception( - std::make_exception_ptr(folly::AsyncSocketException( - folly::AsyncSocketException::SSL_ERROR, - "SSL handshake failed"))); - } catch (...) { - // set_exception() may throw an exception - // In that case, just set the value to false. - promise.set_value(false); - } - } else { - promise.set_value(false); - } - } + [eventHandler = eventHandler_](SocketEvent event) { eventHandler(event); }, [messageHandler = messageHandler_](const std::string& message) { @@ -348,8 +319,6 @@ class JFlipperWebSocket : public facebook::flipper::FlipperSocket { return JFlipperObject::create(std::move(object_)); })); socket_->connect(); - - return connected.get(); } virtual void disconnect() override { @@ -409,7 +378,6 @@ class JFlipperWebSocket : public facebook::flipper::FlipperSocket { facebook::flipper::SocketMessageHandler messageHandler_; jni::global_ref socket_; - bool connecting_; }; class JFlipperSocketProvider : public facebook::flipper::FlipperSocketProvider { diff --git a/android/src/main/java/com/facebook/flipper/android/FlipperSocketImpl.java b/android/src/main/java/com/facebook/flipper/android/FlipperSocketImpl.java index ce4c201cb..464dc8222 100644 --- a/android/src/main/java/com/facebook/flipper/android/FlipperSocketImpl.java +++ b/android/src/main/java/com/facebook/flipper/android/FlipperSocketImpl.java @@ -117,7 +117,7 @@ class FlipperSocketImpl extends WebSocketClient implements FlipperSocket { this.connect(); } catch (Exception e) { - Log.e("Flipper", "Failed to initialize the socket before connect. " + e.getMessage()); + Log.e("flipper", "Failed to initialize the socket before connect. Error: " + e.getMessage()); this.mEventHandler.onConnectionEvent(FlipperSocketEventHandler.SocketEvent.ERROR); } } @@ -139,6 +139,13 @@ class FlipperSocketImpl extends WebSocketClient implements FlipperSocket { @Override public void onClose(int code, String reason, boolean remote) { + /** + * If the socket is not yet open, don't report the close event. Usually, onError is invoked + * instead which is the one that needs reporting. + */ + if (!this.isOpen()) { + return; + } this.mEventHandler.onConnectionEvent(FlipperSocketEventHandler.SocketEvent.CLOSE); } @@ -162,7 +169,6 @@ class FlipperSocketImpl extends WebSocketClient implements FlipperSocket { @Override public void flipperDisconnect() { - this.mEventHandler.onConnectionEvent(FlipperSocketEventHandler.SocketEvent.CLOSE); this.mEventHandler = new FlipperSocketEventHandler() { @Override diff --git a/iOS/FlipperKit/FlipperPlatformWebSocket.mm b/iOS/FlipperKit/FlipperPlatformWebSocket.mm index 76df258f2..d40b13299 100644 --- a/iOS/FlipperKit/FlipperPlatformWebSocket.mm +++ b/iOS/FlipperKit/FlipperPlatformWebSocket.mm @@ -181,11 +181,6 @@ static constexpr int connectionKeepaliveSeconds = 10; [_dispatchQueue cancelAllOperations]; [_dispatchQueue waitUntilAllOperationsAreFinished]; - - // Manually trigger a 'close' event as SocketRocket close method will - // not notify the delegate. SocketRocket only triggers the close event - // when the connection is closed from the server. - _eventHandler(facebook::flipper::SocketEvent::CLOSE); } - (void)send:(NSString*)message diff --git a/iOS/FlipperKit/FlipperWebSocket.h b/iOS/FlipperKit/FlipperWebSocket.h index 8231aa8a4..fd58b44bd 100644 --- a/iOS/FlipperKit/FlipperWebSocket.h +++ b/iOS/FlipperKit/FlipperWebSocket.h @@ -39,7 +39,7 @@ class FlipperWebSocket : public FlipperSocket { virtual void setEventHandler(SocketEventHandler eventHandler) override; virtual void setMessageHandler(SocketMessageHandler messageHandler) override; - virtual bool connect(FlipperConnectionManager* manager) override; + virtual void connect(FlipperConnectionManager* manager) override; virtual void disconnect() override; virtual void send(const folly::dynamic& message, SocketSendHandler completion) diff --git a/iOS/FlipperKit/FlipperWebSocket.mm b/iOS/FlipperKit/FlipperWebSocket.mm index d5dd99917..e2700e182 100644 --- a/iOS/FlipperKit/FlipperWebSocket.mm +++ b/iOS/FlipperKit/FlipperWebSocket.mm @@ -53,9 +53,9 @@ void FlipperWebSocket::setMessageHandler(SocketMessageHandler messageHandler) { messageHandler_ = std::move(messageHandler); } -bool FlipperWebSocket::connect(FlipperConnectionManager* manager) { +void FlipperWebSocket::connect(FlipperConnectionManager* manager) { if (socket_ != NULL) { - return true; + return; } std::string connectionURL = endpoint_.secure ? "wss://" : "ws://"; @@ -72,43 +72,16 @@ bool FlipperWebSocket::connect(FlipperConnectionManager* manager) { connectionURL += payload; } - __block bool fullfilled = false; - __block std::promise promise; - auto connected = promise.get_future(); - NSURL* urlObjc = [NSURL URLWithString:[NSString stringWithUTF8String:connectionURL.c_str()]]; - auto eventHandler = eventHandler_; socket_ = [[FlipperPlatformWebSocket alloc] initWithURL:urlObjc]; socket_.eventHandler = ^(SocketEvent event) { - /** - Only fulfill the promise the first time the event handler is used. If the - open event is received, then set the promise value to true. For any other - event, consider a failure and set to false. - */ - if (!fullfilled) { - fullfilled = true; - if (event == SocketEvent::OPEN) { - promise.set_value(true); - } else if (event == SocketEvent::SSL_ERROR) { - try { - promise.set_exception( - std::make_exception_ptr(SSLException("SSL handshake failed"))); - } catch (...) { - // set_exception() may throw an exception - // In that case, just set the value to false. - promise.set_value(false); - } - } else { - promise.set_value(false); - } - } - eventHandler(event); + eventHandler_(event); }; - auto messageHandler = messageHandler_; + socket_.messageHandler = ^(const std::string& message) { - messageHandler(message); + messageHandler_(message); }; if (endpoint_.secure) { @@ -124,8 +97,6 @@ bool FlipperWebSocket::connect(FlipperConnectionManager* manager) { } [socket_ connect]; - - return connected.get(); } void FlipperWebSocket::disconnect() { @@ -157,9 +128,9 @@ void FlipperWebSocket::send( } /** - Only ever used for insecure connections to receive the device_id from a - signCertificate request. If the intended usage ever changes, then a better - approach needs to be put in place. + * Only ever used for insecure connections to receive the device_id from a + * signCertificate request. If the intended usage ever changes, then a better + * approach needs to be put in place. */ void FlipperWebSocket::sendExpectResponse( const std::string& message, diff --git a/react-native/react-native-flipper/windows/ReactNativeFlipper/FlipperReactBaseSocket.h b/react-native/react-native-flipper/windows/ReactNativeFlipper/FlipperReactBaseSocket.h index 84c49c687..7ed525c03 100644 --- a/react-native/react-native-flipper/windows/ReactNativeFlipper/FlipperReactBaseSocket.h +++ b/react-native/react-native-flipper/windows/ReactNativeFlipper/FlipperReactBaseSocket.h @@ -65,7 +65,7 @@ class FlipperReactBaseSocket { messageHandler_ = std::move(messageHandler); } - virtual bool connect(FlipperConnectionManager* manager) = 0; + virtual void connect(FlipperConnectionManager* manager) = 0; virtual void disconnect() = 0; virtual void send( diff --git a/react-native/react-native-flipper/windows/ReactNativeFlipper/FlipperReactSocket.cpp b/react-native/react-native-flipper/windows/ReactNativeFlipper/FlipperReactSocket.cpp index 90ce96e64..4faf1959d 100644 --- a/react-native/react-native-flipper/windows/ReactNativeFlipper/FlipperReactSocket.cpp +++ b/react-native/react-native-flipper/windows/ReactNativeFlipper/FlipperReactSocket.cpp @@ -55,8 +55,8 @@ void FlipperReactSocket::setMessageHandler( socket_->setMessageHandler(messageHandler); } -bool FlipperReactSocket::connect(FlipperConnectionManager* manager) { - return socket_->connect(manager); +void FlipperReactSocket::connect(FlipperConnectionManager* manager) { + socket_->connect(manager); } void FlipperReactSocket::disconnect() { diff --git a/react-native/react-native-flipper/windows/ReactNativeFlipper/FlipperReactSocket.h b/react-native/react-native-flipper/windows/ReactNativeFlipper/FlipperReactSocket.h index 9f0523a03..46b3afcef 100644 --- a/react-native/react-native-flipper/windows/ReactNativeFlipper/FlipperReactSocket.h +++ b/react-native/react-native-flipper/windows/ReactNativeFlipper/FlipperReactSocket.h @@ -37,7 +37,7 @@ class FlipperReactSocket : public FlipperSocket { virtual void setEventHandler(SocketEventHandler eventHandler) override; virtual void setMessageHandler(SocketMessageHandler messageHandler) override; - virtual bool connect(FlipperConnectionManager* manager) override; + virtual void connect(FlipperConnectionManager* manager) override; virtual void disconnect() override; virtual void send(const folly::dynamic& message, SocketSendHandler completion) diff --git a/react-native/react-native-flipper/windows/ReactNativeFlipper/FlipperReactSocketClient.cpp b/react-native/react-native-flipper/windows/ReactNativeFlipper/FlipperReactSocketClient.cpp index b0ea8c107..a2a29100a 100644 --- a/react-native/react-native-flipper/windows/ReactNativeFlipper/FlipperReactSocketClient.cpp +++ b/react-native/react-native-flipper/windows/ReactNativeFlipper/FlipperReactSocketClient.cpp @@ -134,9 +134,9 @@ FlipperReactSocketClient::getClientCertificate() { return installClientCertificate(); } -bool FlipperReactSocketClient::connect(FlipperConnectionManager* manager) { +void FlipperReactSocketClient::connect(FlipperConnectionManager* manager) { if (status_ != Status::Unconnected) { - return false; + return; } status_ = Status::Connecting; @@ -176,30 +176,34 @@ bool FlipperReactSocketClient::connect(FlipperConnectionManager* manager) { socket_.Closed({this, &FlipperReactSocketClient::OnWebSocketClosed}); try { - this->socket_.ConnectAsync(winrt::Windows::Foundation::Uri(uri)) - .wait_for(std::chrono::seconds(10)); - status_ = Status::Initializing; - scheduler_->schedule( - [eventHandler = eventHandler_]() { eventHandler(SocketEvent::OPEN); }); - return true; + Windows::Foundation::IAsyncAction ^ connectAction; + connectAction = + this->socket_.ConnectAsync(winrt::Windows::Foundation::Uri(uri)); + connectAction->Completed = ref new AsyncActionCompletedHandler( + [eventHandler = eventHandler_]( + Windows::Foundation::IAsyncAction ^ asyncAction, + Windows::Foundation::AsyncStatus asyncStatus) { + if (asyncStatus == Windows::Foundation::AsyncStatus::Completed) { + eventHandler(SocketEvent::OPEN); + } else { + eventHandler(SocketEvent::ERROR); + } + }); + } catch (winrt::hresult_error const& ex) { winrt::Windows::Web::WebErrorStatus webErrorStatus{ winrt::Windows::Networking::Sockets::WebSocketError::GetStatus( ex.to_abi())}; + socket_ = nullptr; + status_ = Status::Unconnected; + eventHandler(SocketEvent::ERROR); } - - disconnect(); - - return false; } void FlipperReactSocketClient::disconnect() { status_ = Status::Closed; - scheduler_->schedule( - [eventHandler = eventHandler_]() { eventHandler(SocketEvent::CLOSE); }); - // socket_.Close(); socket_ = nullptr; } @@ -269,14 +273,10 @@ void FlipperReactSocketClient::OnWebSocketMessageReceived( const std::string payload = winrt::to_string(message); if (overrideHandler_ != nullptr) { - scheduler_->schedule([payload, messageHandler = *overrideHandler_]() { - messageHandler(payload, false); - }); + messageHandler(payload, false); overrideHandler_ = nullptr; } else if (messageHandler_) { - scheduler_->schedule([payload, messageHandler = messageHandler_]() { - messageHandler(payload); - }); + messageHandler(payload); } } catch (winrt::hresult_error const& ex) { // winrt::Windows::Web::WebErrorStatus webErrorStatus{ @@ -291,8 +291,7 @@ void FlipperReactSocketClient::OnWebSocketClosed( return; } status_ = Status::Closed; - scheduler_->schedule( - [eventHandler = eventHandler_]() { eventHandler(SocketEvent::CLOSE); }); + eventHandler(SocketEvent::CLOSE); } } // namespace flipper diff --git a/react-native/react-native-flipper/windows/ReactNativeFlipper/FlipperReactSocketClient.h b/react-native/react-native-flipper/windows/ReactNativeFlipper/FlipperReactSocketClient.h index 44187aada..65c1ee3ab 100644 --- a/react-native/react-native-flipper/windows/ReactNativeFlipper/FlipperReactSocketClient.h +++ b/react-native/react-native-flipper/windows/ReactNativeFlipper/FlipperReactSocketClient.h @@ -40,7 +40,7 @@ class FlipperReactSocketClient : public FlipperReactBaseSocket { virtual ~FlipperReactSocketClient(); - virtual bool connect(FlipperConnectionManager* manager) override; + virtual void connect(FlipperConnectionManager* manager) override; virtual void disconnect() override; virtual void send(const folly::dynamic& message, SocketSendHandler completion) @@ -61,7 +61,6 @@ class FlipperReactSocketClient : public FlipperReactBaseSocket { args); private: - std::promise connected_; winrt::Windows::Networking::Sockets::MessageWebSocket socket_; winrt::event_token messageReceivedEventToken_; winrt::event_token closedEventToken_; diff --git a/xplat/Flipper/ConnectionContextStore.cpp b/xplat/Flipper/ConnectionContextStore.cpp index 806261281..350a9be89 100644 --- a/xplat/Flipper/ConnectionContextStore.cpp +++ b/xplat/Flipper/ConnectionContextStore.cpp @@ -48,7 +48,8 @@ bool ConnectionContextStore::hasRequiredFiles() { std::string config = loadStringFromFile(absoluteFilePath(CONNECTION_CONFIG_FILE)); - if (caCert == "" || clientCert == "" || privateKey == "" || config == "") { + if (caCert.empty() || clientCert.empty() || privateKey.empty() || + config.empty()) { return false; } return true; @@ -56,14 +57,14 @@ bool ConnectionContextStore::hasRequiredFiles() { std::string ConnectionContextStore::getCertificateSigningRequest() { // Use in-memory CSR if already loaded - if (csr != "") { - return csr; + if (!csr_.empty()) { + return csr_; } // Attempt to load existing CSR from previous run of the app - csr = loadStringFromFile(absoluteFilePath(CSR_FILE_NAME)); - if (csr != "") { - return csr; + csr_ = loadStringFromFile(absoluteFilePath(CSR_FILE_NAME)); + if (!csr_.empty()) { + return csr_; } // Clean all state and generate a new one @@ -75,9 +76,9 @@ std::string ConnectionContextStore::getCertificateSigningRequest() { if (!success) { throw new std::runtime_error("Failed to generate CSR"); } - csr = loadStringFromFile(absoluteFilePath(CSR_FILE_NAME)); + csr_ = loadStringFromFile(absoluteFilePath(CSR_FILE_NAME)); - return csr; + return csr_; } std::string ConnectionContextStore::getDeviceId() { @@ -124,7 +125,8 @@ void ConnectionContextStore::storeConnectionConfig(folly::dynamic& config) { writeStringToFile(json, absoluteFilePath(CONNECTION_CONFIG_FILE)); } -std::string ConnectionContextStore::absoluteFilePath(const char* filename) { +std::string ConnectionContextStore::absoluteFilePath( + const char* filename) const { #ifndef WIN32 return std::string(deviceData_.privateAppDirectory + "/sonar/" + filename); #else @@ -159,7 +161,7 @@ std::string ConnectionContextStore::getPath(StoreItem storeItem) { bool ConnectionContextStore::resetState() { // Clear in-memory state - csr = ""; + csr_ = ""; // Delete state from disk std::string dirPath = absoluteFilePath(""); @@ -208,6 +210,18 @@ std::pair ConnectionContextStore::getCertificate() { return std::make_pair(certificate_path, std::string(CERTIFICATE_PASSWORD)); } +bool ConnectionContextStore::hasCertificateSigningRequest() const { + std::string csr = loadStringFromFile(absoluteFilePath(CSR_FILE_NAME)); + return !csr.empty(); +} + +bool ConnectionContextStore::hasClientCertificate() const { + std::string clientCertificate = + loadStringFromFile(absoluteFilePath(CLIENT_CERT_FILE_NAME)); + + return !clientCertificate.empty(); +} + std::string loadStringFromFile(std::string fileName) { if (!fileExists(fileName)) { return ""; diff --git a/xplat/Flipper/ConnectionContextStore.h b/xplat/Flipper/ConnectionContextStore.h index b1e366bce..a10363da3 100644 --- a/xplat/Flipper/ConnectionContextStore.h +++ b/xplat/Flipper/ConnectionContextStore.h @@ -57,11 +57,18 @@ class ConnectionContextStore { */ std::pair getCertificate(); + /** Is there a CSR present. + */ + bool hasCertificateSigningRequest() const; + /** Is there a client certificate present. + */ + bool hasClientCertificate() const; + private: DeviceData deviceData_; - std::string csr = ""; + std::string csr_ = ""; - std::string absoluteFilePath(const char* filename); + std::string absoluteFilePath(const char* filename) const; }; } // namespace flipper diff --git a/xplat/Flipper/FlipperConnectionManagerImpl.cpp b/xplat/Flipper/FlipperConnectionManagerImpl.cpp index d689c43ee..53adf63f7 100644 --- a/xplat/Flipper/FlipperConnectionManagerImpl.cpp +++ b/xplat/Flipper/FlipperConnectionManagerImpl.cpp @@ -20,12 +20,12 @@ #define WRONG_THREAD_EXIT_MSG \ "ERROR: Aborting flipper initialization because it's not running in the flipper thread." -static constexpr int reconnectIntervalSeconds = 2; +static constexpr int RECONNECT_INTERVAL_SECONDS = 3; // Not a public-facing version number. // Used for compatibility checking with desktop flipper. // To be bumped for every core platform interface change. -static constexpr int sdkVersion = 4; +static constexpr int SDK_VERSION = 4; using namespace folly; @@ -66,14 +66,14 @@ FlipperConnectionManagerImpl::FlipperConnectionManagerImpl( std::shared_ptr state, std::shared_ptr contextStore) : deviceData_(config.deviceData), - flipperState_(state), + state_(state), insecurePort(config.insecurePort), securePort(config.securePort), altInsecurePort(config.altInsecurePort), altSecurePort(config.altSecurePort), - flipperScheduler_(config.callbackWorker), + scheduler_(config.callbackWorker), connectionScheduler_(config.connectionWorker), - contextStore_(contextStore), + store_(contextStore), implWrapper_(std::make_shared(this)) { CHECK_THROW(config.callbackWorker, std::invalid_argument); CHECK_THROW(config.connectionWorker, std::invalid_argument); @@ -85,39 +85,52 @@ FlipperConnectionManagerImpl::~FlipperConnectionManagerImpl() { void FlipperConnectionManagerImpl::setCertificateProvider( const std::shared_ptr provider) { - certProvider_ = provider; + certificateProvider_ = provider; }; std::shared_ptr FlipperConnectionManagerImpl::getCertificateProvider() { - return certProvider_; + return certificateProvider_; } void FlipperConnectionManagerImpl::handleSocketEvent(SocketEvent event) { - switch (event) { - case SocketEvent::OPEN: - isConnected_ = true; - if (connectionIsTrusted_) { - callbacks_->onConnected(); - } - break; - case SocketEvent::SSL_ERROR: - // SSL errors are not handled as a connection event - // on this handler. - break; - case SocketEvent::CLOSE: - case SocketEvent::ERROR: - if (!isConnected_) { - return; - } - isConnected_ = false; - if (connectionIsTrusted_) { - connectionIsTrusted_ = false; - callbacks_->onDisconnected(); - } - reconnect(); - break; - } + // Ensure that the event is handled on the correct thread i.e. scheduler. + scheduler_->schedule([this, event]() { + switch (event) { + case SocketEvent::OPEN: + isConnected_ = true; + if (isConnectionTrusted_) { + failedConnectionAttempts_ = 0; + callbacks_->onConnected(); + } else { + requestSignedCertificate(); + } + break; + case SocketEvent::SSL_ERROR: + log("[conn] handleSocketEvent(SSL_ERROR)"); + failedConnectionAttempts_++; + reconnect(); + break; + case SocketEvent::CLOSE: + case SocketEvent::ERROR: + log("[conn] handleSocketEvent(CLOSE_ERROR)"); + if (!isConnected_) { + reconnect(); + return; + } + + failedConnectionAttempts_++; + isConnected_ = false; + + if (isConnectionTrusted_) { + isConnectionTrusted_ = false; + callbacks_->onDisconnected(); + } + + reconnect(); + break; + } + }); } void FlipperConnectionManagerImpl::start() { @@ -126,22 +139,22 @@ void FlipperConnectionManagerImpl::start() { return; } - if (isStarted_) { + if (started_) { log("Already started"); return; } - isStarted_ = true; + started_ = true; - auto step = flipperState_->start("Start connection thread"); + auto step = state_->start("Start connection thread"); - flipperScheduler_->schedule([this, step]() { + scheduler_->schedule([this, step]() { step->complete(); startSync(); }); } void FlipperConnectionManagerImpl::startSync() { - if (!isStarted_) { + if (!started_) { log("Not started"); return; } @@ -153,52 +166,28 @@ void FlipperConnectionManagerImpl::startSync() { log("Already connected"); return; } + + socket_ = nullptr; + bool isClientSetupStep = isCertificateExchangeNeeded(); - auto step = flipperState_->start( - isClientSetupStep ? "Establish pre-setup connection" + auto step = state_->start( + isClientSetupStep ? "Establish certificate exchange connection" : "Establish main connection"); - try { - if (isClientSetupStep) { - bool success = connectAndExchangeCertificate(); - if (!success) { - reconnect(); - return; - } - } else { - if (!connectSecurely()) { - // The expected code path when flipper desktop is not running. - // Don't count as a failed attempt, or it would invalidate the - // connection files for no reason. On iOS devices, we can always connect - // to the local port forwarding server even when it can't connect to - // flipper. In that case we get a Network error instead of a Port not - // open error, so we treat them the same. - step->fail( - "No route to flipper found. Is flipper desktop running? Retrying..."); - reconnect(); - } - } - step->complete(); - } catch (const SSLException& e) { - auto message = std::string(e.what()) + - "\nMake sure the date and time of your device is up to date."; - log(message); - step->fail(message); - failedConnectionAttempts_++; - reconnect(); - } catch (const std::exception& e) { - log(e.what()); - step->fail(e.what()); - failedConnectionAttempts_++; - reconnect(); + if (isClientSetupStep) { + connectAndExchangeCertificate(); + } else { + connectSecurely(); } + step->complete(); } -bool FlipperConnectionManagerImpl::connectAndExchangeCertificate() { +void FlipperConnectionManagerImpl::connectAndExchangeCertificate() { + log("[conn] connectAndExchangeCertificate()"); auto port = insecurePort; auto endpoint = FlipperConnectionEndpoint(deviceData_.host, port, false); - int medium = certProvider_ != nullptr - ? certProvider_->getCertificateExchangeMedium() + int medium = certificateProvider_ != nullptr + ? certificateProvider_->getCertificateExchangeMedium() : FlipperCertificateExchangeMedium::FS_ACCESS; auto payload = std::make_unique(); @@ -206,47 +195,31 @@ bool FlipperConnectionManagerImpl::connectAndExchangeCertificate() { payload->device = deviceData_.device; payload->device_id = "unknown"; payload->app = deviceData_.app; - payload->sdk_version = sdkVersion; + payload->sdk_version = SDK_VERSION; payload->medium = medium; - client_ = FlipperSocketProvider::socketCreate( - endpoint, std::move(payload), flipperScheduler_); - client_->setEventHandler(ConnectionEvents(implWrapper_)); + socket_ = FlipperSocketProvider::socketCreate( + endpoint, std::move(payload), scheduler_); + socket_->setEventHandler(ConnectionEvents(implWrapper_)); - connectionIsTrusted_ = false; - - auto step = - flipperState_->start("Attempt to connect for certificate exchange"); + isConnectionTrusted_ = false; + auto step = state_->start("Attempt to connect for certificate exchange"); step->complete(); - // NON-TLS: - // On failure: clear the client. - // On success: proceed to request the client certificate. - - // Connect is just handled here, move this elsewhere. - if (!client_->connect(this)) { - client_ = nullptr; - return false; - } - - requestSignedCertificate(); - - return true; + socket_->connect(this); } -bool FlipperConnectionManagerImpl::connectSecurely() { - client_ = nullptr; - +void FlipperConnectionManagerImpl::connectSecurely() { auto port = securePort; auto endpoint = FlipperConnectionEndpoint(deviceData_.host, port, true); - int medium = certProvider_ != nullptr - ? certProvider_->getCertificateExchangeMedium() + int medium = certificateProvider_ != nullptr + ? certificateProvider_->getCertificateExchangeMedium() : FlipperCertificateExchangeMedium::FS_ACCESS; - auto loadingDeviceId = flipperState_->start("Load Device Id"); - auto deviceId = contextStore_->getDeviceId(); + auto loadingDeviceId = state_->start("Load Device Id"); + auto deviceId = store_->getDeviceId(); if (deviceId.compare("unknown")) { loadingDeviceId->complete(); } @@ -256,15 +229,15 @@ bool FlipperConnectionManagerImpl::connectSecurely() { payload->device = deviceData_.device; payload->device_id = deviceId; payload->app = deviceData_.app; - payload->sdk_version = sdkVersion; + payload->sdk_version = SDK_VERSION; payload->medium = medium; - payload->csr = contextStore_->getCertificateSigningRequest().c_str(); - payload->csr_path = contextStore_->getCertificateDirectoryPath().c_str(); + payload->csr = store_->getCertificateSigningRequest().c_str(); + payload->csr_path = store_->getCertificateDirectoryPath().c_str(); - client_ = FlipperSocketProvider::socketCreate( - endpoint, std::move(payload), connectionScheduler_, contextStore_.get()); - client_->setEventHandler(ConnectionEvents(implWrapper_)); - client_->setMessageHandler([this](const std::string& msg) { + socket_ = FlipperSocketProvider::socketCreate( + endpoint, std::move(payload), connectionScheduler_, store_.get()); + socket_->setEventHandler(ConnectionEvents(implWrapper_)); + socket_->setMessageHandler([this](const std::string& msg) { std::unique_ptr responder; auto message = folly::parseJson(msg); auto idItr = message.find("id"); @@ -278,54 +251,41 @@ bool FlipperConnectionManagerImpl::connectSecurely() { this->onMessageReceived(folly::parseJson(msg), std::move(responder)); }); - connectionIsTrusted_ = true; - - auto step = flipperState_->start( - "Attempt to connect with existing client certificate"); + isConnectionTrusted_ = true; + auto step = + state_->start("Attempt to connect with existing client certificate"); step->complete(); - // TLS: - // On failure: clear the client. - // On success: clear number of failed attempts. - - // Connect is just handled here, move this elsewhere. - if (!client_->connect(this)) { - client_ = nullptr; - return false; - } - - failedConnectionAttempts_ = 0; - return true; + socket_->connect(this); } void FlipperConnectionManagerImpl::reconnect() { - if (!isStarted_) { + if (!started_) { log("Not started"); return; } - flipperScheduler_->scheduleAfter( - [this]() { startSync(); }, reconnectIntervalSeconds * 1000.0f); + log("[conn] reconnect()"); + scheduler_->scheduleAfter( + [this]() { startSync(); }, RECONNECT_INTERVAL_SECONDS * 1000.0f); } void FlipperConnectionManagerImpl::stop() { - if (certProvider_ && certProvider_->shouldResetCertificateFolder()) { - contextStore_->resetState(); + if (certificateProvider_ && + certificateProvider_->shouldResetCertificateFolder()) { + store_->resetState(); } - if (!isStarted_) { + if (!started_) { log("Not started"); return; } - isStarted_ = false; + started_ = false; std::shared_ptr> joinPromise = std::make_shared>(); std::future join = joinPromise->get_future(); - flipperScheduler_->schedule([this, joinPromise]() { - if (client_) { - client_->disconnect(); - } - client_ = nullptr; + scheduler_->schedule([this, joinPromise]() { + socket_ = nullptr; joinPromise->set_value(); }); @@ -333,7 +293,7 @@ void FlipperConnectionManagerImpl::stop() { } bool FlipperConnectionManagerImpl::isConnected() const { - return isConnected_ && connectionIsTrusted_; + return isConnected_ && isConnectionTrusted_; } void FlipperConnectionManagerImpl::setCallbacks(Callbacks* callbacks) { @@ -341,10 +301,10 @@ void FlipperConnectionManagerImpl::setCallbacks(Callbacks* callbacks) { } void FlipperConnectionManagerImpl::sendMessage(const folly::dynamic& message) { - flipperScheduler_->schedule([this, message]() { + scheduler_->schedule([this, message]() { try { - if (client_) { - client_->send(message, []() {}); + if (socket_) { + socket_->send(message, []() {}); } } catch (std::length_error& e) { // Skip sending messages that are too large. @@ -355,10 +315,10 @@ void FlipperConnectionManagerImpl::sendMessage(const folly::dynamic& message) { } void FlipperConnectionManagerImpl::sendMessageRaw(const std::string& message) { - flipperScheduler_->schedule([this, message]() { + scheduler_->schedule([this, message]() { try { - if (client_) { - client_->send(message, []() {}); + if (socket_) { + socket_->send(message, []() {}); } } catch (std::length_error& e) { // Skip sending messages that are too large. @@ -379,7 +339,7 @@ bool FlipperConnectionManagerImpl::isCertificateExchangeNeeded() { return true; } - auto last_known_medium = contextStore_->getLastKnownMedium(); + auto last_known_medium = store_->getLastKnownMedium(); if (!last_known_medium) { return true; } @@ -387,15 +347,15 @@ bool FlipperConnectionManagerImpl::isCertificateExchangeNeeded() { // When we exchange certs over WWW, we use a fake generated serial number and // a virtual device. If medium changes to FS_ACCESS at some point, we should // restart the exchange process to get the device ID of the real device. - int medium = certProvider_ != nullptr - ? certProvider_->getCertificateExchangeMedium() + int medium = certificateProvider_ != nullptr + ? certificateProvider_->getCertificateExchangeMedium() : FlipperCertificateExchangeMedium::FS_ACCESS; if (last_known_medium != medium) { return true; } - auto step = flipperState_->start("Check required certificates are present"); - bool hasRequiredFiles = contextStore_->hasRequiredFiles(); + auto step = state_->start("Check required certificates are present"); + bool hasRequiredFiles = store_->hasRequiredFiles(); if (hasRequiredFiles) { step->complete(); } @@ -406,109 +366,88 @@ void FlipperConnectionManagerImpl::processSignedCertificateResponse( std::shared_ptr gettingCert, std::string response, bool isError) { - /** - Need to keep track of whether the response has been - handled. On success, the completion handler deallocates the socket which in - turn triggers a disconnect. A disconnect is called within - the context of a subscription handler. This means that the completion - handler can be called again to notify that the stream has - been interrupted because we are effectively still handing the response - read. So, if already handled, ignore and return; - */ - if (certificateExchangeCompleted_) - return; - certificateExchangeCompleted_ = true; if (isError) { auto error = - "Desktop failed to provide certificates. Error from flipper desktop:\n" + + "Flipper failed to provide certificates. Error from Flipper Desktop:\n" + response; log(error); gettingCert->fail(error); - client_ = nullptr; - return; - } - int medium = certProvider_ != nullptr - ? certProvider_->getCertificateExchangeMedium() - : FlipperCertificateExchangeMedium::FS_ACCESS; - if (!response.empty()) { - folly::dynamic config = folly::parseJson(response); - config["medium"] = medium; - contextStore_->storeConnectionConfig(config); - } - if (certProvider_) { - certProvider_->setFlipperState(flipperState_); - auto gettingCertFromProvider = - flipperState_->start("Getting cert from Cert Provider"); + } else { + int medium = certificateProvider_ != nullptr + ? certificateProvider_->getCertificateExchangeMedium() + : FlipperCertificateExchangeMedium::FS_ACCESS; - try { - // Certificates should be present in app's sandbox after it is - // returned. The reason we can't have a completion block here - // is because if the certs are not present after it returns - // then the flipper tries to reconnect on insecured channel - // and recreates the app.csr. By the time completion block is - // called the DeviceCA cert doesn't match app's csr and it - // throws an SSL error. - certProvider_->getCertificates( - contextStore_->getCertificateDirectoryPath(), - contextStore_->getDeviceId()); - gettingCertFromProvider->complete(); - } catch (std::exception& e) { - gettingCertFromProvider->fail(e.what()); - gettingCert->fail(e.what()); - } catch (...) { - gettingCertFromProvider->fail("Exception from certProvider"); - gettingCert->fail("Exception from certProvider"); + if (!response.empty()) { + folly::dynamic config = folly::parseJson(response); + config["medium"] = medium; + store_->storeConnectionConfig(config); } - } - log("Certificate exchange complete."); - gettingCert->complete(); + if (certificateProvider_) { + certificateProvider_->setFlipperState(state_); + auto gettingCertFromProvider = + state_->start("Getting client certificate from Certificate Provider"); - // Disconnect after message sending is complete. - // The client destructor will send a disconnected event - // which will be handled by Flipper which will initiate - // a reconnect sequence. - client_ = nullptr; + try { + // Certificates should be present in app's sandbox after it is + // returned. The reason we can't have a completion block here + // is because if the certs are not present after it returns + // then the flipper tries to reconnect on insecured channel + // and recreates the app.csr. By the time completion block is + // called the DeviceCA cert doesn't match app's csr and it + // throws an SSL error. + certificateProvider_->getCertificates( + store_->getCertificateDirectoryPath(), store_->getDeviceId()); + gettingCertFromProvider->complete(); + } catch (std::exception& e) { + gettingCertFromProvider->fail(e.what()); + gettingCert->fail(e.what()); + } catch (...) { + gettingCertFromProvider->fail( + "Exception thrown from Certificate Provider"); + gettingCert->fail("Exception thrown from Certificate Provider"); + } + } + log("Certificate exchange complete."); + gettingCert->complete(); + } + + socket_ = nullptr; + reconnect(); } void FlipperConnectionManagerImpl::requestSignedCertificate() { - auto resettingState = flipperState_->start("Reset connection store state"); - contextStore_->resetState(); + auto resettingState = state_->start("Reset connection store state"); + store_->resetState(); resettingState->complete(); - auto generatingCSR = flipperState_->start("Generate CSR"); - std::string csr = contextStore_->getCertificateSigningRequest(); + auto generatingCSR = state_->start("Generate CSR"); + std::string csr = store_->getCertificateSigningRequest(); generatingCSR->complete(); - int medium = certProvider_ != nullptr - ? certProvider_->getCertificateExchangeMedium() + int medium = certificateProvider_ != nullptr + ? certificateProvider_->getCertificateExchangeMedium() : FlipperCertificateExchangeMedium::FS_ACCESS; - folly::dynamic message = folly::dynamic::object("method", "signCertificate")( - "csr", csr.c_str())( - "destination", - contextStore_->getCertificateDirectoryPath().c_str())("medium", medium); + folly::dynamic message = + folly::dynamic::object("method", "signCertificate")("csr", csr.c_str())( + "destination", + store_->getCertificateDirectoryPath().c_str())("medium", medium); - auto gettingCert = flipperState_->start("Getting cert from desktop"); + auto gettingCert = state_->start("Getting cert from desktop"); - certificateExchangeCompleted_ = false; - flipperScheduler_->schedule([this, message, gettingCert]() { - if (!client_) { - return; - } - client_->sendExpectResponse( - folly::toJson(message), - [this, gettingCert](const std::string& response, bool isError) { - flipperScheduler_->schedule([this, gettingCert, response, isError]() { - this->processSignedCertificateResponse( - gettingCert, response, isError); - }); + socket_->sendExpectResponse( + folly::toJson(message), + [this, gettingCert](const std::string& response, bool isError) { + scheduler_->schedule([this, gettingCert, response, isError]() { + this->processSignedCertificateResponse( + gettingCert, response, isError); }); - }); + }); failedConnectionAttempts_ = 0; } bool FlipperConnectionManagerImpl::isRunningInOwnThread() { - return flipperScheduler_->isRunningInOwnThread(); + return scheduler_->isRunningInOwnThread(); } } // namespace flipper diff --git a/xplat/Flipper/FlipperConnectionManagerImpl.h b/xplat/Flipper/FlipperConnectionManagerImpl.h index 5e79a3014..60247107a 100644 --- a/xplat/Flipper/FlipperConnectionManagerImpl.h +++ b/xplat/Flipper/FlipperConnectionManagerImpl.h @@ -55,33 +55,35 @@ class FlipperConnectionManagerImpl : public FlipperConnectionManager { private: bool isConnected_ = false; - bool isStarted_ = false; - std::shared_ptr certProvider_ = nullptr; + bool started_ = false; + bool isConnectionTrusted_ = false; + + std::shared_ptr certificateProvider_ = nullptr; + Callbacks* callbacks_; + DeviceData deviceData_; - std::shared_ptr flipperState_; + + std::shared_ptr state_; + int insecurePort; int securePort; int altInsecurePort; int altSecurePort; - Scheduler* flipperScheduler_; + Scheduler* scheduler_; Scheduler* connectionScheduler_; - std::unique_ptr client_; - - bool connectionIsTrusted_; - bool certificateExchangeCompleted_ = false; + std::unique_ptr socket_; int failedConnectionAttempts_ = 0; - int failedSocketConnectionAttempts = 0; - std::shared_ptr contextStore_; + std::shared_ptr store_; std::shared_ptr implWrapper_; void startSync(); - bool connectAndExchangeCertificate(); - bool connectSecurely(); + void connectAndExchangeCertificate(); + void connectSecurely(); void handleSocketEvent(const SocketEvent event); bool isCertificateExchangeNeeded(); void requestSignedCertificate(); diff --git a/xplat/Flipper/FlipperSocket.h b/xplat/Flipper/FlipperSocket.h index 0692e708d..51d9c69df 100644 --- a/xplat/Flipper/FlipperSocket.h +++ b/xplat/Flipper/FlipperSocket.h @@ -37,7 +37,7 @@ class FlipperSocket { used or error. @param manager An instance of FlipperConnectionManager. */ - virtual bool connect(FlipperConnectionManager* manager) = 0; + virtual void connect(FlipperConnectionManager* manager) = 0; /** Disconnect from the endpoint. */ diff --git a/xplat/FlipperWebSocket/BaseClient.h b/xplat/FlipperWebSocket/BaseClient.h index 053987e88..b9e1e55bc 100644 --- a/xplat/FlipperWebSocket/BaseClient.h +++ b/xplat/FlipperWebSocket/BaseClient.h @@ -68,7 +68,7 @@ class BaseClient { messageHandler_ = std::move(messageHandler); } - virtual bool connect(FlipperConnectionManager* manager) = 0; + virtual void connect(FlipperConnectionManager* manager) = 0; virtual void disconnect() = 0; virtual void send( diff --git a/xplat/FlipperWebSocket/FlipperWebSocket.cpp b/xplat/FlipperWebSocket/FlipperWebSocket.cpp index b01dd5618..48754aa4c 100644 --- a/xplat/FlipperWebSocket/FlipperWebSocket.cpp +++ b/xplat/FlipperWebSocket/FlipperWebSocket.cpp @@ -60,8 +60,8 @@ void FlipperWebSocket::setMessageHandler(SocketMessageHandler messageHandler) { socket_->setMessageHandler(messageHandler); } -bool FlipperWebSocket::connect(FlipperConnectionManager* manager) { - return socket_->connect(manager); +void FlipperWebSocket::connect(FlipperConnectionManager* manager) { + socket_->connect(manager); } void FlipperWebSocket::disconnect() { diff --git a/xplat/FlipperWebSocket/FlipperWebSocket.h b/xplat/FlipperWebSocket/FlipperWebSocket.h index 700c940bb..b42f6d75b 100644 --- a/xplat/FlipperWebSocket/FlipperWebSocket.h +++ b/xplat/FlipperWebSocket/FlipperWebSocket.h @@ -41,7 +41,7 @@ class FlipperWebSocket : public FlipperSocket { virtual void setEventHandler(SocketEventHandler eventHandler) override; virtual void setMessageHandler(SocketMessageHandler messageHandler) override; - virtual bool connect(FlipperConnectionManager* manager) override; + virtual void connect(FlipperConnectionManager* manager) override; virtual void disconnect() override; virtual void send(const folly::dynamic& message, SocketSendHandler completion) diff --git a/xplat/FlipperWebSocket/WebSocketClient.cpp b/xplat/FlipperWebSocket/WebSocketClient.cpp index f50c788c1..2f628c635 100644 --- a/xplat/FlipperWebSocket/WebSocketClient.cpp +++ b/xplat/FlipperWebSocket/WebSocketClient.cpp @@ -62,9 +62,9 @@ WebSocketClient::~WebSocketClient() { disconnect(); } -bool WebSocketClient::connect(FlipperConnectionManager* manager) { +void WebSocketClient::connect(FlipperConnectionManager*) { if (status_ != Status::Unconnected) { - return false; + return; } status_ = Status::Connecting; @@ -89,7 +89,8 @@ bool WebSocketClient::connect(FlipperConnectionManager* manager) { if (ec) { status_ = Status::Failed; - return false; + eventHandler_(SocketEvent::ERROR); + return; } handle_ = connection_->get_handle(); @@ -119,18 +120,7 @@ bool WebSocketClient::connect(FlipperConnectionManager* manager) { &socket_, websocketpp::lib::placeholders::_1)); - auto connected = connected_.get_future(); - socket_.connect(connection_); - - auto state = connected.wait_for(std::chrono::seconds(10)); - if (state == std::future_status::ready) { - return connected.get(); - } - - disconnect(); - - return false; } void WebSocketClient::disconnect() { @@ -147,8 +137,6 @@ void WebSocketClient::disconnect() { thread_->join(); } thread_ = nullptr; - scheduler_->schedule( - [eventHandler = eventHandler_]() { eventHandler(SocketEvent::CLOSE); }); } void WebSocketClient::send( @@ -204,8 +192,7 @@ void WebSocketClient::onOpen(SocketClient* c, websocketpp::connection_hdl hdl) { } status_ = Status::Initializing; - scheduler_->schedule( - [eventHandler = eventHandler_]() { eventHandler(SocketEvent::OPEN); }); + eventHandler_(SocketEvent::OPEN); } void WebSocketClient::onMessage( @@ -229,16 +216,14 @@ void WebSocketClient::onFail(SocketClient* c, websocketpp::connection_hdl hdl) { connected_.set_value(false); } status_ = Status::Failed; - scheduler_->schedule( - [eventHandler = eventHandler_]() { eventHandler(SocketEvent::ERROR); }); + eventHandler_(SocketEvent::ERROR); } void WebSocketClient::onClose( SocketClient* c, websocketpp::connection_hdl hdl) { status_ = Status::Closed; - scheduler_->schedule( - [eventHandler = eventHandler_]() { eventHandler(SocketEvent::CLOSE); }); + eventHandler_(SocketEvent::CLOSE); } } // namespace flipper diff --git a/xplat/FlipperWebSocket/WebSocketClient.h b/xplat/FlipperWebSocket/WebSocketClient.h index 47331d7ec..6619a89a8 100644 --- a/xplat/FlipperWebSocket/WebSocketClient.h +++ b/xplat/FlipperWebSocket/WebSocketClient.h @@ -47,7 +47,7 @@ class WebSocketClient : public BaseClient { virtual ~WebSocketClient(); - virtual bool connect(FlipperConnectionManager* manager) override; + virtual void connect(FlipperConnectionManager* manager) override; virtual void disconnect() override; virtual void send(const folly::dynamic& message, SocketSendHandler completion) diff --git a/xplat/FlipperWebSocket/WebSocketTLSClient.cpp b/xplat/FlipperWebSocket/WebSocketTLSClient.cpp index 24fa9bb49..6d1c8e227 100644 --- a/xplat/FlipperWebSocket/WebSocketTLSClient.cpp +++ b/xplat/FlipperWebSocket/WebSocketTLSClient.cpp @@ -65,9 +65,9 @@ WebSocketTLSClient::~WebSocketTLSClient() { disconnect(); } -bool WebSocketTLSClient::connect(FlipperConnectionManager* manager) { +void WebSocketTLSClient::connect(FlipperConnectionManager*) { if (status_ != Status::Unconnected) { - return false; + return; } status_ = Status::Connecting; @@ -98,7 +98,8 @@ bool WebSocketTLSClient::connect(FlipperConnectionManager* manager) { if (ec) { status_ = Status::Failed; - return false; + eventHandler_(SocketEvent::ERROR); + return; } handle_ = connection_->get_handle(); @@ -128,18 +129,7 @@ bool WebSocketTLSClient::connect(FlipperConnectionManager* manager) { &socket_, websocketpp::lib::placeholders::_1)); - auto connected = connected_.get_future(); - socket_.connect(connection_); - - auto state = connected.wait_for(std::chrono::seconds(10)); - if (state == std::future_status::ready) { - return connected.get(); - } - - disconnect(); - - return false; } void WebSocketTLSClient::disconnect() { @@ -157,8 +147,6 @@ void WebSocketTLSClient::disconnect() { } thread_ = nullptr; - scheduler_->schedule( - [eventHandler = eventHandler_]() { eventHandler(SocketEvent::CLOSE); }); } void WebSocketTLSClient::send( @@ -211,13 +199,8 @@ void WebSocketTLSClient::sendExpectResponse( void WebSocketTLSClient::onOpen( SocketTLSClient* c, websocketpp::connection_hdl hdl) { - if (status_ == Status::Connecting) { - connected_.set_value(true); - } - status_ = Status::Initializing; - scheduler_->schedule( - [eventHandler = eventHandler_]() { eventHandler(SocketEvent::OPEN); }); + eventHandler_(SocketEvent::OPEN); } void WebSocketTLSClient::onMessage( @@ -242,36 +225,19 @@ void WebSocketTLSClient::onFail( (reason.find("TLS handshake failed") != std::string::npos || reason.find("Generic TLS related error") != std::string::npos); - if (status_ == Status::Connecting) { - if (sslError) { - try { - connected_.set_exception( - std::make_exception_ptr(SSLException("SSL handshake failed"))); - } catch (...) { - // set_exception() may throw an exception - // In that case, just set the value to false. - connected_.set_value(false); - } - } else { - connected_.set_value(false); - } - } status_ = Status::Failed; - scheduler_->schedule([eventHandler = eventHandler_, sslError]() { - if (sslError) { - eventHandler(SocketEvent::SSL_ERROR); - } else { - eventHandler(SocketEvent::ERROR); - } - }); + if (sslError) { + eventHandler_(SocketEvent::SSL_ERROR); + } else { + eventHandler_(SocketEvent::ERROR); + } } void WebSocketTLSClient::onClose( SocketTLSClient* c, websocketpp::connection_hdl hdl) { status_ = Status::Closed; - scheduler_->schedule( - [eventHandler = eventHandler_]() { eventHandler(SocketEvent::CLOSE); }); + eventHandler_(SocketEvent::CLOSE); } SocketTLSContext WebSocketTLSClient::onTLSInit( diff --git a/xplat/FlipperWebSocket/WebSocketTLSClient.h b/xplat/FlipperWebSocket/WebSocketTLSClient.h index 398037973..d5072f98a 100644 --- a/xplat/FlipperWebSocket/WebSocketTLSClient.h +++ b/xplat/FlipperWebSocket/WebSocketTLSClient.h @@ -50,7 +50,7 @@ class WebSocketTLSClient : public BaseClient { virtual ~WebSocketTLSClient(); - virtual bool connect(FlipperConnectionManager* manager) override; + virtual void connect(FlipperConnectionManager* manager) override; virtual void disconnect() override; virtual void send(const folly::dynamic& message, SocketSendHandler completion) @@ -76,7 +76,6 @@ class WebSocketTLSClient : public BaseClient { SocketTLSThread thread_; websocketpp::connection_hdl handle_; - std::promise connected_; }; } // namespace flipper