Home | History | Annotate | Download | only in libpdx_uds
      1 #include "uds/service_endpoint.h"
      2 
      3 #include <poll.h>
      4 #include <sys/epoll.h>
      5 #include <sys/eventfd.h>
      6 #include <sys/socket.h>
      7 #include <sys/un.h>
      8 #include <algorithm>  // std::min
      9 
     10 #include <android-base/logging.h>
     11 #include <android-base/strings.h>
     12 #include <cutils/sockets.h>
     13 #include <pdx/service.h>
     14 #include <selinux/selinux.h>
     15 #include <uds/channel_manager.h>
     16 #include <uds/client_channel_factory.h>
     17 #include <uds/ipc_helper.h>
     18 
     19 namespace {
     20 
     21 constexpr int kMaxBackLogForSocketListen = 1;
     22 
     23 using android::pdx::BorrowedChannelHandle;
     24 using android::pdx::BorrowedHandle;
     25 using android::pdx::ChannelReference;
     26 using android::pdx::ErrorStatus;
     27 using android::pdx::FileReference;
     28 using android::pdx::LocalChannelHandle;
     29 using android::pdx::LocalHandle;
     30 using android::pdx::Status;
     31 using android::pdx::uds::ChannelInfo;
     32 using android::pdx::uds::ChannelManager;
     33 
     34 struct MessageState {
     35   bool GetLocalFileHandle(int index, LocalHandle* handle) {
     36     if (index < 0) {
     37       handle->Reset(index);
     38     } else if (static_cast<size_t>(index) < request.file_descriptors.size()) {
     39       *handle = std::move(request.file_descriptors[index]);
     40     } else {
     41       return false;
     42     }
     43     return true;
     44   }
     45 
     46   bool GetLocalChannelHandle(int index, LocalChannelHandle* handle) {
     47     if (index < 0) {
     48       *handle = LocalChannelHandle{nullptr, index};
     49     } else if (static_cast<size_t>(index) < request.channels.size()) {
     50       auto& channel_info = request.channels[index];
     51       *handle = ChannelManager::Get().CreateHandle(
     52           std::move(channel_info.data_fd), std::move(channel_info.event_fd));
     53     } else {
     54       return false;
     55     }
     56     return true;
     57   }
     58 
     59   Status<FileReference> PushFileHandle(BorrowedHandle handle) {
     60     if (!handle)
     61       return handle.Get();
     62     response.file_descriptors.push_back(std::move(handle));
     63     return response.file_descriptors.size() - 1;
     64   }
     65 
     66   Status<ChannelReference> PushChannelHandle(BorrowedChannelHandle handle) {
     67     if (!handle)
     68       return handle.value();
     69 
     70     if (auto* channel_data =
     71             ChannelManager::Get().GetChannelData(handle.value())) {
     72       ChannelInfo<BorrowedHandle> channel_info;
     73       channel_info.data_fd.Reset(handle.value());
     74       channel_info.event_fd = channel_data->event_receiver.event_fd();
     75       response.channels.push_back(std::move(channel_info));
     76       return response.channels.size() - 1;
     77     } else {
     78       return ErrorStatus{EINVAL};
     79     }
     80   }
     81 
     82   Status<ChannelReference> PushChannelHandle(BorrowedHandle data_fd,
     83                                              BorrowedHandle event_fd) {
     84     if (!data_fd || !event_fd)
     85       return ErrorStatus{EINVAL};
     86     ChannelInfo<BorrowedHandle> channel_info;
     87     channel_info.data_fd = std::move(data_fd);
     88     channel_info.event_fd = std::move(event_fd);
     89     response.channels.push_back(std::move(channel_info));
     90     return response.channels.size() - 1;
     91   }
     92 
     93   Status<size_t> WriteData(const iovec* vector, size_t vector_length) {
     94     size_t size = 0;
     95     for (size_t i = 0; i < vector_length; i++) {
     96       const auto* data = reinterpret_cast<const uint8_t*>(vector[i].iov_base);
     97       response_data.insert(response_data.end(), data, data + vector[i].iov_len);
     98       size += vector[i].iov_len;
     99     }
    100     return size;
    101   }
    102 
    103   Status<size_t> ReadData(const iovec* vector, size_t vector_length) {
    104     size_t size_remaining = request_data.size() - request_data_read_pos;
    105     size_t size = 0;
    106     for (size_t i = 0; i < vector_length && size_remaining > 0; i++) {
    107       size_t size_to_copy = std::min(size_remaining, vector[i].iov_len);
    108       memcpy(vector[i].iov_base, request_data.data() + request_data_read_pos,
    109              size_to_copy);
    110       size += size_to_copy;
    111       request_data_read_pos += size_to_copy;
    112       size_remaining -= size_to_copy;
    113     }
    114     return size;
    115   }
    116 
    117   android::pdx::uds::RequestHeader<LocalHandle> request;
    118   android::pdx::uds::ResponseHeader<BorrowedHandle> response;
    119   std::vector<LocalHandle> sockets_to_close;
    120   std::vector<uint8_t> request_data;
    121   size_t request_data_read_pos{0};
    122   std::vector<uint8_t> response_data;
    123 };
    124 
    125 }  // anonymous namespace
    126 
    127 namespace android {
    128 namespace pdx {
    129 namespace uds {
    130 
    131 Endpoint::Endpoint(const std::string& endpoint_path, bool blocking,
    132                    bool use_init_socket_fd)
    133     : endpoint_path_{ClientChannelFactory::GetEndpointPath(endpoint_path)},
    134       is_blocking_{blocking} {
    135   LocalHandle fd;
    136   if (use_init_socket_fd) {
    137     // Cut off the /dev/socket/ prefix from the full socket path and use the
    138     // resulting "name" to retrieve the file descriptor for the socket created
    139     // by the init process.
    140     constexpr char prefix[] = "/dev/socket/";
    141     CHECK(android::base::StartsWith(endpoint_path_, prefix))
    142         << "Endpoint::Endpoint: Socket name '" << endpoint_path_
    143         << "' must begin with '" << prefix << "'";
    144     std::string socket_name = endpoint_path_.substr(sizeof(prefix) - 1);
    145     fd.Reset(android_get_control_socket(socket_name.c_str()));
    146     CHECK(fd.IsValid())
    147         << "Endpoint::Endpoint: Unable to obtain the control socket fd for '"
    148         << socket_name << "'";
    149     fcntl(fd.Get(), F_SETFD, FD_CLOEXEC);
    150   } else {
    151     fd.Reset(socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0));
    152     CHECK(fd.IsValid()) << "Endpoint::Endpoint: Failed to create socket: "
    153                         << strerror(errno);
    154 
    155     sockaddr_un local;
    156     local.sun_family = AF_UNIX;
    157     strncpy(local.sun_path, endpoint_path_.c_str(), sizeof(local.sun_path));
    158     local.sun_path[sizeof(local.sun_path) - 1] = '\0';
    159 
    160     unlink(local.sun_path);
    161     int ret =
    162         bind(fd.Get(), reinterpret_cast<sockaddr*>(&local), sizeof(local));
    163     CHECK_EQ(ret, 0) << "Endpoint::Endpoint: bind error: " << strerror(errno);
    164   }
    165   Init(std::move(fd));
    166 }
    167 
    168 Endpoint::Endpoint(LocalHandle socket_fd) { Init(std::move(socket_fd)); }
    169 
    170 void Endpoint::Init(LocalHandle socket_fd) {
    171   if (socket_fd) {
    172     CHECK_EQ(listen(socket_fd.Get(), kMaxBackLogForSocketListen), 0)
    173         << "Endpoint::Endpoint: listen error: " << strerror(errno);
    174   }
    175   cancel_event_fd_.Reset(eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK));
    176   CHECK(cancel_event_fd_.IsValid())
    177       << "Endpoint::Endpoint: Failed to create event fd: " << strerror(errno);
    178 
    179   epoll_fd_.Reset(epoll_create1(EPOLL_CLOEXEC));
    180   CHECK(epoll_fd_.IsValid())
    181       << "Endpoint::Endpoint: Failed to create epoll fd: " << strerror(errno);
    182 
    183   if (socket_fd) {
    184     epoll_event socket_event;
    185     socket_event.events = EPOLLIN | EPOLLRDHUP | EPOLLONESHOT;
    186     socket_event.data.fd = socket_fd.Get();
    187     int ret = epoll_ctl(epoll_fd_.Get(), EPOLL_CTL_ADD, socket_fd.Get(),
    188                         &socket_event);
    189     CHECK_EQ(ret, 0)
    190         << "Endpoint::Endpoint: Failed to add socket fd to epoll fd: "
    191         << strerror(errno);
    192   }
    193 
    194   epoll_event cancel_event;
    195   cancel_event.events = EPOLLIN;
    196   cancel_event.data.fd = cancel_event_fd_.Get();
    197 
    198   int ret = epoll_ctl(epoll_fd_.Get(), EPOLL_CTL_ADD, cancel_event_fd_.Get(),
    199                       &cancel_event);
    200   CHECK_EQ(ret, 0)
    201       << "Endpoint::Endpoint: Failed to add cancel event fd to epoll fd: "
    202       << strerror(errno);
    203   socket_fd_ = std::move(socket_fd);
    204 }
    205 
    206 void* Endpoint::AllocateMessageState() { return new MessageState; }
    207 
    208 void Endpoint::FreeMessageState(void* state) {
    209   delete static_cast<MessageState*>(state);
    210 }
    211 
    212 Status<void> Endpoint::AcceptConnection(Message* message) {
    213   if (!socket_fd_)
    214     return ErrorStatus(EBADF);
    215 
    216   sockaddr_un remote;
    217   socklen_t addrlen = sizeof(remote);
    218   LocalHandle connection_fd{accept4(socket_fd_.Get(),
    219                                     reinterpret_cast<sockaddr*>(&remote),
    220                                     &addrlen, SOCK_CLOEXEC)};
    221   if (!connection_fd) {
    222     ALOGE("Endpoint::AcceptConnection: failed to accept connection: %s",
    223           strerror(errno));
    224     return ErrorStatus(errno);
    225   }
    226 
    227   LocalHandle local_socket;
    228   LocalHandle remote_socket;
    229   auto status = CreateChannelSocketPair(&local_socket, &remote_socket);
    230   if (!status)
    231     return status;
    232 
    233   // Borrow the local channel handle before we move it into OnNewChannel().
    234   BorrowedHandle channel_handle = local_socket.Borrow();
    235   status = OnNewChannel(std::move(local_socket));
    236   if (!status)
    237     return status;
    238 
    239   // Send the channel socket fd to the client.
    240   ChannelConnectionInfo<LocalHandle> connection_info;
    241   connection_info.channel_fd = std::move(remote_socket);
    242   status = SendData(connection_fd.Borrow(), connection_info);
    243 
    244   if (status) {
    245     // Get the CHANNEL_OPEN message from client over the channel socket.
    246     status = ReceiveMessageForChannel(channel_handle, message);
    247   } else {
    248     CloseChannel(GetChannelId(channel_handle));
    249   }
    250 
    251   // Don't need the connection socket anymore. Further communication should
    252   // happen over the channel socket.
    253   shutdown(connection_fd.Get(), SHUT_WR);
    254   return status;
    255 }
    256 
    257 Status<void> Endpoint::SetService(Service* service) {
    258   service_ = service;
    259   return {};
    260 }
    261 
    262 Status<void> Endpoint::SetChannel(int channel_id, Channel* channel) {
    263   std::lock_guard<std::mutex> autolock(channel_mutex_);
    264   auto channel_data = channels_.find(channel_id);
    265   if (channel_data == channels_.end())
    266     return ErrorStatus{EINVAL};
    267   channel_data->second.channel_state = channel;
    268   return {};
    269 }
    270 
    271 Status<void> Endpoint::OnNewChannel(LocalHandle channel_fd) {
    272   std::lock_guard<std::mutex> autolock(channel_mutex_);
    273   Status<void> status;
    274   status.PropagateError(OnNewChannelLocked(std::move(channel_fd), nullptr));
    275   return status;
    276 }
    277 
    278 Status<std::pair<int32_t, Endpoint::ChannelData*>> Endpoint::OnNewChannelLocked(
    279     LocalHandle channel_fd, Channel* channel_state) {
    280   epoll_event event;
    281   event.events = EPOLLIN | EPOLLRDHUP | EPOLLONESHOT;
    282   event.data.fd = channel_fd.Get();
    283   if (epoll_ctl(epoll_fd_.Get(), EPOLL_CTL_ADD, channel_fd.Get(), &event) < 0) {
    284     ALOGE(
    285         "Endpoint::OnNewChannelLocked: Failed to add channel to endpoint: %s\n",
    286         strerror(errno));
    287     return ErrorStatus(errno);
    288   }
    289   ChannelData channel_data;
    290   channel_data.event_set.AddDataFd(channel_fd);
    291   channel_data.data_fd = std::move(channel_fd);
    292   channel_data.channel_state = channel_state;
    293   for (;;) {
    294     // Try new channel IDs until we find one which is not already in the map.
    295     if (last_channel_id_++ == std::numeric_limits<int32_t>::max())
    296       last_channel_id_ = 1;
    297     auto iter = channels_.lower_bound(last_channel_id_);
    298     if (iter == channels_.end() || iter->first != last_channel_id_) {
    299       channel_fd_to_id_.emplace(channel_data.data_fd.Get(), last_channel_id_);
    300       iter = channels_.emplace_hint(iter, last_channel_id_,
    301                                     std::move(channel_data));
    302       return std::make_pair(last_channel_id_, &iter->second);
    303     }
    304   }
    305 }
    306 
    307 Status<void> Endpoint::ReenableEpollEvent(const BorrowedHandle& fd) {
    308   epoll_event event;
    309   event.events = EPOLLIN | EPOLLRDHUP | EPOLLONESHOT;
    310   event.data.fd = fd.Get();
    311   if (epoll_ctl(epoll_fd_.Get(), EPOLL_CTL_MOD, fd.Get(), &event) < 0) {
    312     ALOGE(
    313         "Endpoint::ReenableEpollEvent: Failed to re-enable channel to "
    314         "endpoint: %s\n",
    315         strerror(errno));
    316     return ErrorStatus(errno);
    317   }
    318   return {};
    319 }
    320 
    321 Status<void> Endpoint::CloseChannel(int channel_id) {
    322   std::lock_guard<std::mutex> autolock(channel_mutex_);
    323   return CloseChannelLocked(channel_id);
    324 }
    325 
    326 Status<void> Endpoint::CloseChannelLocked(int32_t channel_id) {
    327   ALOGD_IF(TRACE, "Endpoint::CloseChannelLocked: channel_id=%d", channel_id);
    328 
    329   auto iter = channels_.find(channel_id);
    330   if (iter == channels_.end())
    331     return ErrorStatus{EINVAL};
    332 
    333   int channel_fd = iter->second.data_fd.Get();
    334   Status<void> status;
    335   epoll_event dummy;  // See BUGS in man 2 epoll_ctl.
    336   if (epoll_ctl(epoll_fd_.Get(), EPOLL_CTL_DEL, channel_fd, &dummy) < 0) {
    337     status.SetError(errno);
    338     ALOGE(
    339         "Endpoint::CloseChannelLocked: Failed to remove channel from endpoint: "
    340         "%s\n",
    341         strerror(errno));
    342   } else {
    343     status.SetValue();
    344   }
    345 
    346   channel_fd_to_id_.erase(channel_fd);
    347   channels_.erase(iter);
    348   return status;
    349 }
    350 
    351 Status<void> Endpoint::ModifyChannelEvents(int channel_id, int clear_mask,
    352                                            int set_mask) {
    353   std::lock_guard<std::mutex> autolock(channel_mutex_);
    354 
    355   auto search = channels_.find(channel_id);
    356   if (search != channels_.end()) {
    357     auto& channel_data = search->second;
    358     channel_data.event_set.ModifyEvents(clear_mask, set_mask);
    359     return {};
    360   }
    361 
    362   return ErrorStatus{EINVAL};
    363 }
    364 
    365 Status<void> Endpoint::CreateChannelSocketPair(LocalHandle* local_socket,
    366                                                LocalHandle* remote_socket) {
    367   Status<void> status;
    368   char* endpoint_context = nullptr;
    369   // Make sure the channel socket has the correct SELinux label applied.
    370   // Here we get the label from the endpoint file descriptor, which should be
    371   // something like "u:object_r:pdx_service_endpoint_socket:s0" and replace
    372   // "endpoint" with "channel" to produce the channel label such as this:
    373   // "u:object_r:pdx_service_channel_socket:s0".
    374   if (fgetfilecon_raw(socket_fd_.Get(), &endpoint_context) > 0) {
    375     std::string channel_context = endpoint_context;
    376     freecon(endpoint_context);
    377     const std::string suffix = "_endpoint_socket";
    378     auto pos = channel_context.find(suffix);
    379     if (pos != std::string::npos) {
    380       channel_context.replace(pos, suffix.size(), "_channel_socket");
    381     } else {
    382       ALOGW(
    383           "Endpoint::CreateChannelSocketPair: Endpoint security context '%s' "
    384           "does not contain expected substring '%s'",
    385           channel_context.c_str(), suffix.c_str());
    386     }
    387     ALOGE_IF(setsockcreatecon_raw(channel_context.c_str()) == -1,
    388              "Endpoint::CreateChannelSocketPair: Failed to set channel socket "
    389              "security context: %s",
    390              strerror(errno));
    391   } else {
    392     ALOGE(
    393         "Endpoint::CreateChannelSocketPair: Failed to obtain the endpoint "
    394         "socket's security context: %s",
    395         strerror(errno));
    396   }
    397 
    398   int channel_pair[2] = {};
    399   if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, channel_pair) == -1) {
    400     ALOGE("Endpoint::CreateChannelSocketPair: Failed to create socket pair: %s",
    401           strerror(errno));
    402     status.SetError(errno);
    403     return status;
    404   }
    405 
    406   setsockcreatecon_raw(nullptr);
    407 
    408   local_socket->Reset(channel_pair[0]);
    409   remote_socket->Reset(channel_pair[1]);
    410 
    411   int optval = 1;
    412   if (setsockopt(local_socket->Get(), SOL_SOCKET, SO_PASSCRED, &optval,
    413                  sizeof(optval)) == -1) {
    414     ALOGE(
    415         "Endpoint::CreateChannelSocketPair: Failed to enable the receiving of "
    416         "the credentials for channel %d: %s",
    417         local_socket->Get(), strerror(errno));
    418     status.SetError(errno);
    419   }
    420   return status;
    421 }
    422 
    423 Status<RemoteChannelHandle> Endpoint::PushChannel(Message* message,
    424                                                   int /*flags*/,
    425                                                   Channel* channel,
    426                                                   int* channel_id) {
    427   LocalHandle local_socket;
    428   LocalHandle remote_socket;
    429   auto status = CreateChannelSocketPair(&local_socket, &remote_socket);
    430   if (!status)
    431     return status.error_status();
    432 
    433   std::lock_guard<std::mutex> autolock(channel_mutex_);
    434   auto channel_data = OnNewChannelLocked(std::move(local_socket), channel);
    435   if (!channel_data)
    436     return channel_data.error_status();
    437   *channel_id = channel_data.get().first;
    438 
    439   // Flags are ignored for now.
    440   // TODO(xiaohuit): Implement those.
    441 
    442   auto* state = static_cast<MessageState*>(message->GetState());
    443   Status<ChannelReference> ref = state->PushChannelHandle(
    444       remote_socket.Borrow(),
    445       channel_data.get().second->event_set.event_fd().Borrow());
    446   if (!ref)
    447     return ref.error_status();
    448   state->sockets_to_close.push_back(std::move(remote_socket));
    449   return RemoteChannelHandle{ref.get()};
    450 }
    451 
    452 Status<int> Endpoint::CheckChannel(const Message* /*message*/,
    453                                    ChannelReference /*ref*/,
    454                                    Channel** /*channel*/) {
    455   // TODO(xiaohuit): Implement this.
    456   return ErrorStatus(EFAULT);
    457 }
    458 
    459 Channel* Endpoint::GetChannelState(int32_t channel_id) {
    460   std::lock_guard<std::mutex> autolock(channel_mutex_);
    461   auto channel_data = channels_.find(channel_id);
    462   return (channel_data != channels_.end()) ? channel_data->second.channel_state
    463                                            : nullptr;
    464 }
    465 
    466 BorrowedHandle Endpoint::GetChannelSocketFd(int32_t channel_id) {
    467   std::lock_guard<std::mutex> autolock(channel_mutex_);
    468   BorrowedHandle handle;
    469   auto channel_data = channels_.find(channel_id);
    470   if (channel_data != channels_.end())
    471     handle = channel_data->second.data_fd.Borrow();
    472   return handle;
    473 }
    474 
    475 BorrowedHandle Endpoint::GetChannelEventFd(int32_t channel_id) {
    476   std::lock_guard<std::mutex> autolock(channel_mutex_);
    477   BorrowedHandle handle;
    478   auto channel_data = channels_.find(channel_id);
    479   if (channel_data != channels_.end())
    480     handle = channel_data->second.event_set.event_fd().Borrow();
    481   return handle;
    482 }
    483 
    484 int32_t Endpoint::GetChannelId(const BorrowedHandle& channel_fd) {
    485   std::lock_guard<std::mutex> autolock(channel_mutex_);
    486   auto iter = channel_fd_to_id_.find(channel_fd.Get());
    487   return (iter != channel_fd_to_id_.end()) ? iter->second : -1;
    488 }
    489 
    490 Status<void> Endpoint::ReceiveMessageForChannel(
    491     const BorrowedHandle& channel_fd, Message* message) {
    492   RequestHeader<LocalHandle> request;
    493   int32_t channel_id = GetChannelId(channel_fd);
    494   auto status = ReceiveData(channel_fd.Borrow(), &request);
    495   if (!status) {
    496     if (status.error() == ESHUTDOWN) {
    497       BuildCloseMessage(channel_id, message);
    498       return {};
    499     } else {
    500       CloseChannel(channel_id);
    501       return status;
    502     }
    503   }
    504 
    505   MessageInfo info;
    506   info.pid = request.cred.pid;
    507   info.tid = -1;
    508   info.cid = channel_id;
    509   info.mid = request.is_impulse ? Message::IMPULSE_MESSAGE_ID
    510                                 : GetNextAvailableMessageId();
    511   info.euid = request.cred.uid;
    512   info.egid = request.cred.gid;
    513   info.op = request.op;
    514   info.flags = 0;
    515   info.service = service_;
    516   info.channel = GetChannelState(channel_id);
    517   info.send_len = request.send_len;
    518   info.recv_len = request.max_recv_len;
    519   info.fd_count = request.file_descriptors.size();
    520   static_assert(sizeof(info.impulse) == request.impulse_payload.size(),
    521                 "Impulse payload sizes must be the same in RequestHeader and "
    522                 "MessageInfo");
    523   memcpy(info.impulse, request.impulse_payload.data(),
    524          request.impulse_payload.size());
    525   *message = Message{info};
    526   auto* state = static_cast<MessageState*>(message->GetState());
    527   state->request = std::move(request);
    528   if (request.send_len > 0 && !request.is_impulse) {
    529     state->request_data.resize(request.send_len);
    530     status = ReceiveData(channel_fd, state->request_data.data(),
    531                          state->request_data.size());
    532   }
    533 
    534   if (status && request.is_impulse)
    535     status = ReenableEpollEvent(channel_fd);
    536 
    537   if (!status) {
    538     if (status.error() == ESHUTDOWN) {
    539       BuildCloseMessage(channel_id, message);
    540       return {};
    541     } else {
    542       CloseChannel(channel_id);
    543       return status;
    544     }
    545   }
    546 
    547   return status;
    548 }
    549 
    550 void Endpoint::BuildCloseMessage(int32_t channel_id, Message* message) {
    551   ALOGD_IF(TRACE, "Endpoint::BuildCloseMessage: channel_id=%d", channel_id);
    552   MessageInfo info;
    553   info.pid = -1;
    554   info.tid = -1;
    555   info.cid = channel_id;
    556   info.mid = GetNextAvailableMessageId();
    557   info.euid = -1;
    558   info.egid = -1;
    559   info.op = opcodes::CHANNEL_CLOSE;
    560   info.flags = 0;
    561   info.service = service_;
    562   info.channel = GetChannelState(channel_id);
    563   info.send_len = 0;
    564   info.recv_len = 0;
    565   info.fd_count = 0;
    566   *message = Message{info};
    567 }
    568 
    569 Status<void> Endpoint::MessageReceive(Message* message) {
    570   // Receive at most one event from the epoll set. This should prevent multiple
    571   // dispatch threads from attempting to handle messages on the same socket at
    572   // the same time.
    573   epoll_event event;
    574   int count = RETRY_EINTR(
    575       epoll_wait(epoll_fd_.Get(), &event, 1, is_blocking_ ? -1 : 0));
    576   if (count < 0) {
    577     ALOGE("Endpoint::MessageReceive: Failed to wait for epoll events: %s\n",
    578           strerror(errno));
    579     return ErrorStatus{errno};
    580   } else if (count == 0) {
    581     return ErrorStatus{ETIMEDOUT};
    582   }
    583 
    584   if (event.data.fd == cancel_event_fd_.Get()) {
    585     return ErrorStatus{ESHUTDOWN};
    586   }
    587 
    588   if (socket_fd_ && event.data.fd == socket_fd_.Get()) {
    589     auto status = AcceptConnection(message);
    590     if (!status)
    591       return status;
    592     return ReenableEpollEvent(socket_fd_.Borrow());
    593   }
    594 
    595   BorrowedHandle channel_fd{event.data.fd};
    596   if (event.events & (EPOLLRDHUP | EPOLLHUP)) {
    597     BuildCloseMessage(GetChannelId(channel_fd), message);
    598     return {};
    599   }
    600 
    601   return ReceiveMessageForChannel(channel_fd, message);
    602 }
    603 
    604 Status<void> Endpoint::MessageReply(Message* message, int return_code) {
    605   const int32_t channel_id = message->GetChannelId();
    606   auto channel_socket = GetChannelSocketFd(channel_id);
    607   if (!channel_socket)
    608     return ErrorStatus{EBADF};
    609 
    610   auto* state = static_cast<MessageState*>(message->GetState());
    611   switch (message->GetOp()) {
    612     case opcodes::CHANNEL_CLOSE:
    613       return CloseChannel(channel_id);
    614 
    615     case opcodes::CHANNEL_OPEN:
    616       if (return_code < 0) {
    617         return CloseChannel(channel_id);
    618       } else {
    619         // Reply with the event fd.
    620         auto push_status = state->PushFileHandle(GetChannelEventFd(channel_id));
    621         state->response_data.clear();  // Just in case...
    622         if (!push_status)
    623           return push_status.error_status();
    624         return_code = push_status.get();
    625       }
    626       break;
    627   }
    628 
    629   state->response.ret_code = return_code;
    630   state->response.recv_len = state->response_data.size();
    631   auto status = SendData(channel_socket, state->response);
    632   if (status && !state->response_data.empty()) {
    633     status = SendData(channel_socket, state->response_data.data(),
    634                       state->response_data.size());
    635   }
    636 
    637   if (status)
    638     status = ReenableEpollEvent(channel_socket);
    639 
    640   return status;
    641 }
    642 
    643 Status<void> Endpoint::MessageReplyFd(Message* message, unsigned int push_fd) {
    644   auto* state = static_cast<MessageState*>(message->GetState());
    645   auto ref = state->PushFileHandle(BorrowedHandle{static_cast<int>(push_fd)});
    646   if (!ref)
    647     return ref.error_status();
    648   return MessageReply(message, ref.get());
    649 }
    650 
    651 Status<void> Endpoint::MessageReplyChannelHandle(
    652     Message* message, const LocalChannelHandle& handle) {
    653   auto* state = static_cast<MessageState*>(message->GetState());
    654   auto ref = state->PushChannelHandle(handle.Borrow());
    655   if (!ref)
    656     return ref.error_status();
    657   return MessageReply(message, ref.get());
    658 }
    659 
    660 Status<void> Endpoint::MessageReplyChannelHandle(
    661     Message* message, const BorrowedChannelHandle& handle) {
    662   auto* state = static_cast<MessageState*>(message->GetState());
    663   auto ref = state->PushChannelHandle(handle.Duplicate());
    664   if (!ref)
    665     return ref.error_status();
    666   return MessageReply(message, ref.get());
    667 }
    668 
    669 Status<void> Endpoint::MessageReplyChannelHandle(
    670     Message* message, const RemoteChannelHandle& handle) {
    671   return MessageReply(message, handle.value());
    672 }
    673 
    674 Status<size_t> Endpoint::ReadMessageData(Message* message, const iovec* vector,
    675                                          size_t vector_length) {
    676   auto* state = static_cast<MessageState*>(message->GetState());
    677   return state->ReadData(vector, vector_length);
    678 }
    679 
    680 Status<size_t> Endpoint::WriteMessageData(Message* message, const iovec* vector,
    681                                           size_t vector_length) {
    682   auto* state = static_cast<MessageState*>(message->GetState());
    683   return state->WriteData(vector, vector_length);
    684 }
    685 
    686 Status<FileReference> Endpoint::PushFileHandle(Message* message,
    687                                                const LocalHandle& handle) {
    688   auto* state = static_cast<MessageState*>(message->GetState());
    689   return state->PushFileHandle(handle.Borrow());
    690 }
    691 
    692 Status<FileReference> Endpoint::PushFileHandle(Message* message,
    693                                                const BorrowedHandle& handle) {
    694   auto* state = static_cast<MessageState*>(message->GetState());
    695   return state->PushFileHandle(handle.Duplicate());
    696 }
    697 
    698 Status<FileReference> Endpoint::PushFileHandle(Message* /*message*/,
    699                                                const RemoteHandle& handle) {
    700   return handle.Get();
    701 }
    702 
    703 Status<ChannelReference> Endpoint::PushChannelHandle(
    704     Message* message, const LocalChannelHandle& handle) {
    705   auto* state = static_cast<MessageState*>(message->GetState());
    706   return state->PushChannelHandle(handle.Borrow());
    707 }
    708 
    709 Status<ChannelReference> Endpoint::PushChannelHandle(
    710     Message* message, const BorrowedChannelHandle& handle) {
    711   auto* state = static_cast<MessageState*>(message->GetState());
    712   return state->PushChannelHandle(handle.Duplicate());
    713 }
    714 
    715 Status<ChannelReference> Endpoint::PushChannelHandle(
    716     Message* /*message*/, const RemoteChannelHandle& handle) {
    717   return handle.value();
    718 }
    719 
    720 LocalHandle Endpoint::GetFileHandle(Message* message, FileReference ref) const {
    721   LocalHandle handle;
    722   auto* state = static_cast<MessageState*>(message->GetState());
    723   state->GetLocalFileHandle(ref, &handle);
    724   return handle;
    725 }
    726 
    727 LocalChannelHandle Endpoint::GetChannelHandle(Message* message,
    728                                               ChannelReference ref) const {
    729   LocalChannelHandle handle;
    730   auto* state = static_cast<MessageState*>(message->GetState());
    731   state->GetLocalChannelHandle(ref, &handle);
    732   return handle;
    733 }
    734 
    735 Status<void> Endpoint::Cancel() {
    736   if (eventfd_write(cancel_event_fd_.Get(), 1) < 0)
    737     return ErrorStatus{errno};
    738   return {};
    739 }
    740 
    741 std::unique_ptr<Endpoint> Endpoint::Create(const std::string& endpoint_path,
    742                                            mode_t /*unused_mode*/,
    743                                            bool blocking) {
    744   return std::unique_ptr<Endpoint>(new Endpoint(endpoint_path, blocking));
    745 }
    746 
    747 std::unique_ptr<Endpoint> Endpoint::CreateAndBindSocket(
    748     const std::string& endpoint_path, bool blocking) {
    749   return std::unique_ptr<Endpoint>(
    750       new Endpoint(endpoint_path, blocking, false));
    751 }
    752 
    753 std::unique_ptr<Endpoint> Endpoint::CreateFromSocketFd(LocalHandle socket_fd) {
    754   return std::unique_ptr<Endpoint>(new Endpoint(std::move(socket_fd)));
    755 }
    756 
    757 Status<void> Endpoint::RegisterNewChannelForTests(LocalHandle channel_fd) {
    758   int optval = 1;
    759   if (setsockopt(channel_fd.Get(), SOL_SOCKET, SO_PASSCRED, &optval,
    760                  sizeof(optval)) == -1) {
    761     ALOGE(
    762         "Endpoint::RegisterNewChannelForTests: Failed to enable the receiving"
    763         "of the credentials for channel %d: %s",
    764         channel_fd.Get(), strerror(errno));
    765     return ErrorStatus(errno);
    766   }
    767   return OnNewChannel(std::move(channel_fd));
    768 }
    769 
    770 }  // namespace uds
    771 }  // namespace pdx
    772 }  // namespace android
    773