[cdc_rsync] Use any available server port (#94)

Instead of calling netstat on the remote device to detect available
ports, simply call bind with port 0 to bind to any available port.
Since the port is not yet known when cdc_rsync_server.exe is called,
port forwarding needs to be started AFTER the server reports its port.
This commit is contained in:
Lutz Justen
2023-03-06 14:16:21 +01:00
committed by GitHub
parent 5fd86e4625
commit a8059e8572
10 changed files with 137 additions and 131 deletions

View File

@@ -288,7 +288,7 @@ bool CdcRsyncServer::CheckComponents(
return true;
}
absl::Status CdcRsyncServer::Run(int port) {
absl::Status CdcRsyncServer::Run() {
absl::Status status = Socket::Initialize();
if (!status.ok()) {
return WrapStatus(status, "Failed to initialize sockets");
@@ -296,15 +296,15 @@ absl::Status CdcRsyncServer::Run(int port) {
socket_finalizer_ = std::make_unique<SocketFinalizer>();
socket_ = std::make_unique<ServerSocket>();
int new_port;
ASSIGN_OR_RETURN(new_port, socket_->StartListening(port),
"Failed to start listening on port %i", port);
assert(port != 0);
assert(port == new_port);
int port;
ASSIGN_OR_RETURN(port, socket_->StartListening(0),
"Failed to start listening for connections");
LOG_INFO("cdc_rsync_server listening on port %i", port);
// This is the marker for the client, so it knows it can connect.
printf("Server is listening\n");
// Print port first so the client can easily parse it when it sees "Server is
// listening" without dealing with half-transmitted data.
printf("Port %i: Server is listening\n", port);
fflush(stdout);
status = socket_->WaitForConnection();
@@ -607,7 +607,7 @@ absl::Status CdcRsyncServer::CreateMissingDirs() {
template <typename T>
absl::Status CdcRsyncServer::SendFileIndices(const char* file_type,
const std::vector<T>& files) {
LOG_INFO("Sending indices of missing files to client");
LOG_INFO("Sending indices of %s files to client", file_type);
constexpr char error_fmt[] = "Failed to send indices of %s files.";
AddFileIndicesResponse response;

View File

@@ -43,9 +43,10 @@ class CdcRsyncServer {
// up-to-date by checking their sizes and timestamps.
bool CheckComponents(const std::vector<GameletComponent>& components);
// Listens to |port|, accepts a connection from the client and runs the rsync
// procedure.
absl::Status Run(int port);
// Listens to any available port, accepts a connection from the client and
// runs the rsync procedure. Prints "Port <n>: Server is listening" to stdout,
// so the client can retrieve the selected port.
absl::Status Run();
// Returns the verbosity sent from the client. 0 by default.
int GetVerbosity() const { return verbosity_; }

View File

@@ -62,29 +62,22 @@ ServerExitCode GetExitCode(const absl::Status& status) {
int main(int argc, const char** argv) {
if (argc < 5) {
printf("cdc_rsync_server - Remote component of cdc_rsync. Version: %s\n\n",
BUILD_VERSION);
printf(
"Usage: cdc_rsync_server <port> <build_version> cdc_rsync_server "
"<size> <time> \n");
printf(" where <size> is the file size, <time> is the modified\n");
printf(
" timestamp (Unix epoch) and <build_version> is the build "
"version of the server.\n");
return cdc_ft::kServerExitCodeGenericStartup;
}
printf(R"("cdc_rsync_server - Remote component of cdc_rsync. Version: %s
Usage: cdc_rsync_server <build_version> cdc_rsync_server <size> <modified_time>
<build_version> build version embedded in the component
<size> file size of the component
<modified_time> timestamp (Unix epoch) of the component)",
BUILD_VERSION);
int port = atoi(argv[1]);
if (port == 0) {
SendErrorMessage(absl::StrFormat("Invalid port '%s'", argv[1]).c_str());
return cdc_ft::kServerExitCodeGenericStartup;
}
// The rest is expected to be sets of gamelet component info consisting of
// (filename, filesize, modified_time). This is used check whether the
// (version, filename, size, modified_time). This is used check whether the
// components are up-to-date.
std::vector<cdc_ft::GameletComponent> components =
cdc_ft::GameletComponent::FromCommandLineArgs(argc - 2, argv + 2);
cdc_ft::GameletComponent::FromCommandLineArgs(argc - 1, argv + 1);
cdc_ft::Log::Initialize(
std::make_unique<cdc_ft::ConsoleLog>(cdc_ft::LogLevel::kWarning));
@@ -94,7 +87,7 @@ int main(int argc, const char** argv) {
return cdc_ft::kServerExitCodeOutOfDate;
}
absl::Status status = server.Run(port);
absl::Status status = server.Run();
if (status.ok()) {
return 0;
}