1 /* 2 * Copyright (C) 2019 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include "adbconnection/server.h" 18 19 #include <sys/epoll.h> 20 #include <sys/socket.h> 21 #include <sys/un.h> 22 #include <unistd.h> 23 24 #include <algorithm> 25 #include <array> 26 #include <vector> 27 28 #include <android-base/logging.h> 29 #include <android-base/unique_fd.h> 30 31 #include "adbconnection/process_info.h" 32 33 using android::base::unique_fd; 34 35 #define JDWP_CONTROL_NAME "\0jdwp-control" 36 #define JDWP_CONTROL_NAME_LEN (sizeof(JDWP_CONTROL_NAME) - 1) 37 38 static_assert(JDWP_CONTROL_NAME_LEN <= sizeof(reinterpret_cast<sockaddr_un*>(0)->sun_path)); 39 40 // Listen for incoming jdwp clients forever. 41 void adbconnection_listen(void (*callback)(int fd, ProcessInfo process)) { 42 sockaddr_un addr = {}; 43 socklen_t addrlen = JDWP_CONTROL_NAME_LEN + sizeof(addr.sun_family); 44 45 addr.sun_family = AF_UNIX; 46 memcpy(addr.sun_path, JDWP_CONTROL_NAME, JDWP_CONTROL_NAME_LEN); 47 48 unique_fd s(socket(AF_UNIX, SOCK_SEQPACKET | SOCK_NONBLOCK | SOCK_CLOEXEC, 0)); 49 if (s < 0) { 50 PLOG(ERROR) << "failed to create JDWP control socket"; 51 return; 52 } 53 54 if (bind(s.get(), reinterpret_cast<sockaddr*>(&addr), addrlen) < 0) { 55 PLOG(ERROR) << "failed to bind JDWP control socket"; 56 return; 57 } 58 59 if (listen(s.get(), 4) < 0) { 60 PLOG(ERROR) << "failed to listen on JDWP control socket"; 61 return; 62 } 63 64 std::vector<unique_fd> pending_connections; 65 66 unique_fd epfd(epoll_create1(EPOLL_CLOEXEC)); 67 std::array<epoll_event, 16> events; 68 69 events[0].events = EPOLLIN; 70 events[0].data.fd = -1; 71 if (epoll_ctl(epfd.get(), EPOLL_CTL_ADD, s.get(), &events[0]) != 0) { 72 LOG(FATAL) << "failed to register event with epoll fd"; 73 } 74 75 while (true) { 76 int epoll_rc = TEMP_FAILURE_RETRY(epoll_wait(epfd.get(), events.data(), events.size(), -1)); 77 if (epoll_rc == -1) { 78 PLOG(FATAL) << "epoll_wait failed"; 79 } 80 81 for (int i = 0; i < epoll_rc; ++i) { 82 const epoll_event& event = events[i]; 83 if (event.data.fd == -1) { 84 unique_fd client( 85 TEMP_FAILURE_RETRY(accept4(s.get(), nullptr, nullptr, SOCK_NONBLOCK | SOCK_CLOEXEC))); 86 87 if (client == -1) { 88 PLOG(WARNING) << "failed to accept client on JDWP control socket"; 89 continue; 90 } 91 92 epoll_event register_event; 93 register_event.events = EPOLLIN; 94 register_event.data.fd = client.get(); 95 96 if (epoll_ctl(epfd.get(), EPOLL_CTL_ADD, client.get(), ®ister_event) != 0) { 97 PLOG(FATAL) << "failed to register JDWP client with epoll"; 98 } 99 100 pending_connections.emplace_back(std::move(client)); 101 } else { 102 // n^2, but the backlog should be short. 103 auto it = std::find_if(pending_connections.begin(), pending_connections.end(), 104 [&](const unique_fd& fd) { return fd.get() == event.data.fd; }); 105 106 if (it == pending_connections.end()) { 107 LOG(FATAL) << "failed to find JDWP client (" << event.data.fd 108 << ") in pending connections"; 109 } 110 111 ProcessInfo process; 112 int rc = TEMP_FAILURE_RETRY(recv(it->get(), &process, sizeof(process), MSG_DONTWAIT)); 113 if (rc != sizeof(process)) { 114 LOG(ERROR) << "received data of incorrect size from JDWP client: read " << rc 115 << ", expected " << sizeof(process); 116 } else { 117 callback(it->release(), process); 118 } 119 120 if (epoll_ctl(epfd.get(), EPOLL_CTL_DEL, event.data.fd, nullptr) != 0) { 121 LOG(FATAL) << "failed to delete fd from JDWP epoll fd"; 122 } 123 124 pending_connections.erase(it); 125 } 126 } 127 } 128 } 129