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