blob: 124e2d8dcd30f55ab46995e9504f989298f807f2 [file] [log] [blame]
Dan Albert020292b2015-02-18 18:03:26 -08001/*
2 * Copyright (C) 2015 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
17#include "adb_listeners.h"
18
Dan Albert357bd492015-02-20 17:20:09 -080019#include <stdio.h>
Elliott Hughes1679e922015-02-24 12:37:13 -080020#include <stdlib.h>
Dan Albert357bd492015-02-20 17:20:09 -080021
Josh Gao165460f2017-05-09 13:43:35 -070022#include <algorithm>
23#include <list>
Pirama Arumuga Nainar5231aff2018-08-08 10:33:24 -070024#include <memory>
Josh Gao165460f2017-05-09 13:43:35 -070025
Elliott Hughesf55ead92015-12-04 22:00:26 -080026#include <android-base/stringprintf.h>
David Pursell19d0c232016-04-07 11:25:48 -070027#include <android-base/strings.h>
Josh Gao165460f2017-05-09 13:43:35 -070028#include <android-base/thread_annotations.h>
Elliott Hughes43df1092015-07-23 17:12:58 -070029#include <cutils/sockets.h>
Elliott Hughes88b4c852015-04-30 17:32:03 -070030
Josh Gao4a5a95d2016-08-24 18:38:44 -070031#include "socket_spec.h"
Dan Albert020292b2015-02-18 18:03:26 -080032#include "sysdeps.h"
Dan Albertb302d122015-02-24 15:51:19 -080033#include "transport.h"
Dan Albert020292b2015-02-18 18:03:26 -080034
David Pursell19d0c232016-04-07 11:25:48 -070035// A listener is an entity which binds to a local port and, upon receiving a connection on that
36// port, creates an asocket to connect the new local connection to a specific remote service.
37//
38// TODO: some listeners read from the new connection to determine what exact service to connect to
39// on the far side.
40class alistener {
41 public:
42 alistener(const std::string& _local_name, const std::string& _connect_to);
43 ~alistener();
44
Josh Gao9528df22018-05-14 11:14:33 -070045 fdevent* fde = nullptr;
David Pursell19d0c232016-04-07 11:25:48 -070046 int fd = -1;
47
48 std::string local_name;
49 std::string connect_to;
50 atransport* transport = nullptr;
51 adisconnect disconnect;
52
53 private:
54 DISALLOW_COPY_AND_ASSIGN(alistener);
Dan Albert020292b2015-02-18 18:03:26 -080055};
56
David Pursell19d0c232016-04-07 11:25:48 -070057alistener::alistener(const std::string& _local_name, const std::string& _connect_to)
58 : local_name(_local_name), connect_to(_connect_to) {
59}
60
61alistener::~alistener() {
62 // Closes the corresponding fd.
Josh Gao9528df22018-05-14 11:14:33 -070063 fdevent_destroy(fde);
David Pursell19d0c232016-04-07 11:25:48 -070064
65 if (transport) {
66 transport->RemoveDisconnect(&disconnect);
67 }
68}
69
70// listener_list retains ownership of all created alistener objects. Removing an alistener from
71// this list will cause it to be deleted.
Josh Gao165460f2017-05-09 13:43:35 -070072static auto& listener_list_mutex = *new std::mutex();
David Pursell19d0c232016-04-07 11:25:48 -070073typedef std::list<std::unique_ptr<alistener>> ListenerList;
Josh Gao165460f2017-05-09 13:43:35 -070074static ListenerList& listener_list GUARDED_BY(listener_list_mutex) = *new ListenerList();
David Pursell19d0c232016-04-07 11:25:48 -070075
Josh Gao65d18e22020-04-22 20:57:26 -070076#if ADB_HOST
Elliott Hughesd98ca8a2015-05-29 17:55:19 -070077static void ss_listener_event_func(int _fd, unsigned ev, void *_l) {
Elliott Hughes54e3efe2015-11-20 22:01:06 -080078 if (ev & FDE_READ) {
Josh Gaoc2705962019-01-23 15:36:42 -080079 unique_fd fd(adb_socket_accept(_fd, nullptr, nullptr));
Elliott Hughes54e3efe2015-11-20 22:01:06 -080080 if (fd < 0) return;
Dan Albert020292b2015-02-18 18:03:26 -080081
Elliott Hughes54e3efe2015-11-20 22:01:06 -080082 int rcv_buf_size = CHUNK_SIZE;
Josh Gaoc2705962019-01-23 15:36:42 -080083 adb_setsockopt(fd.get(), SOL_SOCKET, SO_RCVBUF, &rcv_buf_size, sizeof(rcv_buf_size));
Dan Albert020292b2015-02-18 18:03:26 -080084
Josh Gaoc2705962019-01-23 15:36:42 -080085 asocket* s = create_local_socket(std::move(fd));
Elliott Hughes54e3efe2015-11-20 22:01:06 -080086 if (s) {
Dan Albert020292b2015-02-18 18:03:26 -080087 connect_to_smartsocket(s);
88 return;
89 }
Dan Albert020292b2015-02-18 18:03:26 -080090 }
91}
Josh Gao65d18e22020-04-22 20:57:26 -070092#endif
Dan Albert020292b2015-02-18 18:03:26 -080093
Elliott Hughesd98ca8a2015-05-29 17:55:19 -070094static void listener_event_func(int _fd, unsigned ev, void* _l)
Dan Albert020292b2015-02-18 18:03:26 -080095{
Dan Albertf30d73c2015-02-25 17:51:28 -080096 alistener* listener = reinterpret_cast<alistener*>(_l);
Dan Albert020292b2015-02-18 18:03:26 -080097
Dan Albertf30d73c2015-02-25 17:51:28 -080098 if (ev & FDE_READ) {
Josh Gaoc2705962019-01-23 15:36:42 -080099 unique_fd fd(adb_socket_accept(_fd, nullptr, nullptr));
Dan Albertf30d73c2015-02-25 17:51:28 -0800100 if (fd < 0) {
101 return;
102 }
Dan Albert020292b2015-02-18 18:03:26 -0800103
Josh Gaoc2705962019-01-23 15:36:42 -0800104 asocket* s = create_local_socket(std::move(fd));
Dan Albertf30d73c2015-02-25 17:51:28 -0800105 if (s) {
106 s->transport = listener->transport;
Josh Gao4a037e22018-12-20 17:00:13 -0800107 connect_to_remote(s, listener->connect_to);
Dan Albert020292b2015-02-18 18:03:26 -0800108 return;
109 }
Dan Albert020292b2015-02-18 18:03:26 -0800110 }
111}
112
David Pursell19d0c232016-04-07 11:25:48 -0700113// Called as a transport disconnect function. |arg| is the raw alistener*.
Josh Gao165460f2017-05-09 13:43:35 -0700114static void listener_disconnect(void* arg, atransport*) EXCLUDES(listener_list_mutex) {
115 std::lock_guard<std::mutex> lock(listener_list_mutex);
David Pursell19d0c232016-04-07 11:25:48 -0700116 for (auto iter = listener_list.begin(); iter != listener_list.end(); ++iter) {
117 if (iter->get() == arg) {
118 (*iter)->transport = nullptr;
119 listener_list.erase(iter);
120 return;
Dan Albert020292b2015-02-18 18:03:26 -0800121 }
Dan Albert020292b2015-02-18 18:03:26 -0800122 }
David Pursell19d0c232016-04-07 11:25:48 -0700123}
124
Elliott Hughes88b4c852015-04-30 17:32:03 -0700125// Write the list of current listeners (network redirections) into a string.
Josh Gao165460f2017-05-09 13:43:35 -0700126std::string format_listeners() EXCLUDES(listener_list_mutex) {
127 std::lock_guard<std::mutex> lock(listener_list_mutex);
Elliott Hughes88b4c852015-04-30 17:32:03 -0700128 std::string result;
David Pursell19d0c232016-04-07 11:25:48 -0700129 for (auto& l : listener_list) {
Dan Albert020292b2015-02-18 18:03:26 -0800130 // Ignore special listeners like those for *smartsocket*
Elliott Hughes88b4c852015-04-30 17:32:03 -0700131 if (l->connect_to[0] == '*') {
132 continue;
Dan Albert020292b2015-02-18 18:03:26 -0800133 }
Elliott Hughes88b4c852015-04-30 17:32:03 -0700134 // <device-serial> " " <local-name> " " <remote-name> "\n"
Elliott Hughes52591782015-07-21 17:09:06 -0700135 // Entries from "adb reverse" have no serial.
Luis Hector Chavezb4edbdf2018-07-18 21:18:27 -0700136 android::base::StringAppendF(
137 &result, "%s %s %s\n",
138 !l->transport->serial.empty() ? l->transport->serial.c_str() : "(reverse)",
139 l->local_name.c_str(), l->connect_to.c_str());
Dan Albert020292b2015-02-18 18:03:26 -0800140 }
141 return result;
142}
143
Josh Gao165460f2017-05-09 13:43:35 -0700144InstallStatus remove_listener(const char* local_name, atransport* transport)
145 EXCLUDES(listener_list_mutex) {
146 std::lock_guard<std::mutex> lock(listener_list_mutex);
David Pursell19d0c232016-04-07 11:25:48 -0700147 for (auto iter = listener_list.begin(); iter != listener_list.end(); ++iter) {
148 if (local_name == (*iter)->local_name) {
149 listener_list.erase(iter);
Elliott Hughesa585cbd2015-04-20 08:09:20 -0700150 return INSTALL_STATUS_OK;
Dan Albert020292b2015-02-18 18:03:26 -0800151 }
152 }
Elliott Hughesa585cbd2015-04-20 08:09:20 -0700153 return INSTALL_STATUS_LISTENER_NOT_FOUND;
Dan Albert020292b2015-02-18 18:03:26 -0800154}
155
Josh Gao165460f2017-05-09 13:43:35 -0700156void remove_all_listeners() EXCLUDES(listener_list_mutex) {
157 std::lock_guard<std::mutex> lock(listener_list_mutex);
David Pursell19d0c232016-04-07 11:25:48 -0700158 auto iter = listener_list.begin();
159 while (iter != listener_list.end()) {
Dan Albert020292b2015-02-18 18:03:26 -0800160 // Never remove smart sockets.
David Pursell19d0c232016-04-07 11:25:48 -0700161 if ((*iter)->connect_to[0] == '*') {
162 ++iter;
163 } else {
164 iter = listener_list.erase(iter);
165 }
Dan Albert020292b2015-02-18 18:03:26 -0800166 }
167}
168
Josh Gao65d18e22020-04-22 20:57:26 -0700169void enable_server_sockets() EXCLUDES(listener_list_mutex) {
Daniel Colascione232c39c2019-11-13 17:51:19 -0800170 std::lock_guard<std::mutex> lock(listener_list_mutex);
171 for (auto& l : listener_list) {
172 if (l->connect_to == "*smartsocket*") {
173 fdevent_set(l->fde, FDE_READ);
174 }
175 }
176}
177
Josh Gao65d18e22020-04-22 20:57:26 -0700178#if ADB_HOST
Josh Gao165460f2017-05-09 13:43:35 -0700179void close_smartsockets() EXCLUDES(listener_list_mutex) {
180 std::lock_guard<std::mutex> lock(listener_list_mutex);
181 auto pred = [](const std::unique_ptr<alistener>& listener) {
182 return listener->local_name == "*smartsocket*";
183 };
Josh Gao8b532802017-10-20 17:57:42 -0700184 listener_list.remove_if(pred);
Josh Gao165460f2017-05-09 13:43:35 -0700185}
Josh Gao65d18e22020-04-22 20:57:26 -0700186#endif
Josh Gao165460f2017-05-09 13:43:35 -0700187
David Pursell19d0c232016-04-07 11:25:48 -0700188InstallStatus install_listener(const std::string& local_name, const char* connect_to,
Daniel Colascione232c39c2019-11-13 17:51:19 -0800189 atransport* transport, int flags, int* resolved_tcp_port,
Josh Gao165460f2017-05-09 13:43:35 -0700190 std::string* error) EXCLUDES(listener_list_mutex) {
191 std::lock_guard<std::mutex> lock(listener_list_mutex);
David Pursell19d0c232016-04-07 11:25:48 -0700192 for (auto& l : listener_list) {
Elliott Hughesfb596842015-05-01 17:04:38 -0700193 if (local_name == l->local_name) {
David Pursell19d0c232016-04-07 11:25:48 -0700194 // Can't repurpose a smartsocket.
Josh Gao65d18e22020-04-22 20:57:26 -0700195 if (l->connect_to[0] == '*') {
Spencer Low32625852015-08-11 16:45:32 -0700196 *error = "cannot repurpose smartsocket";
Dan Albert020292b2015-02-18 18:03:26 -0800197 return INSTALL_STATUS_INTERNAL_ERROR;
198 }
199
Daniel Colascione232c39c2019-11-13 17:51:19 -0800200 // Can't repurpose a listener if INSTALL_LISTENER_NO_REBIND is set
201 if (flags & INSTALL_LISTENER_NO_REBIND) {
Spencer Low32625852015-08-11 16:45:32 -0700202 *error = "cannot rebind";
Dan Albert020292b2015-02-18 18:03:26 -0800203 return INSTALL_STATUS_CANNOT_REBIND;
204 }
205
David Pursell19d0c232016-04-07 11:25:48 -0700206 l->connect_to = connect_to;
Dan Albert020292b2015-02-18 18:03:26 -0800207 if (l->transport != transport) {
Yabin Cui2d4c1982015-08-28 15:09:44 -0700208 l->transport->RemoveDisconnect(&l->disconnect);
Dan Albert020292b2015-02-18 18:03:26 -0800209 l->transport = transport;
Yabin Cui2d4c1982015-08-28 15:09:44 -0700210 l->transport->AddDisconnect(&l->disconnect);
Dan Albert020292b2015-02-18 18:03:26 -0800211 }
212 return INSTALL_STATUS_OK;
213 }
214 }
215
Josh Gaof2a988c2018-03-07 16:51:08 -0800216 auto listener = std::make_unique<alistener>(local_name, connect_to);
Dan Albert020292b2015-02-18 18:03:26 -0800217
Josh Gao4a5a95d2016-08-24 18:38:44 -0700218 int resolved = 0;
219 listener->fd = socket_spec_listen(listener->local_name, error, &resolved);
Dan Albertf30d73c2015-02-25 17:51:28 -0800220 if (listener->fd < 0) {
Dan Albertf30d73c2015-02-25 17:51:28 -0800221 return INSTALL_STATUS_CANNOT_BIND;
Dan Albert020292b2015-02-18 18:03:26 -0800222 }
223
Josh Gao4a5a95d2016-08-24 18:38:44 -0700224 // If the caller requested port 0, update the listener name with the resolved port.
225 if (resolved != 0) {
226 listener->local_name = android::base::StringPrintf("tcp:%d", resolved);
227 if (resolved_tcp_port) {
228 *resolved_tcp_port = resolved;
229 }
230 }
231
Dan Albertf30d73c2015-02-25 17:51:28 -0800232 close_on_exec(listener->fd);
David Pursell19d0c232016-04-07 11:25:48 -0700233 if (listener->connect_to == "*smartsocket*") {
Josh Gao65d18e22020-04-22 20:57:26 -0700234#if ADB_HOST
Josh Gao9528df22018-05-14 11:14:33 -0700235 listener->fde = fdevent_create(listener->fd, ss_listener_event_func, listener.get());
Josh Gao65d18e22020-04-22 20:57:26 -0700236#else
237 LOG(FATAL) << "attempted to connect to *smartsocket* in daemon";
238#endif
Dan Albert020292b2015-02-18 18:03:26 -0800239 } else {
Josh Gao9528df22018-05-14 11:14:33 -0700240 listener->fde = fdevent_create(listener->fd, listener_event_func, listener.get());
Dan Albert020292b2015-02-18 18:03:26 -0800241 }
Daniel Colascione232c39c2019-11-13 17:51:19 -0800242 if ((flags & INSTALL_LISTENER_DISABLED) == 0) {
243 fdevent_set(listener->fde, FDE_READ);
244 }
Dan Albert020292b2015-02-18 18:03:26 -0800245
Dan Albertf30d73c2015-02-25 17:51:28 -0800246 listener->transport = transport;
Dan Albert020292b2015-02-18 18:03:26 -0800247
248 if (transport) {
David Pursell19d0c232016-04-07 11:25:48 -0700249 listener->disconnect.opaque = listener.get();
Josh Gao165460f2017-05-09 13:43:35 -0700250 listener->disconnect.func = listener_disconnect;
Yabin Cui2d4c1982015-08-28 15:09:44 -0700251 transport->AddDisconnect(&listener->disconnect);
Dan Albert020292b2015-02-18 18:03:26 -0800252 }
Dan Albert020292b2015-02-18 18:03:26 -0800253
David Pursell19d0c232016-04-07 11:25:48 -0700254 listener_list.push_back(std::move(listener));
255 return INSTALL_STATUS_OK;
Dan Albert020292b2015-02-18 18:03:26 -0800256}