service_endpoint.cpp revision 409c6eecdca80e95a110d63bc70b1c2dfcf49100
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> 14e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <uds/channel_manager.h> 15e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <uds/client_channel_factory.h> 16e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <uds/ipc_helper.h> 17e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 18e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkonamespace { 19e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 20e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoconstexpr int kMaxBackLogForSocketListen = 1; 21e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 22e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkousing android::pdx::BorrowedChannelHandle; 23e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkousing android::pdx::BorrowedHandle; 24e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkousing android::pdx::ChannelReference; 25f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenkousing android::pdx::ErrorStatus; 26e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkousing android::pdx::FileReference; 27e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkousing android::pdx::LocalChannelHandle; 28e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkousing android::pdx::LocalHandle; 29e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkousing android::pdx::Status; 30e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkousing android::pdx::uds::ChannelInfo; 31e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkousing android::pdx::uds::ChannelManager; 32e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 33e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostruct MessageState { 34e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko bool GetLocalFileHandle(int index, LocalHandle* handle) { 35e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (index < 0) { 36e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko handle->Reset(index); 37e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } else if (static_cast<size_t>(index) < request.file_descriptors.size()) { 38e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko *handle = std::move(request.file_descriptors[index]); 39e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } else { 40e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return false; 41e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 42e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return true; 43e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 44e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 45e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko bool GetLocalChannelHandle(int index, LocalChannelHandle* handle) { 46e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (index < 0) { 47e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko *handle = LocalChannelHandle{nullptr, index}; 48e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } else if (static_cast<size_t>(index) < request.channels.size()) { 49e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto& channel_info = request.channels[index]; 50e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko *handle = ChannelManager::Get().CreateHandle( 51e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::move(channel_info.data_fd), std::move(channel_info.event_fd)); 52e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } else { 53e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return false; 54e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 55e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return true; 56e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 57e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 58f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko Status<FileReference> PushFileHandle(BorrowedHandle handle) { 59e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (!handle) 60e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return handle.Get(); 61e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko response.file_descriptors.push_back(std::move(handle)); 62e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return response.file_descriptors.size() - 1; 63e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 64e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 65f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko Status<ChannelReference> PushChannelHandle(BorrowedChannelHandle handle) { 66e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (!handle) 67e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return handle.value(); 686890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka 696890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka if (auto* channel_data = 706890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka ChannelManager::Get().GetChannelData(handle.value())) { 716890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka ChannelInfo<BorrowedHandle> channel_info; 726890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka channel_info.data_fd.Reset(handle.value()); 736890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka channel_info.event_fd = channel_data->event_receiver.event_fd(); 746890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka response.channels.push_back(std::move(channel_info)); 756890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka return response.channels.size() - 1; 766890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka } else { 77f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko return ErrorStatus{EINVAL}; 786890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka } 79e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 80e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 81f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko Status<ChannelReference> PushChannelHandle(BorrowedHandle data_fd, 82f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko BorrowedHandle event_fd) { 83e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (!data_fd || !event_fd) 84f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko return ErrorStatus{EINVAL}; 85e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ChannelInfo<BorrowedHandle> channel_info; 86e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko channel_info.data_fd = std::move(data_fd); 87e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko channel_info.event_fd = std::move(event_fd); 88e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko response.channels.push_back(std::move(channel_info)); 89e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return response.channels.size() - 1; 90e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 91e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 92f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko Status<size_t> WriteData(const iovec* vector, size_t vector_length) { 93f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko size_t size = 0; 94e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko for (size_t i = 0; i < vector_length; i++) { 95e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const auto* data = reinterpret_cast<const uint8_t*>(vector[i].iov_base); 96e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko response_data.insert(response_data.end(), data, data + vector[i].iov_len); 97e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size += vector[i].iov_len; 98e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 99e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return size; 100e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 101e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 102f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko Status<size_t> ReadData(const iovec* vector, size_t vector_length) { 103e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_t size_remaining = request_data.size() - request_data_read_pos; 104f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko size_t size = 0; 105e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko for (size_t i = 0; i < vector_length && size_remaining > 0; i++) { 106e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_t size_to_copy = std::min(size_remaining, vector[i].iov_len); 107e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko memcpy(vector[i].iov_base, request_data.data() + request_data_read_pos, 108e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_to_copy); 109e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size += size_to_copy; 110e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko request_data_read_pos += size_to_copy; 111e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_remaining -= size_to_copy; 112e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 113e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return size; 114e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 115e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 116e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko android::pdx::uds::RequestHeader<LocalHandle> request; 117e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko android::pdx::uds::ResponseHeader<BorrowedHandle> response; 118e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::vector<LocalHandle> sockets_to_close; 119e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::vector<uint8_t> request_data; 120e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_t request_data_read_pos{0}; 121e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::vector<uint8_t> response_data; 122e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}; 123e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 124e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} // anonymous namespace 125e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 126e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkonamespace android { 127e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkonamespace pdx { 128e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkonamespace uds { 129e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 130409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex VakulenkoEndpoint::Endpoint(const std::string& endpoint_path, bool blocking, 131409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko bool use_init_socket_fd) 132e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko : endpoint_path_{ClientChannelFactory::GetEndpointPath(endpoint_path)}, 133e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko is_blocking_{blocking} { 134409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko LocalHandle fd; 135409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko if (use_init_socket_fd) { 136409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko // Cut off the /dev/socket/ prefix from the full socket path and use the 137409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko // resulting "name" to retrieve the file descriptor for the socket created 138409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko // by the init process. 139409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko constexpr char prefix[] = "/dev/socket/"; 140409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko CHECK(android::base::StartsWith(endpoint_path_, prefix)) 141409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko << "Endpoint::Endpoint: Socket name '" << endpoint_path_ 142409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko << "' must begin with '" << prefix << "'"; 143409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko std::string socket_name = endpoint_path_.substr(sizeof(prefix) - 1); 144409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko fd.Reset(android_get_control_socket(socket_name.c_str())); 145409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko CHECK(fd.IsValid()) 146409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko << "Endpoint::Endpoint: Unable to obtain the control socket fd for '" 147409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko << socket_name << "'"; 148409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko fcntl(fd.Get(), F_SETFD, FD_CLOEXEC); 149409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko } else { 150409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko fd.Reset(socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0)); 151409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko CHECK(fd.IsValid()) << "Endpoint::Endpoint: Failed to create socket: " 152409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko << strerror(errno); 153409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko 154409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko sockaddr_un local; 155409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko local.sun_family = AF_UNIX; 156409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko strncpy(local.sun_path, endpoint_path_.c_str(), sizeof(local.sun_path)); 157409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko local.sun_path[sizeof(local.sun_path) - 1] = '\0'; 158409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko 159409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko unlink(local.sun_path); 160409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko int ret = 161409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko bind(fd.Get(), reinterpret_cast<sockaddr*>(&local), sizeof(local)); 162409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko CHECK_EQ(ret, 0) << "Endpoint::Endpoint: bind error: " << strerror(errno); 163e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 164409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko CHECK_EQ(listen(fd.Get(), kMaxBackLogForSocketListen), 0) 165409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko << "Endpoint::Endpoint: listen error: " << strerror(errno); 166e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 167e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko cancel_event_fd_.Reset(eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK)); 168409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko CHECK(cancel_event_fd_.IsValid()) 169409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko << "Endpoint::Endpoint: Failed to create event fd: " << strerror(errno); 170e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 171409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko epoll_fd_.Reset(epoll_create1(EPOLL_CLOEXEC)); 172409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko CHECK(epoll_fd_.IsValid()) 173409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko << "Endpoint::Endpoint: Failed to create epoll fd: " << strerror(errno); 174e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 175e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko epoll_event socket_event; 176e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko socket_event.events = EPOLLIN | EPOLLRDHUP | EPOLLONESHOT; 177e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko socket_event.data.fd = fd.Get(); 178e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 179e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko epoll_event cancel_event; 180e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko cancel_event.events = EPOLLIN; 181e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko cancel_event.data.fd = cancel_event_fd_.Get(); 182e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 183409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko int ret = epoll_ctl(epoll_fd_.Get(), EPOLL_CTL_ADD, fd.Get(), &socket_event); 184409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko CHECK_EQ(ret, 0) 185409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko << "Endpoint::Endpoint: Failed to add socket fd to epoll fd: " 186409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko << strerror(errno); 187409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko ret = epoll_ctl(epoll_fd_.Get(), EPOLL_CTL_ADD, cancel_event_fd_.Get(), 188409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko &cancel_event); 189409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko CHECK_EQ(ret, 0) 190409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko << "Endpoint::Endpoint: Failed to add cancel event fd to epoll fd: " 191409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko << strerror(errno); 192409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko socket_fd_ = std::move(fd); 193e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 194e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 195e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkovoid* Endpoint::AllocateMessageState() { return new MessageState; } 196e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 197e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkovoid Endpoint::FreeMessageState(void* state) { 198e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko delete static_cast<MessageState*>(state); 199e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 200e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 201e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoStatus<void> Endpoint::AcceptConnection(Message* message) { 202e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko sockaddr_un remote; 203e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko socklen_t addrlen = sizeof(remote); 204409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko LocalHandle channel_fd{accept4(socket_fd_.Get(), 205409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko reinterpret_cast<sockaddr*>(&remote), &addrlen, 206409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko SOCK_CLOEXEC)}; 207e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (!channel_fd) { 208e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ALOGE("Endpoint::AcceptConnection: failed to accept connection: %s", 209e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko strerror(errno)); 210e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ErrorStatus(errno); 211e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 212e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 213e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int optval = 1; 214e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (setsockopt(channel_fd.Get(), SOL_SOCKET, SO_PASSCRED, &optval, 215e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko sizeof(optval)) == -1) { 216e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ALOGE( 217e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko "Endpoint::AcceptConnection: Failed to enable the receiving of the " 218e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko "credentials for channel %d: %s", 219e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko channel_fd.Get(), strerror(errno)); 220e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ErrorStatus(errno); 221e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 222e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 223e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto status = ReceiveMessageForChannel(channel_fd.Get(), message); 224e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (status) 225e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko status = OnNewChannel(std::move(channel_fd)); 226e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return status; 227e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 228e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 229f0a7bd033941e26e380232a0515e903cf8e678e5Alex VakulenkoStatus<void> Endpoint::SetService(Service* service) { 230e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko service_ = service; 231f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko return {}; 232e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 233e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 234f0a7bd033941e26e380232a0515e903cf8e678e5Alex VakulenkoStatus<void> Endpoint::SetChannel(int channel_id, Channel* channel) { 235e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::lock_guard<std::mutex> autolock(channel_mutex_); 236e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto channel_data = channels_.find(channel_id); 237e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (channel_data == channels_.end()) 238f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko return ErrorStatus{EINVAL}; 239e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko channel_data->second.channel_state = channel; 240f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko return {}; 241e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 242e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 243e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoStatus<void> Endpoint::OnNewChannel(LocalHandle channel_fd) { 244e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::lock_guard<std::mutex> autolock(channel_mutex_); 245e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko Status<void> status; 246e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko status.PropagateError(OnNewChannelLocked(std::move(channel_fd), nullptr)); 247e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return status; 248e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 249e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 250e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoStatus<Endpoint::ChannelData*> Endpoint::OnNewChannelLocked( 251e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko LocalHandle channel_fd, Channel* channel_state) { 252e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko epoll_event event; 253e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko event.events = EPOLLIN | EPOLLRDHUP | EPOLLONESHOT; 254e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko event.data.fd = channel_fd.Get(); 255e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (epoll_ctl(epoll_fd_.Get(), EPOLL_CTL_ADD, channel_fd.Get(), &event) < 0) { 256e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ALOGE( 257e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko "Endpoint::OnNewChannelLocked: Failed to add channel to endpoint: %s\n", 258e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko strerror(errno)); 259e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ErrorStatus(errno); 260e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 261e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ChannelData channel_data; 2626890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka const int channel_id = channel_fd.Get(); 2636890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka channel_data.event_set.AddDataFd(channel_fd); 264e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko channel_data.data_fd = std::move(channel_fd); 265e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko channel_data.channel_state = channel_state; 266e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto pair = channels_.emplace(channel_id, std::move(channel_data)); 267e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return &pair.first->second; 268e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 269e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 270e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoStatus<void> Endpoint::ReenableEpollEvent(int fd) { 271e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko epoll_event event; 272e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko event.events = EPOLLIN | EPOLLRDHUP | EPOLLONESHOT; 273e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko event.data.fd = fd; 274e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (epoll_ctl(epoll_fd_.Get(), EPOLL_CTL_MOD, fd, &event) < 0) { 275e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ALOGE( 276e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko "Endpoint::ReenableEpollEvent: Failed to re-enable channel to " 277e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko "endpoint: %s\n", 278e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko strerror(errno)); 279e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ErrorStatus(errno); 280e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 281e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return {}; 282e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 283e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 284f0a7bd033941e26e380232a0515e903cf8e678e5Alex VakulenkoStatus<void> Endpoint::CloseChannel(int channel_id) { 285e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::lock_guard<std::mutex> autolock(channel_mutex_); 286e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return CloseChannelLocked(channel_id); 287e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 288e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 289f0a7bd033941e26e380232a0515e903cf8e678e5Alex VakulenkoStatus<void> Endpoint::CloseChannelLocked(int channel_id) { 2906890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka ALOGD_IF(TRACE, "Endpoint::CloseChannelLocked: channel_id=%d", channel_id); 2916890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka 292e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto channel_data = channels_.find(channel_id); 293e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (channel_data == channels_.end()) 294f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko return ErrorStatus{EINVAL}; 295e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 296f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko Status<void> status; 297e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko epoll_event dummy; // See BUGS in man 2 epoll_ctl. 298e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (epoll_ctl(epoll_fd_.Get(), EPOLL_CTL_DEL, channel_id, &dummy) < 0) { 299f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko status.SetError(errno); 300e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ALOGE( 301e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko "Endpoint::CloseChannelLocked: Failed to remove channel from endpoint: " 302e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko "%s\n", 303e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko strerror(errno)); 304f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko } else { 305f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko status.SetValue(); 306e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 307e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 308e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko channels_.erase(channel_data); 309f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko return status; 310e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 311e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 312f0a7bd033941e26e380232a0515e903cf8e678e5Alex VakulenkoStatus<void> Endpoint::ModifyChannelEvents(int channel_id, int clear_mask, 313f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko int set_mask) { 314e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::lock_guard<std::mutex> autolock(channel_mutex_); 315e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 3166890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka auto search = channels_.find(channel_id); 3176890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka if (search != channels_.end()) { 3186890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka auto& channel_data = search->second; 3196890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka channel_data.event_set.ModifyEvents(clear_mask, set_mask); 320f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko return {}; 321e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 322e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 323f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko return ErrorStatus{EINVAL}; 324e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 325e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 326e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoStatus<RemoteChannelHandle> Endpoint::PushChannel(Message* message, 327e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int /*flags*/, 328e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko Channel* channel, 329e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int* channel_id) { 330e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int channel_pair[2] = {}; 331409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, channel_pair) == -1) { 332e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ALOGE("Endpoint::PushChannel: Failed to create a socket pair: %s", 333e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko strerror(errno)); 334e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ErrorStatus(errno); 335e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 336e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 337e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko LocalHandle local_socket{channel_pair[0]}; 338e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko LocalHandle remote_socket{channel_pair[1]}; 339e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 340e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int optval = 1; 341e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (setsockopt(local_socket.Get(), SOL_SOCKET, SO_PASSCRED, &optval, 342e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko sizeof(optval)) == -1) { 343e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ALOGE( 344e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko "Endpoint::PushChannel: Failed to enable the receiving of the " 345e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko "credentials for channel %d: %s", 346e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko local_socket.Get(), strerror(errno)); 347e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ErrorStatus(errno); 348e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 349e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 350e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::lock_guard<std::mutex> autolock(channel_mutex_); 351e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko *channel_id = local_socket.Get(); 352e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto channel_data = OnNewChannelLocked(std::move(local_socket), channel); 353e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (!channel_data) 354f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko return channel_data.error_status(); 355e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 356e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Flags are ignored for now. 357e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // TODO(xiaohuit): Implement those. 358e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 359e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto* state = static_cast<MessageState*>(message->GetState()); 360f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko Status<ChannelReference> ref = state->PushChannelHandle( 3616890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka remote_socket.Borrow(), 3626890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka channel_data.get()->event_set.event_fd().Borrow()); 363f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko if (!ref) 364f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko return ref.error_status(); 365e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko state->sockets_to_close.push_back(std::move(remote_socket)); 366f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko return RemoteChannelHandle{ref.get()}; 367e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 368e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 369e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoStatus<int> Endpoint::CheckChannel(const Message* /*message*/, 370e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ChannelReference /*ref*/, 371e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko Channel** /*channel*/) { 372e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // TODO(xiaohuit): Implement this. 373e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ErrorStatus(EFAULT); 374e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 375e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 376e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoChannel* Endpoint::GetChannelState(int channel_id) { 377e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::lock_guard<std::mutex> autolock(channel_mutex_); 378e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto channel_data = channels_.find(channel_id); 379e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return (channel_data != channels_.end()) ? channel_data->second.channel_state 380e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko : nullptr; 381e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 382e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 383e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoint Endpoint::GetChannelSocketFd(int channel_id) { 384e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::lock_guard<std::mutex> autolock(channel_mutex_); 385e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto channel_data = channels_.find(channel_id); 386e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return (channel_data != channels_.end()) ? channel_data->second.data_fd.Get() 387e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko : -1; 388e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 389e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 390e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoint Endpoint::GetChannelEventFd(int channel_id) { 391e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::lock_guard<std::mutex> autolock(channel_mutex_); 392e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto channel_data = channels_.find(channel_id); 3936890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka return (channel_data != channels_.end()) 3946890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka ? channel_data->second.event_set.event_fd().Get() 3956890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka : -1; 396e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 397e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 398e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoStatus<void> Endpoint::ReceiveMessageForChannel(int channel_id, 399e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko Message* message) { 400e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko RequestHeader<LocalHandle> request; 401e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto status = ReceiveData(channel_id, &request); 402e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (!status) { 4036890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka if (status.error() == ESHUTDOWN) { 4046890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka BuildCloseMessage(channel_id, message); 4056890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka return {}; 4066890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka } else { 4076890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka CloseChannel(channel_id); 4086890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka return status; 4096890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka } 410e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 4116890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka 412e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko MessageInfo info; 413e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko info.pid = request.cred.pid; 414e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko info.tid = -1; 415e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko info.cid = channel_id; 416e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko info.mid = request.is_impulse ? Message::IMPULSE_MESSAGE_ID 417e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko : GetNextAvailableMessageId(); 418e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko info.euid = request.cred.uid; 419e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko info.egid = request.cred.gid; 420e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko info.op = request.op; 421e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko info.flags = 0; 422e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko info.service = service_; 423e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko info.channel = GetChannelState(channel_id); 424e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko info.send_len = request.send_len; 425e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko info.recv_len = request.max_recv_len; 426e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko info.fd_count = request.file_descriptors.size(); 427e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko static_assert(sizeof(info.impulse) == request.impulse_payload.size(), 428e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko "Impulse payload sizes must be the same in RequestHeader and " 429e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko "MessageInfo"); 430e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko memcpy(info.impulse, request.impulse_payload.data(), 431e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko request.impulse_payload.size()); 432e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko *message = Message{info}; 433e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto* state = static_cast<MessageState*>(message->GetState()); 434e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko state->request = std::move(request); 435e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (request.send_len > 0 && !request.is_impulse) { 436e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko state->request_data.resize(request.send_len); 437e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko status = ReceiveData(channel_id, state->request_data.data(), 438e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko state->request_data.size()); 439e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 440e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 441e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (status && request.is_impulse) 442e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko status = ReenableEpollEvent(channel_id); 443e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 4446890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka if (!status) { 4456890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka if (status.error() == ESHUTDOWN) { 4466890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka BuildCloseMessage(channel_id, message); 4476890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka return {}; 4486890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka } else { 4496890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka CloseChannel(channel_id); 4506890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka return status; 4516890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka } 4526890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka } 453e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 454e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return status; 455e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 456e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 4576890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabakavoid Endpoint::BuildCloseMessage(int channel_id, Message* message) { 4586890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka ALOGD_IF(TRACE, "Endpoint::BuildCloseMessage: channel_id=%d", channel_id); 4596890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka MessageInfo info; 4606890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka info.pid = -1; 4616890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka info.tid = -1; 4626890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka info.cid = channel_id; 4636890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka info.mid = GetNextAvailableMessageId(); 4646890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka info.euid = -1; 4656890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka info.egid = -1; 4666890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka info.op = opcodes::CHANNEL_CLOSE; 4676890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka info.flags = 0; 4686890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka info.service = service_; 4696890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka info.channel = GetChannelState(channel_id); 4706890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka info.send_len = 0; 4716890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka info.recv_len = 0; 4726890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka info.fd_count = 0; 4736890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka *message = Message{info}; 4746890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka} 475e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 476f0a7bd033941e26e380232a0515e903cf8e678e5Alex VakulenkoStatus<void> Endpoint::MessageReceive(Message* message) { 4776890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka // Receive at most one event from the epoll set. This should prevent multiple 4786890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka // dispatch threads from attempting to handle messages on the same socket at 4796890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka // the same time. 480e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko epoll_event event; 481e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int count = RETRY_EINTR( 482e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko epoll_wait(epoll_fd_.Get(), &event, 1, is_blocking_ ? -1 : 0)); 483e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (count < 0) { 484e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ALOGE("Endpoint::MessageReceive: Failed to wait for epoll events: %s\n", 485e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko strerror(errno)); 486f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko return ErrorStatus{errno}; 487e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } else if (count == 0) { 488f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko return ErrorStatus{ETIMEDOUT}; 489e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 490e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 491e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (event.data.fd == cancel_event_fd_.Get()) { 492f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko return ErrorStatus{ESHUTDOWN}; 493e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 494e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 495e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (event.data.fd == socket_fd_.Get()) { 496e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto status = AcceptConnection(message); 497e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (!status) 498f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko return status; 499f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko return ReenableEpollEvent(socket_fd_.Get()); 500e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 501e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 502e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int channel_id = event.data.fd; 5036890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka if (event.events & (EPOLLRDHUP | EPOLLHUP)) { 5046890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka BuildCloseMessage(channel_id, message); 505f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko return {}; 506e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 507e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 508f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko return ReceiveMessageForChannel(channel_id, message); 509e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 510e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 511f0a7bd033941e26e380232a0515e903cf8e678e5Alex VakulenkoStatus<void> Endpoint::MessageReply(Message* message, int return_code) { 5126890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka const int channel_id = message->GetChannelId(); 5136890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka const int channel_socket = GetChannelSocketFd(channel_id); 514e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (channel_socket < 0) 515f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko return ErrorStatus{EBADF}; 516e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 517e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto* state = static_cast<MessageState*>(message->GetState()); 518e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko switch (message->GetOp()) { 519e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko case opcodes::CHANNEL_CLOSE: 5206890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka return CloseChannel(channel_id); 521e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 522e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko case opcodes::CHANNEL_OPEN: 523f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko if (return_code < 0) { 5246890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka return CloseChannel(channel_id); 525f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko } else { 526f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko // Reply with the event fd. 527f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko auto push_status = state->PushFileHandle( 528f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko BorrowedHandle{GetChannelEventFd(channel_socket)}); 529f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko state->response_data.clear(); // Just in case... 530f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko if (!push_status) 531f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko return push_status.error_status(); 532f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko return_code = push_status.get(); 533f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko } 534e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko break; 535e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 536e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 537e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko state->response.ret_code = return_code; 538e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko state->response.recv_len = state->response_data.size(); 539e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto status = SendData(channel_socket, state->response); 540e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (status && !state->response_data.empty()) { 541e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko status = SendData(channel_socket, state->response_data.data(), 542e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko state->response_data.size()); 543e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 544e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 545e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (status) 546e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko status = ReenableEpollEvent(channel_socket); 547e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 548f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko return status; 549e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 550e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 551f0a7bd033941e26e380232a0515e903cf8e678e5Alex VakulenkoStatus<void> Endpoint::MessageReplyFd(Message* message, unsigned int push_fd) { 552e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto* state = static_cast<MessageState*>(message->GetState()); 553e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto ref = state->PushFileHandle(BorrowedHandle{static_cast<int>(push_fd)}); 554f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko if (!ref) 555f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko return ref.error_status(); 556f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko return MessageReply(message, ref.get()); 557e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 558e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 559f0a7bd033941e26e380232a0515e903cf8e678e5Alex VakulenkoStatus<void> Endpoint::MessageReplyChannelHandle( 560f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko Message* message, const LocalChannelHandle& handle) { 561e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto* state = static_cast<MessageState*>(message->GetState()); 562e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto ref = state->PushChannelHandle(handle.Borrow()); 563f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko if (!ref) 564f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko return ref.error_status(); 565f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko return MessageReply(message, ref.get()); 566e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 567e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 568f0a7bd033941e26e380232a0515e903cf8e678e5Alex VakulenkoStatus<void> Endpoint::MessageReplyChannelHandle( 569f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko Message* message, const BorrowedChannelHandle& handle) { 570e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto* state = static_cast<MessageState*>(message->GetState()); 571e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto ref = state->PushChannelHandle(handle.Duplicate()); 572f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko if (!ref) 573f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko return ref.error_status(); 574f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko return MessageReply(message, ref.get()); 575e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 576e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 577f0a7bd033941e26e380232a0515e903cf8e678e5Alex VakulenkoStatus<void> Endpoint::MessageReplyChannelHandle( 578f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko Message* message, const RemoteChannelHandle& handle) { 579e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return MessageReply(message, handle.value()); 580e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 581e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 582f0a7bd033941e26e380232a0515e903cf8e678e5Alex VakulenkoStatus<size_t> Endpoint::ReadMessageData(Message* message, const iovec* vector, 583f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko size_t vector_length) { 584e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto* state = static_cast<MessageState*>(message->GetState()); 585e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return state->ReadData(vector, vector_length); 586e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 587e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 588f0a7bd033941e26e380232a0515e903cf8e678e5Alex VakulenkoStatus<size_t> Endpoint::WriteMessageData(Message* message, const iovec* vector, 589f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko size_t vector_length) { 590e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto* state = static_cast<MessageState*>(message->GetState()); 591e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return state->WriteData(vector, vector_length); 592e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 593e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 594f0a7bd033941e26e380232a0515e903cf8e678e5Alex VakulenkoStatus<FileReference> Endpoint::PushFileHandle(Message* message, 595f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko const LocalHandle& handle) { 596e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto* state = static_cast<MessageState*>(message->GetState()); 597e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return state->PushFileHandle(handle.Borrow()); 598e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 599e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 600f0a7bd033941e26e380232a0515e903cf8e678e5Alex VakulenkoStatus<FileReference> Endpoint::PushFileHandle(Message* message, 601f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko const BorrowedHandle& handle) { 602e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto* state = static_cast<MessageState*>(message->GetState()); 603e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return state->PushFileHandle(handle.Duplicate()); 604e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 605e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 606f0a7bd033941e26e380232a0515e903cf8e678e5Alex VakulenkoStatus<FileReference> Endpoint::PushFileHandle(Message* /*message*/, 607f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko const RemoteHandle& handle) { 608e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return handle.Get(); 609e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 610e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 611f0a7bd033941e26e380232a0515e903cf8e678e5Alex VakulenkoStatus<ChannelReference> Endpoint::PushChannelHandle( 612f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko Message* message, const LocalChannelHandle& handle) { 613e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto* state = static_cast<MessageState*>(message->GetState()); 614e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return state->PushChannelHandle(handle.Borrow()); 615e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 616e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 617f0a7bd033941e26e380232a0515e903cf8e678e5Alex VakulenkoStatus<ChannelReference> Endpoint::PushChannelHandle( 618e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko Message* message, const BorrowedChannelHandle& handle) { 619e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto* state = static_cast<MessageState*>(message->GetState()); 620e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return state->PushChannelHandle(handle.Duplicate()); 621e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 622e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 623f0a7bd033941e26e380232a0515e903cf8e678e5Alex VakulenkoStatus<ChannelReference> Endpoint::PushChannelHandle( 624e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko Message* /*message*/, const RemoteChannelHandle& handle) { 625e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return handle.value(); 626e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 627e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 628e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoLocalHandle Endpoint::GetFileHandle(Message* message, FileReference ref) const { 629e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko LocalHandle handle; 630e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto* state = static_cast<MessageState*>(message->GetState()); 631e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko state->GetLocalFileHandle(ref, &handle); 632e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return handle; 633e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 634e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 635e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoLocalChannelHandle Endpoint::GetChannelHandle(Message* message, 636e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ChannelReference ref) const { 637e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko LocalChannelHandle handle; 638e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto* state = static_cast<MessageState*>(message->GetState()); 639e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko state->GetLocalChannelHandle(ref, &handle); 640e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return handle; 641e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 642e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 643f0a7bd033941e26e380232a0515e903cf8e678e5Alex VakulenkoStatus<void> Endpoint::Cancel() { 644f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko if (eventfd_write(cancel_event_fd_.Get(), 1) < 0) 645f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko return ErrorStatus{errno}; 646f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko return {}; 647e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 648e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 649e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostd::unique_ptr<Endpoint> Endpoint::Create(const std::string& endpoint_path, 650e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko mode_t /*unused_mode*/, 651e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko bool blocking) { 652e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return std::unique_ptr<Endpoint>(new Endpoint(endpoint_path, blocking)); 653e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 654e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 655f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenkostd::unique_ptr<Endpoint> Endpoint::CreateAndBindSocket( 656f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko const std::string& endpoint_path, bool blocking) { 657409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko return std::unique_ptr<Endpoint>( 658409c6eecdca80e95a110d63bc70b1c2dfcf49100Alex Vakulenko new Endpoint(endpoint_path, blocking, false)); 659f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko} 660f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko 661e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} // namespace uds 662e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} // namespace pdx 663e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} // namespace android 664