| // Copyright 2018 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "base/command_line.h" |
| #include "base/strings/string_number_conversions.h" |
| #include "base/strings/string_split.h" |
| #include "base/task/single_thread_task_executor.h" |
| #include "net/base/ip_endpoint.h" |
| #include "net/test/tcp_socket_proxy.h" |
| |
| const char kPortsSwitch[] = "ports"; |
| const char kRemoteAddressSwitch[] = "remote-address"; |
| |
| int main(int argc, char** argv) { |
| base::CommandLine::Init(argc, argv); |
| |
| base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); |
| |
| if (!command_line->HasSwitch(kPortsSwitch)) { |
| LOG(ERROR) << "--" << kPortsSwitch << " was not specified."; |
| return 1; |
| } |
| |
| std::vector<std::string> ports_strings = |
| base::SplitString(command_line->GetSwitchValueASCII(kPortsSwitch), ",", |
| base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY); |
| if (ports_strings.empty()) { |
| LOG(ERROR) << "At least one port must be specified with --" << kPortsSwitch; |
| return 1; |
| } |
| |
| std::vector<int> ports; |
| for (auto& port_string : ports_strings) { |
| int port; |
| if (!base::StringToInt(port_string, &port) || port <= 0 || port > 65535) { |
| LOG(ERROR) << "Invalid value specified for --" << kPortsSwitch << ": " |
| << port_string; |
| return 1; |
| } |
| ports.push_back(port); |
| } |
| |
| if (!command_line->HasSwitch(kRemoteAddressSwitch)) { |
| LOG(ERROR) << "--" << kRemoteAddressSwitch << " was not specified."; |
| return 1; |
| } |
| |
| std::string remote_address_str = |
| command_line->GetSwitchValueASCII(kRemoteAddressSwitch); |
| net::IPAddress remote_address; |
| if (!remote_address.AssignFromIPLiteral(remote_address_str)) { |
| LOG(ERROR) << "Invalid value specified for --" << kRemoteAddressSwitch |
| << ": " << remote_address_str; |
| return 1; |
| } |
| |
| base::SingleThreadTaskExecutor io_task_executor(base::MessagePump::Type::IO); |
| |
| std::vector<std::unique_ptr<net::TcpSocketProxy>> proxies; |
| |
| for (int port : ports) { |
| auto test_server_proxy = |
| std::make_unique<net::TcpSocketProxy>(io_task_executor.task_runner()); |
| if (!test_server_proxy->Initialize(port)) { |
| LOG(ERROR) << "Can't bind proxy to port " << port; |
| return 1; |
| } |
| LOG(INFO) << "Listening on port " << test_server_proxy->local_port(); |
| test_server_proxy->Start(net::IPEndPoint(remote_address, port)); |
| proxies.push_back(std::move(test_server_proxy)); |
| } |
| |
| // Run the task executor indefinitely. |
| base::RunLoop().Run(); |
| |
| return 0; |
| } |