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