blob: 43a925282d48adfdb9fc700dffe6f553ed971245 [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
Elliott Hughesd98ca8a2015-05-29 17:55:19 -070076static void ss_listener_event_func(int _fd, unsigned ev, void *_l) {
Elliott Hughes54e3efe2015-11-20 22:01:06 -080077 if (ev & FDE_READ) {
Josh Gaoc2705962019-01-23 15:36:42 -080078 unique_fd fd(adb_socket_accept(_fd, nullptr, nullptr));
Elliott Hughes54e3efe2015-11-20 22:01:06 -080079 if (fd < 0) return;
Dan Albert020292b2015-02-18 18:03:26 -080080
Elliott Hughes54e3efe2015-11-20 22:01:06 -080081 int rcv_buf_size = CHUNK_SIZE;
Josh Gaoc2705962019-01-23 15:36:42 -080082 adb_setsockopt(fd.get(), SOL_SOCKET, SO_RCVBUF, &rcv_buf_size, sizeof(rcv_buf_size));
Dan Albert020292b2015-02-18 18:03:26 -080083
Josh Gaoc2705962019-01-23 15:36:42 -080084 asocket* s = create_local_socket(std::move(fd));
Elliott Hughes54e3efe2015-11-20 22:01:06 -080085 if (s) {
Dan Albert020292b2015-02-18 18:03:26 -080086 connect_to_smartsocket(s);
87 return;
88 }
Dan Albert020292b2015-02-18 18:03:26 -080089 }
90}
91
Elliott Hughesd98ca8a2015-05-29 17:55:19 -070092static void listener_event_func(int _fd, unsigned ev, void* _l)
Dan Albert020292b2015-02-18 18:03:26 -080093{
Dan Albertf30d73c2015-02-25 17:51:28 -080094 alistener* listener = reinterpret_cast<alistener*>(_l);
Dan Albert020292b2015-02-18 18:03:26 -080095
Dan Albertf30d73c2015-02-25 17:51:28 -080096 if (ev & FDE_READ) {
Josh Gaoc2705962019-01-23 15:36:42 -080097 unique_fd fd(adb_socket_accept(_fd, nullptr, nullptr));
Dan Albertf30d73c2015-02-25 17:51:28 -080098 if (fd < 0) {
99 return;
100 }
Dan Albert020292b2015-02-18 18:03:26 -0800101
Josh Gaoc2705962019-01-23 15:36:42 -0800102 asocket* s = create_local_socket(std::move(fd));
Dan Albertf30d73c2015-02-25 17:51:28 -0800103 if (s) {
104 s->transport = listener->transport;
Josh Gao4a037e22018-12-20 17:00:13 -0800105 connect_to_remote(s, listener->connect_to);
Dan Albert020292b2015-02-18 18:03:26 -0800106 return;
107 }
Dan Albert020292b2015-02-18 18:03:26 -0800108 }
109}
110
David Pursell19d0c232016-04-07 11:25:48 -0700111// Called as a transport disconnect function. |arg| is the raw alistener*.
Josh Gao165460f2017-05-09 13:43:35 -0700112static void listener_disconnect(void* arg, atransport*) EXCLUDES(listener_list_mutex) {
113 std::lock_guard<std::mutex> lock(listener_list_mutex);
David Pursell19d0c232016-04-07 11:25:48 -0700114 for (auto iter = listener_list.begin(); iter != listener_list.end(); ++iter) {
115 if (iter->get() == arg) {
116 (*iter)->transport = nullptr;
117 listener_list.erase(iter);
118 return;
Dan Albert020292b2015-02-18 18:03:26 -0800119 }
Dan Albert020292b2015-02-18 18:03:26 -0800120 }
David Pursell19d0c232016-04-07 11:25:48 -0700121}
122
Elliott Hughes88b4c852015-04-30 17:32:03 -0700123// Write the list of current listeners (network redirections) into a string.
Josh Gao165460f2017-05-09 13:43:35 -0700124std::string format_listeners() EXCLUDES(listener_list_mutex) {
125 std::lock_guard<std::mutex> lock(listener_list_mutex);
Elliott Hughes88b4c852015-04-30 17:32:03 -0700126 std::string result;
David Pursell19d0c232016-04-07 11:25:48 -0700127 for (auto& l : listener_list) {
Dan Albert020292b2015-02-18 18:03:26 -0800128 // Ignore special listeners like those for *smartsocket*
Elliott Hughes88b4c852015-04-30 17:32:03 -0700129 if (l->connect_to[0] == '*') {
130 continue;
Dan Albert020292b2015-02-18 18:03:26 -0800131 }
Elliott Hughes88b4c852015-04-30 17:32:03 -0700132 // <device-serial> " " <local-name> " " <remote-name> "\n"
Elliott Hughes52591782015-07-21 17:09:06 -0700133 // Entries from "adb reverse" have no serial.
Luis Hector Chavezb4edbdf2018-07-18 21:18:27 -0700134 android::base::StringAppendF(
135 &result, "%s %s %s\n",
136 !l->transport->serial.empty() ? l->transport->serial.c_str() : "(reverse)",
137 l->local_name.c_str(), l->connect_to.c_str());
Dan Albert020292b2015-02-18 18:03:26 -0800138 }
139 return result;
140}
141
Josh Gao165460f2017-05-09 13:43:35 -0700142InstallStatus remove_listener(const char* local_name, atransport* transport)
143 EXCLUDES(listener_list_mutex) {
144 std::lock_guard<std::mutex> lock(listener_list_mutex);
David Pursell19d0c232016-04-07 11:25:48 -0700145 for (auto iter = listener_list.begin(); iter != listener_list.end(); ++iter) {
146 if (local_name == (*iter)->local_name) {
147 listener_list.erase(iter);
Elliott Hughesa585cbd2015-04-20 08:09:20 -0700148 return INSTALL_STATUS_OK;
Dan Albert020292b2015-02-18 18:03:26 -0800149 }
150 }
Elliott Hughesa585cbd2015-04-20 08:09:20 -0700151 return INSTALL_STATUS_LISTENER_NOT_FOUND;
Dan Albert020292b2015-02-18 18:03:26 -0800152}
153
Josh Gao165460f2017-05-09 13:43:35 -0700154void remove_all_listeners() EXCLUDES(listener_list_mutex) {
155 std::lock_guard<std::mutex> lock(listener_list_mutex);
David Pursell19d0c232016-04-07 11:25:48 -0700156 auto iter = listener_list.begin();
157 while (iter != listener_list.end()) {
Dan Albert020292b2015-02-18 18:03:26 -0800158 // Never remove smart sockets.
David Pursell19d0c232016-04-07 11:25:48 -0700159 if ((*iter)->connect_to[0] == '*') {
160 ++iter;
161 } else {
162 iter = listener_list.erase(iter);
163 }
Dan Albert020292b2015-02-18 18:03:26 -0800164 }
165}
166
Daniel Colascione232c39c2019-11-13 17:51:19 -0800167void enable_daemon_sockets() EXCLUDES(listener_list_mutex) {
168 std::lock_guard<std::mutex> lock(listener_list_mutex);
169 for (auto& l : listener_list) {
170 if (l->connect_to == "*smartsocket*") {
171 fdevent_set(l->fde, FDE_READ);
172 }
173 }
174}
175
Josh Gao165460f2017-05-09 13:43:35 -0700176void close_smartsockets() EXCLUDES(listener_list_mutex) {
177 std::lock_guard<std::mutex> lock(listener_list_mutex);
178 auto pred = [](const std::unique_ptr<alistener>& listener) {
179 return listener->local_name == "*smartsocket*";
180 };
Josh Gao8b532802017-10-20 17:57:42 -0700181 listener_list.remove_if(pred);
Josh Gao165460f2017-05-09 13:43:35 -0700182}
183
David Pursell19d0c232016-04-07 11:25:48 -0700184InstallStatus install_listener(const std::string& local_name, const char* connect_to,
Daniel Colascione232c39c2019-11-13 17:51:19 -0800185 atransport* transport, int flags, int* resolved_tcp_port,
Josh Gao165460f2017-05-09 13:43:35 -0700186 std::string* error) EXCLUDES(listener_list_mutex) {
187 std::lock_guard<std::mutex> lock(listener_list_mutex);
David Pursell19d0c232016-04-07 11:25:48 -0700188 for (auto& l : listener_list) {
Elliott Hughesfb596842015-05-01 17:04:38 -0700189 if (local_name == l->local_name) {
David Pursell19d0c232016-04-07 11:25:48 -0700190 // Can't repurpose a smartsocket.
Dan Albert020292b2015-02-18 18:03:26 -0800191 if(l->connect_to[0] == '*') {
Spencer Low32625852015-08-11 16:45:32 -0700192 *error = "cannot repurpose smartsocket";
Dan Albert020292b2015-02-18 18:03:26 -0800193 return INSTALL_STATUS_INTERNAL_ERROR;
194 }
195
Daniel Colascione232c39c2019-11-13 17:51:19 -0800196 // Can't repurpose a listener if INSTALL_LISTENER_NO_REBIND is set
197 if (flags & INSTALL_LISTENER_NO_REBIND) {
Spencer Low32625852015-08-11 16:45:32 -0700198 *error = "cannot rebind";
Dan Albert020292b2015-02-18 18:03:26 -0800199 return INSTALL_STATUS_CANNOT_REBIND;
200 }
201
David Pursell19d0c232016-04-07 11:25:48 -0700202 l->connect_to = connect_to;
Dan Albert020292b2015-02-18 18:03:26 -0800203 if (l->transport != transport) {
Yabin Cui2d4c1982015-08-28 15:09:44 -0700204 l->transport->RemoveDisconnect(&l->disconnect);
Dan Albert020292b2015-02-18 18:03:26 -0800205 l->transport = transport;
Yabin Cui2d4c1982015-08-28 15:09:44 -0700206 l->transport->AddDisconnect(&l->disconnect);
Dan Albert020292b2015-02-18 18:03:26 -0800207 }
208 return INSTALL_STATUS_OK;
209 }
210 }
211
Josh Gaof2a988c2018-03-07 16:51:08 -0800212 auto listener = std::make_unique<alistener>(local_name, connect_to);
Dan Albert020292b2015-02-18 18:03:26 -0800213
Josh Gao4a5a95d2016-08-24 18:38:44 -0700214 int resolved = 0;
215 listener->fd = socket_spec_listen(listener->local_name, error, &resolved);
Dan Albertf30d73c2015-02-25 17:51:28 -0800216 if (listener->fd < 0) {
Dan Albertf30d73c2015-02-25 17:51:28 -0800217 return INSTALL_STATUS_CANNOT_BIND;
Dan Albert020292b2015-02-18 18:03:26 -0800218 }
219
Josh Gao4a5a95d2016-08-24 18:38:44 -0700220 // If the caller requested port 0, update the listener name with the resolved port.
221 if (resolved != 0) {
222 listener->local_name = android::base::StringPrintf("tcp:%d", resolved);
223 if (resolved_tcp_port) {
224 *resolved_tcp_port = resolved;
225 }
226 }
227
Dan Albertf30d73c2015-02-25 17:51:28 -0800228 close_on_exec(listener->fd);
David Pursell19d0c232016-04-07 11:25:48 -0700229 if (listener->connect_to == "*smartsocket*") {
Josh Gao9528df22018-05-14 11:14:33 -0700230 listener->fde = fdevent_create(listener->fd, ss_listener_event_func, listener.get());
Dan Albert020292b2015-02-18 18:03:26 -0800231 } else {
Josh Gao9528df22018-05-14 11:14:33 -0700232 listener->fde = fdevent_create(listener->fd, listener_event_func, listener.get());
Dan Albert020292b2015-02-18 18:03:26 -0800233 }
Daniel Colascione232c39c2019-11-13 17:51:19 -0800234 if ((flags & INSTALL_LISTENER_DISABLED) == 0) {
235 fdevent_set(listener->fde, FDE_READ);
236 }
Dan Albert020292b2015-02-18 18:03:26 -0800237
Dan Albertf30d73c2015-02-25 17:51:28 -0800238 listener->transport = transport;
Dan Albert020292b2015-02-18 18:03:26 -0800239
240 if (transport) {
David Pursell19d0c232016-04-07 11:25:48 -0700241 listener->disconnect.opaque = listener.get();
Josh Gao165460f2017-05-09 13:43:35 -0700242 listener->disconnect.func = listener_disconnect;
Yabin Cui2d4c1982015-08-28 15:09:44 -0700243 transport->AddDisconnect(&listener->disconnect);
Dan Albert020292b2015-02-18 18:03:26 -0800244 }
Dan Albert020292b2015-02-18 18:03:26 -0800245
David Pursell19d0c232016-04-07 11:25:48 -0700246 listener_list.push_back(std::move(listener));
247 return INSTALL_STATUS_OK;
Dan Albert020292b2015-02-18 18:03:26 -0800248}