service_endpoint.cpp revision 6890d95ec8b96970202518b439bfa8ab2d9dbf77
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 10e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <pdx/service.h> 11e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <uds/channel_manager.h> 12e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <uds/client_channel_factory.h> 13e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <uds/ipc_helper.h> 14e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 15e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkonamespace { 16e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 17e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoconstexpr int kMaxBackLogForSocketListen = 1; 18e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 19e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkousing android::pdx::BorrowedChannelHandle; 20e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkousing android::pdx::BorrowedHandle; 21e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkousing android::pdx::ChannelReference; 22e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkousing android::pdx::FileReference; 23e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkousing android::pdx::LocalChannelHandle; 24e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkousing android::pdx::LocalHandle; 25e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkousing android::pdx::Status; 26e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkousing android::pdx::uds::ChannelInfo; 27e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkousing android::pdx::uds::ChannelManager; 28e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 29e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostruct MessageState { 30e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko bool GetLocalFileHandle(int index, LocalHandle* handle) { 31e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (index < 0) { 32e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko handle->Reset(index); 33e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } else if (static_cast<size_t>(index) < request.file_descriptors.size()) { 34e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko *handle = std::move(request.file_descriptors[index]); 35e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } else { 36e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return false; 37e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 38e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return true; 39e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 40e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 41e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko bool GetLocalChannelHandle(int index, LocalChannelHandle* handle) { 42e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (index < 0) { 43e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko *handle = LocalChannelHandle{nullptr, index}; 44e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } else if (static_cast<size_t>(index) < request.channels.size()) { 45e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto& channel_info = request.channels[index]; 46e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko *handle = ChannelManager::Get().CreateHandle( 47e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::move(channel_info.data_fd), std::move(channel_info.event_fd)); 48e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } else { 49e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return false; 50e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 51e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return true; 52e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 53e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 54e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko FileReference PushFileHandle(BorrowedHandle handle) { 55e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (!handle) 56e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return handle.Get(); 57e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko response.file_descriptors.push_back(std::move(handle)); 58e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return response.file_descriptors.size() - 1; 59e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 60e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 61e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ChannelReference PushChannelHandle(BorrowedChannelHandle handle) { 62e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (!handle) 63e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return handle.value(); 646890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka 656890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka if (auto* channel_data = 666890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka ChannelManager::Get().GetChannelData(handle.value())) { 676890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka ChannelInfo<BorrowedHandle> channel_info; 686890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka channel_info.data_fd.Reset(handle.value()); 696890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka channel_info.event_fd = channel_data->event_receiver.event_fd(); 706890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka response.channels.push_back(std::move(channel_info)); 716890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka return response.channels.size() - 1; 726890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka } else { 736890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka return -1; 746890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka } 75e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 76e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 77e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ChannelReference PushChannelHandle(BorrowedHandle data_fd, 78e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko BorrowedHandle event_fd) { 79e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (!data_fd || !event_fd) 80e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return -1; 81e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ChannelInfo<BorrowedHandle> channel_info; 82e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko channel_info.data_fd = std::move(data_fd); 83e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko channel_info.event_fd = std::move(event_fd); 84e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko response.channels.push_back(std::move(channel_info)); 85e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return response.channels.size() - 1; 86e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 87e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 88e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ssize_t WriteData(const iovec* vector, size_t vector_length) { 89e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ssize_t size = 0; 90e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko for (size_t i = 0; i < vector_length; i++) { 91e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const auto* data = reinterpret_cast<const uint8_t*>(vector[i].iov_base); 92e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko response_data.insert(response_data.end(), data, data + vector[i].iov_len); 93e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size += vector[i].iov_len; 94e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 95e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return size; 96e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 97e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 98e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ssize_t ReadData(const iovec* vector, size_t vector_length) { 99e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_t size_remaining = request_data.size() - request_data_read_pos; 100e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ssize_t size = 0; 101e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko for (size_t i = 0; i < vector_length && size_remaining > 0; i++) { 102e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_t size_to_copy = std::min(size_remaining, vector[i].iov_len); 103e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko memcpy(vector[i].iov_base, request_data.data() + request_data_read_pos, 104e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_to_copy); 105e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size += size_to_copy; 106e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko request_data_read_pos += size_to_copy; 107e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_remaining -= size_to_copy; 108e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 109e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return size; 110e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 111e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 112e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko android::pdx::uds::RequestHeader<LocalHandle> request; 113e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko android::pdx::uds::ResponseHeader<BorrowedHandle> response; 114e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::vector<LocalHandle> sockets_to_close; 115e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::vector<uint8_t> request_data; 116e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_t request_data_read_pos{0}; 117e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::vector<uint8_t> response_data; 118e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}; 119e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 120e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} // anonymous namespace 121e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 122e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkonamespace android { 123e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkonamespace pdx { 124e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkonamespace uds { 125e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 126e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoEndpoint::Endpoint(const std::string& endpoint_path, bool blocking) 127e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko : endpoint_path_{ClientChannelFactory::GetEndpointPath(endpoint_path)}, 128e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko is_blocking_{blocking} { 129e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko LocalHandle fd{socket(AF_UNIX, SOCK_STREAM, 0)}; 130e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (!fd) { 131e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ALOGE("Endpoint::Endpoint: Failed to create socket: %s", strerror(errno)); 132e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return; 133e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 134e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 135e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko sockaddr_un local; 136e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko local.sun_family = AF_UNIX; 137e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko strncpy(local.sun_path, endpoint_path_.c_str(), sizeof(local.sun_path)); 138e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko local.sun_path[sizeof(local.sun_path) - 1] = '\0'; 139e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 140e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko unlink(local.sun_path); 141e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (bind(fd.Get(), (struct sockaddr*)&local, sizeof(local)) == -1) { 142e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ALOGE("Endpoint::Endpoint: bind error: %s", strerror(errno)); 143e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return; 144e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 145e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (listen(fd.Get(), kMaxBackLogForSocketListen) == -1) { 146e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ALOGE("Endpoint::Endpoint: listen error: %s", strerror(errno)); 147e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return; 148e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 149e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 150e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko cancel_event_fd_.Reset(eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK)); 151e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (!cancel_event_fd_) { 152e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ALOGE("Endpoint::Endpoint: Failed to create event fd: %s\n", 153e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko strerror(errno)); 154e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return; 155e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 156e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 157e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko epoll_fd_.Reset(epoll_create(1)); // Size arg is ignored, but must be > 0. 158e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (!epoll_fd_) { 159e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ALOGE("Endpoint::Endpoint: Failed to create epoll fd: %s\n", 160e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko strerror(errno)); 161e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return; 162e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 163e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 164e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko epoll_event socket_event; 165e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko socket_event.events = EPOLLIN | EPOLLRDHUP | EPOLLONESHOT; 166e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko socket_event.data.fd = fd.Get(); 167e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 168e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko epoll_event cancel_event; 169e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko cancel_event.events = EPOLLIN; 170e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko cancel_event.data.fd = cancel_event_fd_.Get(); 171e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 172e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (epoll_ctl(epoll_fd_.Get(), EPOLL_CTL_ADD, fd.Get(), &socket_event) < 0 || 173e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko epoll_ctl(epoll_fd_.Get(), EPOLL_CTL_ADD, cancel_event_fd_.Get(), 174e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko &cancel_event) < 0) { 175e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ALOGE("Endpoint::Endpoint: Failed to add event fd to epoll fd: %s\n", 176e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko strerror(errno)); 177e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko cancel_event_fd_.Close(); 178e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko epoll_fd_.Close(); 179e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } else { 180e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko socket_fd_ = std::move(fd); 181e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 182e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 183e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 184e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkovoid* Endpoint::AllocateMessageState() { return new MessageState; } 185e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 186e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkovoid Endpoint::FreeMessageState(void* state) { 187e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko delete static_cast<MessageState*>(state); 188e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 189e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 190e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoStatus<void> Endpoint::AcceptConnection(Message* message) { 191e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko sockaddr_un remote; 192e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko socklen_t addrlen = sizeof(remote); 193e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko LocalHandle channel_fd{ 194e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko accept(socket_fd_.Get(), reinterpret_cast<sockaddr*>(&remote), &addrlen)}; 195e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (!channel_fd) { 196e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ALOGE("Endpoint::AcceptConnection: failed to accept connection: %s", 197e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko strerror(errno)); 198e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ErrorStatus(errno); 199e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 200e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 201e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int optval = 1; 202e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (setsockopt(channel_fd.Get(), SOL_SOCKET, SO_PASSCRED, &optval, 203e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko sizeof(optval)) == -1) { 204e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ALOGE( 205e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko "Endpoint::AcceptConnection: Failed to enable the receiving of the " 206e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko "credentials for channel %d: %s", 207e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko channel_fd.Get(), strerror(errno)); 208e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ErrorStatus(errno); 209e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 210e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 211e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto status = ReceiveMessageForChannel(channel_fd.Get(), message); 212e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (status) 213e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko status = OnNewChannel(std::move(channel_fd)); 214e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return status; 215e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 216e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 217e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoint Endpoint::SetService(Service* service) { 218e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko service_ = service; 219e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return 0; 220e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 221e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 222e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoint Endpoint::SetChannel(int channel_id, Channel* channel) { 223e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::lock_guard<std::mutex> autolock(channel_mutex_); 224e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto channel_data = channels_.find(channel_id); 225e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (channel_data == channels_.end()) 226e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return -EINVAL; 227e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko channel_data->second.channel_state = channel; 228e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return 0; 229e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 230e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 231e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoStatus<void> Endpoint::OnNewChannel(LocalHandle channel_fd) { 232e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::lock_guard<std::mutex> autolock(channel_mutex_); 233e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko Status<void> status; 234e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko status.PropagateError(OnNewChannelLocked(std::move(channel_fd), nullptr)); 235e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return status; 236e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 237e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 238e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoStatus<Endpoint::ChannelData*> Endpoint::OnNewChannelLocked( 239e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko LocalHandle channel_fd, Channel* channel_state) { 240e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko epoll_event event; 241e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko event.events = EPOLLIN | EPOLLRDHUP | EPOLLONESHOT; 242e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko event.data.fd = channel_fd.Get(); 243e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (epoll_ctl(epoll_fd_.Get(), EPOLL_CTL_ADD, channel_fd.Get(), &event) < 0) { 244e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ALOGE( 245e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko "Endpoint::OnNewChannelLocked: Failed to add channel to endpoint: %s\n", 246e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko strerror(errno)); 247e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ErrorStatus(errno); 248e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 249e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ChannelData channel_data; 2506890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka const int channel_id = channel_fd.Get(); 2516890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka channel_data.event_set.AddDataFd(channel_fd); 252e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko channel_data.data_fd = std::move(channel_fd); 253e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko channel_data.channel_state = channel_state; 254e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto pair = channels_.emplace(channel_id, std::move(channel_data)); 255e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return &pair.first->second; 256e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 257e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 258e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoStatus<void> Endpoint::ReenableEpollEvent(int fd) { 259e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko epoll_event event; 260e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko event.events = EPOLLIN | EPOLLRDHUP | EPOLLONESHOT; 261e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko event.data.fd = fd; 262e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (epoll_ctl(epoll_fd_.Get(), EPOLL_CTL_MOD, fd, &event) < 0) { 263e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ALOGE( 264e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko "Endpoint::ReenableEpollEvent: Failed to re-enable channel to " 265e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko "endpoint: %s\n", 266e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko strerror(errno)); 267e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ErrorStatus(errno); 268e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 269e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return {}; 270e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 271e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 272e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoint Endpoint::CloseChannel(int channel_id) { 273e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::lock_guard<std::mutex> autolock(channel_mutex_); 274e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return CloseChannelLocked(channel_id); 275e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 276e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 277e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoint Endpoint::CloseChannelLocked(int channel_id) { 2786890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka ALOGD_IF(TRACE, "Endpoint::CloseChannelLocked: channel_id=%d", channel_id); 2796890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka 280e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto channel_data = channels_.find(channel_id); 281e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (channel_data == channels_.end()) 282e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return -EINVAL; 283e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 284e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int ret = 0; 285e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko epoll_event dummy; // See BUGS in man 2 epoll_ctl. 286e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (epoll_ctl(epoll_fd_.Get(), EPOLL_CTL_DEL, channel_id, &dummy) < 0) { 287e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ret = -errno; 288e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ALOGE( 289e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko "Endpoint::CloseChannelLocked: Failed to remove channel from endpoint: " 290e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko "%s\n", 291e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko strerror(errno)); 292e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 293e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 294e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko channels_.erase(channel_data); 295e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ret; 296e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 297e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 298e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoint Endpoint::ModifyChannelEvents(int channel_id, int clear_mask, 299e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int set_mask) { 300e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::lock_guard<std::mutex> autolock(channel_mutex_); 301e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 3026890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka auto search = channels_.find(channel_id); 3036890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka if (search != channels_.end()) { 3046890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka auto& channel_data = search->second; 3056890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka channel_data.event_set.ModifyEvents(clear_mask, set_mask); 306e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return 0; 307e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 308e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 3096890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka return -EINVAL; 310e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 311e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 312e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoStatus<RemoteChannelHandle> Endpoint::PushChannel(Message* message, 313e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int /*flags*/, 314e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko Channel* channel, 315e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int* channel_id) { 316e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int channel_pair[2] = {}; 317e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (socketpair(AF_UNIX, SOCK_STREAM, 0, channel_pair) == -1) { 318e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ALOGE("Endpoint::PushChannel: Failed to create a socket pair: %s", 319e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko strerror(errno)); 320e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ErrorStatus(errno); 321e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 322e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 323e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko LocalHandle local_socket{channel_pair[0]}; 324e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko LocalHandle remote_socket{channel_pair[1]}; 325e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 326e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int optval = 1; 327e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (setsockopt(local_socket.Get(), SOL_SOCKET, SO_PASSCRED, &optval, 328e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko sizeof(optval)) == -1) { 329e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ALOGE( 330e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko "Endpoint::PushChannel: Failed to enable the receiving of the " 331e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko "credentials for channel %d: %s", 332e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko local_socket.Get(), strerror(errno)); 333e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ErrorStatus(errno); 334e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 335e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 336e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::lock_guard<std::mutex> autolock(channel_mutex_); 337e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko *channel_id = local_socket.Get(); 338e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto channel_data = OnNewChannelLocked(std::move(local_socket), channel); 339e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (!channel_data) 340e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ErrorStatus(channel_data.error()); 341e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 342e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Flags are ignored for now. 343e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // TODO(xiaohuit): Implement those. 344e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 345e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto* state = static_cast<MessageState*>(message->GetState()); 346e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ChannelReference ref = state->PushChannelHandle( 3476890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka remote_socket.Borrow(), 3486890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka channel_data.get()->event_set.event_fd().Borrow()); 349e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko state->sockets_to_close.push_back(std::move(remote_socket)); 350e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return RemoteChannelHandle{ref}; 351e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 352e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 353e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoStatus<int> Endpoint::CheckChannel(const Message* /*message*/, 354e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ChannelReference /*ref*/, 355e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko Channel** /*channel*/) { 356e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // TODO(xiaohuit): Implement this. 357e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ErrorStatus(EFAULT); 358e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 359e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 360e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoint Endpoint::DefaultHandleMessage(const MessageInfo& /* info */) { 361e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ALOGE( 362e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko "Endpoint::CheckChannel: Not implemented! Endpoint DefaultHandleMessage " 363e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko "does nothing!"); 364e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return 0; 365e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 366e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 367e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoChannel* Endpoint::GetChannelState(int channel_id) { 368e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::lock_guard<std::mutex> autolock(channel_mutex_); 369e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto channel_data = channels_.find(channel_id); 370e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return (channel_data != channels_.end()) ? channel_data->second.channel_state 371e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko : nullptr; 372e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 373e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 374e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoint Endpoint::GetChannelSocketFd(int channel_id) { 375e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::lock_guard<std::mutex> autolock(channel_mutex_); 376e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto channel_data = channels_.find(channel_id); 377e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return (channel_data != channels_.end()) ? channel_data->second.data_fd.Get() 378e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko : -1; 379e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 380e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 381e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoint Endpoint::GetChannelEventFd(int channel_id) { 382e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::lock_guard<std::mutex> autolock(channel_mutex_); 383e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto channel_data = channels_.find(channel_id); 3846890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka return (channel_data != channels_.end()) 3856890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka ? channel_data->second.event_set.event_fd().Get() 3866890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka : -1; 387e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 388e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 389e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoStatus<void> Endpoint::ReceiveMessageForChannel(int channel_id, 390e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko Message* message) { 391e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko RequestHeader<LocalHandle> request; 392e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto status = ReceiveData(channel_id, &request); 393e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (!status) { 3946890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka if (status.error() == ESHUTDOWN) { 3956890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka BuildCloseMessage(channel_id, message); 3966890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka return {}; 3976890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka } else { 3986890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka CloseChannel(channel_id); 3996890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka return status; 4006890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka } 401e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 4026890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka 403e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko MessageInfo info; 404e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko info.pid = request.cred.pid; 405e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko info.tid = -1; 406e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko info.cid = channel_id; 407e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko info.mid = request.is_impulse ? Message::IMPULSE_MESSAGE_ID 408e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko : GetNextAvailableMessageId(); 409e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko info.euid = request.cred.uid; 410e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko info.egid = request.cred.gid; 411e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko info.op = request.op; 412e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko info.flags = 0; 413e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko info.service = service_; 414e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko info.channel = GetChannelState(channel_id); 415e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko info.send_len = request.send_len; 416e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko info.recv_len = request.max_recv_len; 417e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko info.fd_count = request.file_descriptors.size(); 418e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko static_assert(sizeof(info.impulse) == request.impulse_payload.size(), 419e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko "Impulse payload sizes must be the same in RequestHeader and " 420e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko "MessageInfo"); 421e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko memcpy(info.impulse, request.impulse_payload.data(), 422e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko request.impulse_payload.size()); 423e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko *message = Message{info}; 424e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto* state = static_cast<MessageState*>(message->GetState()); 425e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko state->request = std::move(request); 426e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (request.send_len > 0 && !request.is_impulse) { 427e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko state->request_data.resize(request.send_len); 428e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko status = ReceiveData(channel_id, state->request_data.data(), 429e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko state->request_data.size()); 430e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 431e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 432e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (status && request.is_impulse) 433e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko status = ReenableEpollEvent(channel_id); 434e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 4356890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka if (!status) { 4366890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka if (status.error() == ESHUTDOWN) { 4376890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka BuildCloseMessage(channel_id, message); 4386890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka return {}; 4396890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka } else { 4406890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka CloseChannel(channel_id); 4416890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka return status; 4426890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka } 4436890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka } 444e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 445e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return status; 446e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 447e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 4486890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabakavoid Endpoint::BuildCloseMessage(int channel_id, Message* message) { 4496890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka ALOGD_IF(TRACE, "Endpoint::BuildCloseMessage: channel_id=%d", channel_id); 4506890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka MessageInfo info; 4516890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka info.pid = -1; 4526890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka info.tid = -1; 4536890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka info.cid = channel_id; 4546890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka info.mid = GetNextAvailableMessageId(); 4556890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka info.euid = -1; 4566890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka info.egid = -1; 4576890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka info.op = opcodes::CHANNEL_CLOSE; 4586890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka info.flags = 0; 4596890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka info.service = service_; 4606890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka info.channel = GetChannelState(channel_id); 4616890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka info.send_len = 0; 4626890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka info.recv_len = 0; 4636890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka info.fd_count = 0; 4646890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka *message = Message{info}; 4656890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka} 466e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 4676890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabakaint Endpoint::MessageReceive(Message* message) { 4686890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka // Receive at most one event from the epoll set. This should prevent multiple 4696890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka // dispatch threads from attempting to handle messages on the same socket at 4706890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka // the same time. 471e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko epoll_event event; 472e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int count = RETRY_EINTR( 473e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko epoll_wait(epoll_fd_.Get(), &event, 1, is_blocking_ ? -1 : 0)); 474e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (count < 0) { 475e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ALOGE("Endpoint::MessageReceive: Failed to wait for epoll events: %s\n", 476e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko strerror(errno)); 477e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return -errno; 478e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } else if (count == 0) { 479e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return -ETIMEDOUT; 480e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 481e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 482e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (event.data.fd == cancel_event_fd_.Get()) { 483e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return -ESHUTDOWN; 484e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 485e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 486e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (event.data.fd == socket_fd_.Get()) { 487e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto status = AcceptConnection(message); 488e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (!status) 489e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return -status.error(); 490e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko status = ReenableEpollEvent(socket_fd_.Get()); 491e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return status ? 0 : -status.error(); 492e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 493e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 494e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int channel_id = event.data.fd; 4956890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka if (event.events & (EPOLLRDHUP | EPOLLHUP)) { 4966890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka BuildCloseMessage(channel_id, message); 497e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return 0; 498e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 499e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 500e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto status = ReceiveMessageForChannel(channel_id, message); 501e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (!status) 502e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return -status.error(); 503e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return 0; 504e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 505e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 506e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoint Endpoint::MessageReply(Message* message, int return_code) { 5076890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka const int channel_id = message->GetChannelId(); 5086890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka const int channel_socket = GetChannelSocketFd(channel_id); 509e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (channel_socket < 0) 510e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return -EBADF; 511e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 512e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto* state = static_cast<MessageState*>(message->GetState()); 513e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko switch (message->GetOp()) { 514e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko case opcodes::CHANNEL_CLOSE: 5156890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka return CloseChannel(channel_id); 516e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 517e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko case opcodes::CHANNEL_OPEN: 518e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (return_code < 0) 5196890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka return CloseChannel(channel_id); 520e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Reply with the event fd. 521e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return_code = state->PushFileHandle( 522e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko BorrowedHandle{GetChannelEventFd(channel_socket)}); 523e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko state->response_data.clear(); // Just in case... 524e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko break; 525e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 526e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 527e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko state->response.ret_code = return_code; 528e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko state->response.recv_len = state->response_data.size(); 529e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto status = SendData(channel_socket, state->response); 530e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (status && !state->response_data.empty()) { 531e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko status = SendData(channel_socket, state->response_data.data(), 532e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko state->response_data.size()); 533e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 534e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 535e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (status) 536e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko status = ReenableEpollEvent(channel_socket); 537e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 538e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return status ? 0 : -status.error(); 539e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 540e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 541e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoint Endpoint::MessageReplyFd(Message* message, unsigned int push_fd) { 542e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto* state = static_cast<MessageState*>(message->GetState()); 543e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto ref = state->PushFileHandle(BorrowedHandle{static_cast<int>(push_fd)}); 544e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return MessageReply(message, ref); 545e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 546e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 547e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoint Endpoint::MessageReplyChannelHandle(Message* message, 548e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const LocalChannelHandle& handle) { 549e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto* state = static_cast<MessageState*>(message->GetState()); 550e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto ref = state->PushChannelHandle(handle.Borrow()); 551e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return MessageReply(message, ref); 552e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 553e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 554e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoint Endpoint::MessageReplyChannelHandle(Message* message, 555e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const BorrowedChannelHandle& handle) { 556e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto* state = static_cast<MessageState*>(message->GetState()); 557e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto ref = state->PushChannelHandle(handle.Duplicate()); 558e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return MessageReply(message, ref); 559e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 560e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 561e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoint Endpoint::MessageReplyChannelHandle(Message* message, 562e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const RemoteChannelHandle& handle) { 563e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return MessageReply(message, handle.value()); 564e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 565e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 566e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkossize_t Endpoint::ReadMessageData(Message* message, const iovec* vector, 567e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_t vector_length) { 568e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto* state = static_cast<MessageState*>(message->GetState()); 569e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return state->ReadData(vector, vector_length); 570e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 571e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 572e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkossize_t Endpoint::WriteMessageData(Message* message, const iovec* vector, 573e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_t vector_length) { 574e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto* state = static_cast<MessageState*>(message->GetState()); 575e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return state->WriteData(vector, vector_length); 576e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 577e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 578e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoFileReference Endpoint::PushFileHandle(Message* message, 579e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const LocalHandle& handle) { 580e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto* state = static_cast<MessageState*>(message->GetState()); 581e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return state->PushFileHandle(handle.Borrow()); 582e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 583e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 584e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoFileReference Endpoint::PushFileHandle(Message* message, 585e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const BorrowedHandle& handle) { 586e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto* state = static_cast<MessageState*>(message->GetState()); 587e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return state->PushFileHandle(handle.Duplicate()); 588e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 589e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 590e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoFileReference Endpoint::PushFileHandle(Message* /*message*/, 591e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const RemoteHandle& handle) { 592e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return handle.Get(); 593e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 594e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 595e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoChannelReference Endpoint::PushChannelHandle(Message* message, 596e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const LocalChannelHandle& handle) { 597e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto* state = static_cast<MessageState*>(message->GetState()); 598e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return state->PushChannelHandle(handle.Borrow()); 599e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 600e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 601e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoChannelReference Endpoint::PushChannelHandle( 602e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko Message* message, const BorrowedChannelHandle& handle) { 603e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto* state = static_cast<MessageState*>(message->GetState()); 604e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return state->PushChannelHandle(handle.Duplicate()); 605e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 606e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 607e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoChannelReference Endpoint::PushChannelHandle( 608e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko Message* /*message*/, const RemoteChannelHandle& handle) { 609e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return handle.value(); 610e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 611e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 612e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoLocalHandle Endpoint::GetFileHandle(Message* message, FileReference ref) const { 613e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko LocalHandle handle; 614e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto* state = static_cast<MessageState*>(message->GetState()); 615e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko state->GetLocalFileHandle(ref, &handle); 616e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return handle; 617e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 618e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 619e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoLocalChannelHandle Endpoint::GetChannelHandle(Message* message, 620e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ChannelReference ref) const { 621e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko LocalChannelHandle handle; 622e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto* state = static_cast<MessageState*>(message->GetState()); 623e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko state->GetLocalChannelHandle(ref, &handle); 624e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return handle; 625e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 626e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 627e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoint Endpoint::Cancel() { 628e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return (eventfd_write(cancel_event_fd_.Get(), 1) < 0) ? -errno : 0; 629e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 630e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 631e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostd::unique_ptr<Endpoint> Endpoint::Create(const std::string& endpoint_path, 632e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko mode_t /*unused_mode*/, 633e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko bool blocking) { 634e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return std::unique_ptr<Endpoint>(new Endpoint(endpoint_path, blocking)); 635e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 636e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 637e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} // namespace uds 638e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} // namespace pdx 639e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} // namespace android 640