106 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			106 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			C++
		
	
	
	
| /*
 | |
|  * 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;
 | |
| }
 |