You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
106 lines
3.4 KiB
106 lines
3.4 KiB
/*
|
|
* Copyright (C) 2007 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#define TRACE_TAG TRANSPORT
|
|
|
|
#include "sysdeps.h"
|
|
#include "transport.h"
|
|
|
|
#include <errno.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <sys/types.h>
|
|
|
|
#include <condition_variable>
|
|
#include <functional>
|
|
#include <memory>
|
|
#include <mutex>
|
|
#include <thread>
|
|
#include <unordered_map>
|
|
#include <vector>
|
|
|
|
#include <android-base/parsenetaddress.h>
|
|
#include <android-base/stringprintf.h>
|
|
#include <android-base/thread_annotations.h>
|
|
#include <cutils/sockets.h>
|
|
|
|
#if !ADB_HOST
|
|
#include <android-base/properties.h>
|
|
#endif
|
|
|
|
#include "adb.h"
|
|
#include "adb_io.h"
|
|
#include "adb_unique_fd.h"
|
|
#include "adb_utils.h"
|
|
#include "socket_spec.h"
|
|
#include "sysdeps/chrono.h"
|
|
|
|
void server_socket_thread(std::function<unique_fd(std::string_view, std::string*)> listen_func,
|
|
std::string_view addr) {
|
|
adb_thread_setname("server socket");
|
|
|
|
unique_fd serverfd;
|
|
std::string error;
|
|
|
|
while (serverfd == -1) {
|
|
errno = 0;
|
|
serverfd = listen_func(addr, &error);
|
|
if (errno == EAFNOSUPPORT || errno == EINVAL || errno == EPROTONOSUPPORT) {
|
|
D("unrecoverable error: '%s'", error.c_str());
|
|
return;
|
|
} else if (serverfd < 0) {
|
|
D("server: cannot bind socket yet: %s", error.c_str());
|
|
std::this_thread::sleep_for(1s);
|
|
continue;
|
|
}
|
|
close_on_exec(serverfd.get());
|
|
}
|
|
|
|
while (true) {
|
|
D("server: trying to get new connection from fd %d", serverfd.get());
|
|
unique_fd fd(adb_socket_accept(serverfd, nullptr, nullptr));
|
|
if (fd >= 0) {
|
|
D("server: new connection on fd %d", fd.get());
|
|
close_on_exec(fd.get());
|
|
disable_tcp_nagle(fd.get());
|
|
std::string serial = android::base::StringPrintf("host-%d", fd.get());
|
|
// We don't care about port value in "register_socket_transport" as it is used
|
|
// only from ADB_HOST. "server_socket_thread" is never called from ADB_HOST.
|
|
register_socket_transport(
|
|
std::move(fd), std::move(serial), 0, 1,
|
|
[](atransport*) { return ReconnectResult::Abort; }, false);
|
|
}
|
|
}
|
|
D("transport: server_socket_thread() exiting");
|
|
}
|
|
|
|
unique_fd adb_listen(std::string_view addr, std::string* error) {
|
|
return unique_fd{socket_spec_listen(addr, error, nullptr)};
|
|
}
|
|
|
|
void local_init(const std::string& addr) {
|
|
D("transport: local server init");
|
|
std::thread(server_socket_thread, adb_listen, addr).detach();
|
|
}
|
|
|
|
int init_socket_transport(atransport* t, unique_fd fd, int adb_port, int local) {
|
|
t->type = kTransportLocal;
|
|
auto fd_connection = std::make_unique<FdConnection>(std::move(fd));
|
|
t->SetConnection(std::make_unique<BlockingConnectionAdapter>(std::move(fd_connection)));
|
|
return 0;
|
|
}
|