blob: 1b75090a9228d37433a18fb559eb1b04bc866c9a [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 Hughese67f1f82015-04-30 17:32:03 -070022#include <base/stringprintf.h>
Elliott Hughes381cfa92015-07-23 17:12:58 -070023#include <cutils/sockets.h>
Elliott Hughese67f1f82015-04-30 17:32:03 -070024
Dan Alberte9fca142015-02-18 18:03:26 -080025#include "sysdeps.h"
Dan Albert76649012015-02-24 15:51:19 -080026#include "transport.h"
Dan Alberte9fca142015-02-18 18:03:26 -080027
28int gListenAll = 0; /* Not static because it is used in commandline.c. */
29
Elliott Hughes424af022015-05-29 17:55:19 -070030static alistener listener_list = {
Dan Alberte9fca142015-02-18 18:03:26 -080031 .next = &listener_list,
32 .prev = &listener_list,
33};
34
Elliott Hughes424af022015-05-29 17:55:19 -070035static void ss_listener_event_func(int _fd, unsigned ev, void *_l) {
Elliott Hughescc65c3b2015-11-20 22:01:06 -080036 if (ev & FDE_READ) {
Dan Alberte9fca142015-02-18 18:03:26 -080037 struct sockaddr addr;
Elliott Hughescc65c3b2015-11-20 22:01:06 -080038 socklen_t alen = sizeof(addr);
39 int fd = adb_socket_accept(_fd, &addr, &alen);
40 if (fd < 0) return;
Dan Alberte9fca142015-02-18 18:03:26 -080041
Elliott Hughescc65c3b2015-11-20 22:01:06 -080042 int rcv_buf_size = CHUNK_SIZE;
43 adb_setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &rcv_buf_size, sizeof(rcv_buf_size));
Dan Alberte9fca142015-02-18 18:03:26 -080044
Elliott Hughescc65c3b2015-11-20 22:01:06 -080045 asocket* s = create_local_socket(fd);
46 if (s) {
Dan Alberte9fca142015-02-18 18:03:26 -080047 connect_to_smartsocket(s);
48 return;
49 }
50
51 adb_close(fd);
52 }
53}
54
Elliott Hughes424af022015-05-29 17:55:19 -070055static void listener_event_func(int _fd, unsigned ev, void* _l)
Dan Alberte9fca142015-02-18 18:03:26 -080056{
Dan Albertbac34742015-02-25 17:51:28 -080057 alistener* listener = reinterpret_cast<alistener*>(_l);
Dan Alberte9fca142015-02-18 18:03:26 -080058 asocket *s;
59
Dan Albertbac34742015-02-25 17:51:28 -080060 if (ev & FDE_READ) {
Dan Alberte9fca142015-02-18 18:03:26 -080061 struct sockaddr addr;
62 socklen_t alen;
63 int fd;
64
65 alen = sizeof(addr);
66 fd = adb_socket_accept(_fd, &addr, &alen);
Dan Albertbac34742015-02-25 17:51:28 -080067 if (fd < 0) {
68 return;
69 }
Dan Alberte9fca142015-02-18 18:03:26 -080070
71 s = create_local_socket(fd);
Dan Albertbac34742015-02-25 17:51:28 -080072 if (s) {
73 s->transport = listener->transport;
74 connect_to_remote(s, listener->connect_to);
Dan Alberte9fca142015-02-18 18:03:26 -080075 return;
76 }
77
78 adb_close(fd);
79 }
80}
81
82static void free_listener(alistener* l)
83{
84 if (l->next) {
85 l->next->prev = l->prev;
86 l->prev->next = l->next;
87 l->next = l->prev = l;
88 }
89
90 // closes the corresponding fd
91 fdevent_remove(&l->fde);
92
93 if (l->local_name)
94 free((char*)l->local_name);
95
96 if (l->connect_to)
97 free((char*)l->connect_to);
98
99 if (l->transport) {
Yabin Cuib3298242015-08-28 15:09:44 -0700100 l->transport->RemoveDisconnect(&l->disconnect);
Dan Alberte9fca142015-02-18 18:03:26 -0800101 }
102 free(l);
103}
104
Yabin Cuib3298242015-08-28 15:09:44 -0700105static void listener_disconnect(void* arg, atransport*) {
106 alistener* listener = reinterpret_cast<alistener*>(arg);
107 listener->transport = nullptr;
108 free_listener(listener);
Dan Alberte9fca142015-02-18 18:03:26 -0800109}
110
Spencer Low5200c662015-07-30 23:07:55 -0700111static int local_name_to_fd(const char* name, std::string* error) {
Elliott Hughes424af022015-05-29 17:55:19 -0700112 if (!strncmp("tcp:", name, 4)) {
113 int port = atoi(name + 4);
Dan Alberte9fca142015-02-18 18:03:26 -0800114 if (gListenAll > 0) {
Spencer Low5200c662015-07-30 23:07:55 -0700115 return network_inaddr_any_server(port, SOCK_STREAM, error);
Dan Alberte9fca142015-02-18 18:03:26 -0800116 } else {
Spencer Low5200c662015-07-30 23:07:55 -0700117 return network_loopback_server(port, SOCK_STREAM, error);
Dan Alberte9fca142015-02-18 18:03:26 -0800118 }
Dan Alberte9fca142015-02-18 18:03:26 -0800119 }
Elliott Hughes095307e2015-07-09 10:03:18 -0700120#if !defined(_WIN32) // No Unix-domain sockets on Windows.
Elliott Hughes424af022015-05-29 17:55:19 -0700121 // It's nonsensical to support the "reserved" space on the adb host side
122 if (!strncmp(name, "local:", 6)) {
Spencer Low5200c662015-07-30 23:07:55 -0700123 return network_local_server(name + 6,
124 ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM, error);
Elliott Hughes424af022015-05-29 17:55:19 -0700125 } else if (!strncmp(name, "localabstract:", 14)) {
Spencer Low5200c662015-07-30 23:07:55 -0700126 return network_local_server(name + 14,
127 ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM, error);
Elliott Hughes424af022015-05-29 17:55:19 -0700128 } else if (!strncmp(name, "localfilesystem:", 16)) {
Spencer Low5200c662015-07-30 23:07:55 -0700129 return network_local_server(name + 16,
130 ANDROID_SOCKET_NAMESPACE_FILESYSTEM, SOCK_STREAM, error);
Dan Alberte9fca142015-02-18 18:03:26 -0800131 }
132
133#endif
Spencer Low5200c662015-07-30 23:07:55 -0700134 *error = android::base::StringPrintf("unknown local portname '%s'", name);
Dan Alberte9fca142015-02-18 18:03:26 -0800135 return -1;
136}
137
Elliott Hughese67f1f82015-04-30 17:32:03 -0700138// Write the list of current listeners (network redirections) into a string.
139std::string format_listeners() {
140 std::string result;
141 for (alistener* l = listener_list.next; l != &listener_list; l = l->next) {
Dan Alberte9fca142015-02-18 18:03:26 -0800142 // Ignore special listeners like those for *smartsocket*
Elliott Hughese67f1f82015-04-30 17:32:03 -0700143 if (l->connect_to[0] == '*') {
144 continue;
Dan Alberte9fca142015-02-18 18:03:26 -0800145 }
Elliott Hughese67f1f82015-04-30 17:32:03 -0700146 // <device-serial> " " <local-name> " " <remote-name> "\n"
Elliott Hughes34c20bb2015-07-21 17:09:06 -0700147 // Entries from "adb reverse" have no serial.
Elliott Hughese67f1f82015-04-30 17:32:03 -0700148 android::base::StringAppendF(&result, "%s %s %s\n",
Elliott Hughes34c20bb2015-07-21 17:09:06 -0700149 l->transport->serial ? l->transport->serial : "(reverse)",
150 l->local_name, l->connect_to);
Dan Alberte9fca142015-02-18 18:03:26 -0800151 }
152 return result;
153}
154
Elliott Hughes3bd73c12015-05-05 13:10:43 -0700155InstallStatus remove_listener(const char *local_name, atransport* transport) {
Dan Alberte9fca142015-02-18 18:03:26 -0800156 alistener *l;
157
158 for (l = listener_list.next; l != &listener_list; l = l->next) {
159 if (!strcmp(local_name, l->local_name)) {
Yabin Cuib3298242015-08-28 15:09:44 -0700160 free_listener(l);
Elliott Hughes7b506092015-04-20 08:09:20 -0700161 return INSTALL_STATUS_OK;
Dan Alberte9fca142015-02-18 18:03:26 -0800162 }
163 }
Elliott Hughes7b506092015-04-20 08:09:20 -0700164 return INSTALL_STATUS_LISTENER_NOT_FOUND;
Dan Alberte9fca142015-02-18 18:03:26 -0800165}
166
167void remove_all_listeners(void)
168{
169 alistener *l, *l_next;
170 for (l = listener_list.next; l != &listener_list; l = l_next) {
171 l_next = l->next;
172 // Never remove smart sockets.
173 if (l->connect_to[0] == '*')
174 continue;
Yabin Cuib3298242015-08-28 15:09:44 -0700175 free_listener(l);
Dan Alberte9fca142015-02-18 18:03:26 -0800176 }
177}
178
Elliott Hughes3bd73c12015-05-05 13:10:43 -0700179InstallStatus install_listener(const std::string& local_name,
Dan Alberte9fca142015-02-18 18:03:26 -0800180 const char *connect_to,
181 atransport* transport,
Spencer Low5200c662015-07-30 23:07:55 -0700182 int no_rebind,
183 std::string* error)
Dan Alberte9fca142015-02-18 18:03:26 -0800184{
Dan Albertbac34742015-02-25 17:51:28 -0800185 for (alistener* l = listener_list.next; l != &listener_list; l = l->next) {
Elliott Hughesab52c182015-05-01 17:04:38 -0700186 if (local_name == l->local_name) {
Dan Albertbac34742015-02-25 17:51:28 -0800187 char* cto;
Dan Alberte9fca142015-02-18 18:03:26 -0800188
Dan Albertbac34742015-02-25 17:51:28 -0800189 /* can't repurpose a smartsocket */
Dan Alberte9fca142015-02-18 18:03:26 -0800190 if(l->connect_to[0] == '*') {
Spencer Lowbf7c6052015-08-11 16:45:32 -0700191 *error = "cannot repurpose smartsocket";
Dan Alberte9fca142015-02-18 18:03:26 -0800192 return INSTALL_STATUS_INTERNAL_ERROR;
193 }
194
Dan Albertbac34742015-02-25 17:51:28 -0800195 /* can't repurpose a listener if 'no_rebind' is true */
Dan Alberte9fca142015-02-18 18:03:26 -0800196 if (no_rebind) {
Spencer Lowbf7c6052015-08-11 16:45:32 -0700197 *error = "cannot rebind";
Dan Alberte9fca142015-02-18 18:03:26 -0800198 return INSTALL_STATUS_CANNOT_REBIND;
199 }
200
201 cto = strdup(connect_to);
202 if(cto == 0) {
Spencer Lowbf7c6052015-08-11 16:45:32 -0700203 *error = "cannot duplicate string";
Dan Alberte9fca142015-02-18 18:03:26 -0800204 return INSTALL_STATUS_INTERNAL_ERROR;
205 }
206
Dan Alberte9fca142015-02-18 18:03:26 -0800207 free((void*) l->connect_to);
208 l->connect_to = cto;
209 if (l->transport != transport) {
Yabin Cuib3298242015-08-28 15:09:44 -0700210 l->transport->RemoveDisconnect(&l->disconnect);
Dan Alberte9fca142015-02-18 18:03:26 -0800211 l->transport = transport;
Yabin Cuib3298242015-08-28 15:09:44 -0700212 l->transport->AddDisconnect(&l->disconnect);
Dan Alberte9fca142015-02-18 18:03:26 -0800213 }
214 return INSTALL_STATUS_OK;
215 }
216 }
217
Dan Albertbac34742015-02-25 17:51:28 -0800218 alistener* listener = reinterpret_cast<alistener*>(
219 calloc(1, sizeof(alistener)));
220 if (listener == nullptr) {
221 goto nomem;
222 }
Dan Alberte9fca142015-02-18 18:03:26 -0800223
Elliott Hughesab52c182015-05-01 17:04:38 -0700224 listener->local_name = strdup(local_name.c_str());
Dan Albertbac34742015-02-25 17:51:28 -0800225 if (listener->local_name == nullptr) {
226 goto nomem;
227 }
Dan Alberte9fca142015-02-18 18:03:26 -0800228
Dan Albertbac34742015-02-25 17:51:28 -0800229 listener->connect_to = strdup(connect_to);
230 if (listener->connect_to == nullptr) {
231 goto nomem;
232 }
233
Spencer Low5200c662015-07-30 23:07:55 -0700234 listener->fd = local_name_to_fd(listener->local_name, error);
Dan Albertbac34742015-02-25 17:51:28 -0800235 if (listener->fd < 0) {
236 free(listener->local_name);
237 free(listener->connect_to);
238 free(listener);
Dan Albertbac34742015-02-25 17:51:28 -0800239 return INSTALL_STATUS_CANNOT_BIND;
Dan Alberte9fca142015-02-18 18:03:26 -0800240 }
241
Dan Albertbac34742015-02-25 17:51:28 -0800242 close_on_exec(listener->fd);
243 if (!strcmp(listener->connect_to, "*smartsocket*")) {
244 fdevent_install(&listener->fde, listener->fd, ss_listener_event_func,
245 listener);
Dan Alberte9fca142015-02-18 18:03:26 -0800246 } else {
Dan Albertbac34742015-02-25 17:51:28 -0800247 fdevent_install(&listener->fde, listener->fd, listener_event_func,
248 listener);
Dan Alberte9fca142015-02-18 18:03:26 -0800249 }
Dan Albertbac34742015-02-25 17:51:28 -0800250 fdevent_set(&listener->fde, FDE_READ);
Dan Alberte9fca142015-02-18 18:03:26 -0800251
Dan Albertbac34742015-02-25 17:51:28 -0800252 listener->next = &listener_list;
253 listener->prev = listener_list.prev;
254 listener->next->prev = listener;
255 listener->prev->next = listener;
256 listener->transport = transport;
Dan Alberte9fca142015-02-18 18:03:26 -0800257
258 if (transport) {
Dan Albertbac34742015-02-25 17:51:28 -0800259 listener->disconnect.opaque = listener;
260 listener->disconnect.func = listener_disconnect;
Yabin Cuib3298242015-08-28 15:09:44 -0700261 transport->AddDisconnect(&listener->disconnect);
Dan Alberte9fca142015-02-18 18:03:26 -0800262 }
263 return INSTALL_STATUS_OK;
264
265nomem:
266 fatal("cannot allocate listener");
267 return INSTALL_STATUS_INTERNAL_ERROR;
268}