• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
alistener(const std::string & _local_name,const std::string & _connect_to)57 alistener::alistener(const std::string& _local_name, const std::string& _connect_to)
58     : local_name(_local_name), connect_to(_connect_to) {
59 }
60 
~alistener()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 
ss_listener_event_func(int _fd,unsigned ev,void * _l)76 static void ss_listener_event_func(int _fd, unsigned ev, void *_l) {
77     if (ev & FDE_READ) {
78         unique_fd fd(adb_socket_accept(_fd, nullptr, nullptr));
79         if (fd < 0) return;
80 
81         int rcv_buf_size = CHUNK_SIZE;
82         adb_setsockopt(fd.get(), SOL_SOCKET, SO_RCVBUF, &rcv_buf_size, sizeof(rcv_buf_size));
83 
84         asocket* s = create_local_socket(std::move(fd));
85         if (s) {
86             connect_to_smartsocket(s);
87             return;
88         }
89     }
90 }
91 
listener_event_func(int _fd,unsigned ev,void * _l)92 static void listener_event_func(int _fd, unsigned ev, void* _l)
93 {
94     alistener* listener = reinterpret_cast<alistener*>(_l);
95 
96     if (ev & FDE_READ) {
97         unique_fd fd(adb_socket_accept(_fd, nullptr, nullptr));
98         if (fd < 0) {
99             return;
100         }
101 
102         asocket* s = create_local_socket(std::move(fd));
103         if (s) {
104             s->transport = listener->transport;
105             connect_to_remote(s, listener->connect_to);
106             return;
107         }
108     }
109 }
110 
111 // Called as a transport disconnect function. |arg| is the raw alistener*.
listener_disconnect(void * arg,atransport *)112 static void listener_disconnect(void* arg, atransport*) EXCLUDES(listener_list_mutex) {
113     std::lock_guard<std::mutex> lock(listener_list_mutex);
114     for (auto iter = listener_list.begin(); iter != listener_list.end(); ++iter) {
115         if (iter->get() == arg) {
116             (*iter)->transport = nullptr;
117             listener_list.erase(iter);
118             return;
119         }
120     }
121 }
122 
123 // Write the list of current listeners (network redirections) into a string.
format_listeners()124 std::string format_listeners() EXCLUDES(listener_list_mutex) {
125     std::lock_guard<std::mutex> lock(listener_list_mutex);
126     std::string result;
127     for (auto& l : listener_list) {
128         // Ignore special listeners like those for *smartsocket*
129         if (l->connect_to[0] == '*') {
130             continue;
131         }
132         //  <device-serial> " " <local-name> " " <remote-name> "\n"
133         // Entries from "adb reverse" have no serial.
134         android::base::StringAppendF(
135                 &result, "%s %s %s\n",
136                 !l->transport->serial.empty() ? l->transport->serial.c_str() : "(reverse)",
137                 l->local_name.c_str(), l->connect_to.c_str());
138     }
139     return result;
140 }
141 
remove_listener(const char * local_name,atransport * transport)142 InstallStatus remove_listener(const char* local_name, atransport* transport)
143     EXCLUDES(listener_list_mutex) {
144     std::lock_guard<std::mutex> lock(listener_list_mutex);
145     for (auto iter = listener_list.begin(); iter != listener_list.end(); ++iter) {
146         if (local_name == (*iter)->local_name) {
147             listener_list.erase(iter);
148             return INSTALL_STATUS_OK;
149         }
150     }
151     return INSTALL_STATUS_LISTENER_NOT_FOUND;
152 }
153 
remove_all_listeners()154 void remove_all_listeners() EXCLUDES(listener_list_mutex) {
155     std::lock_guard<std::mutex> lock(listener_list_mutex);
156     auto iter = listener_list.begin();
157     while (iter != listener_list.end()) {
158         // Never remove smart sockets.
159         if ((*iter)->connect_to[0] == '*') {
160             ++iter;
161         } else {
162             iter = listener_list.erase(iter);
163         }
164     }
165 }
166 
close_smartsockets()167 void close_smartsockets() EXCLUDES(listener_list_mutex) {
168     std::lock_guard<std::mutex> lock(listener_list_mutex);
169     auto pred = [](const std::unique_ptr<alistener>& listener) {
170         return listener->local_name == "*smartsocket*";
171     };
172     listener_list.remove_if(pred);
173 }
174 
install_listener(const std::string & local_name,const char * connect_to,atransport * transport,int no_rebind,int * resolved_tcp_port,std::string * error)175 InstallStatus install_listener(const std::string& local_name, const char* connect_to,
176                                atransport* transport, int no_rebind, int* resolved_tcp_port,
177                                std::string* error) EXCLUDES(listener_list_mutex) {
178     std::lock_guard<std::mutex> lock(listener_list_mutex);
179     for (auto& l : listener_list) {
180         if (local_name == l->local_name) {
181             // Can't repurpose a smartsocket.
182             if(l->connect_to[0] == '*') {
183                 *error = "cannot repurpose smartsocket";
184                 return INSTALL_STATUS_INTERNAL_ERROR;
185             }
186 
187             // Can't repurpose a listener if 'no_rebind' is true.
188             if (no_rebind) {
189                 *error = "cannot rebind";
190                 return INSTALL_STATUS_CANNOT_REBIND;
191             }
192 
193             l->connect_to = connect_to;
194             if (l->transport != transport) {
195                 l->transport->RemoveDisconnect(&l->disconnect);
196                 l->transport = transport;
197                 l->transport->AddDisconnect(&l->disconnect);
198             }
199             return INSTALL_STATUS_OK;
200         }
201     }
202 
203     auto listener = std::make_unique<alistener>(local_name, connect_to);
204 
205     int resolved = 0;
206     listener->fd = socket_spec_listen(listener->local_name, error, &resolved);
207     if (listener->fd < 0) {
208         return INSTALL_STATUS_CANNOT_BIND;
209     }
210 
211     // If the caller requested port 0, update the listener name with the resolved port.
212     if (resolved != 0) {
213         listener->local_name = android::base::StringPrintf("tcp:%d", resolved);
214         if (resolved_tcp_port) {
215             *resolved_tcp_port = resolved;
216         }
217     }
218 
219     close_on_exec(listener->fd);
220     if (listener->connect_to == "*smartsocket*") {
221         listener->fde = fdevent_create(listener->fd, ss_listener_event_func, listener.get());
222     } else {
223         listener->fde = fdevent_create(listener->fd, listener_event_func, listener.get());
224     }
225     fdevent_set(listener->fde, FDE_READ);
226 
227     listener->transport = transport;
228 
229     if (transport) {
230         listener->disconnect.opaque = listener.get();
231         listener->disconnect.func = listener_disconnect;
232         transport->AddDisconnect(&listener->disconnect);
233     }
234 
235     listener_list.push_back(std::move(listener));
236     return INSTALL_STATUS_OK;
237 }
238