blob: 3fc4719cf1a6514236c630c78df11e0fd645ec90 [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>
23
Dan Alberte9fca142015-02-18 18:03:26 -080024#include "sysdeps.h"
Dan Albert76649012015-02-24 15:51:19 -080025#include "transport.h"
Dan Alberte9fca142015-02-18 18:03:26 -080026
27int gListenAll = 0; /* Not static because it is used in commandline.c. */
28
29alistener listener_list = {
30 .next = &listener_list,
31 .prev = &listener_list,
32};
33
34void ss_listener_event_func(int _fd, unsigned ev, void *_l)
35{
36 asocket *s;
37
38 if(ev & FDE_READ) {
39 struct sockaddr addr;
40 socklen_t alen;
41 int fd;
42
43 alen = sizeof(addr);
44 fd = adb_socket_accept(_fd, &addr, &alen);
45 if(fd < 0) return;
46
47 adb_socket_setbufsize(fd, CHUNK_SIZE);
48
49 s = create_local_socket(fd);
50 if(s) {
51 connect_to_smartsocket(s);
52 return;
53 }
54
55 adb_close(fd);
56 }
57}
58
Dan Albertbac34742015-02-25 17:51:28 -080059void listener_event_func(int _fd, unsigned ev, void* _l)
Dan Alberte9fca142015-02-18 18:03:26 -080060{
Dan Albertbac34742015-02-25 17:51:28 -080061 alistener* listener = reinterpret_cast<alistener*>(_l);
Dan Alberte9fca142015-02-18 18:03:26 -080062 asocket *s;
63
Dan Albertbac34742015-02-25 17:51:28 -080064 if (ev & FDE_READ) {
Dan Alberte9fca142015-02-18 18:03:26 -080065 struct sockaddr addr;
66 socklen_t alen;
67 int fd;
68
69 alen = sizeof(addr);
70 fd = adb_socket_accept(_fd, &addr, &alen);
Dan Albertbac34742015-02-25 17:51:28 -080071 if (fd < 0) {
72 return;
73 }
Dan Alberte9fca142015-02-18 18:03:26 -080074
75 s = create_local_socket(fd);
Dan Albertbac34742015-02-25 17:51:28 -080076 if (s) {
77 s->transport = listener->transport;
78 connect_to_remote(s, listener->connect_to);
Dan Alberte9fca142015-02-18 18:03:26 -080079 return;
80 }
81
82 adb_close(fd);
83 }
84}
85
86static void free_listener(alistener* l)
87{
88 if (l->next) {
89 l->next->prev = l->prev;
90 l->prev->next = l->next;
91 l->next = l->prev = l;
92 }
93
94 // closes the corresponding fd
95 fdevent_remove(&l->fde);
96
97 if (l->local_name)
98 free((char*)l->local_name);
99
100 if (l->connect_to)
101 free((char*)l->connect_to);
102
103 if (l->transport) {
104 remove_transport_disconnect(l->transport, &l->disconnect);
105 }
106 free(l);
107}
108
Dan Albertbac34742015-02-25 17:51:28 -0800109void listener_disconnect(void* listener, atransport* t)
Dan Alberte9fca142015-02-18 18:03:26 -0800110{
Dan Albertbac34742015-02-25 17:51:28 -0800111 free_listener(reinterpret_cast<alistener*>(listener));
Dan Alberte9fca142015-02-18 18:03:26 -0800112}
113
114int local_name_to_fd(const char *name)
115{
116 int port;
117
118 if(!strncmp("tcp:", name, 4)){
119 int ret;
120 port = atoi(name + 4);
121
122 if (gListenAll > 0) {
123 ret = socket_inaddr_any_server(port, SOCK_STREAM);
124 } else {
125 ret = socket_loopback_server(port, SOCK_STREAM);
126 }
127
128 return ret;
129 }
130#ifndef HAVE_WIN32_IPC /* no Unix-domain sockets on Win32 */
131 // It's non-sensical to support the "reserved" space on the adb host side
132 if(!strncmp(name, "local:", 6)) {
133 return socket_local_server(name + 6,
134 ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM);
135 } else if(!strncmp(name, "localabstract:", 14)) {
136 return socket_local_server(name + 14,
137 ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM);
138 } else if(!strncmp(name, "localfilesystem:", 16)) {
139 return socket_local_server(name + 16,
140 ANDROID_SOCKET_NAMESPACE_FILESYSTEM, SOCK_STREAM);
141 }
142
143#endif
144 printf("unknown local portname '%s'\n", name);
145 return -1;
146}
147
Elliott Hughese67f1f82015-04-30 17:32:03 -0700148// Write the list of current listeners (network redirections) into a string.
149std::string format_listeners() {
150 std::string result;
151 for (alistener* l = listener_list.next; l != &listener_list; l = l->next) {
Dan Alberte9fca142015-02-18 18:03:26 -0800152 // Ignore special listeners like those for *smartsocket*
Elliott Hughese67f1f82015-04-30 17:32:03 -0700153 if (l->connect_to[0] == '*') {
154 continue;
Dan Alberte9fca142015-02-18 18:03:26 -0800155 }
Elliott Hughese67f1f82015-04-30 17:32:03 -0700156 // <device-serial> " " <local-name> " " <remote-name> "\n"
157 android::base::StringAppendF(&result, "%s %s %s\n",
158 l->transport->serial, l->local_name, l->connect_to);
Dan Alberte9fca142015-02-18 18:03:26 -0800159 }
160 return result;
161}
162
Elliott Hughes7b506092015-04-20 08:09:20 -0700163install_status_t remove_listener(const char *local_name, atransport* transport)
Dan Alberte9fca142015-02-18 18:03:26 -0800164{
165 alistener *l;
166
167 for (l = listener_list.next; l != &listener_list; l = l->next) {
168 if (!strcmp(local_name, l->local_name)) {
169 listener_disconnect(l, l->transport);
Elliott Hughes7b506092015-04-20 08:09:20 -0700170 return INSTALL_STATUS_OK;
Dan Alberte9fca142015-02-18 18:03:26 -0800171 }
172 }
Elliott Hughes7b506092015-04-20 08:09:20 -0700173 return INSTALL_STATUS_LISTENER_NOT_FOUND;
Dan Alberte9fca142015-02-18 18:03:26 -0800174}
175
176void remove_all_listeners(void)
177{
178 alistener *l, *l_next;
179 for (l = listener_list.next; l != &listener_list; l = l_next) {
180 l_next = l->next;
181 // Never remove smart sockets.
182 if (l->connect_to[0] == '*')
183 continue;
184 listener_disconnect(l, l->transport);
185 }
186}
187
Elliott Hughesab52c182015-05-01 17:04:38 -0700188install_status_t install_listener(const std::string& local_name,
Dan Alberte9fca142015-02-18 18:03:26 -0800189 const char *connect_to,
190 atransport* transport,
191 int no_rebind)
192{
Dan Albertbac34742015-02-25 17:51:28 -0800193 for (alistener* l = listener_list.next; l != &listener_list; l = l->next) {
Elliott Hughesab52c182015-05-01 17:04:38 -0700194 if (local_name == l->local_name) {
Dan Albertbac34742015-02-25 17:51:28 -0800195 char* cto;
Dan Alberte9fca142015-02-18 18:03:26 -0800196
Dan Albertbac34742015-02-25 17:51:28 -0800197 /* can't repurpose a smartsocket */
Dan Alberte9fca142015-02-18 18:03:26 -0800198 if(l->connect_to[0] == '*') {
199 return INSTALL_STATUS_INTERNAL_ERROR;
200 }
201
Dan Albertbac34742015-02-25 17:51:28 -0800202 /* can't repurpose a listener if 'no_rebind' is true */
Dan Alberte9fca142015-02-18 18:03:26 -0800203 if (no_rebind) {
204 return INSTALL_STATUS_CANNOT_REBIND;
205 }
206
207 cto = strdup(connect_to);
208 if(cto == 0) {
209 return INSTALL_STATUS_INTERNAL_ERROR;
210 }
211
Dan Alberte9fca142015-02-18 18:03:26 -0800212 free((void*) l->connect_to);
213 l->connect_to = cto;
214 if (l->transport != transport) {
215 remove_transport_disconnect(l->transport, &l->disconnect);
216 l->transport = transport;
217 add_transport_disconnect(l->transport, &l->disconnect);
218 }
219 return INSTALL_STATUS_OK;
220 }
221 }
222
Dan Albertbac34742015-02-25 17:51:28 -0800223 alistener* listener = reinterpret_cast<alistener*>(
224 calloc(1, sizeof(alistener)));
225 if (listener == nullptr) {
226 goto nomem;
227 }
Dan Alberte9fca142015-02-18 18:03:26 -0800228
Elliott Hughesab52c182015-05-01 17:04:38 -0700229 listener->local_name = strdup(local_name.c_str());
Dan Albertbac34742015-02-25 17:51:28 -0800230 if (listener->local_name == nullptr) {
231 goto nomem;
232 }
Dan Alberte9fca142015-02-18 18:03:26 -0800233
Dan Albertbac34742015-02-25 17:51:28 -0800234 listener->connect_to = strdup(connect_to);
235 if (listener->connect_to == nullptr) {
236 goto nomem;
237 }
238
Elliott Hughesab52c182015-05-01 17:04:38 -0700239 listener->fd = local_name_to_fd(listener->local_name);
Dan Albertbac34742015-02-25 17:51:28 -0800240 if (listener->fd < 0) {
Elliott Hughesab52c182015-05-01 17:04:38 -0700241 printf("cannot bind '%s': %s\n", listener->local_name, strerror(errno));
Dan Albertbac34742015-02-25 17:51:28 -0800242 free(listener->local_name);
243 free(listener->connect_to);
244 free(listener);
Dan Albertbac34742015-02-25 17:51:28 -0800245 return INSTALL_STATUS_CANNOT_BIND;
Dan Alberte9fca142015-02-18 18:03:26 -0800246 }
247
Dan Albertbac34742015-02-25 17:51:28 -0800248 close_on_exec(listener->fd);
249 if (!strcmp(listener->connect_to, "*smartsocket*")) {
250 fdevent_install(&listener->fde, listener->fd, ss_listener_event_func,
251 listener);
Dan Alberte9fca142015-02-18 18:03:26 -0800252 } else {
Dan Albertbac34742015-02-25 17:51:28 -0800253 fdevent_install(&listener->fde, listener->fd, listener_event_func,
254 listener);
Dan Alberte9fca142015-02-18 18:03:26 -0800255 }
Dan Albertbac34742015-02-25 17:51:28 -0800256 fdevent_set(&listener->fde, FDE_READ);
Dan Alberte9fca142015-02-18 18:03:26 -0800257
Dan Albertbac34742015-02-25 17:51:28 -0800258 listener->next = &listener_list;
259 listener->prev = listener_list.prev;
260 listener->next->prev = listener;
261 listener->prev->next = listener;
262 listener->transport = transport;
Dan Alberte9fca142015-02-18 18:03:26 -0800263
264 if (transport) {
Dan Albertbac34742015-02-25 17:51:28 -0800265 listener->disconnect.opaque = listener;
266 listener->disconnect.func = listener_disconnect;
267 add_transport_disconnect(transport, &listener->disconnect);
Dan Alberte9fca142015-02-18 18:03:26 -0800268 }
269 return INSTALL_STATUS_OK;
270
271nomem:
272 fatal("cannot allocate listener");
273 return INSTALL_STATUS_INTERNAL_ERROR;
274}