blob: fecf452c1c4e99d4e4de99596a72058eecfa6ed9 [file] [log] [blame]
Dan Alberte9fca142015-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 Albertbf106472015-02-20 17:20:09 -080019#include <stdio.h>
Elliott Hughes3b967f52015-02-24 12:37:13 -080020#include <stdlib.h>
Dan Albertbf106472015-02-20 17:20:09 -080021
Josh Gao01b7bc42017-05-09 13:43:35 -070022#include <algorithm>
23#include <list>
24
Elliott Hughes4f713192015-12-04 22:00:26 -080025#include <android-base/stringprintf.h>
David Purselleaae97e2016-04-07 11:25:48 -070026#include <android-base/strings.h>
Josh Gao01b7bc42017-05-09 13:43:35 -070027#include <android-base/thread_annotations.h>
Elliott Hughes381cfa92015-07-23 17:12:58 -070028#include <cutils/sockets.h>
Elliott Hughese67f1f82015-04-30 17:32:03 -070029
Josh Gaocfb21412016-08-24 18:38:44 -070030#include "socket_spec.h"
Dan Alberte9fca142015-02-18 18:03:26 -080031#include "sysdeps.h"
Josh Gao28589bb2018-03-07 16:51:08 -080032#include "sysdeps/memory.h"
Dan Albert76649012015-02-24 15:51:19 -080033#include "transport.h"
Dan Alberte9fca142015-02-18 18:03:26 -080034
David Purselleaae97e2016-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
45 fdevent fde;
46 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 Alberte9fca142015-02-18 18:03:26 -080055};
56
David Purselleaae97e2016-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.
63 fdevent_remove(&fde);
64
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 Gao01b7bc42017-05-09 13:43:35 -070072static auto& listener_list_mutex = *new std::mutex();
David Purselleaae97e2016-04-07 11:25:48 -070073typedef std::list<std::unique_ptr<alistener>> ListenerList;
Josh Gao01b7bc42017-05-09 13:43:35 -070074static ListenerList& listener_list GUARDED_BY(listener_list_mutex) = *new ListenerList();
David Purselleaae97e2016-04-07 11:25:48 -070075
Elliott Hughes424af022015-05-29 17:55:19 -070076static void ss_listener_event_func(int _fd, unsigned ev, void *_l) {
Elliott Hughescc65c3b2015-11-20 22:01:06 -080077 if (ev & FDE_READ) {
Josh Gao78e1eb12016-08-23 15:41:56 -070078 int fd = adb_socket_accept(_fd, nullptr, nullptr);
Elliott Hughescc65c3b2015-11-20 22:01:06 -080079 if (fd < 0) return;
Dan Alberte9fca142015-02-18 18:03:26 -080080
Elliott Hughescc65c3b2015-11-20 22:01:06 -080081 int rcv_buf_size = CHUNK_SIZE;
82 adb_setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &rcv_buf_size, sizeof(rcv_buf_size));
Dan Alberte9fca142015-02-18 18:03:26 -080083
Elliott Hughescc65c3b2015-11-20 22:01:06 -080084 asocket* s = create_local_socket(fd);
85 if (s) {
Dan Alberte9fca142015-02-18 18:03:26 -080086 connect_to_smartsocket(s);
87 return;
88 }
89
90 adb_close(fd);
91 }
92}
93
Elliott Hughes424af022015-05-29 17:55:19 -070094static void listener_event_func(int _fd, unsigned ev, void* _l)
Dan Alberte9fca142015-02-18 18:03:26 -080095{
Dan Albertbac34742015-02-25 17:51:28 -080096 alistener* listener = reinterpret_cast<alistener*>(_l);
Dan Alberte9fca142015-02-18 18:03:26 -080097 asocket *s;
98
Dan Albertbac34742015-02-25 17:51:28 -080099 if (ev & FDE_READ) {
Josh Gao78e1eb12016-08-23 15:41:56 -0700100 int fd = adb_socket_accept(_fd, nullptr, nullptr);
Dan Albertbac34742015-02-25 17:51:28 -0800101 if (fd < 0) {
102 return;
103 }
Dan Alberte9fca142015-02-18 18:03:26 -0800104
105 s = create_local_socket(fd);
Dan Albertbac34742015-02-25 17:51:28 -0800106 if (s) {
107 s->transport = listener->transport;
David Purselleaae97e2016-04-07 11:25:48 -0700108 connect_to_remote(s, listener->connect_to.c_str());
Dan Alberte9fca142015-02-18 18:03:26 -0800109 return;
110 }
111
112 adb_close(fd);
113 }
114}
115
David Purselleaae97e2016-04-07 11:25:48 -0700116// Called as a transport disconnect function. |arg| is the raw alistener*.
Josh Gao01b7bc42017-05-09 13:43:35 -0700117static void listener_disconnect(void* arg, atransport*) EXCLUDES(listener_list_mutex) {
118 std::lock_guard<std::mutex> lock(listener_list_mutex);
David Purselleaae97e2016-04-07 11:25:48 -0700119 for (auto iter = listener_list.begin(); iter != listener_list.end(); ++iter) {
120 if (iter->get() == arg) {
121 (*iter)->transport = nullptr;
122 listener_list.erase(iter);
123 return;
Dan Alberte9fca142015-02-18 18:03:26 -0800124 }
Dan Alberte9fca142015-02-18 18:03:26 -0800125 }
David Purselleaae97e2016-04-07 11:25:48 -0700126}
127
Elliott Hughese67f1f82015-04-30 17:32:03 -0700128// Write the list of current listeners (network redirections) into a string.
Josh Gao01b7bc42017-05-09 13:43:35 -0700129std::string format_listeners() EXCLUDES(listener_list_mutex) {
130 std::lock_guard<std::mutex> lock(listener_list_mutex);
Elliott Hughese67f1f82015-04-30 17:32:03 -0700131 std::string result;
David Purselleaae97e2016-04-07 11:25:48 -0700132 for (auto& l : listener_list) {
Dan Alberte9fca142015-02-18 18:03:26 -0800133 // Ignore special listeners like those for *smartsocket*
Elliott Hughese67f1f82015-04-30 17:32:03 -0700134 if (l->connect_to[0] == '*') {
135 continue;
Dan Alberte9fca142015-02-18 18:03:26 -0800136 }
Elliott Hughese67f1f82015-04-30 17:32:03 -0700137 // <device-serial> " " <local-name> " " <remote-name> "\n"
Elliott Hughes34c20bb2015-07-21 17:09:06 -0700138 // Entries from "adb reverse" have no serial.
Elliott Hughese67f1f82015-04-30 17:32:03 -0700139 android::base::StringAppendF(&result, "%s %s %s\n",
Elliott Hughes34c20bb2015-07-21 17:09:06 -0700140 l->transport->serial ? l->transport->serial : "(reverse)",
David Purselleaae97e2016-04-07 11:25:48 -0700141 l->local_name.c_str(), l->connect_to.c_str());
Dan Alberte9fca142015-02-18 18:03:26 -0800142 }
143 return result;
144}
145
Josh Gao01b7bc42017-05-09 13:43:35 -0700146InstallStatus remove_listener(const char* local_name, atransport* transport)
147 EXCLUDES(listener_list_mutex) {
148 std::lock_guard<std::mutex> lock(listener_list_mutex);
David Purselleaae97e2016-04-07 11:25:48 -0700149 for (auto iter = listener_list.begin(); iter != listener_list.end(); ++iter) {
150 if (local_name == (*iter)->local_name) {
151 listener_list.erase(iter);
Elliott Hughes7b506092015-04-20 08:09:20 -0700152 return INSTALL_STATUS_OK;
Dan Alberte9fca142015-02-18 18:03:26 -0800153 }
154 }
Elliott Hughes7b506092015-04-20 08:09:20 -0700155 return INSTALL_STATUS_LISTENER_NOT_FOUND;
Dan Alberte9fca142015-02-18 18:03:26 -0800156}
157
Josh Gao01b7bc42017-05-09 13:43:35 -0700158void remove_all_listeners() EXCLUDES(listener_list_mutex) {
159 std::lock_guard<std::mutex> lock(listener_list_mutex);
David Purselleaae97e2016-04-07 11:25:48 -0700160 auto iter = listener_list.begin();
161 while (iter != listener_list.end()) {
Dan Alberte9fca142015-02-18 18:03:26 -0800162 // Never remove smart sockets.
David Purselleaae97e2016-04-07 11:25:48 -0700163 if ((*iter)->connect_to[0] == '*') {
164 ++iter;
165 } else {
166 iter = listener_list.erase(iter);
167 }
Dan Alberte9fca142015-02-18 18:03:26 -0800168 }
169}
170
Josh Gao01b7bc42017-05-09 13:43:35 -0700171void close_smartsockets() EXCLUDES(listener_list_mutex) {
172 std::lock_guard<std::mutex> lock(listener_list_mutex);
173 auto pred = [](const std::unique_ptr<alistener>& listener) {
174 return listener->local_name == "*smartsocket*";
175 };
Josh Gao4dfaa882017-10-20 17:57:42 -0700176 listener_list.remove_if(pred);
Josh Gao01b7bc42017-05-09 13:43:35 -0700177}
178
David Purselleaae97e2016-04-07 11:25:48 -0700179InstallStatus install_listener(const std::string& local_name, const char* connect_to,
180 atransport* transport, int no_rebind, int* resolved_tcp_port,
Josh Gao01b7bc42017-05-09 13:43:35 -0700181 std::string* error) EXCLUDES(listener_list_mutex) {
182 std::lock_guard<std::mutex> lock(listener_list_mutex);
David Purselleaae97e2016-04-07 11:25:48 -0700183 for (auto& l : listener_list) {
Elliott Hughesab52c182015-05-01 17:04:38 -0700184 if (local_name == l->local_name) {
David Purselleaae97e2016-04-07 11:25:48 -0700185 // Can't repurpose a smartsocket.
Dan Alberte9fca142015-02-18 18:03:26 -0800186 if(l->connect_to[0] == '*') {
Spencer Lowbf7c6052015-08-11 16:45:32 -0700187 *error = "cannot repurpose smartsocket";
Dan Alberte9fca142015-02-18 18:03:26 -0800188 return INSTALL_STATUS_INTERNAL_ERROR;
189 }
190
David Purselleaae97e2016-04-07 11:25:48 -0700191 // Can't repurpose a listener if 'no_rebind' is true.
Dan Alberte9fca142015-02-18 18:03:26 -0800192 if (no_rebind) {
Spencer Lowbf7c6052015-08-11 16:45:32 -0700193 *error = "cannot rebind";
Dan Alberte9fca142015-02-18 18:03:26 -0800194 return INSTALL_STATUS_CANNOT_REBIND;
195 }
196
David Purselleaae97e2016-04-07 11:25:48 -0700197 l->connect_to = connect_to;
Dan Alberte9fca142015-02-18 18:03:26 -0800198 if (l->transport != transport) {
Yabin Cuib3298242015-08-28 15:09:44 -0700199 l->transport->RemoveDisconnect(&l->disconnect);
Dan Alberte9fca142015-02-18 18:03:26 -0800200 l->transport = transport;
Yabin Cuib3298242015-08-28 15:09:44 -0700201 l->transport->AddDisconnect(&l->disconnect);
Dan Alberte9fca142015-02-18 18:03:26 -0800202 }
203 return INSTALL_STATUS_OK;
204 }
205 }
206
Josh Gao28589bb2018-03-07 16:51:08 -0800207 auto listener = std::make_unique<alistener>(local_name, connect_to);
Dan Alberte9fca142015-02-18 18:03:26 -0800208
Josh Gaocfb21412016-08-24 18:38:44 -0700209 int resolved = 0;
210 listener->fd = socket_spec_listen(listener->local_name, error, &resolved);
Dan Albertbac34742015-02-25 17:51:28 -0800211 if (listener->fd < 0) {
Dan Albertbac34742015-02-25 17:51:28 -0800212 return INSTALL_STATUS_CANNOT_BIND;
Dan Alberte9fca142015-02-18 18:03:26 -0800213 }
214
Josh Gaocfb21412016-08-24 18:38:44 -0700215 // If the caller requested port 0, update the listener name with the resolved port.
216 if (resolved != 0) {
217 listener->local_name = android::base::StringPrintf("tcp:%d", resolved);
218 if (resolved_tcp_port) {
219 *resolved_tcp_port = resolved;
220 }
221 }
222
Dan Albertbac34742015-02-25 17:51:28 -0800223 close_on_exec(listener->fd);
David Purselleaae97e2016-04-07 11:25:48 -0700224 if (listener->connect_to == "*smartsocket*") {
225 fdevent_install(&listener->fde, listener->fd, ss_listener_event_func, listener.get());
Dan Alberte9fca142015-02-18 18:03:26 -0800226 } else {
David Purselleaae97e2016-04-07 11:25:48 -0700227 fdevent_install(&listener->fde, listener->fd, listener_event_func, listener.get());
Dan Alberte9fca142015-02-18 18:03:26 -0800228 }
Dan Albertbac34742015-02-25 17:51:28 -0800229 fdevent_set(&listener->fde, FDE_READ);
Dan Alberte9fca142015-02-18 18:03:26 -0800230
Dan Albertbac34742015-02-25 17:51:28 -0800231 listener->transport = transport;
Dan Alberte9fca142015-02-18 18:03:26 -0800232
233 if (transport) {
David Purselleaae97e2016-04-07 11:25:48 -0700234 listener->disconnect.opaque = listener.get();
Josh Gao01b7bc42017-05-09 13:43:35 -0700235 listener->disconnect.func = listener_disconnect;
Yabin Cuib3298242015-08-28 15:09:44 -0700236 transport->AddDisconnect(&listener->disconnect);
Dan Alberte9fca142015-02-18 18:03:26 -0800237 }
Dan Alberte9fca142015-02-18 18:03:26 -0800238
David Purselleaae97e2016-04-07 11:25:48 -0700239 listener_list.push_back(std::move(listener));
240 return INSTALL_STATUS_OK;
Dan Alberte9fca142015-02-18 18:03:26 -0800241}