OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include <errno.h> |
| 6 #include <signal.h> |
| 7 #include <stdio.h> |
| 8 #include <stdlib.h> |
| 9 |
| 10 #include <vector> |
| 11 #include <string> |
| 12 |
| 13 #include "base/command_line.h" |
| 14 #include "base/lazy_instance.h" |
| 15 #include "base/logging.h" |
| 16 #include "base/memory/scoped_vector.h" |
| 17 #include "base/string_number_conversions.h" |
| 18 #include "base/string_piece.h" |
| 19 #include "base/string_split.h" |
| 20 #include "base/stringprintf.h" |
| 21 #include "tools/android/common/daemon.h" |
| 22 #include "tools/android/forwarder2/host_controller.h" |
| 23 #include "tools/android/forwarder2/pipe_notifier.h" |
| 24 |
| 25 using base::StringToInt; |
| 26 using forwarder::HostController; |
| 27 using std::string; |
| 28 using std::vector; |
| 29 |
| 30 namespace { |
| 31 |
| 32 const int kDefaultAdbPort = 3000; |
| 33 |
| 34 // Need to be global to be able to accessed from the signal handler. |
| 35 base::LazyInstance<forwarder::PipeNotifier>::Leaky g_notifier; |
| 36 |
| 37 void KillHandler(int unused) { |
| 38 g_notifier.Get().Notify(); |
| 39 } |
| 40 |
| 41 // Format of arg: <Device port>[:<Forward to port>:<Forward to address>] |
| 42 bool ParseForwardArg(const string& arg, |
| 43 int* device_port, |
| 44 string* forward_to_host, |
| 45 int* forward_to_port) { |
| 46 vector<string> arg_pieces; |
| 47 base::SplitString(arg, ':', &arg_pieces); |
| 48 if (arg_pieces.size() == 0 || !StringToInt(arg_pieces[0], device_port)) |
| 49 return false; |
| 50 |
| 51 if (*device_port == 0) { |
| 52 // TODO(felipeg): handle the case where we want to dynamically allocate the |
| 53 // port. Althogh the Socket already supports it, we have to |
| 54 // communicate the port from one forwarder to the other. |
| 55 LOG(ERROR) << "Dynamically allocate the port is not yet implemented."; |
| 56 return false; |
| 57 } |
| 58 |
| 59 if (arg_pieces.size() > 1) { |
| 60 if (!StringToInt(arg_pieces[1], forward_to_port)) |
| 61 return false; |
| 62 if (arg_pieces.size() > 2) |
| 63 *forward_to_host = arg_pieces[2]; |
| 64 } else { |
| 65 *forward_to_port = *device_port; |
| 66 } |
| 67 |
| 68 printf("Forwarding device port %d to host %d:%s\n", |
| 69 *device_port, *forward_to_port, forward_to_host->c_str()); |
| 70 return true; |
| 71 } |
| 72 |
| 73 } // namespace |
| 74 |
| 75 int main(int argc, char** argv) { |
| 76 printf("Host forwarder to handle incoming connections from Android.\n"); |
| 77 printf("Like 'adb forward' but in the reverse direction\n"); |
| 78 |
| 79 CommandLine command_line(argc, argv); |
| 80 bool show_help = tools::HasHelpSwitch(command_line); |
| 81 string adb_port_str = command_line.GetSwitchValueASCII("adb_port"); |
| 82 int adb_port = kDefaultAdbPort; |
| 83 if (!adb_port_str.empty() && !StringToInt(adb_port_str, &adb_port)) { |
| 84 printf("Could not parse adb port number: %s\n", adb_port_str.c_str()); |
| 85 show_help = true; |
| 86 } |
| 87 CommandLine::StringVector forward_args = command_line.GetArgs(); |
| 88 if (show_help || forward_args.empty()) { |
| 89 tools::ShowHelp( |
| 90 argv[0], |
| 91 "[--adb_port=<adb port>] " |
| 92 "<Device port>[:<Forward to port>:<Forward to address>] ...", |
| 93 base::StringPrintf( |
| 94 " <adb port> is the TCP port Adb is configured to forward to." |
| 95 " Default is %d\n" |
| 96 " <Forward to port> default is <Device port>\n" |
| 97 " <Forward to address> default is 127.0.0.1.", |
| 98 kDefaultAdbPort).c_str()); |
| 99 return 0; |
| 100 } |
| 101 |
| 102 ScopedVector<HostController> controllers; |
| 103 int failed_count = 0; |
| 104 for (size_t i = 0; i < forward_args.size(); ++i) { |
| 105 int device_port = 0; |
| 106 string forward_to_host; |
| 107 int forward_to_port = 0; |
| 108 if (ParseForwardArg(forward_args[i], |
| 109 &device_port, |
| 110 &forward_to_host, |
| 111 &forward_to_port)) { |
| 112 HostController* host_controller( |
| 113 new HostController(device_port, |
| 114 forward_to_host, |
| 115 forward_to_port, |
| 116 adb_port, |
| 117 g_notifier.Get().receiver_fd())); |
| 118 host_controller->Start(); |
| 119 controllers.push_back(host_controller); |
| 120 } else { |
| 121 printf("Couldn't start forwarder server for port spec: %s\n", |
| 122 forward_args[i].c_str()); |
| 123 ++failed_count; |
| 124 } |
| 125 } |
| 126 |
| 127 // Signal handler must be installed after the for loop above where we start |
| 128 // the host_controllers and push_back into the vector. Otherwise a race |
| 129 // condition may occur. |
| 130 signal(SIGTERM, KillHandler); |
| 131 signal(SIGINT, KillHandler); |
| 132 |
| 133 if (controllers.size() == 0) { |
| 134 printf("No forwarder servers could be started. Exiting.\n"); |
| 135 return failed_count; |
| 136 } |
| 137 |
| 138 // TODO(felipeg): We should check if the controllers are really alive before |
| 139 // printing Ready. |
| 140 printf("Host Forwarder Ready.\n"); |
| 141 for (int i = 0; i < controllers.size(); ++i) |
| 142 controllers[i]->Join(); |
| 143 |
| 144 return 0; |
| 145 } |
OLD | NEW |