Refactor endpoint verification prior to connection
Summary: ^ There's a similar issue/request for Android. So, this change moves the code out from the FlipperKit into Flipper as to be able to reuse it. Reviewed By: aigoncharov Differential Revision: D35961745 fbshipit-source-id: aa255db582a7852dc06c2feaba389d1dac3b0f67
This commit is contained in:
committed by
Facebook GitHub Bot
parent
2120a94dc3
commit
3826f2c8ef
@@ -8,12 +8,9 @@
|
||||
#ifdef FB_SONARKIT_ENABLED
|
||||
|
||||
#import "FlipperPlatformWebSocket.h"
|
||||
#import <Flipper/FlipperConnectionEndpointVerifier.h>
|
||||
#import <Flipper/Log.h>
|
||||
#import <SocketRocket/SocketRocket.h>
|
||||
#include <netdb.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/socket.h>
|
||||
#include <unistd.h>
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
67
xplat/Flipper/FlipperConnectionEndpointVerifier.cpp
Normal file
67
xplat/Flipper/FlipperConnectionEndpointVerifier.cpp
Normal file
@@ -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 <netdb.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/fcntl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <unistd.h>
|
||||
#include <cstring>
|
||||
|
||||
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
|
||||
20
xplat/Flipper/FlipperConnectionEndpointVerifier.h
Normal file
20
xplat/Flipper/FlipperConnectionEndpointVerifier.h
Normal file
@@ -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 <string>
|
||||
|
||||
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
|
||||
Reference in New Issue
Block a user