1e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include "uds/service_endpoint.h" 2e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 3e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <poll.h> 4e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <sys/epoll.h> 5e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <sys/eventfd.h> 6e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <sys/socket.h> 7e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <sys/un.h> 8e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <algorithm> // std::min 9e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 10409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko#include <android-base/logging.h> 11409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko#include <android-base/strings.h> 12409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko#include <cutils/sockets.h> 13e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <pdx/service.h> 144a7762afb4fa8495e711fcc2da322fc388e700bcAlex Vakulenko#include <selinux/selinux.h> 15e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <uds/channel_manager.h> 16e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <uds/client_channel_factory.h> 17e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <uds/ipc_helper.h> 18e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 19e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkonamespace { 20e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 21e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoconstexpr int kMaxBackLogForSocketListen = 1; 22e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 23e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkousing android::pdx::BorrowedChannelHandle; 24e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkousing android::pdx::BorrowedHandle; 25e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkousing android::pdx::ChannelReference; 26f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenkousing android::pdx::ErrorStatus; 27e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkousing android::pdx::FileReference; 28e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkousing android::pdx::LocalChannelHandle; 29e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkousing android::pdx::LocalHandle; 30e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkousing android::pdx::Status; 31e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkousing android::pdx::uds::ChannelInfo; 32e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkousing android::pdx::uds::ChannelManager; 33e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 34e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostruct MessageState { 35e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko bool GetLocalFileHandle(int index, LocalHandle* handle) { 36e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (index < 0) { 37e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko handle->Reset(index); 38e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } else if (static_cast<size_t>(index) < request.file_descriptors.size()) { 39e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko *handle = std::move(request.file_descriptors[index]); 40e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } else { 41e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return false; 42e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 43e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return true; 44e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 45e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 46e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko bool GetLocalChannelHandle(int index, LocalChannelHandle* handle) { 47e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (index < 0) { 48e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko *handle = LocalChannelHandle{nullptr, index}; 49e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } else if (static_cast<size_t>(index) < request.channels.size()) { 50e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto& channel_info = request.channels[index]; 51e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko *handle = ChannelManager::Get().CreateHandle( 52e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::move(channel_info.data_fd), std::move(channel_info.event_fd)); 53e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } else { 54e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return false; 55e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 56e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return true; 57e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 58e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 59f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko Status<FileReference> PushFileHandle(BorrowedHandle handle) { 60e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (!handle) 61e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return handle.Get(); 62e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko response.file_descriptors.push_back(std::move(handle)); 63e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return response.file_descriptors.size() - 1; 64e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 65e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 66f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko Status<ChannelReference> PushChannelHandle(BorrowedChannelHandle handle) { 67e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (!handle) 68e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return handle.value(); 696890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka 706890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka if (auto* channel_data = 716890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka ChannelManager::Get().GetChannelData(handle.value())) { 726890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka ChannelInfo<BorrowedHandle> channel_info; 736890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka channel_info.data_fd.Reset(handle.value()); 746890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka channel_info.event_fd = channel_data->event_receiver.event_fd(); 756890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka response.channels.push_back(std::move(channel_info)); 766890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka return response.channels.size() - 1; 776890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka } else { 78f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko return ErrorStatus{EINVAL}; 796890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka } 80e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 81e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 82f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko Status<ChannelReference> PushChannelHandle(BorrowedHandle data_fd, 83f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko BorrowedHandle event_fd) { 84e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (!data_fd || !event_fd) 85f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko return ErrorStatus{EINVAL}; 86e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ChannelInfo<BorrowedHandle> channel_info; 87e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko channel_info.data_fd = std::move(data_fd); 88e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko channel_info.event_fd = std::move(event_fd); 89e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko response.channels.push_back(std::move(channel_info)); 90e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return response.channels.size() - 1; 91e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 92e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 93f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko Status<size_t> WriteData(const iovec* vector, size_t vector_length) { 94f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko size_t size = 0; 95e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko for (size_t i = 0; i < vector_length; i++) { 96e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const auto* data = reinterpret_cast<const uint8_t*>(vector[i].iov_base); 97e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko response_data.insert(response_data.end(), data, data + vector[i].iov_len); 98e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size += vector[i].iov_len; 99e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 100e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return size; 101e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 102e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 103f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko Status<size_t> ReadData(const iovec* vector, size_t vector_length) { 104e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_t size_remaining = request_data.size() - request_data_read_pos; 105f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko size_t size = 0; 106e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko for (size_t i = 0; i < vector_length && size_remaining > 0; i++) { 107e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_t size_to_copy = std::min(size_remaining, vector[i].iov_len); 108e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko memcpy(vector[i].iov_base, request_data.data() + request_data_read_pos, 109e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_to_copy); 110e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size += size_to_copy; 111e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko request_data_read_pos += size_to_copy; 112e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_remaining -= size_to_copy; 113e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 114e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return size; 115e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 116e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 117e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko android::pdx::uds::RequestHeader<LocalHandle> request; 118e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko android::pdx::uds::ResponseHeader<BorrowedHandle> response; 119e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::vector<LocalHandle> sockets_to_close; 120e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::vector<uint8_t> request_data; 121e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_t request_data_read_pos{0}; 122e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::vector<uint8_t> response_data; 123e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}; 124e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 125e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} // anonymous namespace 126e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 127e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkonamespace android { 128e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkonamespace pdx { 129e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkonamespace uds { 130e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 131409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex VakulenkoEndpoint::Endpoint(const std::string& endpoint_path, bool blocking, 132409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko bool use_init_socket_fd) 133e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko : endpoint_path_{ClientChannelFactory::GetEndpointPath(endpoint_path)}, 134e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko is_blocking_{blocking} { 135409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko LocalHandle fd; 136409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko if (use_init_socket_fd) { 137409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko // Cut off the /dev/socket/ prefix from the full socket path and use the 138409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko // resulting "name" to retrieve the file descriptor for the socket created 139409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko // by the init process. 140409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko constexpr char prefix[] = "/dev/socket/"; 141409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko CHECK(android::base::StartsWith(endpoint_path_, prefix)) 142409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko << "Endpoint::Endpoint: Socket name '" << endpoint_path_ 143409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko << "' must begin with '" << prefix << "'"; 144409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko std::string socket_name = endpoint_path_.substr(sizeof(prefix) - 1); 145409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko fd.Reset(android_get_control_socket(socket_name.c_str())); 146409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko CHECK(fd.IsValid()) 147409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko << "Endpoint::Endpoint: Unable to obtain the control socket fd for '" 148409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko << socket_name << "'"; 149409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko fcntl(fd.Get(), F_SETFD, FD_CLOEXEC); 150409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko } else { 151409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko fd.Reset(socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0)); 152409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko CHECK(fd.IsValid()) << "Endpoint::Endpoint: Failed to create socket: " 153409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko << strerror(errno); 154409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko 155409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko sockaddr_un local; 156409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko local.sun_family = AF_UNIX; 157409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko strncpy(local.sun_path, endpoint_path_.c_str(), sizeof(local.sun_path)); 158409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko local.sun_path[sizeof(local.sun_path) - 1] = '\0'; 159409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko 160409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko unlink(local.sun_path); 161409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko int ret = 162409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko bind(fd.Get(), reinterpret_cast<sockaddr*>(&local), sizeof(local)); 163409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko CHECK_EQ(ret, 0) << "Endpoint::Endpoint: bind error: " << strerror(errno); 164e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 1656eefa42d33bdddc3603211634f98937b00abc532Alex Vakulenko Init(std::move(fd)); 1666eefa42d33bdddc3603211634f98937b00abc532Alex Vakulenko} 1676eefa42d33bdddc3603211634f98937b00abc532Alex Vakulenko 1686eefa42d33bdddc3603211634f98937b00abc532Alex VakulenkoEndpoint::Endpoint(LocalHandle socket_fd) { Init(std::move(socket_fd)); } 169e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 1706eefa42d33bdddc3603211634f98937b00abc532Alex Vakulenkovoid Endpoint::Init(LocalHandle socket_fd) { 1716eefa42d33bdddc3603211634f98937b00abc532Alex Vakulenko if (socket_fd) { 1726eefa42d33bdddc3603211634f98937b00abc532Alex Vakulenko CHECK_EQ(listen(socket_fd.Get(), kMaxBackLogForSocketListen), 0) 1736eefa42d33bdddc3603211634f98937b00abc532Alex Vakulenko << "Endpoint::Endpoint: listen error: " << strerror(errno); 1746eefa42d33bdddc3603211634f98937b00abc532Alex Vakulenko } 175e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko cancel_event_fd_.Reset(eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK)); 176409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko CHECK(cancel_event_fd_.IsValid()) 177409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko << "Endpoint::Endpoint: Failed to create event fd: " << strerror(errno); 178e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 179409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko epoll_fd_.Reset(epoll_create1(EPOLL_CLOEXEC)); 180409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko CHECK(epoll_fd_.IsValid()) 181409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko << "Endpoint::Endpoint: Failed to create epoll fd: " << strerror(errno); 182e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 1836eefa42d33bdddc3603211634f98937b00abc532Alex Vakulenko if (socket_fd) { 1846eefa42d33bdddc3603211634f98937b00abc532Alex Vakulenko epoll_event socket_event; 1856eefa42d33bdddc3603211634f98937b00abc532Alex Vakulenko socket_event.events = EPOLLIN | EPOLLRDHUP | EPOLLONESHOT; 1866eefa42d33bdddc3603211634f98937b00abc532Alex Vakulenko socket_event.data.fd = socket_fd.Get(); 1876eefa42d33bdddc3603211634f98937b00abc532Alex Vakulenko int ret = epoll_ctl(epoll_fd_.Get(), EPOLL_CTL_ADD, socket_fd.Get(), 1886eefa42d33bdddc3603211634f98937b00abc532Alex Vakulenko &socket_event); 1896eefa42d33bdddc3603211634f98937b00abc532Alex Vakulenko CHECK_EQ(ret, 0) 1906eefa42d33bdddc3603211634f98937b00abc532Alex Vakulenko << "Endpoint::Endpoint: Failed to add socket fd to epoll fd: " 1916eefa42d33bdddc3603211634f98937b00abc532Alex Vakulenko << strerror(errno); 1926eefa42d33bdddc3603211634f98937b00abc532Alex Vakulenko } 193e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 194e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko epoll_event cancel_event; 195e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko cancel_event.events = EPOLLIN; 196e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko cancel_event.data.fd = cancel_event_fd_.Get(); 197e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 1986eefa42d33bdddc3603211634f98937b00abc532Alex Vakulenko int ret = epoll_ctl(epoll_fd_.Get(), EPOLL_CTL_ADD, cancel_event_fd_.Get(), 1996eefa42d33bdddc3603211634f98937b00abc532Alex Vakulenko &cancel_event); 200409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko CHECK_EQ(ret, 0) 201409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko << "Endpoint::Endpoint: Failed to add cancel event fd to epoll fd: " 202409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko << strerror(errno); 2036eefa42d33bdddc3603211634f98937b00abc532Alex Vakulenko socket_fd_ = std::move(socket_fd); 204e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 205e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 206e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkovoid* Endpoint::AllocateMessageState() { return new MessageState; } 207e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 208e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkovoid Endpoint::FreeMessageState(void* state) { 209e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko delete static_cast<MessageState*>(state); 210e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 211e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 212e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoStatus<void> Endpoint::AcceptConnection(Message* message) { 2136eefa42d33bdddc3603211634f98937b00abc532Alex Vakulenko if (!socket_fd_) 2146eefa42d33bdddc3603211634f98937b00abc532Alex Vakulenko return ErrorStatus(EBADF); 2156eefa42d33bdddc3603211634f98937b00abc532Alex Vakulenko 216e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko sockaddr_un remote; 217e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko socklen_t addrlen = sizeof(remote); 218e41826ac301b9afad1cbfe59c57e27f2495be968Alex Vakulenko LocalHandle connection_fd{accept4(socket_fd_.Get(), 219e41826ac301b9afad1cbfe59c57e27f2495be968Alex Vakulenko reinterpret_cast<sockaddr*>(&remote), 220e41826ac301b9afad1cbfe59c57e27f2495be968Alex Vakulenko &addrlen, SOCK_CLOEXEC)}; 221e41826ac301b9afad1cbfe59c57e27f2495be968Alex Vakulenko if (!connection_fd) { 222e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ALOGE("Endpoint::AcceptConnection: failed to accept connection: %s", 223e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko strerror(errno)); 224e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ErrorStatus(errno); 225e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 226e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 227e41826ac301b9afad1cbfe59c57e27f2495be968Alex Vakulenko LocalHandle local_socket; 228e41826ac301b9afad1cbfe59c57e27f2495be968Alex Vakulenko LocalHandle remote_socket; 229e41826ac301b9afad1cbfe59c57e27f2495be968Alex Vakulenko auto status = CreateChannelSocketPair(&local_socket, &remote_socket); 230e41826ac301b9afad1cbfe59c57e27f2495be968Alex Vakulenko if (!status) 231e41826ac301b9afad1cbfe59c57e27f2495be968Alex Vakulenko return status; 232e41826ac301b9afad1cbfe59c57e27f2495be968Alex Vakulenko 233e41826ac301b9afad1cbfe59c57e27f2495be968Alex Vakulenko // Borrow the local channel handle before we move it into OnNewChannel(). 234e41826ac301b9afad1cbfe59c57e27f2495be968Alex Vakulenko BorrowedHandle channel_handle = local_socket.Borrow(); 235e41826ac301b9afad1cbfe59c57e27f2495be968Alex Vakulenko status = OnNewChannel(std::move(local_socket)); 236e41826ac301b9afad1cbfe59c57e27f2495be968Alex Vakulenko if (!status) 237e41826ac301b9afad1cbfe59c57e27f2495be968Alex Vakulenko return status; 238e41826ac301b9afad1cbfe59c57e27f2495be968Alex Vakulenko 239e41826ac301b9afad1cbfe59c57e27f2495be968Alex Vakulenko // Send the channel socket fd to the client. 240e41826ac301b9afad1cbfe59c57e27f2495be968Alex Vakulenko ChannelConnectionInfo<LocalHandle> connection_info; 241e41826ac301b9afad1cbfe59c57e27f2495be968Alex Vakulenko connection_info.channel_fd = std::move(remote_socket); 242e41826ac301b9afad1cbfe59c57e27f2495be968Alex Vakulenko status = SendData(connection_fd.Borrow(), connection_info); 243e41826ac301b9afad1cbfe59c57e27f2495be968Alex Vakulenko 244e41826ac301b9afad1cbfe59c57e27f2495be968Alex Vakulenko if (status) { 245e41826ac301b9afad1cbfe59c57e27f2495be968Alex Vakulenko // Get the CHANNEL_OPEN message from client over the channel socket. 246e41826ac301b9afad1cbfe59c57e27f2495be968Alex Vakulenko status = ReceiveMessageForChannel(channel_handle, message); 247e41826ac301b9afad1cbfe59c57e27f2495be968Alex Vakulenko } else { 248e41826ac301b9afad1cbfe59c57e27f2495be968Alex Vakulenko CloseChannel(GetChannelId(channel_handle)); 249e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 250e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 251e41826ac301b9afad1cbfe59c57e27f2495be968Alex Vakulenko // Don't need the connection socket anymore. Further communication should 252e41826ac301b9afad1cbfe59c57e27f2495be968Alex Vakulenko // happen over the channel socket. 253e41826ac301b9afad1cbfe59c57e27f2495be968Alex Vakulenko shutdown(connection_fd.Get(), SHUT_WR); 254e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return status; 255e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 256e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 257f0a7bd033941e26e380232a0515e903cf8e678e5Alex VakulenkoStatus<void> Endpoint::SetService(Service* service) { 258e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko service_ = service; 259f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko return {}; 260e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 261e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 262f0a7bd033941e26e380232a0515e903cf8e678e5Alex VakulenkoStatus<void> Endpoint::SetChannel(int channel_id, Channel* channel) { 263e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::lock_guard<std::mutex> autolock(channel_mutex_); 264e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto channel_data = channels_.find(channel_id); 265e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (channel_data == channels_.end()) 266f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko return ErrorStatus{EINVAL}; 267e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko channel_data->second.channel_state = channel; 268f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko return {}; 269e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 270e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 271e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoStatus<void> Endpoint::OnNewChannel(LocalHandle channel_fd) { 272e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::lock_guard<std::mutex> autolock(channel_mutex_); 273e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko Status<void> status; 274e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko status.PropagateError(OnNewChannelLocked(std::move(channel_fd), nullptr)); 275e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return status; 276e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 277e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 27809aa736ee6136787b18807d7ab459feba23cec04Alex VakulenkoStatus<std::pair<int32_t, Endpoint::ChannelData*>> Endpoint::OnNewChannelLocked( 279e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko LocalHandle channel_fd, Channel* channel_state) { 280e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko epoll_event event; 281e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko event.events = EPOLLIN | EPOLLRDHUP | EPOLLONESHOT; 282e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko event.data.fd = channel_fd.Get(); 283e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (epoll_ctl(epoll_fd_.Get(), EPOLL_CTL_ADD, channel_fd.Get(), &event) < 0) { 284e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ALOGE( 285e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko "Endpoint::OnNewChannelLocked: Failed to add channel to endpoint: %s\n", 286e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko strerror(errno)); 287e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ErrorStatus(errno); 288e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 289e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ChannelData channel_data; 2906890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka channel_data.event_set.AddDataFd(channel_fd); 291e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko channel_data.data_fd = std::move(channel_fd); 292e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko channel_data.channel_state = channel_state; 29309aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko for (;;) { 29409aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko // Try new channel IDs until we find one which is not already in the map. 29509aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko if (last_channel_id_++ == std::numeric_limits<int32_t>::max()) 29609aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko last_channel_id_ = 1; 29709aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko auto iter = channels_.lower_bound(last_channel_id_); 29809aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko if (iter == channels_.end() || iter->first != last_channel_id_) { 29909aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko channel_fd_to_id_.emplace(channel_data.data_fd.Get(), last_channel_id_); 30009aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko iter = channels_.emplace_hint(iter, last_channel_id_, 30109aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko std::move(channel_data)); 30209aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko return std::make_pair(last_channel_id_, &iter->second); 30309aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko } 30409aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko } 305e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 306e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 30709aa736ee6136787b18807d7ab459feba23cec04Alex VakulenkoStatus<void> Endpoint::ReenableEpollEvent(const BorrowedHandle& fd) { 308e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko epoll_event event; 309e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko event.events = EPOLLIN | EPOLLRDHUP | EPOLLONESHOT; 31009aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko event.data.fd = fd.Get(); 31109aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko if (epoll_ctl(epoll_fd_.Get(), EPOLL_CTL_MOD, fd.Get(), &event) < 0) { 312e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ALOGE( 313e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko "Endpoint::ReenableEpollEvent: Failed to re-enable channel to " 314e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko "endpoint: %s\n", 315e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko strerror(errno)); 316e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ErrorStatus(errno); 317e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 318e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return {}; 319e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 320e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 321f0a7bd033941e26e380232a0515e903cf8e678e5Alex VakulenkoStatus<void> Endpoint::CloseChannel(int channel_id) { 322e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::lock_guard<std::mutex> autolock(channel_mutex_); 323e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return CloseChannelLocked(channel_id); 324e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 325e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 32609aa736ee6136787b18807d7ab459feba23cec04Alex VakulenkoStatus<void> Endpoint::CloseChannelLocked(int32_t channel_id) { 3276890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka ALOGD_IF(TRACE, "Endpoint::CloseChannelLocked: channel_id=%d", channel_id); 3286890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka 32909aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko auto iter = channels_.find(channel_id); 33009aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko if (iter == channels_.end()) 331f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko return ErrorStatus{EINVAL}; 332e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 33309aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko int channel_fd = iter->second.data_fd.Get(); 334f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko Status<void> status; 335e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko epoll_event dummy; // See BUGS in man 2 epoll_ctl. 33609aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko if (epoll_ctl(epoll_fd_.Get(), EPOLL_CTL_DEL, channel_fd, &dummy) < 0) { 337f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko status.SetError(errno); 338e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ALOGE( 339e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko "Endpoint::CloseChannelLocked: Failed to remove channel from endpoint: " 340e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko "%s\n", 341e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko strerror(errno)); 342f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko } else { 343f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko status.SetValue(); 344e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 345e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 34609aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko channel_fd_to_id_.erase(channel_fd); 34709aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko channels_.erase(iter); 348f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko return status; 349e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 350e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 351f0a7bd033941e26e380232a0515e903cf8e678e5Alex VakulenkoStatus<void> Endpoint::ModifyChannelEvents(int channel_id, int clear_mask, 352f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko int set_mask) { 353e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::lock_guard<std::mutex> autolock(channel_mutex_); 354e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 3556890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka auto search = channels_.find(channel_id); 3566890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka if (search != channels_.end()) { 3576890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka auto& channel_data = search->second; 3586890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka channel_data.event_set.ModifyEvents(clear_mask, set_mask); 359f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko return {}; 360e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 361e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 362f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko return ErrorStatus{EINVAL}; 363e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 364e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 365e41826ac301b9afad1cbfe59c57e27f2495be968Alex VakulenkoStatus<void> Endpoint::CreateChannelSocketPair(LocalHandle* local_socket, 366e41826ac301b9afad1cbfe59c57e27f2495be968Alex Vakulenko LocalHandle* remote_socket) { 367e41826ac301b9afad1cbfe59c57e27f2495be968Alex Vakulenko Status<void> status; 3684a7762afb4fa8495e711fcc2da322fc388e700bcAlex Vakulenko char* endpoint_context = nullptr; 3694a7762afb4fa8495e711fcc2da322fc388e700bcAlex Vakulenko // Make sure the channel socket has the correct SELinux label applied. 3704a7762afb4fa8495e711fcc2da322fc388e700bcAlex Vakulenko // Here we get the label from the endpoint file descriptor, which should be 3714a7762afb4fa8495e711fcc2da322fc388e700bcAlex Vakulenko // something like "u:object_r:pdx_service_endpoint_socket:s0" and replace 3724a7762afb4fa8495e711fcc2da322fc388e700bcAlex Vakulenko // "endpoint" with "channel" to produce the channel label such as this: 3734a7762afb4fa8495e711fcc2da322fc388e700bcAlex Vakulenko // "u:object_r:pdx_service_channel_socket:s0". 3744a7762afb4fa8495e711fcc2da322fc388e700bcAlex Vakulenko if (fgetfilecon_raw(socket_fd_.Get(), &endpoint_context) > 0) { 3754a7762afb4fa8495e711fcc2da322fc388e700bcAlex Vakulenko std::string channel_context = endpoint_context; 3764a7762afb4fa8495e711fcc2da322fc388e700bcAlex Vakulenko freecon(endpoint_context); 3774a7762afb4fa8495e711fcc2da322fc388e700bcAlex Vakulenko const std::string suffix = "_endpoint_socket"; 3784a7762afb4fa8495e711fcc2da322fc388e700bcAlex Vakulenko auto pos = channel_context.find(suffix); 3794a7762afb4fa8495e711fcc2da322fc388e700bcAlex Vakulenko if (pos != std::string::npos) { 3804a7762afb4fa8495e711fcc2da322fc388e700bcAlex Vakulenko channel_context.replace(pos, suffix.size(), "_channel_socket"); 3814a7762afb4fa8495e711fcc2da322fc388e700bcAlex Vakulenko } else { 3824a7762afb4fa8495e711fcc2da322fc388e700bcAlex Vakulenko ALOGW( 3834a7762afb4fa8495e711fcc2da322fc388e700bcAlex Vakulenko "Endpoint::CreateChannelSocketPair: Endpoint security context '%s' " 3844a7762afb4fa8495e711fcc2da322fc388e700bcAlex Vakulenko "does not contain expected substring '%s'", 3854a7762afb4fa8495e711fcc2da322fc388e700bcAlex Vakulenko channel_context.c_str(), suffix.c_str()); 3864a7762afb4fa8495e711fcc2da322fc388e700bcAlex Vakulenko } 3874a7762afb4fa8495e711fcc2da322fc388e700bcAlex Vakulenko ALOGE_IF(setsockcreatecon_raw(channel_context.c_str()) == -1, 3884a7762afb4fa8495e711fcc2da322fc388e700bcAlex Vakulenko "Endpoint::CreateChannelSocketPair: Failed to set channel socket " 3894a7762afb4fa8495e711fcc2da322fc388e700bcAlex Vakulenko "security context: %s", 3904a7762afb4fa8495e711fcc2da322fc388e700bcAlex Vakulenko strerror(errno)); 3914a7762afb4fa8495e711fcc2da322fc388e700bcAlex Vakulenko } else { 3924a7762afb4fa8495e711fcc2da322fc388e700bcAlex Vakulenko ALOGE( 3934a7762afb4fa8495e711fcc2da322fc388e700bcAlex Vakulenko "Endpoint::CreateChannelSocketPair: Failed to obtain the endpoint " 3944a7762afb4fa8495e711fcc2da322fc388e700bcAlex Vakulenko "socket's security context: %s", 3954a7762afb4fa8495e711fcc2da322fc388e700bcAlex Vakulenko strerror(errno)); 3964a7762afb4fa8495e711fcc2da322fc388e700bcAlex Vakulenko } 3974a7762afb4fa8495e711fcc2da322fc388e700bcAlex Vakulenko 398e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int channel_pair[2] = {}; 399409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, channel_pair) == -1) { 400e41826ac301b9afad1cbfe59c57e27f2495be968Alex Vakulenko ALOGE("Endpoint::CreateChannelSocketPair: Failed to create socket pair: %s", 401e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko strerror(errno)); 402e41826ac301b9afad1cbfe59c57e27f2495be968Alex Vakulenko status.SetError(errno); 403e41826ac301b9afad1cbfe59c57e27f2495be968Alex Vakulenko return status; 404e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 405e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 4064a7762afb4fa8495e711fcc2da322fc388e700bcAlex Vakulenko setsockcreatecon_raw(nullptr); 4074a7762afb4fa8495e711fcc2da322fc388e700bcAlex Vakulenko 408e41826ac301b9afad1cbfe59c57e27f2495be968Alex Vakulenko local_socket->Reset(channel_pair[0]); 409e41826ac301b9afad1cbfe59c57e27f2495be968Alex Vakulenko remote_socket->Reset(channel_pair[1]); 410e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 411e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int optval = 1; 412e41826ac301b9afad1cbfe59c57e27f2495be968Alex Vakulenko if (setsockopt(local_socket->Get(), SOL_SOCKET, SO_PASSCRED, &optval, 413e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko sizeof(optval)) == -1) { 414e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ALOGE( 415e41826ac301b9afad1cbfe59c57e27f2495be968Alex Vakulenko "Endpoint::CreateChannelSocketPair: Failed to enable the receiving of " 416e41826ac301b9afad1cbfe59c57e27f2495be968Alex Vakulenko "the credentials for channel %d: %s", 417e41826ac301b9afad1cbfe59c57e27f2495be968Alex Vakulenko local_socket->Get(), strerror(errno)); 418e41826ac301b9afad1cbfe59c57e27f2495be968Alex Vakulenko status.SetError(errno); 419e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 420e41826ac301b9afad1cbfe59c57e27f2495be968Alex Vakulenko return status; 421e41826ac301b9afad1cbfe59c57e27f2495be968Alex Vakulenko} 422e41826ac301b9afad1cbfe59c57e27f2495be968Alex Vakulenko 423e41826ac301b9afad1cbfe59c57e27f2495be968Alex VakulenkoStatus<RemoteChannelHandle> Endpoint::PushChannel(Message* message, 424e41826ac301b9afad1cbfe59c57e27f2495be968Alex Vakulenko int /*flags*/, 425e41826ac301b9afad1cbfe59c57e27f2495be968Alex Vakulenko Channel* channel, 426e41826ac301b9afad1cbfe59c57e27f2495be968Alex Vakulenko int* channel_id) { 427e41826ac301b9afad1cbfe59c57e27f2495be968Alex Vakulenko LocalHandle local_socket; 428e41826ac301b9afad1cbfe59c57e27f2495be968Alex Vakulenko LocalHandle remote_socket; 429e41826ac301b9afad1cbfe59c57e27f2495be968Alex Vakulenko auto status = CreateChannelSocketPair(&local_socket, &remote_socket); 430e41826ac301b9afad1cbfe59c57e27f2495be968Alex Vakulenko if (!status) 431e41826ac301b9afad1cbfe59c57e27f2495be968Alex Vakulenko return status.error_status(); 432e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 433e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::lock_guard<std::mutex> autolock(channel_mutex_); 434e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto channel_data = OnNewChannelLocked(std::move(local_socket), channel); 435e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (!channel_data) 436f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko return channel_data.error_status(); 43709aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko *channel_id = channel_data.get().first; 438e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 439e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Flags are ignored for now. 440e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // TODO(xiaohuit): Implement those. 441e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 442e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto* state = static_cast<MessageState*>(message->GetState()); 443f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko Status<ChannelReference> ref = state->PushChannelHandle( 4446890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka remote_socket.Borrow(), 44509aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko channel_data.get().second->event_set.event_fd().Borrow()); 446f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko if (!ref) 447f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko return ref.error_status(); 448e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko state->sockets_to_close.push_back(std::move(remote_socket)); 449f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko return RemoteChannelHandle{ref.get()}; 450e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 451e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 452e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoStatus<int> Endpoint::CheckChannel(const Message* /*message*/, 453e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ChannelReference /*ref*/, 454e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko Channel** /*channel*/) { 455e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // TODO(xiaohuit): Implement this. 456e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ErrorStatus(EFAULT); 457e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 458e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 45909aa736ee6136787b18807d7ab459feba23cec04Alex VakulenkoChannel* Endpoint::GetChannelState(int32_t channel_id) { 460e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::lock_guard<std::mutex> autolock(channel_mutex_); 461e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto channel_data = channels_.find(channel_id); 462e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return (channel_data != channels_.end()) ? channel_data->second.channel_state 463e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko : nullptr; 464e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 465e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 46609aa736ee6136787b18807d7ab459feba23cec04Alex VakulenkoBorrowedHandle Endpoint::GetChannelSocketFd(int32_t channel_id) { 467e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::lock_guard<std::mutex> autolock(channel_mutex_); 46809aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko BorrowedHandle handle; 469e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto channel_data = channels_.find(channel_id); 47009aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko if (channel_data != channels_.end()) 47109aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko handle = channel_data->second.data_fd.Borrow(); 47209aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko return handle; 473e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 474e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 47509aa736ee6136787b18807d7ab459feba23cec04Alex VakulenkoBorrowedHandle Endpoint::GetChannelEventFd(int32_t channel_id) { 476e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::lock_guard<std::mutex> autolock(channel_mutex_); 47709aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko BorrowedHandle handle; 478e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto channel_data = channels_.find(channel_id); 47909aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko if (channel_data != channels_.end()) 48009aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko handle = channel_data->second.event_set.event_fd().Borrow(); 48109aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko return handle; 48209aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko} 48309aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko 48409aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenkoint32_t Endpoint::GetChannelId(const BorrowedHandle& channel_fd) { 48509aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko std::lock_guard<std::mutex> autolock(channel_mutex_); 48609aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko auto iter = channel_fd_to_id_.find(channel_fd.Get()); 48709aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko return (iter != channel_fd_to_id_.end()) ? iter->second : -1; 488e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 489e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 49009aa736ee6136787b18807d7ab459feba23cec04Alex VakulenkoStatus<void> Endpoint::ReceiveMessageForChannel( 49109aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko const BorrowedHandle& channel_fd, Message* message) { 492e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko RequestHeader<LocalHandle> request; 49309aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko int32_t channel_id = GetChannelId(channel_fd); 49409aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko auto status = ReceiveData(channel_fd.Borrow(), &request); 495e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (!status) { 4966890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka if (status.error() == ESHUTDOWN) { 4976890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka BuildCloseMessage(channel_id, message); 4986890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka return {}; 4996890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka } else { 5006890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka CloseChannel(channel_id); 5016890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka return status; 5026890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka } 503e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 5046890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka 505e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko MessageInfo info; 506e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko info.pid = request.cred.pid; 507e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko info.tid = -1; 508e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko info.cid = channel_id; 509e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko info.mid = request.is_impulse ? Message::IMPULSE_MESSAGE_ID 510e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko : GetNextAvailableMessageId(); 511e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko info.euid = request.cred.uid; 512e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko info.egid = request.cred.gid; 513e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko info.op = request.op; 514e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko info.flags = 0; 515e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko info.service = service_; 516e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko info.channel = GetChannelState(channel_id); 517e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko info.send_len = request.send_len; 518e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko info.recv_len = request.max_recv_len; 519e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko info.fd_count = request.file_descriptors.size(); 520e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko static_assert(sizeof(info.impulse) == request.impulse_payload.size(), 521e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko "Impulse payload sizes must be the same in RequestHeader and " 522e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko "MessageInfo"); 523e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko memcpy(info.impulse, request.impulse_payload.data(), 524e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko request.impulse_payload.size()); 525e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko *message = Message{info}; 526e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto* state = static_cast<MessageState*>(message->GetState()); 527e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko state->request = std::move(request); 528e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (request.send_len > 0 && !request.is_impulse) { 529e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko state->request_data.resize(request.send_len); 53009aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko status = ReceiveData(channel_fd, state->request_data.data(), 531e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko state->request_data.size()); 532e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 533e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 534e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (status && request.is_impulse) 53509aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko status = ReenableEpollEvent(channel_fd); 536e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 5376890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka if (!status) { 5386890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka if (status.error() == ESHUTDOWN) { 5396890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka BuildCloseMessage(channel_id, message); 5406890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka return {}; 5416890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka } else { 5426890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka CloseChannel(channel_id); 5436890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka return status; 5446890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka } 5456890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka } 546e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 547e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return status; 548e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 549e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 55009aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenkovoid Endpoint::BuildCloseMessage(int32_t channel_id, Message* message) { 5516890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka ALOGD_IF(TRACE, "Endpoint::BuildCloseMessage: channel_id=%d", channel_id); 5526890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka MessageInfo info; 5536890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka info.pid = -1; 5546890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka info.tid = -1; 5556890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka info.cid = channel_id; 5566890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka info.mid = GetNextAvailableMessageId(); 5576890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka info.euid = -1; 5586890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka info.egid = -1; 5596890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka info.op = opcodes::CHANNEL_CLOSE; 5606890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka info.flags = 0; 5616890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka info.service = service_; 5626890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka info.channel = GetChannelState(channel_id); 5636890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka info.send_len = 0; 5646890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka info.recv_len = 0; 5656890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka info.fd_count = 0; 5666890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka *message = Message{info}; 5676890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka} 568e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 569f0a7bd033941e26e380232a0515e903cf8e678e5Alex VakulenkoStatus<void> Endpoint::MessageReceive(Message* message) { 5706890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka // Receive at most one event from the epoll set. This should prevent multiple 5716890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka // dispatch threads from attempting to handle messages on the same socket at 5726890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka // the same time. 573e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko epoll_event event; 574e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int count = RETRY_EINTR( 575e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko epoll_wait(epoll_fd_.Get(), &event, 1, is_blocking_ ? -1 : 0)); 576e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (count < 0) { 577e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ALOGE("Endpoint::MessageReceive: Failed to wait for epoll events: %s\n", 578e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko strerror(errno)); 579f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko return ErrorStatus{errno}; 580e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } else if (count == 0) { 581f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko return ErrorStatus{ETIMEDOUT}; 582e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 583e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 584e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (event.data.fd == cancel_event_fd_.Get()) { 585f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko return ErrorStatus{ESHUTDOWN}; 586e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 587e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 5886eefa42d33bdddc3603211634f98937b00abc532Alex Vakulenko if (socket_fd_ && event.data.fd == socket_fd_.Get()) { 589e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto status = AcceptConnection(message); 590e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (!status) 591f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko return status; 59209aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko return ReenableEpollEvent(socket_fd_.Borrow()); 593e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 594e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 59509aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko BorrowedHandle channel_fd{event.data.fd}; 5966890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka if (event.events & (EPOLLRDHUP | EPOLLHUP)) { 59709aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko BuildCloseMessage(GetChannelId(channel_fd), message); 598f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko return {}; 599e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 600e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 60109aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko return ReceiveMessageForChannel(channel_fd, message); 602e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 603e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 604f0a7bd033941e26e380232a0515e903cf8e678e5Alex VakulenkoStatus<void> Endpoint::MessageReply(Message* message, int return_code) { 60509aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko const int32_t channel_id = message->GetChannelId(); 60609aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko auto channel_socket = GetChannelSocketFd(channel_id); 60709aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko if (!channel_socket) 608f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko return ErrorStatus{EBADF}; 609e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 610e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto* state = static_cast<MessageState*>(message->GetState()); 611e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko switch (message->GetOp()) { 612e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko case opcodes::CHANNEL_CLOSE: 6136890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka return CloseChannel(channel_id); 614e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 615e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko case opcodes::CHANNEL_OPEN: 616f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko if (return_code < 0) { 6176890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka return CloseChannel(channel_id); 618f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko } else { 619f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko // Reply with the event fd. 62009aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko auto push_status = state->PushFileHandle(GetChannelEventFd(channel_id)); 621f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko state->response_data.clear(); // Just in case... 622f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko if (!push_status) 623f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko return push_status.error_status(); 624f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko return_code = push_status.get(); 625f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko } 626e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko break; 627e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 628e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 629e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko state->response.ret_code = return_code; 630e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko state->response.recv_len = state->response_data.size(); 631e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto status = SendData(channel_socket, state->response); 632e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (status && !state->response_data.empty()) { 633e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko status = SendData(channel_socket, state->response_data.data(), 634e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko state->response_data.size()); 635e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 636e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 637e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (status) 638e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko status = ReenableEpollEvent(channel_socket); 639e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 640f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko return status; 641e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 642e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 643f0a7bd033941e26e380232a0515e903cf8e678e5Alex VakulenkoStatus<void> Endpoint::MessageReplyFd(Message* message, unsigned int push_fd) { 644e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto* state = static_cast<MessageState*>(message->GetState()); 645e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto ref = state->PushFileHandle(BorrowedHandle{static_cast<int>(push_fd)}); 646f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko if (!ref) 647f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko return ref.error_status(); 648f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko return MessageReply(message, ref.get()); 649e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 650e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 651f0a7bd033941e26e380232a0515e903cf8e678e5Alex VakulenkoStatus<void> Endpoint::MessageReplyChannelHandle( 652f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko Message* message, const LocalChannelHandle& handle) { 653e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto* state = static_cast<MessageState*>(message->GetState()); 654e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto ref = state->PushChannelHandle(handle.Borrow()); 655f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko if (!ref) 656f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko return ref.error_status(); 657f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko return MessageReply(message, ref.get()); 658e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 659e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 660f0a7bd033941e26e380232a0515e903cf8e678e5Alex VakulenkoStatus<void> Endpoint::MessageReplyChannelHandle( 661f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko Message* message, const BorrowedChannelHandle& handle) { 662e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto* state = static_cast<MessageState*>(message->GetState()); 663e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto ref = state->PushChannelHandle(handle.Duplicate()); 664f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko if (!ref) 665f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko return ref.error_status(); 666f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko return MessageReply(message, ref.get()); 667e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 668e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 669f0a7bd033941e26e380232a0515e903cf8e678e5Alex VakulenkoStatus<void> Endpoint::MessageReplyChannelHandle( 670f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko Message* message, const RemoteChannelHandle& handle) { 671e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return MessageReply(message, handle.value()); 672e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 673e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 674f0a7bd033941e26e380232a0515e903cf8e678e5Alex VakulenkoStatus<size_t> Endpoint::ReadMessageData(Message* message, const iovec* vector, 675f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko size_t vector_length) { 676e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto* state = static_cast<MessageState*>(message->GetState()); 677e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return state->ReadData(vector, vector_length); 678e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 679e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 680f0a7bd033941e26e380232a0515e903cf8e678e5Alex VakulenkoStatus<size_t> Endpoint::WriteMessageData(Message* message, const iovec* vector, 681f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko size_t vector_length) { 682e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto* state = static_cast<MessageState*>(message->GetState()); 683e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return state->WriteData(vector, vector_length); 684e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 685e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 686f0a7bd033941e26e380232a0515e903cf8e678e5Alex VakulenkoStatus<FileReference> Endpoint::PushFileHandle(Message* message, 687f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko const LocalHandle& handle) { 688e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto* state = static_cast<MessageState*>(message->GetState()); 689e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return state->PushFileHandle(handle.Borrow()); 690e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 691e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 692f0a7bd033941e26e380232a0515e903cf8e678e5Alex VakulenkoStatus<FileReference> Endpoint::PushFileHandle(Message* message, 693f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko const BorrowedHandle& handle) { 694e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto* state = static_cast<MessageState*>(message->GetState()); 695e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return state->PushFileHandle(handle.Duplicate()); 696e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 697e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 698f0a7bd033941e26e380232a0515e903cf8e678e5Alex VakulenkoStatus<FileReference> Endpoint::PushFileHandle(Message* /*message*/, 699f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko const RemoteHandle& handle) { 700e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return handle.Get(); 701e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 702e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 703f0a7bd033941e26e380232a0515e903cf8e678e5Alex VakulenkoStatus<ChannelReference> Endpoint::PushChannelHandle( 704f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko Message* message, const LocalChannelHandle& handle) { 705e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto* state = static_cast<MessageState*>(message->GetState()); 706e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return state->PushChannelHandle(handle.Borrow()); 707e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 708e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 709f0a7bd033941e26e380232a0515e903cf8e678e5Alex VakulenkoStatus<ChannelReference> Endpoint::PushChannelHandle( 710e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko Message* message, const BorrowedChannelHandle& handle) { 711e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto* state = static_cast<MessageState*>(message->GetState()); 712e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return state->PushChannelHandle(handle.Duplicate()); 713e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 714e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 715f0a7bd033941e26e380232a0515e903cf8e678e5Alex VakulenkoStatus<ChannelReference> Endpoint::PushChannelHandle( 716e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko Message* /*message*/, const RemoteChannelHandle& handle) { 717e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return handle.value(); 718e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 719e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 720e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoLocalHandle Endpoint::GetFileHandle(Message* message, FileReference ref) const { 721e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko LocalHandle handle; 722e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto* state = static_cast<MessageState*>(message->GetState()); 723e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko state->GetLocalFileHandle(ref, &handle); 724e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return handle; 725e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 726e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 727e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoLocalChannelHandle Endpoint::GetChannelHandle(Message* message, 728e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ChannelReference ref) const { 729e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko LocalChannelHandle handle; 730e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto* state = static_cast<MessageState*>(message->GetState()); 731e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko state->GetLocalChannelHandle(ref, &handle); 732e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return handle; 733e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 734e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 735f0a7bd033941e26e380232a0515e903cf8e678e5Alex VakulenkoStatus<void> Endpoint::Cancel() { 736f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko if (eventfd_write(cancel_event_fd_.Get(), 1) < 0) 737f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko return ErrorStatus{errno}; 738f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko return {}; 739e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 740e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 741e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostd::unique_ptr<Endpoint> Endpoint::Create(const std::string& endpoint_path, 742e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko mode_t /*unused_mode*/, 743e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko bool blocking) { 744e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return std::unique_ptr<Endpoint>(new Endpoint(endpoint_path, blocking)); 745e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 746e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 747f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenkostd::unique_ptr<Endpoint> Endpoint::CreateAndBindSocket( 748f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko const std::string& endpoint_path, bool blocking) { 749409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko return std::unique_ptr<Endpoint>( 750409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko new Endpoint(endpoint_path, blocking, false)); 751f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko} 752f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko 7536eefa42d33bdddc3603211634f98937b00abc532Alex Vakulenkostd::unique_ptr<Endpoint> Endpoint::CreateFromSocketFd(LocalHandle socket_fd) { 7546eefa42d33bdddc3603211634f98937b00abc532Alex Vakulenko return std::unique_ptr<Endpoint>(new Endpoint(std::move(socket_fd))); 7556eefa42d33bdddc3603211634f98937b00abc532Alex Vakulenko} 7566eefa42d33bdddc3603211634f98937b00abc532Alex Vakulenko 7576eefa42d33bdddc3603211634f98937b00abc532Alex VakulenkoStatus<void> Endpoint::RegisterNewChannelForTests(LocalHandle channel_fd) { 7586eefa42d33bdddc3603211634f98937b00abc532Alex Vakulenko int optval = 1; 7596eefa42d33bdddc3603211634f98937b00abc532Alex Vakulenko if (setsockopt(channel_fd.Get(), SOL_SOCKET, SO_PASSCRED, &optval, 7606eefa42d33bdddc3603211634f98937b00abc532Alex Vakulenko sizeof(optval)) == -1) { 7616eefa42d33bdddc3603211634f98937b00abc532Alex Vakulenko ALOGE( 7626eefa42d33bdddc3603211634f98937b00abc532Alex Vakulenko "Endpoint::RegisterNewChannelForTests: Failed to enable the receiving" 7636eefa42d33bdddc3603211634f98937b00abc532Alex Vakulenko "of the credentials for channel %d: %s", 7646eefa42d33bdddc3603211634f98937b00abc532Alex Vakulenko channel_fd.Get(), strerror(errno)); 7656eefa42d33bdddc3603211634f98937b00abc532Alex Vakulenko return ErrorStatus(errno); 7666eefa42d33bdddc3603211634f98937b00abc532Alex Vakulenko } 7676eefa42d33bdddc3603211634f98937b00abc532Alex Vakulenko return OnNewChannel(std::move(channel_fd)); 7686eefa42d33bdddc3603211634f98937b00abc532Alex Vakulenko} 7696eefa42d33bdddc3603211634f98937b00abc532Alex Vakulenko 770e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} // namespace uds 771e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} // namespace pdx 772e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} // namespace android 773