1 /* 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 19 #include <stdio.h> 20 #include <stdlib.h> 21 22 #include <base/stringprintf.h> 23 24 #include "sysdeps.h" 25 #include "transport.h" 26 27 int gListenAll = 0; /* Not static because it is used in commandline.c. */ 28 29 alistener listener_list = { 30 .next = &listener_list, 31 .prev = &listener_list, 32 }; 33 34 void 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 59 void listener_event_func(int _fd, unsigned ev, void* _l) 60 { 61 alistener* listener = reinterpret_cast<alistener*>(_l); 62 asocket *s; 63 64 if (ev & FDE_READ) { 65 struct sockaddr addr; 66 socklen_t alen; 67 int fd; 68 69 alen = sizeof(addr); 70 fd = adb_socket_accept(_fd, &addr, &alen); 71 if (fd < 0) { 72 return; 73 } 74 75 s = create_local_socket(fd); 76 if (s) { 77 s->transport = listener->transport; 78 connect_to_remote(s, listener->connect_to); 79 return; 80 } 81 82 adb_close(fd); 83 } 84 } 85 86 static 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 109 void listener_disconnect(void* listener, atransport* t) 110 { 111 free_listener(reinterpret_cast<alistener*>(listener)); 112 } 113 114 int 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 148 // Write the list of current listeners (network redirections) into a string. 149 std::string format_listeners() { 150 std::string result; 151 for (alistener* l = listener_list.next; l != &listener_list; l = l->next) { 152 // Ignore special listeners like those for *smartsocket* 153 if (l->connect_to[0] == '*') { 154 continue; 155 } 156 // <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); 159 } 160 return result; 161 } 162 163 install_status_t remove_listener(const char *local_name, atransport* transport) 164 { 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); 170 return INSTALL_STATUS_OK; 171 } 172 } 173 return INSTALL_STATUS_LISTENER_NOT_FOUND; 174 } 175 176 void 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 188 install_status_t install_listener(const std::string& local_name, 189 const char *connect_to, 190 atransport* transport, 191 int no_rebind) 192 { 193 for (alistener* l = listener_list.next; l != &listener_list; l = l->next) { 194 if (local_name == l->local_name) { 195 char* cto; 196 197 /* can't repurpose a smartsocket */ 198 if(l->connect_to[0] == '*') { 199 return INSTALL_STATUS_INTERNAL_ERROR; 200 } 201 202 /* can't repurpose a listener if 'no_rebind' is true */ 203 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 212 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 223 alistener* listener = reinterpret_cast<alistener*>( 224 calloc(1, sizeof(alistener))); 225 if (listener == nullptr) { 226 goto nomem; 227 } 228 229 listener->local_name = strdup(local_name.c_str()); 230 if (listener->local_name == nullptr) { 231 goto nomem; 232 } 233 234 listener->connect_to = strdup(connect_to); 235 if (listener->connect_to == nullptr) { 236 goto nomem; 237 } 238 239 listener->fd = local_name_to_fd(listener->local_name); 240 if (listener->fd < 0) { 241 printf("cannot bind '%s': %s\n", listener->local_name, strerror(errno)); 242 free(listener->local_name); 243 free(listener->connect_to); 244 free(listener); 245 return INSTALL_STATUS_CANNOT_BIND; 246 } 247 248 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); 252 } else { 253 fdevent_install(&listener->fde, listener->fd, listener_event_func, 254 listener); 255 } 256 fdevent_set(&listener->fde, FDE_READ); 257 258 listener->next = &listener_list; 259 listener->prev = listener_list.prev; 260 listener->next->prev = listener; 261 listener->prev->next = listener; 262 listener->transport = transport; 263 264 if (transport) { 265 listener->disconnect.opaque = listener; 266 listener->disconnect.func = listener_disconnect; 267 add_transport_disconnect(transport, &listener->disconnect); 268 } 269 return INSTALL_STATUS_OK; 270 271 nomem: 272 fatal("cannot allocate listener"); 273 return INSTALL_STATUS_INTERNAL_ERROR; 274 } 275