The Android Open Source Project | 9ca14dc | 2009-03-03 19:32:55 -0800 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2007 The Android Open Source Project |
| 3 | * |
| 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | * you may not use this file except in compliance with the License. |
| 6 | * You may obtain a copy of the License at |
| 7 | * |
| 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | * |
| 10 | * Unless required by applicable law or agreed to in writing, software |
| 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | * See the License for the specific language governing permissions and |
| 14 | * limitations under the License. |
| 15 | */ |
| 16 | |
Yabin Cui | 19bec5b | 2015-09-22 15:52:57 -0700 | [diff] [blame] | 17 | #define TRACE_TAG TRANSPORT |
Dan Albert | db6fe64 | 2015-03-19 15:21:08 -0700 | [diff] [blame] | 18 | |
| 19 | #include "sysdeps.h" |
| 20 | #include "transport.h" |
| 21 | |
Dan Albert | b302d12 | 2015-02-24 15:51:19 -0800 | [diff] [blame] | 22 | #include <errno.h> |
The Android Open Source Project | 9ca14dc | 2009-03-03 19:32:55 -0800 | [diff] [blame] | 23 | #include <stdio.h> |
| 24 | #include <stdlib.h> |
| 25 | #include <string.h> |
Dan Albert | b302d12 | 2015-02-24 15:51:19 -0800 | [diff] [blame] | 26 | #include <sys/types.h> |
The Android Open Source Project | 9ca14dc | 2009-03-03 19:32:55 -0800 | [diff] [blame] | 27 | |
Pirama Arumuga Nainar | bd4d4e1 | 2016-09-06 13:34:42 -0700 | [diff] [blame] | 28 | #include <condition_variable> |
Cody Schuffelen | 637aaf5 | 2019-01-04 18:51:11 -0800 | [diff] [blame] | 29 | #include <functional> |
Pirama Arumuga Nainar | 5231aff | 2018-08-08 10:33:24 -0700 | [diff] [blame] | 30 | #include <memory> |
Josh Gao | e7daf57 | 2016-09-21 12:37:10 -0700 | [diff] [blame] | 31 | #include <mutex> |
Elliott Hughes | 7392598 | 2016-11-15 12:37:32 -0800 | [diff] [blame] | 32 | #include <thread> |
Josh Gao | 395b86a | 2018-01-28 20:32:46 -0800 | [diff] [blame] | 33 | #include <unordered_map> |
Yabin Cui | f401ead | 2016-04-29 16:53:52 -0700 | [diff] [blame] | 34 | #include <vector> |
| 35 | |
Casey Dahlin | 3122cdf | 2016-06-23 14:19:37 -0700 | [diff] [blame] | 36 | #include <android-base/parsenetaddress.h> |
Elliott Hughes | f55ead9 | 2015-12-04 22:00:26 -0800 | [diff] [blame] | 37 | #include <android-base/stringprintf.h> |
Josh Gao | 395b86a | 2018-01-28 20:32:46 -0800 | [diff] [blame] | 38 | #include <android-base/thread_annotations.h> |
Elliott Hughes | 43df109 | 2015-07-23 17:12:58 -0700 | [diff] [blame] | 39 | #include <cutils/sockets.h> |
Elliott Hughes | fb59684 | 2015-05-01 17:04:38 -0700 | [diff] [blame] | 40 | |
Dan Albert | b302d12 | 2015-02-24 15:51:19 -0800 | [diff] [blame] | 41 | #if !ADB_HOST |
Elliott Hughes | 8b249d2 | 2016-09-23 15:40:03 -0700 | [diff] [blame] | 42 | #include <android-base/properties.h> |
Dan Albert | b302d12 | 2015-02-24 15:51:19 -0800 | [diff] [blame] | 43 | #endif |
Dan Albert | db6fe64 | 2015-03-19 15:21:08 -0700 | [diff] [blame] | 44 | |
| 45 | #include "adb.h" |
| 46 | #include "adb_io.h" |
Josh Gao | 395b86a | 2018-01-28 20:32:46 -0800 | [diff] [blame] | 47 | #include "adb_unique_fd.h" |
Elliott Hughes | 43df109 | 2015-07-23 17:12:58 -0700 | [diff] [blame] | 48 | #include "adb_utils.h" |
Cody Schuffelen | 331a908 | 2019-01-02 14:17:29 -0800 | [diff] [blame] | 49 | #include "socket_spec.h" |
Josh Gao | 70267e4 | 2016-11-15 18:55:47 -0800 | [diff] [blame] | 50 | #include "sysdeps/chrono.h" |
The Android Open Source Project | 9ca14dc | 2009-03-03 19:32:55 -0800 | [diff] [blame] | 51 | |
The Android Open Source Project | 9ca14dc | 2009-03-03 19:32:55 -0800 | [diff] [blame] | 52 | #if ADB_HOST |
Josh Gao | 89513a5 | 2016-05-06 02:37:24 -0700 | [diff] [blame] | 53 | |
| 54 | // Android Wear has been using port 5601 in all of its documentation/tooling, |
| 55 | // but we search for emulators on ports [5554, 5555 + ADB_LOCAL_TRANSPORT_MAX]. |
Tim Baverstock | 96ee6b1 | 2019-02-08 16:27:16 +0000 | [diff] [blame] | 56 | // Avoid stomping on their port by restricting the active scanning range. |
| 57 | // Once emulators self-(re-)register, they'll have to avoid 5601 in their own way. |
| 58 | static int adb_local_transport_max_port = DEFAULT_ADB_LOCAL_TRANSPORT_PORT + 16 * 2 - 1; |
Josh Gao | 89513a5 | 2016-05-06 02:37:24 -0700 | [diff] [blame] | 59 | |
Josh Gao | e7daf57 | 2016-09-21 12:37:10 -0700 | [diff] [blame] | 60 | static std::mutex& local_transports_lock = *new std::mutex(); |
Josh Gao | 89513a5 | 2016-05-06 02:37:24 -0700 | [diff] [blame] | 61 | |
Tim Baverstock | 96ee6b1 | 2019-02-08 16:27:16 +0000 | [diff] [blame] | 62 | static void adb_local_transport_max_port_env_override() { |
| 63 | const char* env_max_s = getenv("ADB_LOCAL_TRANSPORT_MAX_PORT"); |
| 64 | if (env_max_s != nullptr) { |
| 65 | size_t env_max; |
| 66 | if (ParseUint(&env_max, env_max_s, nullptr) && env_max < 65536) { |
| 67 | // < DEFAULT_ADB_LOCAL_TRANSPORT_PORT harmlessly mimics ADB_EMU=0 |
| 68 | adb_local_transport_max_port = env_max; |
| 69 | D("transport: ADB_LOCAL_TRANSPORT_MAX_PORT read as %d", adb_local_transport_max_port); |
| 70 | } else { |
| 71 | D("transport: ADB_LOCAL_TRANSPORT_MAX_PORT '%s' invalid or >= 65536, so ignored", |
| 72 | env_max_s); |
| 73 | } |
| 74 | } |
| 75 | } |
| 76 | |
Josh Gao | 395b86a | 2018-01-28 20:32:46 -0800 | [diff] [blame] | 77 | // We keep a map from emulator port to transport. |
| 78 | // TODO: weak_ptr? |
| 79 | static auto& local_transports GUARDED_BY(local_transports_lock) = |
| 80 | *new std::unordered_map<int, atransport*>(); |
The Android Open Source Project | 9ca14dc | 2009-03-03 19:32:55 -0800 | [diff] [blame] | 81 | #endif /* ADB_HOST */ |
| 82 | |
Yabin Cui | f401ead | 2016-04-29 16:53:52 -0700 | [diff] [blame] | 83 | bool local_connect(int port) { |
Elliott Hughes | 43df109 | 2015-07-23 17:12:58 -0700 | [diff] [blame] | 84 | std::string dummy; |
Josh Gao | 395b86a | 2018-01-28 20:32:46 -0800 | [diff] [blame] | 85 | return local_connect_arbitrary_ports(port - 1, port, &dummy) == 0; |
Stefan Hilzinger | 1ec0342 | 2010-04-26 10:17:43 +0100 | [diff] [blame] | 86 | } |
| 87 | |
Luis Hector Chavez | 0aeda10 | 2018-04-20 10:31:29 -0700 | [diff] [blame] | 88 | std::tuple<unique_fd, int, std::string> tcp_connect(const std::string& address, |
| 89 | std::string* response) { |
Cody Schuffelen | 331a908 | 2019-01-02 14:17:29 -0800 | [diff] [blame] | 90 | unique_fd fd; |
Casey Dahlin | 3122cdf | 2016-06-23 14:19:37 -0700 | [diff] [blame] | 91 | int port = DEFAULT_ADB_LOCAL_TRANSPORT_PORT; |
Cody Schuffelen | 331a908 | 2019-01-02 14:17:29 -0800 | [diff] [blame] | 92 | std::string serial; |
Cody Schuffelen | 637aaf5 | 2019-01-04 18:51:11 -0800 | [diff] [blame] | 93 | std::string prefix_addr = address.starts_with("vsock:") ? address : "tcp:" + address; |
| 94 | if (socket_spec_connect(&fd, prefix_addr, &port, &serial, response)) { |
Cody Schuffelen | 331a908 | 2019-01-02 14:17:29 -0800 | [diff] [blame] | 95 | close_on_exec(fd); |
| 96 | if (!set_tcp_keepalive(fd, 1)) { |
| 97 | D("warning: failed to configure TCP keepalives (%s)", strerror(errno)); |
| 98 | } |
Luis Hector Chavez | 0aeda10 | 2018-04-20 10:31:29 -0700 | [diff] [blame] | 99 | return std::make_tuple(std::move(fd), port, serial); |
Casey Dahlin | 3122cdf | 2016-06-23 14:19:37 -0700 | [diff] [blame] | 100 | } |
Cody Schuffelen | 637aaf5 | 2019-01-04 18:51:11 -0800 | [diff] [blame] | 101 | return std::make_tuple(unique_fd(), 0, serial); |
Luis Hector Chavez | 0aeda10 | 2018-04-20 10:31:29 -0700 | [diff] [blame] | 102 | } |
| 103 | |
| 104 | void connect_device(const std::string& address, std::string* response) { |
| 105 | if (address.empty()) { |
| 106 | *response = "empty address"; |
| 107 | return; |
| 108 | } |
| 109 | |
Josh Gao | 8d7080c | 2018-08-10 16:03:09 -0700 | [diff] [blame] | 110 | D("connection requested to '%s'", address.c_str()); |
Luis Hector Chavez | 0aeda10 | 2018-04-20 10:31:29 -0700 | [diff] [blame] | 111 | unique_fd fd; |
| 112 | int port; |
| 113 | std::string serial; |
| 114 | std::tie(fd, port, serial) = tcp_connect(address, response); |
Cody Schuffelen | 637aaf5 | 2019-01-04 18:51:11 -0800 | [diff] [blame] | 115 | if (fd.get() == -1) { |
| 116 | return; |
| 117 | } |
Luis Hector Chavez | 0aeda10 | 2018-04-20 10:31:29 -0700 | [diff] [blame] | 118 | auto reconnect = [address](atransport* t) { |
| 119 | std::string response; |
| 120 | unique_fd fd; |
| 121 | int port; |
| 122 | std::string serial; |
| 123 | std::tie(fd, port, serial) = tcp_connect(address, &response); |
| 124 | if (fd == -1) { |
| 125 | D("reconnect failed: %s", response.c_str()); |
Josh Gao | d24580d | 2018-08-30 11:37:00 -0700 | [diff] [blame] | 126 | return ReconnectResult::Retry; |
Luis Hector Chavez | 0aeda10 | 2018-04-20 10:31:29 -0700 | [diff] [blame] | 127 | } |
Luis Hector Chavez | 0aeda10 | 2018-04-20 10:31:29 -0700 | [diff] [blame] | 128 | // This invokes the part of register_socket_transport() that needs to be |
| 129 | // invoked if the atransport* has already been setup. This eventually |
| 130 | // calls atransport->SetConnection() with a newly created Connection* |
| 131 | // that will in turn send the CNXN packet. |
Josh Gao | d24580d | 2018-08-30 11:37:00 -0700 | [diff] [blame] | 132 | return init_socket_transport(t, std::move(fd), port, 0) >= 0 ? ReconnectResult::Success |
| 133 | : ReconnectResult::Retry; |
Luis Hector Chavez | 0aeda10 | 2018-04-20 10:31:29 -0700 | [diff] [blame] | 134 | }; |
| 135 | |
Josh Gao | 597044d | 2018-08-08 16:20:14 -0700 | [diff] [blame] | 136 | int error; |
| 137 | if (!register_socket_transport(std::move(fd), serial, port, 0, std::move(reconnect), &error)) { |
| 138 | if (error == EALREADY) { |
Luis Hector Chavez | 7771920 | 2018-04-17 14:09:21 -0700 | [diff] [blame] | 139 | *response = android::base::StringPrintf("already connected to %s", serial.c_str()); |
Josh Gao | 597044d | 2018-08-08 16:20:14 -0700 | [diff] [blame] | 140 | } else if (error == EPERM) { |
| 141 | *response = android::base::StringPrintf("failed to authenticate to %s", serial.c_str()); |
Luis Hector Chavez | 7771920 | 2018-04-17 14:09:21 -0700 | [diff] [blame] | 142 | } else { |
| 143 | *response = android::base::StringPrintf("failed to connect to %s", serial.c_str()); |
| 144 | } |
Casey Dahlin | 3122cdf | 2016-06-23 14:19:37 -0700 | [diff] [blame] | 145 | } else { |
| 146 | *response = android::base::StringPrintf("connected to %s", serial.c_str()); |
| 147 | } |
| 148 | } |
| 149 | |
| 150 | |
Elliott Hughes | 43df109 | 2015-07-23 17:12:58 -0700 | [diff] [blame] | 151 | int local_connect_arbitrary_ports(int console_port, int adb_port, std::string* error) { |
Josh Gao | d8d51f4 | 2018-07-25 17:27:34 -0700 | [diff] [blame] | 152 | unique_fd fd; |
The Android Open Source Project | 9ca14dc | 2009-03-03 19:32:55 -0800 | [diff] [blame] | 153 | |
| 154 | #if ADB_HOST |
Lingfeng Yang | 5edb12b | 2016-10-06 12:22:55 -0700 | [diff] [blame] | 155 | if (find_emulator_transport_by_adb_port(adb_port) != nullptr || |
| 156 | find_emulator_transport_by_console_port(console_port) != nullptr) { |
Yabin Cui | d802bcf | 2015-07-31 14:10:54 -0700 | [diff] [blame] | 157 | return -1; |
| 158 | } |
| 159 | |
The Android Open Source Project | 9ca14dc | 2009-03-03 19:32:55 -0800 | [diff] [blame] | 160 | const char *host = getenv("ADBHOST"); |
| 161 | if (host) { |
Josh Gao | d8d51f4 | 2018-07-25 17:27:34 -0700 | [diff] [blame] | 162 | fd.reset(network_connect(host, adb_port, SOCK_STREAM, 0, error)); |
The Android Open Source Project | 9ca14dc | 2009-03-03 19:32:55 -0800 | [diff] [blame] | 163 | } |
| 164 | #endif |
| 165 | if (fd < 0) { |
Josh Gao | d8d51f4 | 2018-07-25 17:27:34 -0700 | [diff] [blame] | 166 | fd.reset(network_loopback_client(adb_port, SOCK_STREAM, error)); |
The Android Open Source Project | 9ca14dc | 2009-03-03 19:32:55 -0800 | [diff] [blame] | 167 | } |
| 168 | |
| 169 | if (fd >= 0) { |
Josh Gao | d8d51f4 | 2018-07-25 17:27:34 -0700 | [diff] [blame] | 170 | D("client: connected on remote on fd %d", fd.get()); |
| 171 | close_on_exec(fd.get()); |
| 172 | disable_tcp_nagle(fd.get()); |
Lingfeng Yang | 5edb12b | 2016-10-06 12:22:55 -0700 | [diff] [blame] | 173 | std::string serial = getEmulatorSerialString(console_port); |
Josh Gao | a3a7147 | 2018-08-02 13:58:24 -0700 | [diff] [blame] | 174 | if (register_socket_transport(std::move(fd), std::move(serial), adb_port, 1, |
Josh Gao | d24580d | 2018-08-30 11:37:00 -0700 | [diff] [blame] | 175 | [](atransport*) { return ReconnectResult::Abort; })) { |
Yabin Cui | d802bcf | 2015-07-31 14:10:54 -0700 | [diff] [blame] | 176 | return 0; |
| 177 | } |
The Android Open Source Project | 9ca14dc | 2009-03-03 19:32:55 -0800 | [diff] [blame] | 178 | } |
| 179 | return -1; |
| 180 | } |
| 181 | |
Yabin Cui | 5fe6d0d | 2015-08-11 13:40:42 -0700 | [diff] [blame] | 182 | #if ADB_HOST |
Yabin Cui | f401ead | 2016-04-29 16:53:52 -0700 | [diff] [blame] | 183 | |
| 184 | static void PollAllLocalPortsForEmulator() { |
Yabin Cui | f401ead | 2016-04-29 16:53:52 -0700 | [diff] [blame] | 185 | // Try to connect to any number of running emulator instances. |
Tim Baverstock | 96ee6b1 | 2019-02-08 16:27:16 +0000 | [diff] [blame] | 186 | for (int port = DEFAULT_ADB_LOCAL_TRANSPORT_PORT; port <= adb_local_transport_max_port; |
| 187 | port += 2) { |
| 188 | local_connect(port); // Note, uses port and port-1, so '=max_port' is OK. |
Yabin Cui | f401ead | 2016-04-29 16:53:52 -0700 | [diff] [blame] | 189 | } |
| 190 | } |
| 191 | |
| 192 | // Retry the disconnected local port for 60 times, and sleep 1 second between two retries. |
Elliott Hughes | c3462f4 | 2018-09-05 12:13:11 -0700 | [diff] [blame] | 193 | static constexpr uint32_t LOCAL_PORT_RETRY_COUNT = 60; |
| 194 | static constexpr auto LOCAL_PORT_RETRY_INTERVAL = 1s; |
Yabin Cui | f401ead | 2016-04-29 16:53:52 -0700 | [diff] [blame] | 195 | |
| 196 | struct RetryPort { |
| 197 | int port; |
| 198 | uint32_t retry_count; |
| 199 | }; |
| 200 | |
| 201 | // Retry emulators just kicked. |
| 202 | static std::vector<RetryPort>& retry_ports = *new std::vector<RetryPort>; |
| 203 | std::mutex &retry_ports_lock = *new std::mutex; |
| 204 | std::condition_variable &retry_ports_cond = *new std::condition_variable; |
| 205 | |
Josh Gao | 0f3312a | 2017-04-12 17:00:49 -0700 | [diff] [blame] | 206 | static void client_socket_thread(int) { |
Siva Velusamy | 2669cf9 | 2015-08-28 16:37:29 -0700 | [diff] [blame] | 207 | adb_thread_setname("client_socket_thread"); |
Yabin Cui | 815ad88 | 2015-09-02 17:44:28 -0700 | [diff] [blame] | 208 | D("transport: client_socket_thread() starting"); |
Yabin Cui | f401ead | 2016-04-29 16:53:52 -0700 | [diff] [blame] | 209 | PollAllLocalPortsForEmulator(); |
Yabin Cui | d802bcf | 2015-07-31 14:10:54 -0700 | [diff] [blame] | 210 | while (true) { |
Yabin Cui | f401ead | 2016-04-29 16:53:52 -0700 | [diff] [blame] | 211 | std::vector<RetryPort> ports; |
| 212 | // Collect retry ports. |
| 213 | { |
| 214 | std::unique_lock<std::mutex> lock(retry_ports_lock); |
| 215 | while (retry_ports.empty()) { |
| 216 | retry_ports_cond.wait(lock); |
| 217 | } |
| 218 | retry_ports.swap(ports); |
Yabin Cui | d802bcf | 2015-07-31 14:10:54 -0700 | [diff] [blame] | 219 | } |
Yabin Cui | f401ead | 2016-04-29 16:53:52 -0700 | [diff] [blame] | 220 | // Sleep here instead of the end of loop, because if we immediately try to reconnect |
| 221 | // the emulator just kicked, the adbd on the emulator may not have time to remove the |
| 222 | // just kicked transport. |
Elliott Hughes | 7392598 | 2016-11-15 12:37:32 -0800 | [diff] [blame] | 223 | std::this_thread::sleep_for(LOCAL_PORT_RETRY_INTERVAL); |
Yabin Cui | f401ead | 2016-04-29 16:53:52 -0700 | [diff] [blame] | 224 | |
| 225 | // Try connecting retry ports. |
| 226 | std::vector<RetryPort> next_ports; |
| 227 | for (auto& port : ports) { |
| 228 | VLOG(TRANSPORT) << "retry port " << port.port << ", last retry_count " |
| 229 | << port.retry_count; |
| 230 | if (local_connect(port.port)) { |
| 231 | VLOG(TRANSPORT) << "retry port " << port.port << " successfully"; |
| 232 | continue; |
| 233 | } |
| 234 | if (--port.retry_count > 0) { |
| 235 | next_ports.push_back(port); |
| 236 | } else { |
| 237 | VLOG(TRANSPORT) << "stop retrying port " << port.port; |
| 238 | } |
| 239 | } |
| 240 | |
| 241 | // Copy back left retry ports. |
| 242 | { |
| 243 | std::unique_lock<std::mutex> lock(retry_ports_lock); |
| 244 | retry_ports.insert(retry_ports.end(), next_ports.begin(), next_ports.end()); |
| 245 | } |
The Android Open Source Project | 9ca14dc | 2009-03-03 19:32:55 -0800 | [diff] [blame] | 246 | } |
The Android Open Source Project | 9ca14dc | 2009-03-03 19:32:55 -0800 | [diff] [blame] | 247 | } |
| 248 | |
Josh Gao | 0560feb | 2019-01-22 19:36:15 -0800 | [diff] [blame] | 249 | #else // !ADB_HOST |
Yabin Cui | 5fe6d0d | 2015-08-11 13:40:42 -0700 | [diff] [blame] | 250 | |
Josh Gao | 80e8192 | 2019-01-30 13:59:51 -0800 | [diff] [blame] | 251 | void server_socket_thread(std::function<unique_fd(int, std::string*)> listen_func, int port) { |
Siva Velusamy | 2669cf9 | 2015-08-28 16:37:29 -0700 | [diff] [blame] | 252 | adb_thread_setname("server socket"); |
Josh Gao | 80e8192 | 2019-01-30 13:59:51 -0800 | [diff] [blame] | 253 | |
| 254 | unique_fd serverfd; |
| 255 | std::string error; |
| 256 | |
Josh Gao | fa3107e | 2018-07-25 17:21:49 -0700 | [diff] [blame] | 257 | while (serverfd == -1) { |
Cody Schuffelen | 637aaf5 | 2019-01-04 18:51:11 -0800 | [diff] [blame] | 258 | errno = 0; |
Josh Gao | 80e8192 | 2019-01-30 13:59:51 -0800 | [diff] [blame] | 259 | serverfd = listen_func(port, &error); |
Cody Schuffelen | 637aaf5 | 2019-01-04 18:51:11 -0800 | [diff] [blame] | 260 | if (errno == EAFNOSUPPORT || errno == EINVAL || errno == EPROTONOSUPPORT) { |
| 261 | D("unrecoverable error: '%s'", error.c_str()); |
| 262 | return; |
| 263 | } else if (serverfd < 0) { |
Josh Gao | fa3107e | 2018-07-25 17:21:49 -0700 | [diff] [blame] | 264 | D("server: cannot bind socket yet: %s", error.c_str()); |
| 265 | std::this_thread::sleep_for(1s); |
| 266 | continue; |
The Android Open Source Project | 9ca14dc | 2009-03-03 19:32:55 -0800 | [diff] [blame] | 267 | } |
Josh Gao | fa3107e | 2018-07-25 17:21:49 -0700 | [diff] [blame] | 268 | close_on_exec(serverfd.get()); |
| 269 | } |
The Android Open Source Project | 9ca14dc | 2009-03-03 19:32:55 -0800 | [diff] [blame] | 270 | |
Josh Gao | fa3107e | 2018-07-25 17:21:49 -0700 | [diff] [blame] | 271 | while (true) { |
Josh Gao | 80e8192 | 2019-01-30 13:59:51 -0800 | [diff] [blame] | 272 | D("server: trying to get new connection from fd %d", serverfd.get()); |
Josh Gao | fa3107e | 2018-07-25 17:21:49 -0700 | [diff] [blame] | 273 | unique_fd fd(adb_socket_accept(serverfd, nullptr, nullptr)); |
| 274 | if (fd >= 0) { |
| 275 | D("server: new connection on fd %d", fd.get()); |
| 276 | close_on_exec(fd.get()); |
| 277 | disable_tcp_nagle(fd.get()); |
| 278 | std::string serial = android::base::StringPrintf("host-%d", fd.get()); |
Josh Gao | a3a7147 | 2018-08-02 13:58:24 -0700 | [diff] [blame] | 279 | register_socket_transport(std::move(fd), std::move(serial), port, 1, |
Josh Gao | d24580d | 2018-08-30 11:37:00 -0700 | [diff] [blame] | 280 | [](atransport*) { return ReconnectResult::Abort; }); |
The Android Open Source Project | 9ca14dc | 2009-03-03 19:32:55 -0800 | [diff] [blame] | 281 | } |
| 282 | } |
Yabin Cui | 815ad88 | 2015-09-02 17:44:28 -0700 | [diff] [blame] | 283 | D("transport: server_socket_thread() exiting"); |
The Android Open Source Project | 9ca14dc | 2009-03-03 19:32:55 -0800 | [diff] [blame] | 284 | } |
| 285 | |
Josh Gao | 0560feb | 2019-01-22 19:36:15 -0800 | [diff] [blame] | 286 | #endif |
Vladimir Chtchetkine | 7c9339d | 2011-12-09 15:49:47 -0800 | [diff] [blame] | 287 | |
Josh Gao | 80e8192 | 2019-01-30 13:59:51 -0800 | [diff] [blame] | 288 | unique_fd tcp_listen_inaddr_any(int port, std::string* error) { |
| 289 | return unique_fd{network_inaddr_any_server(port, SOCK_STREAM, error)}; |
| 290 | } |
| 291 | |
| 292 | #if !ADB_HOST |
| 293 | static unique_fd vsock_listen(int port, std::string* error) { |
| 294 | return unique_fd{ |
| 295 | socket_spec_listen(android::base::StringPrintf("vsock:%d", port), error, nullptr) |
| 296 | }; |
| 297 | } |
| 298 | #endif |
| 299 | |
Josh Gao | 0560feb | 2019-01-22 19:36:15 -0800 | [diff] [blame] | 300 | void local_init(int port) { |
Vladimir Chtchetkine | 4bdc776 | 2011-12-13 12:19:29 -0800 | [diff] [blame] | 301 | #if ADB_HOST |
Cody Schuffelen | 637aaf5 | 2019-01-04 18:51:11 -0800 | [diff] [blame] | 302 | D("transport: local client init"); |
| 303 | std::thread(client_socket_thread, port).detach(); |
Tim Baverstock | 96ee6b1 | 2019-02-08 16:27:16 +0000 | [diff] [blame] | 304 | adb_local_transport_max_port_env_override(); |
Josh Gao | 0560feb | 2019-01-22 19:36:15 -0800 | [diff] [blame] | 305 | #elif !defined(__ANDROID__) |
| 306 | // Host adbd. |
Cody Schuffelen | 637aaf5 | 2019-01-04 18:51:11 -0800 | [diff] [blame] | 307 | D("transport: local server init"); |
Josh Gao | 80e8192 | 2019-01-30 13:59:51 -0800 | [diff] [blame] | 308 | std::thread(server_socket_thread, tcp_listen_inaddr_any, port).detach(); |
| 309 | std::thread(server_socket_thread, vsock_listen, port).detach(); |
Vladimir Chtchetkine | 4bdc776 | 2011-12-13 12:19:29 -0800 | [diff] [blame] | 310 | #else |
Cody Schuffelen | 637aaf5 | 2019-01-04 18:51:11 -0800 | [diff] [blame] | 311 | D("transport: local server init"); |
Elliott Hughes | 8b249d2 | 2016-09-23 15:40:03 -0700 | [diff] [blame] | 312 | // For the adbd daemon in the system image we need to distinguish |
| 313 | // between the device, and the emulator. |
Cody Schuffelen | 637aaf5 | 2019-01-04 18:51:11 -0800 | [diff] [blame] | 314 | if (use_qemu_goldfish()) { |
| 315 | std::thread(qemu_socket_thread, port).detach(); |
| 316 | } else { |
Josh Gao | 80e8192 | 2019-01-30 13:59:51 -0800 | [diff] [blame] | 317 | std::thread(server_socket_thread, tcp_listen_inaddr_any, port).detach(); |
Cody Schuffelen | 637aaf5 | 2019-01-04 18:51:11 -0800 | [diff] [blame] | 318 | } |
Josh Gao | 80e8192 | 2019-01-30 13:59:51 -0800 | [diff] [blame] | 319 | std::thread(server_socket_thread, vsock_listen, port).detach(); |
Yabin Cui | 5fe6d0d | 2015-08-11 13:40:42 -0700 | [diff] [blame] | 320 | #endif // !ADB_HOST |
The Android Open Source Project | 9ca14dc | 2009-03-03 19:32:55 -0800 | [diff] [blame] | 321 | } |
| 322 | |
The Android Open Source Project | 9ca14dc | 2009-03-03 19:32:55 -0800 | [diff] [blame] | 323 | #if ADB_HOST |
Josh Gao | 395b86a | 2018-01-28 20:32:46 -0800 | [diff] [blame] | 324 | struct EmulatorConnection : public FdConnection { |
| 325 | EmulatorConnection(unique_fd fd, int local_port) |
| 326 | : FdConnection(std::move(fd)), local_port_(local_port) {} |
The Android Open Source Project | 9ca14dc | 2009-03-03 19:32:55 -0800 | [diff] [blame] | 327 | |
Josh Gao | 395b86a | 2018-01-28 20:32:46 -0800 | [diff] [blame] | 328 | ~EmulatorConnection() { |
| 329 | VLOG(TRANSPORT) << "remote_close, local_port = " << local_port_; |
Yabin Cui | f401ead | 2016-04-29 16:53:52 -0700 | [diff] [blame] | 330 | std::unique_lock<std::mutex> lock(retry_ports_lock); |
| 331 | RetryPort port; |
Josh Gao | 395b86a | 2018-01-28 20:32:46 -0800 | [diff] [blame] | 332 | port.port = local_port_; |
Yabin Cui | f401ead | 2016-04-29 16:53:52 -0700 | [diff] [blame] | 333 | port.retry_count = LOCAL_PORT_RETRY_COUNT; |
| 334 | retry_ports.push_back(port); |
| 335 | retry_ports_cond.notify_one(); |
| 336 | } |
The Android Open Source Project | 9ca14dc | 2009-03-03 19:32:55 -0800 | [diff] [blame] | 337 | |
Josh Gao | 395b86a | 2018-01-28 20:32:46 -0800 | [diff] [blame] | 338 | void Close() override { |
| 339 | std::lock_guard<std::mutex> lock(local_transports_lock); |
| 340 | local_transports.erase(local_port_); |
| 341 | FdConnection::Close(); |
| 342 | } |
Stefan Hilzinger | 1ec0342 | 2010-04-26 10:17:43 +0100 | [diff] [blame] | 343 | |
Josh Gao | 395b86a | 2018-01-28 20:32:46 -0800 | [diff] [blame] | 344 | int local_port_; |
| 345 | }; |
| 346 | |
Stefan Hilzinger | 1ec0342 | 2010-04-26 10:17:43 +0100 | [diff] [blame] | 347 | /* Only call this function if you already hold local_transports_lock. */ |
Yabin Cui | f401ead | 2016-04-29 16:53:52 -0700 | [diff] [blame] | 348 | static atransport* find_emulator_transport_by_adb_port_locked(int adb_port) |
Josh Gao | 395b86a | 2018-01-28 20:32:46 -0800 | [diff] [blame] | 349 | REQUIRES(local_transports_lock) { |
| 350 | auto it = local_transports.find(adb_port); |
| 351 | if (it == local_transports.end()) { |
| 352 | return nullptr; |
Stefan Hilzinger | 1ec0342 | 2010-04-26 10:17:43 +0100 | [diff] [blame] | 353 | } |
Josh Gao | 395b86a | 2018-01-28 20:32:46 -0800 | [diff] [blame] | 354 | return it->second; |
Stefan Hilzinger | 1ec0342 | 2010-04-26 10:17:43 +0100 | [diff] [blame] | 355 | } |
| 356 | |
Josh Gao | 395b86a | 2018-01-28 20:32:46 -0800 | [diff] [blame] | 357 | atransport* find_emulator_transport_by_adb_port(int adb_port) { |
Josh Gao | e7daf57 | 2016-09-21 12:37:10 -0700 | [diff] [blame] | 358 | std::lock_guard<std::mutex> lock(local_transports_lock); |
Josh Gao | 395b86a | 2018-01-28 20:32:46 -0800 | [diff] [blame] | 359 | return find_emulator_transport_by_adb_port_locked(adb_port); |
Stefan Hilzinger | 1ec0342 | 2010-04-26 10:17:43 +0100 | [diff] [blame] | 360 | } |
| 361 | |
Josh Gao | 395b86a | 2018-01-28 20:32:46 -0800 | [diff] [blame] | 362 | atransport* find_emulator_transport_by_console_port(int console_port) { |
Lingfeng Yang | 5edb12b | 2016-10-06 12:22:55 -0700 | [diff] [blame] | 363 | return find_transport(getEmulatorSerialString(console_port).c_str()); |
| 364 | } |
Stefan Hilzinger | 1ec0342 | 2010-04-26 10:17:43 +0100 | [diff] [blame] | 365 | #endif |
| 366 | |
Tao Bao | 49042e3 | 2018-07-30 20:45:27 -0700 | [diff] [blame] | 367 | std::string getEmulatorSerialString(int console_port) { |
| 368 | return android::base::StringPrintf("emulator-%d", console_port); |
| 369 | } |
| 370 | |
Josh Gao | fa3107e | 2018-07-25 17:21:49 -0700 | [diff] [blame] | 371 | int init_socket_transport(atransport* t, unique_fd fd, int adb_port, int local) { |
Josh Gao | 395b86a | 2018-01-28 20:32:46 -0800 | [diff] [blame] | 372 | int fail = 0; |
The Android Open Source Project | 9ca14dc | 2009-03-03 19:32:55 -0800 | [diff] [blame] | 373 | |
The Android Open Source Project | 9ca14dc | 2009-03-03 19:32:55 -0800 | [diff] [blame] | 374 | t->type = kTransportLocal; |
| 375 | |
| 376 | #if ADB_HOST |
Josh Gao | 395b86a | 2018-01-28 20:32:46 -0800 | [diff] [blame] | 377 | // Emulator connection. |
Yabin Cui | 5fe6d0d | 2015-08-11 13:40:42 -0700 | [diff] [blame] | 378 | if (local) { |
Josh Gao | f2a988c | 2018-03-07 16:51:08 -0800 | [diff] [blame] | 379 | auto emulator_connection = std::make_unique<EmulatorConnection>(std::move(fd), adb_port); |
Luis Hector Chavez | 3c7881d | 2018-04-25 08:56:41 -0700 | [diff] [blame] | 380 | t->SetConnection( |
| 381 | std::make_unique<BlockingConnectionAdapter>(std::move(emulator_connection))); |
Josh Gao | e7daf57 | 2016-09-21 12:37:10 -0700 | [diff] [blame] | 382 | std::lock_guard<std::mutex> lock(local_transports_lock); |
Josh Gao | e7daf57 | 2016-09-21 12:37:10 -0700 | [diff] [blame] | 383 | atransport* existing_transport = find_emulator_transport_by_adb_port_locked(adb_port); |
Yi Kong | 86e6718 | 2018-07-13 18:15:16 -0700 | [diff] [blame] | 384 | if (existing_transport != nullptr) { |
Josh Gao | e7daf57 | 2016-09-21 12:37:10 -0700 | [diff] [blame] | 385 | D("local transport for port %d already registered (%p)?", adb_port, existing_transport); |
| 386 | fail = -1; |
Josh Gao | e7daf57 | 2016-09-21 12:37:10 -0700 | [diff] [blame] | 387 | } else { |
Josh Gao | 395b86a | 2018-01-28 20:32:46 -0800 | [diff] [blame] | 388 | local_transports[adb_port] = t; |
Josh Gao | e7daf57 | 2016-09-21 12:37:10 -0700 | [diff] [blame] | 389 | } |
Josh Gao | 395b86a | 2018-01-28 20:32:46 -0800 | [diff] [blame] | 390 | |
| 391 | return fail; |
The Android Open Source Project | 9ca14dc | 2009-03-03 19:32:55 -0800 | [diff] [blame] | 392 | } |
| 393 | #endif |
Josh Gao | 395b86a | 2018-01-28 20:32:46 -0800 | [diff] [blame] | 394 | |
| 395 | // Regular tcp connection. |
Josh Gao | f2a988c | 2018-03-07 16:51:08 -0800 | [diff] [blame] | 396 | auto fd_connection = std::make_unique<FdConnection>(std::move(fd)); |
Luis Hector Chavez | 3c7881d | 2018-04-25 08:56:41 -0700 | [diff] [blame] | 397 | t->SetConnection(std::make_unique<BlockingConnectionAdapter>(std::move(fd_connection))); |
The Android Open Source Project | 9ca14dc | 2009-03-03 19:32:55 -0800 | [diff] [blame] | 398 | return fail; |
| 399 | } |