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> 23381cfa9a8bc262dcd823a8bb6adc189595a2fe7dElliott Hughes#include <cutils/sockets.h> 24e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes 25e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert#include "sysdeps.h" 267664901a355b959f312e9acff5a0fd31b7139623Dan Albert#include "transport.h" 27e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert 28e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albertint gListenAll = 0; /* Not static because it is used in commandline.c. */ 29e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert 30424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughesstatic alistener listener_list = { 31e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert .next = &listener_list, 32e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert .prev = &listener_list, 33e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert}; 34e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert 35424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughesstatic void ss_listener_event_func(int _fd, unsigned ev, void *_l) { 36cc65c3b9f8edc6fb48ffe725376e65fac42851d6Elliott Hughes if (ev & FDE_READ) { 377e16cc15b5e16ec35f4c9f0516a6cacf90326856Erik Kline sockaddr_storage ss; 387e16cc15b5e16ec35f4c9f0516a6cacf90326856Erik Kline sockaddr* addrp = reinterpret_cast<sockaddr*>(&ss); 397e16cc15b5e16ec35f4c9f0516a6cacf90326856Erik Kline socklen_t alen = sizeof(ss); 407e16cc15b5e16ec35f4c9f0516a6cacf90326856Erik Kline int fd = adb_socket_accept(_fd, addrp, &alen); 41cc65c3b9f8edc6fb48ffe725376e65fac42851d6Elliott Hughes if (fd < 0) return; 42e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert 43cc65c3b9f8edc6fb48ffe725376e65fac42851d6Elliott Hughes int rcv_buf_size = CHUNK_SIZE; 44cc65c3b9f8edc6fb48ffe725376e65fac42851d6Elliott Hughes adb_setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &rcv_buf_size, sizeof(rcv_buf_size)); 45e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert 46cc65c3b9f8edc6fb48ffe725376e65fac42851d6Elliott Hughes asocket* s = create_local_socket(fd); 47cc65c3b9f8edc6fb48ffe725376e65fac42851d6Elliott Hughes if (s) { 48e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert connect_to_smartsocket(s); 49e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert return; 50e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert } 51e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert 52e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert adb_close(fd); 53e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert } 54e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert} 55e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert 56424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughesstatic void listener_event_func(int _fd, unsigned ev, void* _l) 57e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert{ 58bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert alistener* listener = reinterpret_cast<alistener*>(_l); 59e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert asocket *s; 60e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert 61bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert if (ev & FDE_READ) { 627e16cc15b5e16ec35f4c9f0516a6cacf90326856Erik Kline sockaddr_storage ss; 637e16cc15b5e16ec35f4c9f0516a6cacf90326856Erik Kline sockaddr* addrp = reinterpret_cast<sockaddr*>(&ss); 64e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert socklen_t alen; 65e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert int fd; 66e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert 677e16cc15b5e16ec35f4c9f0516a6cacf90326856Erik Kline alen = sizeof(ss); 687e16cc15b5e16ec35f4c9f0516a6cacf90326856Erik Kline fd = adb_socket_accept(_fd, addrp, &alen); 69bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert if (fd < 0) { 70bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert return; 71bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert } 72e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert 73e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert s = create_local_socket(fd); 74bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert if (s) { 75bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert s->transport = listener->transport; 76bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert connect_to_remote(s, listener->connect_to); 77e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert return; 78e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert } 79e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert 80e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert adb_close(fd); 81e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert } 82e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert} 83e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert 847e16cc15b5e16ec35f4c9f0516a6cacf90326856Erik Klinestatic void free_listener(alistener* l) 85e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert{ 86e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert if (l->next) { 87e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert l->next->prev = l->prev; 88e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert l->prev->next = l->next; 89e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert l->next = l->prev = l; 90e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert } 91e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert 92e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert // closes the corresponding fd 93e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert fdevent_remove(&l->fde); 94e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert 95e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert if (l->local_name) 96e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert free((char*)l->local_name); 97e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert 98e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert if (l->connect_to) 99e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert free((char*)l->connect_to); 100e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert 101e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert if (l->transport) { 102b329824e6c5373ae303269dca285d835ce57e514Yabin Cui l->transport->RemoveDisconnect(&l->disconnect); 103e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert } 104e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert free(l); 105e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert} 106e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert 107b329824e6c5373ae303269dca285d835ce57e514Yabin Cuistatic void listener_disconnect(void* arg, atransport*) { 108b329824e6c5373ae303269dca285d835ce57e514Yabin Cui alistener* listener = reinterpret_cast<alistener*>(arg); 109b329824e6c5373ae303269dca285d835ce57e514Yabin Cui listener->transport = nullptr; 110b329824e6c5373ae303269dca285d835ce57e514Yabin Cui free_listener(listener); 111e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert} 112e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert 1135200c6670f041550c23821fec8e8e49b30ef6d29Spencer Lowstatic int local_name_to_fd(const char* name, std::string* error) { 114424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes if (!strncmp("tcp:", name, 4)) { 115424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes int port = atoi(name + 4); 116e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert if (gListenAll > 0) { 1175200c6670f041550c23821fec8e8e49b30ef6d29Spencer Low return network_inaddr_any_server(port, SOCK_STREAM, error); 118e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert } else { 1195200c6670f041550c23821fec8e8e49b30ef6d29Spencer Low return network_loopback_server(port, SOCK_STREAM, error); 120e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert } 121e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert } 122095307ec4950f06539f460ad621e0e1d3b246e19Elliott Hughes#if !defined(_WIN32) // No Unix-domain sockets on Windows. 123424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes // It's nonsensical to support the "reserved" space on the adb host side 124424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes if (!strncmp(name, "local:", 6)) { 1255200c6670f041550c23821fec8e8e49b30ef6d29Spencer Low return network_local_server(name + 6, 1265200c6670f041550c23821fec8e8e49b30ef6d29Spencer Low ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM, error); 127424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes } else if (!strncmp(name, "localabstract:", 14)) { 1285200c6670f041550c23821fec8e8e49b30ef6d29Spencer Low return network_local_server(name + 14, 1295200c6670f041550c23821fec8e8e49b30ef6d29Spencer Low ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM, error); 130424af02f363a305a349ff99e1cc253ac5bc642c9Elliott Hughes } else if (!strncmp(name, "localfilesystem:", 16)) { 1315200c6670f041550c23821fec8e8e49b30ef6d29Spencer Low return network_local_server(name + 16, 1325200c6670f041550c23821fec8e8e49b30ef6d29Spencer Low ANDROID_SOCKET_NAMESPACE_FILESYSTEM, SOCK_STREAM, error); 133e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert } 134e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert 135e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert#endif 1365200c6670f041550c23821fec8e8e49b30ef6d29Spencer Low *error = android::base::StringPrintf("unknown local portname '%s'", name); 137e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert return -1; 138e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert} 139e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert 140e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes// Write the list of current listeners (network redirections) into a string. 141e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughesstd::string format_listeners() { 142e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes std::string result; 143e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes for (alistener* l = listener_list.next; l != &listener_list; l = l->next) { 144e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert // Ignore special listeners like those for *smartsocket* 145e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes if (l->connect_to[0] == '*') { 146e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes continue; 147e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert } 148e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes // <device-serial> " " <local-name> " " <remote-name> "\n" 14934c20bbdfffe0475555d3028e6a441198c85cc62Elliott Hughes // Entries from "adb reverse" have no serial. 150e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes android::base::StringAppendF(&result, "%s %s %s\n", 15134c20bbdfffe0475555d3028e6a441198c85cc62Elliott Hughes l->transport->serial ? l->transport->serial : "(reverse)", 15234c20bbdfffe0475555d3028e6a441198c85cc62Elliott Hughes l->local_name, l->connect_to); 153e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert } 154e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert return result; 155e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert} 156e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert 1573bd73c12c07dcefc965abeef535ac53c4754d682Elliott HughesInstallStatus remove_listener(const char *local_name, atransport* transport) { 158e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert alistener *l; 159e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert 160e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert for (l = listener_list.next; l != &listener_list; l = l->next) { 161e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert if (!strcmp(local_name, l->local_name)) { 162b329824e6c5373ae303269dca285d835ce57e514Yabin Cui free_listener(l); 1637b506090e1ac51f4990f17621c6e33847b0632a2Elliott Hughes return INSTALL_STATUS_OK; 164e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert } 165e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert } 1667b506090e1ac51f4990f17621c6e33847b0632a2Elliott Hughes return INSTALL_STATUS_LISTENER_NOT_FOUND; 167e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert} 168e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert 169e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albertvoid remove_all_listeners(void) 170e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert{ 171e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert alistener *l, *l_next; 172e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert for (l = listener_list.next; l != &listener_list; l = l_next) { 173e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert l_next = l->next; 174e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert // Never remove smart sockets. 175e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert if (l->connect_to[0] == '*') 176e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert continue; 177b329824e6c5373ae303269dca285d835ce57e514Yabin Cui free_listener(l); 178e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert } 179e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert} 180e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert 1813bd73c12c07dcefc965abeef535ac53c4754d682Elliott HughesInstallStatus install_listener(const std::string& local_name, 182e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert const char *connect_to, 183e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert atransport* transport, 1845200c6670f041550c23821fec8e8e49b30ef6d29Spencer Low int no_rebind, 1855200c6670f041550c23821fec8e8e49b30ef6d29Spencer Low std::string* error) 186e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert{ 187bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert for (alistener* l = listener_list.next; l != &listener_list; l = l->next) { 188ab52c181fa4c1c9891644635dc5653cda5b90e2bElliott Hughes if (local_name == l->local_name) { 189bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert char* cto; 190e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert 191bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert /* can't repurpose a smartsocket */ 192e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert if(l->connect_to[0] == '*') { 193bf7c605d87f87c03066c384cecb0f0c91aa31403Spencer Low *error = "cannot repurpose smartsocket"; 194e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert return INSTALL_STATUS_INTERNAL_ERROR; 195e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert } 196e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert 197bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert /* can't repurpose a listener if 'no_rebind' is true */ 198e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert if (no_rebind) { 199bf7c605d87f87c03066c384cecb0f0c91aa31403Spencer Low *error = "cannot rebind"; 200e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert return INSTALL_STATUS_CANNOT_REBIND; 201e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert } 202e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert 203e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert cto = strdup(connect_to); 204e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert if(cto == 0) { 205bf7c605d87f87c03066c384cecb0f0c91aa31403Spencer Low *error = "cannot duplicate string"; 206e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert return INSTALL_STATUS_INTERNAL_ERROR; 207e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert } 208e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert 209e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert free((void*) l->connect_to); 210e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert l->connect_to = cto; 211e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert if (l->transport != transport) { 212b329824e6c5373ae303269dca285d835ce57e514Yabin Cui l->transport->RemoveDisconnect(&l->disconnect); 213e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert l->transport = transport; 214b329824e6c5373ae303269dca285d835ce57e514Yabin Cui l->transport->AddDisconnect(&l->disconnect); 215e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert } 216e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert return INSTALL_STATUS_OK; 217e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert } 218e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert } 219e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert 220bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert alistener* listener = reinterpret_cast<alistener*>( 221bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert calloc(1, sizeof(alistener))); 222bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert if (listener == nullptr) { 223bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert goto nomem; 224bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert } 225bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert 226ab52c181fa4c1c9891644635dc5653cda5b90e2bElliott Hughes listener->local_name = strdup(local_name.c_str()); 227bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert if (listener->local_name == nullptr) { 228bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert goto nomem; 229bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert } 230e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert 231bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert listener->connect_to = strdup(connect_to); 232bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert if (listener->connect_to == nullptr) { 233bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert goto nomem; 234bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert } 235e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert 2365200c6670f041550c23821fec8e8e49b30ef6d29Spencer Low listener->fd = local_name_to_fd(listener->local_name, error); 237bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert if (listener->fd < 0) { 238bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert free(listener->local_name); 239bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert free(listener->connect_to); 240bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert free(listener); 241bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert return INSTALL_STATUS_CANNOT_BIND; 242e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert } 243e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert 244bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert close_on_exec(listener->fd); 245bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert if (!strcmp(listener->connect_to, "*smartsocket*")) { 246bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert fdevent_install(&listener->fde, listener->fd, ss_listener_event_func, 247bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert listener); 248e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert } else { 249bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert fdevent_install(&listener->fde, listener->fd, listener_event_func, 250bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert listener); 251e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert } 252bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert fdevent_set(&listener->fde, FDE_READ); 253e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert 254bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert listener->next = &listener_list; 255bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert listener->prev = listener_list.prev; 256bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert listener->next->prev = listener; 257bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert listener->prev->next = listener; 258bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert listener->transport = transport; 259e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert 260e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert if (transport) { 261bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert listener->disconnect.opaque = listener; 262bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert listener->disconnect.func = listener_disconnect; 263b329824e6c5373ae303269dca285d835ce57e514Yabin Cui transport->AddDisconnect(&listener->disconnect); 264e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert } 265e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert return INSTALL_STATUS_OK; 266e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert 267e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albertnomem: 268e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert fatal("cannot allocate listener"); 269e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert return INSTALL_STATUS_INTERNAL_ERROR; 270e9fca14c9e555a9d02e1d94ba6d3b290673ea26bDan Albert} 271