diff --git a/iOS/FlipperKit/FlipperPlatformWebSocket.mm b/iOS/FlipperKit/FlipperPlatformWebSocket.mm index 1ec55c0c1..f8787fbe5 100644 --- a/iOS/FlipperKit/FlipperPlatformWebSocket.mm +++ b/iOS/FlipperKit/FlipperPlatformWebSocket.mm @@ -8,12 +8,9 @@ #ifdef FB_SONARKIT_ENABLED #import "FlipperPlatformWebSocket.h" +#import #import #import -#include -#include -#include -#include static constexpr int connectionKeepaliveSeconds = 10; @@ -152,52 +149,8 @@ static constexpr int connectionKeepaliveSeconds = 10; // there is a process listening at the specified port. // CFNetwork seems to be quite verbose when the host cannot be reached // causing unnecessary and annoying logs to be printed to the console. - struct addrinfo hints; - - memset(&hints, 0, sizeof(hints)); - hints.ai_family = AF_UNSPEC; - hints.ai_socktype = SOCK_STREAM; - hints.ai_flags = AI_PASSIVE; - struct addrinfo* address; - getaddrinfo( - strongSelf->_url.host.UTF8String, - strongSelf->_url.port.stringValue.UTF8String, - &hints, - &address); - - int sfd = - socket(address->ai_family, address->ai_socktype, address->ai_protocol); - - fcntl(sfd, F_SETFL, O_NONBLOCK); - connect(sfd, address->ai_addr, address->ai_addrlen); - - fd_set fdset; - struct timeval tv; - - FD_ZERO(&fdset); - FD_SET(sfd, &fdset); - // Set a timeout of 3 seconds. - tv.tv_sec = 3; - tv.tv_usec = 0; - - bool listening = false; - if (select(sfd + 1, NULL, &fdset, NULL, &tv) == 1) { - int so_error; - socklen_t len = sizeof so_error; - - getsockopt(sfd, SOL_SOCKET, SO_ERROR, &so_error, &len); - - if (so_error == 0) { - listening = true; - } - // If there's an error, most likely there is no process - // listening at the specified host/port (ECONNREFUSED). - } - - freeaddrinfo(address); - close(sfd); - - if (!listening) { + if (!facebook::flipper::ConnectionEndpointVerifier::verify( + strongSelf->_url.host.UTF8String, strongSelf->_url.port.intValue)) { strongSelf->_eventHandler(facebook::flipper::SocketEvent::ERROR); return; } diff --git a/xplat/Flipper/FlipperConnectionEndpointVerifier.cpp b/xplat/Flipper/FlipperConnectionEndpointVerifier.cpp new file mode 100644 index 000000000..02211592a --- /dev/null +++ b/xplat/Flipper/FlipperConnectionEndpointVerifier.cpp @@ -0,0 +1,67 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#include "FlipperConnectionEndpointVerifier.h" +#include +#include +#include +#include +#include +#include + +namespace facebook { +namespace flipper { + +bool ConnectionEndpointVerifier::verify(const std::string& host, int port) { + auto sport = std::to_string(port); + + struct addrinfo hints; + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_PASSIVE; + struct addrinfo* address; + getaddrinfo(host.c_str(), sport.c_str(), &hints, &address); + + int sfd = + socket(address->ai_family, address->ai_socktype, address->ai_protocol); + + fcntl(sfd, F_SETFL, O_NONBLOCK); + connect(sfd, address->ai_addr, address->ai_addrlen); + + fd_set fdset; + struct timeval tv; + + FD_ZERO(&fdset); + FD_SET(sfd, &fdset); + // Set a timeout of 3 seconds. + tv.tv_sec = 3; + tv.tv_usec = 0; + + bool listening = false; + if (select(sfd + 1, NULL, &fdset, NULL, &tv) == 1) { + int so_error; + socklen_t len = sizeof so_error; + + getsockopt(sfd, SOL_SOCKET, SO_ERROR, &so_error, &len); + + if (so_error == 0) { + listening = true; + } + // If there's an error, most likely there is no process + // listening at the specified host/port (ECONNREFUSED). + } + + freeaddrinfo(address); + close(sfd); + + return listening; +} + +} // namespace flipper +} // namespace facebook diff --git a/xplat/Flipper/FlipperConnectionEndpointVerifier.h b/xplat/Flipper/FlipperConnectionEndpointVerifier.h new file mode 100644 index 000000000..b83020798 --- /dev/null +++ b/xplat/Flipper/FlipperConnectionEndpointVerifier.h @@ -0,0 +1,20 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include + +namespace facebook { +namespace flipper { +struct ConnectionEndpointVerifier { + /** Verifies whether the given endpoint is listening + for incoming connections. */ + static bool verify(const std::string& host, int port); +}; +} // namespace flipper +} // namespace facebook