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 <algorithm> 23 #include <list> 24 #include <memory> 25 26 #include <android-base/stringprintf.h> 27 #include <android-base/strings.h> 28 #include <android-base/thread_annotations.h> 29 #include <cutils/sockets.h> 30 31 #include "socket_spec.h" 32 #include "sysdeps.h" 33 #include "transport.h" 34 35 // 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. 40 class alistener { 41 public: 42 alistener(const std::string& _local_name, const std::string& _connect_to); 43 ~alistener(); 44 45 fdevent* fde = nullptr; 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); 55 }; 56 57 alistener::alistener(const std::string& _local_name, const std::string& _connect_to) 58 : local_name(_local_name), connect_to(_connect_to) { 59 } 60 61 alistener::~alistener() { 62 // Closes the corresponding fd. 63 fdevent_destroy(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. 72 static auto& listener_list_mutex = *new std::mutex(); 73 typedef std::list<std::unique_ptr<alistener>> ListenerList; 74 static ListenerList& listener_list GUARDED_BY(listener_list_mutex) = *new ListenerList(); 75 76 #if ADB_HOST 77 static void ss_listener_event_func(int _fd, unsigned ev, void *_l) { 78 if (ev & FDE_READ) { 79 unique_fd fd(adb_socket_accept(_fd, nullptr, nullptr)); 80 if (fd < 0) return; 81 82 int rcv_buf_size = CHUNK_SIZE; 83 adb_setsockopt(fd.get(), SOL_SOCKET, SO_RCVBUF, &rcv_buf_size, sizeof(rcv_buf_size)); 84 85 asocket* s = create_local_socket(std::move(fd)); 86 if (s) { 87 connect_to_smartsocket(s); 88 return; 89 } 90 } 91 } 92 #endif 93 94 static void listener_event_func(int _fd, unsigned ev, void* _l) 95 { 96 alistener* listener = reinterpret_cast<alistener*>(_l); 97 98 if (ev & FDE_READ) { 99 unique_fd fd(adb_socket_accept(_fd, nullptr, nullptr)); 100 if (fd < 0) { 101 return; 102 } 103 104 asocket* s = create_local_socket(std::move(fd)); 105 if (s) { 106 s->transport = listener->transport; 107 connect_to_remote(s, listener->connect_to); 108 return; 109 } 110 } 111 } 112 113 // Called as a transport disconnect function. |arg| is the raw alistener*. 114 static void listener_disconnect(void* arg, atransport*) EXCLUDES(listener_list_mutex) { 115 std::lock_guard<std::mutex> lock(listener_list_mutex); 116 for (auto iter = listener_list.begin(); iter != listener_list.end(); ++iter) { 117 if (iter->get() == arg) { 118 (*iter)->transport = nullptr; 119 listener_list.erase(iter); 120 return; 121 } 122 } 123 } 124 125 // Write the list of current listeners (network redirections) into a string. 126 std::string format_listeners() EXCLUDES(listener_list_mutex) { 127 std::lock_guard<std::mutex> lock(listener_list_mutex); 128 std::string result; 129 for (auto& l : listener_list) { 130 // Ignore special listeners like those for *smartsocket* 131 if (l->connect_to[0] == '*') { 132 continue; 133 } 134 // <device-serial> " " <local-name> " " <remote-name> "\n" 135 // Entries from "adb reverse" have no serial. 136 android::base::StringAppendF( 137 &result, "%s %s %s\n", 138 !l->transport->serial.empty() ? l->transport->serial.c_str() : "(reverse)", 139 l->local_name.c_str(), l->connect_to.c_str()); 140 } 141 return result; 142 } 143 144 InstallStatus remove_listener(const char* local_name, atransport* transport) 145 EXCLUDES(listener_list_mutex) { 146 std::lock_guard<std::mutex> lock(listener_list_mutex); 147 for (auto iter = listener_list.begin(); iter != listener_list.end(); ++iter) { 148 if (local_name == (*iter)->local_name) { 149 listener_list.erase(iter); 150 return INSTALL_STATUS_OK; 151 } 152 } 153 return INSTALL_STATUS_LISTENER_NOT_FOUND; 154 } 155 156 void remove_all_listeners() EXCLUDES(listener_list_mutex) { 157 std::lock_guard<std::mutex> lock(listener_list_mutex); 158 auto iter = listener_list.begin(); 159 while (iter != listener_list.end()) { 160 // Never remove smart sockets. 161 if ((*iter)->connect_to[0] == '*') { 162 ++iter; 163 } else { 164 iter = listener_list.erase(iter); 165 } 166 } 167 } 168 169 void enable_server_sockets() EXCLUDES(listener_list_mutex) { 170 std::lock_guard<std::mutex> lock(listener_list_mutex); 171 for (auto& l : listener_list) { 172 if (l->connect_to == "*smartsocket*") { 173 fdevent_set(l->fde, FDE_READ); 174 } 175 } 176 } 177 178 #if ADB_HOST 179 void close_smartsockets() EXCLUDES(listener_list_mutex) { 180 std::lock_guard<std::mutex> lock(listener_list_mutex); 181 auto pred = [](const std::unique_ptr<alistener>& listener) { 182 return listener->local_name == "*smartsocket*"; 183 }; 184 listener_list.remove_if(pred); 185 } 186 #endif 187 188 InstallStatus install_listener(const std::string& local_name, const char* connect_to, 189 atransport* transport, int flags, int* resolved_tcp_port, 190 std::string* error) EXCLUDES(listener_list_mutex) { 191 std::lock_guard<std::mutex> lock(listener_list_mutex); 192 for (auto& l : listener_list) { 193 if (local_name == l->local_name) { 194 // Can't repurpose a smartsocket. 195 if (l->connect_to[0] == '*') { 196 *error = "cannot repurpose smartsocket"; 197 return INSTALL_STATUS_INTERNAL_ERROR; 198 } 199 200 // Can't repurpose a listener if INSTALL_LISTENER_NO_REBIND is set 201 if (flags & INSTALL_LISTENER_NO_REBIND) { 202 *error = "cannot rebind"; 203 return INSTALL_STATUS_CANNOT_REBIND; 204 } 205 206 l->connect_to = connect_to; 207 if (l->transport != transport) { 208 l->transport->RemoveDisconnect(&l->disconnect); 209 l->transport = transport; 210 l->transport->AddDisconnect(&l->disconnect); 211 } 212 return INSTALL_STATUS_OK; 213 } 214 } 215 216 auto listener = std::make_unique<alistener>(local_name, connect_to); 217 218 int resolved = 0; 219 listener->fd = socket_spec_listen(listener->local_name, error, &resolved); 220 if (listener->fd < 0) { 221 return INSTALL_STATUS_CANNOT_BIND; 222 } 223 224 // If the caller requested port 0, update the listener name with the resolved port. 225 if (resolved != 0) { 226 listener->local_name = android::base::StringPrintf("tcp:%d", resolved); 227 if (resolved_tcp_port) { 228 *resolved_tcp_port = resolved; 229 } 230 } 231 232 close_on_exec(listener->fd); 233 if (listener->connect_to == "*smartsocket*") { 234 #if ADB_HOST 235 listener->fde = fdevent_create(listener->fd, ss_listener_event_func, listener.get()); 236 #else 237 LOG(FATAL) << "attempted to connect to *smartsocket* in daemon"; 238 #endif 239 } else { 240 listener->fde = fdevent_create(listener->fd, listener_event_func, listener.get()); 241 } 242 if ((flags & INSTALL_LISTENER_DISABLED) == 0) { 243 fdevent_set(listener->fde, FDE_READ); 244 } 245 246 listener->transport = transport; 247 248 if (transport) { 249 listener->disconnect.opaque = listener.get(); 250 listener->disconnect.func = listener_disconnect; 251 transport->AddDisconnect(&listener->disconnect); 252 } 253 254 listener_list.push_back(std::move(listener)); 255 return INSTALL_STATUS_OK; 256 } 257