1e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert/*
2e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert * Copyright (C) 2015 The Android Open Source Project
3e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert *
4e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert * Licensed under the Apache License, Version 2.0 (the "License");
5e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert * you may not use this file except in compliance with the License.
6e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert * You may obtain a copy of the License at
7e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert *
8e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert *      http://www.apache.org/licenses/LICENSE-2.0
9e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert *
10e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert * Unless required by applicable law or agreed to in writing, software
11e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert * distributed under the License is distributed on an "AS IS" BASIS,
12e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert * See the License for the specific language governing permissions and
14e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert * limitations under the License.
15e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert */
16e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert
17e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert#include "adb_listeners.h"
18e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert
19bf10647b61704a8dbe01b7381ebed5aefaa074e0Dan Albert#include <stdio.h>
203b967f52f2d859c736028b8c5983fd759c5e62b6Elliott Hughes#include <stdlib.h>
21bf10647b61704a8dbe01b7381ebed5aefaa074e0Dan Albert
224f71319df011d796a60a43fc1bc68e16fbf7d321Elliott Hughes#include <android-base/stringprintf.h>
23eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell#include <android-base/strings.h>
24381cfa9a8bc262dcd823a8bb6adc189595a2fe7dElliott Hughes#include <cutils/sockets.h>
25e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes
26cfb21412e5e3a716fc45601f35d3b58ce5f78f46Josh Gao#include "socket_spec.h"
27e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert#include "sysdeps.h"
287664901a355b959f312e9acff5a0fd31b7139623Dan Albert#include "transport.h"
29e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert
30eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell// A listener is an entity which binds to a local port and, upon receiving a connection on that
31eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell// port, creates an asocket to connect the new local connection to a specific remote service.
32eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell//
33eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell// TODO: some listeners read from the new connection to determine what exact service to connect to
34eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell// on the far side.
35eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursellclass alistener {
36eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell  public:
37eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell    alistener(const std::string& _local_name, const std::string& _connect_to);
38eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell    ~alistener();
39eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell
40eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell    fdevent fde;
41eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell    int fd = -1;
42eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell
43eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell    std::string local_name;
44eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell    std::string connect_to;
45eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell    atransport* transport = nullptr;
46eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell    adisconnect disconnect;
47eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell
48eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell  private:
49eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell    DISALLOW_COPY_AND_ASSIGN(alistener);
50e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert};
51e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert
52eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursellalistener::alistener(const std::string& _local_name, const std::string& _connect_to)
53eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell    : local_name(_local_name), connect_to(_connect_to) {
54eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell}
55eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell
56eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursellalistener::~alistener() {
57eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell    // Closes the corresponding fd.
58eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell    fdevent_remove(&fde);
59eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell
60eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell    if (transport) {
61eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell        transport->RemoveDisconnect(&disconnect);
62eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell    }
63eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell}
64eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell
65eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell// listener_list retains ownership of all created alistener objects. Removing an alistener from
66eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell// this list will cause it to be deleted.
67eaae97e127717750b4264d9b6617b845f9bc701fDavid Purselltypedef std::list<std::unique_ptr<alistener>> ListenerList;
68eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursellstatic ListenerList& listener_list = *new ListenerList();
69eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell
70424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughesstatic void ss_listener_event_func(int _fd, unsigned ev, void *_l) {
71cc65c3b9f8edc6fb48ffe725376e65fac42851d6Elliott Hughes    if (ev & FDE_READ) {
7278e1eb1949fd48bcb0578276ffdc2ff3c7ddd89bJosh Gao        int fd = adb_socket_accept(_fd, nullptr, nullptr);
73cc65c3b9f8edc6fb48ffe725376e65fac42851d6Elliott Hughes        if (fd < 0) return;
74e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert
75cc65c3b9f8edc6fb48ffe725376e65fac42851d6Elliott Hughes        int rcv_buf_size = CHUNK_SIZE;
76cc65c3b9f8edc6fb48ffe725376e65fac42851d6Elliott Hughes        adb_setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &rcv_buf_size, sizeof(rcv_buf_size));
77e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert
78cc65c3b9f8edc6fb48ffe725376e65fac42851d6Elliott Hughes        asocket* s = create_local_socket(fd);
79cc65c3b9f8edc6fb48ffe725376e65fac42851d6Elliott Hughes        if (s) {
80e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert            connect_to_smartsocket(s);
81e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert            return;
82e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert        }
83e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert
84e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert        adb_close(fd);
85e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert    }
86e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert}
87e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert
88424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughesstatic void listener_event_func(int _fd, unsigned ev, void* _l)
89e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert{
90bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert    alistener* listener = reinterpret_cast<alistener*>(_l);
91e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert    asocket *s;
92e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert
93bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert    if (ev & FDE_READ) {
9478e1eb1949fd48bcb0578276ffdc2ff3c7ddd89bJosh Gao        int fd = adb_socket_accept(_fd, nullptr, nullptr);
95bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert        if (fd < 0) {
96bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert            return;
97bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert        }
98e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert
99e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert        s = create_local_socket(fd);
100bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert        if (s) {
101bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert            s->transport = listener->transport;
102eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell            connect_to_remote(s, listener->connect_to.c_str());
103e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert            return;
104e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert        }
105e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert
106e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert        adb_close(fd);
107e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert    }
108e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert}
109e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert
110eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell// Called as a transport disconnect function. |arg| is the raw alistener*.
111b329824e6c5373ae303269dca285d835ce57e514Yabin Cuistatic void listener_disconnect(void* arg, atransport*) {
112eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell    for (auto iter = listener_list.begin(); iter != listener_list.end(); ++iter) {
113eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell        if (iter->get() == arg) {
114eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell            (*iter)->transport = nullptr;
115eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell            listener_list.erase(iter);
116eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell            return;
117eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell        }
118eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell    }
119e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert}
120e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert
121e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes// Write the list of current listeners (network redirections) into a string.
122e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughesstd::string format_listeners() {
123e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes    std::string result;
124eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell    for (auto& l : listener_list) {
125e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert        // Ignore special listeners like those for *smartsocket*
126e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes        if (l->connect_to[0] == '*') {
127e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes            continue;
128e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert        }
129e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes        //  <device-serial> " " <local-name> " " <remote-name> "\n"
13034c20bbdfffe0475555d3028e6a441198c85cc62Elliott Hughes        // Entries from "adb reverse" have no serial.
131e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes        android::base::StringAppendF(&result, "%s %s %s\n",
13234c20bbdfffe0475555d3028e6a441198c85cc62Elliott Hughes                                     l->transport->serial ? l->transport->serial : "(reverse)",
133eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell                                     l->local_name.c_str(), l->connect_to.c_str());
134e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert    }
135e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert    return result;
136e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert}
137e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert
138eaae97e127717750b4264d9b6617b845f9bc701fDavid PursellInstallStatus remove_listener(const char* local_name, atransport* transport) {
139eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell    for (auto iter = listener_list.begin(); iter != listener_list.end(); ++iter) {
140eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell        if (local_name == (*iter)->local_name) {
141eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell            listener_list.erase(iter);
1427b506090e1ac51f4990f17621c6e33847b0632a2Elliott Hughes            return INSTALL_STATUS_OK;
143e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert        }
144e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert    }
1457b506090e1ac51f4990f17621c6e33847b0632a2Elliott Hughes    return INSTALL_STATUS_LISTENER_NOT_FOUND;
146e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert}
147e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert
148eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursellvoid remove_all_listeners() {
149eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell    auto iter = listener_list.begin();
150eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell    while (iter != listener_list.end()) {
151e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert        // Never remove smart sockets.
152eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell        if ((*iter)->connect_to[0] == '*') {
153eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell            ++iter;
154eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell        } else {
155eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell            iter = listener_list.erase(iter);
156eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell        }
157e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert    }
158e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert}
159e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert
160eaae97e127717750b4264d9b6617b845f9bc701fDavid PursellInstallStatus install_listener(const std::string& local_name, const char* connect_to,
161eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell                               atransport* transport, int no_rebind, int* resolved_tcp_port,
162eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell                               std::string* error) {
163eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell    for (auto& l : listener_list) {
164ab52c181fa4c1c9891644635dc5653cda5b90e2bElliott Hughes        if (local_name == l->local_name) {
165eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell            // Can't repurpose a smartsocket.
166e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert            if(l->connect_to[0] == '*') {
167bf7c605d87f87c03066c384cecb0f0c91aa31403Spencer Low                *error = "cannot repurpose smartsocket";
168e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert                return INSTALL_STATUS_INTERNAL_ERROR;
169e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert            }
170e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert
171eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell            // Can't repurpose a listener if 'no_rebind' is true.
172e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert            if (no_rebind) {
173bf7c605d87f87c03066c384cecb0f0c91aa31403Spencer Low                *error = "cannot rebind";
174e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert                return INSTALL_STATUS_CANNOT_REBIND;
175e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert            }
176e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert
177eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell            l->connect_to = connect_to;
178e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert            if (l->transport != transport) {
179b329824e6c5373ae303269dca285d835ce57e514Yabin Cui                l->transport->RemoveDisconnect(&l->disconnect);
180e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert                l->transport = transport;
181b329824e6c5373ae303269dca285d835ce57e514Yabin Cui                l->transport->AddDisconnect(&l->disconnect);
182e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert            }
183e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert            return INSTALL_STATUS_OK;
184e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert        }
185e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert    }
186e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert
187eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell    std::unique_ptr<alistener> listener(new alistener(local_name, connect_to));
188e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert
189cfb21412e5e3a716fc45601f35d3b58ce5f78f46Josh Gao    int resolved = 0;
190cfb21412e5e3a716fc45601f35d3b58ce5f78f46Josh Gao    listener->fd = socket_spec_listen(listener->local_name, error, &resolved);
191bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert    if (listener->fd < 0) {
192bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert        return INSTALL_STATUS_CANNOT_BIND;
193e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert    }
194e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert
195cfb21412e5e3a716fc45601f35d3b58ce5f78f46Josh Gao    // If the caller requested port 0, update the listener name with the resolved port.
196cfb21412e5e3a716fc45601f35d3b58ce5f78f46Josh Gao    if (resolved != 0) {
197cfb21412e5e3a716fc45601f35d3b58ce5f78f46Josh Gao        listener->local_name = android::base::StringPrintf("tcp:%d", resolved);
198cfb21412e5e3a716fc45601f35d3b58ce5f78f46Josh Gao        if (resolved_tcp_port) {
199cfb21412e5e3a716fc45601f35d3b58ce5f78f46Josh Gao            *resolved_tcp_port = resolved;
200cfb21412e5e3a716fc45601f35d3b58ce5f78f46Josh Gao        }
201cfb21412e5e3a716fc45601f35d3b58ce5f78f46Josh Gao    }
202cfb21412e5e3a716fc45601f35d3b58ce5f78f46Josh Gao
203bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert    close_on_exec(listener->fd);
204eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell    if (listener->connect_to == "*smartsocket*") {
205eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell        fdevent_install(&listener->fde, listener->fd, ss_listener_event_func, listener.get());
206e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert    } else {
207eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell        fdevent_install(&listener->fde, listener->fd, listener_event_func, listener.get());
208e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert    }
209bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert    fdevent_set(&listener->fde, FDE_READ);
210e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert
211bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert    listener->transport = transport;
212e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert
213e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert    if (transport) {
214eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell        listener->disconnect.opaque = listener.get();
215bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert        listener->disconnect.func   = listener_disconnect;
216b329824e6c5373ae303269dca285d835ce57e514Yabin Cui        transport->AddDisconnect(&listener->disconnect);
217e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert    }
218e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert
219eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell    listener_list.push_back(std::move(listener));
220eaae97e127717750b4264d9b6617b845f9bc701fDavid Pursell    return INSTALL_STATUS_OK;
221e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert}
222