blob: f54603cade6c4b7cf293786f54a98f483fe2c6f6 [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
Elliott Hughes4f713192015-12-04 22:00:26 -080022#include <android-base/stringprintf.h>
David Purselleaae97e2016-04-07 11:25:48 -070023#include <android-base/strings.h>
Elliott Hughes381cfa92015-07-23 17:12:58 -070024#include <cutils/sockets.h>
Elliott Hughese67f1f82015-04-30 17:32:03 -070025
Dan Alberte9fca142015-02-18 18:03:26 -080026#include "sysdeps.h"
Dan Albert76649012015-02-24 15:51:19 -080027#include "transport.h"
Dan Alberte9fca142015-02-18 18:03:26 -080028
David Purselleaae97e2016-04-07 11:25:48 -070029// Not static because it is used in commandline.c.
30int gListenAll = 0;
Dan Alberte9fca142015-02-18 18:03:26 -080031
David Purselleaae97e2016-04-07 11:25:48 -070032// A listener is an entity which binds to a local port and, upon receiving a connection on that
33// port, creates an asocket to connect the new local connection to a specific remote service.
34//
35// TODO: some listeners read from the new connection to determine what exact service to connect to
36// on the far side.
37class alistener {
38 public:
39 alistener(const std::string& _local_name, const std::string& _connect_to);
40 ~alistener();
41
42 fdevent fde;
43 int fd = -1;
44
45 std::string local_name;
46 std::string connect_to;
47 atransport* transport = nullptr;
48 adisconnect disconnect;
49
50 private:
51 DISALLOW_COPY_AND_ASSIGN(alistener);
Dan Alberte9fca142015-02-18 18:03:26 -080052};
53
David Purselleaae97e2016-04-07 11:25:48 -070054alistener::alistener(const std::string& _local_name, const std::string& _connect_to)
55 : local_name(_local_name), connect_to(_connect_to) {
56}
57
58alistener::~alistener() {
59 // Closes the corresponding fd.
60 fdevent_remove(&fde);
61
62 if (transport) {
63 transport->RemoveDisconnect(&disconnect);
64 }
65}
66
67// listener_list retains ownership of all created alistener objects. Removing an alistener from
68// this list will cause it to be deleted.
69typedef std::list<std::unique_ptr<alistener>> ListenerList;
70static ListenerList& listener_list = *new ListenerList();
71
Elliott Hughes424af022015-05-29 17:55:19 -070072static void ss_listener_event_func(int _fd, unsigned ev, void *_l) {
Elliott Hughescc65c3b2015-11-20 22:01:06 -080073 if (ev & FDE_READ) {
Erik Kline7e16cc12015-12-01 17:27:59 +090074 sockaddr_storage ss;
75 sockaddr* addrp = reinterpret_cast<sockaddr*>(&ss);
76 socklen_t alen = sizeof(ss);
77 int fd = adb_socket_accept(_fd, addrp, &alen);
Elliott Hughescc65c3b2015-11-20 22:01:06 -080078 if (fd < 0) return;
Dan Alberte9fca142015-02-18 18:03:26 -080079
Elliott Hughescc65c3b2015-11-20 22:01:06 -080080 int rcv_buf_size = CHUNK_SIZE;
81 adb_setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &rcv_buf_size, sizeof(rcv_buf_size));
Dan Alberte9fca142015-02-18 18:03:26 -080082
Elliott Hughescc65c3b2015-11-20 22:01:06 -080083 asocket* s = create_local_socket(fd);
84 if (s) {
Dan Alberte9fca142015-02-18 18:03:26 -080085 connect_to_smartsocket(s);
86 return;
87 }
88
89 adb_close(fd);
90 }
91}
92
Elliott Hughes424af022015-05-29 17:55:19 -070093static void listener_event_func(int _fd, unsigned ev, void* _l)
Dan Alberte9fca142015-02-18 18:03:26 -080094{
Dan Albertbac34742015-02-25 17:51:28 -080095 alistener* listener = reinterpret_cast<alistener*>(_l);
Dan Alberte9fca142015-02-18 18:03:26 -080096 asocket *s;
97
Dan Albertbac34742015-02-25 17:51:28 -080098 if (ev & FDE_READ) {
Erik Kline7e16cc12015-12-01 17:27:59 +090099 sockaddr_storage ss;
100 sockaddr* addrp = reinterpret_cast<sockaddr*>(&ss);
Dan Alberte9fca142015-02-18 18:03:26 -0800101 socklen_t alen;
102 int fd;
103
Erik Kline7e16cc12015-12-01 17:27:59 +0900104 alen = sizeof(ss);
105 fd = adb_socket_accept(_fd, addrp, &alen);
Dan Albertbac34742015-02-25 17:51:28 -0800106 if (fd < 0) {
107 return;
108 }
Dan Alberte9fca142015-02-18 18:03:26 -0800109
110 s = create_local_socket(fd);
Dan Albertbac34742015-02-25 17:51:28 -0800111 if (s) {
112 s->transport = listener->transport;
David Purselleaae97e2016-04-07 11:25:48 -0700113 connect_to_remote(s, listener->connect_to.c_str());
Dan Alberte9fca142015-02-18 18:03:26 -0800114 return;
115 }
116
117 adb_close(fd);
118 }
119}
120
David Purselleaae97e2016-04-07 11:25:48 -0700121// Called as a transport disconnect function. |arg| is the raw alistener*.
Yabin Cuib3298242015-08-28 15:09:44 -0700122static void listener_disconnect(void* arg, atransport*) {
David Purselleaae97e2016-04-07 11:25:48 -0700123 for (auto iter = listener_list.begin(); iter != listener_list.end(); ++iter) {
124 if (iter->get() == arg) {
125 (*iter)->transport = nullptr;
126 listener_list.erase(iter);
127 return;
Dan Alberte9fca142015-02-18 18:03:26 -0800128 }
Dan Alberte9fca142015-02-18 18:03:26 -0800129 }
David Purselleaae97e2016-04-07 11:25:48 -0700130}
131
132int local_name_to_fd(alistener* listener, int* resolved_tcp_port, std::string* error) {
133 if (android::base::StartsWith(listener->local_name, "tcp:")) {
134 int requested_port = atoi(&listener->local_name[4]);
135 int sock = -1;
136 if (gListenAll > 0) {
137 sock = network_inaddr_any_server(requested_port, SOCK_STREAM, error);
138 } else {
139 sock = network_loopback_server(requested_port, SOCK_STREAM, error);
140 }
141
142 // If the caller requested port 0, update the listener name with the resolved port.
143 if (sock >= 0 && requested_port == 0) {
144 int local_port = adb_socket_get_local_port(sock);
145 if (local_port > 0) {
146 listener->local_name = android::base::StringPrintf("tcp:%d", local_port);
147 if (resolved_tcp_port != nullptr) {
148 *resolved_tcp_port = local_port;
149 }
150 }
151 }
152
153 return sock;
154 }
Elliott Hughes095307e2015-07-09 10:03:18 -0700155#if !defined(_WIN32) // No Unix-domain sockets on Windows.
David Purselleaae97e2016-04-07 11:25:48 -0700156 // It's nonsensical to support the "reserved" space on the adb host side.
157 if (android::base::StartsWith(listener->local_name, "local:")) {
158 return network_local_server(&listener->local_name[6], ANDROID_SOCKET_NAMESPACE_ABSTRACT,
159 SOCK_STREAM, error);
160 } else if (android::base::StartsWith(listener->local_name, "localabstract:")) {
161 return network_local_server(&listener->local_name[14], ANDROID_SOCKET_NAMESPACE_ABSTRACT,
162 SOCK_STREAM, error);
163 } else if (android::base::StartsWith(listener->local_name, "localfilesystem:")) {
164 return network_local_server(&listener->local_name[16], ANDROID_SOCKET_NAMESPACE_FILESYSTEM,
165 SOCK_STREAM, error);
Dan Alberte9fca142015-02-18 18:03:26 -0800166 }
167
168#endif
David Purselleaae97e2016-04-07 11:25:48 -0700169 *error = android::base::StringPrintf("unknown local portname '%s'",
170 listener->local_name.c_str());
Dan Alberte9fca142015-02-18 18:03:26 -0800171 return -1;
172}
173
Elliott Hughese67f1f82015-04-30 17:32:03 -0700174// Write the list of current listeners (network redirections) into a string.
175std::string format_listeners() {
176 std::string result;
David Purselleaae97e2016-04-07 11:25:48 -0700177 for (auto& l : listener_list) {
Dan Alberte9fca142015-02-18 18:03:26 -0800178 // Ignore special listeners like those for *smartsocket*
Elliott Hughese67f1f82015-04-30 17:32:03 -0700179 if (l->connect_to[0] == '*') {
180 continue;
Dan Alberte9fca142015-02-18 18:03:26 -0800181 }
Elliott Hughese67f1f82015-04-30 17:32:03 -0700182 // <device-serial> " " <local-name> " " <remote-name> "\n"
Elliott Hughes34c20bb2015-07-21 17:09:06 -0700183 // Entries from "adb reverse" have no serial.
Elliott Hughese67f1f82015-04-30 17:32:03 -0700184 android::base::StringAppendF(&result, "%s %s %s\n",
Elliott Hughes34c20bb2015-07-21 17:09:06 -0700185 l->transport->serial ? l->transport->serial : "(reverse)",
David Purselleaae97e2016-04-07 11:25:48 -0700186 l->local_name.c_str(), l->connect_to.c_str());
Dan Alberte9fca142015-02-18 18:03:26 -0800187 }
188 return result;
189}
190
David Purselleaae97e2016-04-07 11:25:48 -0700191InstallStatus remove_listener(const char* local_name, atransport* transport) {
192 for (auto iter = listener_list.begin(); iter != listener_list.end(); ++iter) {
193 if (local_name == (*iter)->local_name) {
194 listener_list.erase(iter);
Elliott Hughes7b506092015-04-20 08:09:20 -0700195 return INSTALL_STATUS_OK;
Dan Alberte9fca142015-02-18 18:03:26 -0800196 }
197 }
Elliott Hughes7b506092015-04-20 08:09:20 -0700198 return INSTALL_STATUS_LISTENER_NOT_FOUND;
Dan Alberte9fca142015-02-18 18:03:26 -0800199}
200
David Purselleaae97e2016-04-07 11:25:48 -0700201void remove_all_listeners() {
202 auto iter = listener_list.begin();
203 while (iter != listener_list.end()) {
Dan Alberte9fca142015-02-18 18:03:26 -0800204 // Never remove smart sockets.
David Purselleaae97e2016-04-07 11:25:48 -0700205 if ((*iter)->connect_to[0] == '*') {
206 ++iter;
207 } else {
208 iter = listener_list.erase(iter);
209 }
Dan Alberte9fca142015-02-18 18:03:26 -0800210 }
211}
212
David Purselleaae97e2016-04-07 11:25:48 -0700213InstallStatus install_listener(const std::string& local_name, const char* connect_to,
214 atransport* transport, int no_rebind, int* resolved_tcp_port,
215 std::string* error) {
216 for (auto& l : listener_list) {
Elliott Hughesab52c182015-05-01 17:04:38 -0700217 if (local_name == l->local_name) {
David Purselleaae97e2016-04-07 11:25:48 -0700218 // Can't repurpose a smartsocket.
Dan Alberte9fca142015-02-18 18:03:26 -0800219 if(l->connect_to[0] == '*') {
Spencer Lowbf7c6052015-08-11 16:45:32 -0700220 *error = "cannot repurpose smartsocket";
Dan Alberte9fca142015-02-18 18:03:26 -0800221 return INSTALL_STATUS_INTERNAL_ERROR;
222 }
223
David Purselleaae97e2016-04-07 11:25:48 -0700224 // Can't repurpose a listener if 'no_rebind' is true.
Dan Alberte9fca142015-02-18 18:03:26 -0800225 if (no_rebind) {
Spencer Lowbf7c6052015-08-11 16:45:32 -0700226 *error = "cannot rebind";
Dan Alberte9fca142015-02-18 18:03:26 -0800227 return INSTALL_STATUS_CANNOT_REBIND;
228 }
229
David Purselleaae97e2016-04-07 11:25:48 -0700230 l->connect_to = connect_to;
Dan Alberte9fca142015-02-18 18:03:26 -0800231 if (l->transport != transport) {
Yabin Cuib3298242015-08-28 15:09:44 -0700232 l->transport->RemoveDisconnect(&l->disconnect);
Dan Alberte9fca142015-02-18 18:03:26 -0800233 l->transport = transport;
Yabin Cuib3298242015-08-28 15:09:44 -0700234 l->transport->AddDisconnect(&l->disconnect);
Dan Alberte9fca142015-02-18 18:03:26 -0800235 }
236 return INSTALL_STATUS_OK;
237 }
238 }
239
David Purselleaae97e2016-04-07 11:25:48 -0700240 std::unique_ptr<alistener> listener(new alistener(local_name, connect_to));
Dan Alberte9fca142015-02-18 18:03:26 -0800241
David Purselleaae97e2016-04-07 11:25:48 -0700242 listener->fd = local_name_to_fd(listener.get(), resolved_tcp_port, error);
Dan Albertbac34742015-02-25 17:51:28 -0800243 if (listener->fd < 0) {
Dan Albertbac34742015-02-25 17:51:28 -0800244 return INSTALL_STATUS_CANNOT_BIND;
Dan Alberte9fca142015-02-18 18:03:26 -0800245 }
246
Dan Albertbac34742015-02-25 17:51:28 -0800247 close_on_exec(listener->fd);
David Purselleaae97e2016-04-07 11:25:48 -0700248 if (listener->connect_to == "*smartsocket*") {
249 fdevent_install(&listener->fde, listener->fd, ss_listener_event_func, listener.get());
Dan Alberte9fca142015-02-18 18:03:26 -0800250 } else {
David Purselleaae97e2016-04-07 11:25:48 -0700251 fdevent_install(&listener->fde, listener->fd, listener_event_func, listener.get());
Dan Alberte9fca142015-02-18 18:03:26 -0800252 }
Dan Albertbac34742015-02-25 17:51:28 -0800253 fdevent_set(&listener->fde, FDE_READ);
Dan Alberte9fca142015-02-18 18:03:26 -0800254
Dan Albertbac34742015-02-25 17:51:28 -0800255 listener->transport = transport;
Dan Alberte9fca142015-02-18 18:03:26 -0800256
257 if (transport) {
David Purselleaae97e2016-04-07 11:25:48 -0700258 listener->disconnect.opaque = listener.get();
Dan Albertbac34742015-02-25 17:51:28 -0800259 listener->disconnect.func = listener_disconnect;
Yabin Cuib3298242015-08-28 15:09:44 -0700260 transport->AddDisconnect(&listener->disconnect);
Dan Alberte9fca142015-02-18 18:03:26 -0800261 }
Dan Alberte9fca142015-02-18 18:03:26 -0800262
David Purselleaae97e2016-04-07 11:25:48 -0700263 listener_list.push_back(std::move(listener));
264 return INSTALL_STATUS_OK;
Dan Alberte9fca142015-02-18 18:03:26 -0800265}