1#ifndef ANDROID_PDX_UDS_SERVICE_ENDPOINT_H_
2#define ANDROID_PDX_UDS_SERVICE_ENDPOINT_H_
3
4#include <sys/stat.h>
5#include <map>
6#include <memory>
7#include <mutex>
8#include <string>
9#include <unordered_map>
10#include <utility>
11#include <vector>
12
13#include <pdx/service.h>
14#include <pdx/service_endpoint.h>
15#include <uds/channel_event_set.h>
16
17namespace android {
18namespace pdx {
19namespace uds {
20
21class Endpoint : public pdx::Endpoint {
22 public:
23  enum {
24    kIpcTag = 0x00736674,  // 'uds'
25  };
26
27  // Blocking modes for service endpoint. Controls whether the epoll set is in
28  // blocking mode or not for message receive.
29  enum {
30    kBlocking = true,
31    kNonBlocking = false,
32    kDefaultBlocking = kNonBlocking,
33  };
34
35  enum : mode_t {
36    kDefaultMode = 0,
37  };
38
39  ~Endpoint() override = default;
40
41  uint32_t GetIpcTag() const override { return kIpcTag; }
42  Status<void> SetService(Service* service) override;
43  Status<void> SetChannel(int channel_id, Channel* channel) override;
44  Status<void> CloseChannel(int channel_id) override;
45  Status<void> ModifyChannelEvents(int channel_id, int clear_mask,
46                                   int set_mask) override;
47  Status<RemoteChannelHandle> PushChannel(Message* message, int flags,
48                                          Channel* channel,
49                                          int* channel_id) override;
50  Status<int> CheckChannel(const Message* message, ChannelReference ref,
51                           Channel** channel) override;
52  Status<void> MessageReceive(Message* message) override;
53  Status<void> MessageReply(Message* message, int return_code) override;
54  Status<void> MessageReplyFd(Message* message, unsigned int push_fd) override;
55  Status<void> MessageReplyChannelHandle(
56      Message* message, const LocalChannelHandle& handle) override;
57  Status<void> MessageReplyChannelHandle(
58      Message* message, const BorrowedChannelHandle& handle) override;
59  Status<void> MessageReplyChannelHandle(
60      Message* message, const RemoteChannelHandle& handle) override;
61  Status<size_t> ReadMessageData(Message* message, const iovec* vector,
62                                 size_t vector_length) override;
63  Status<size_t> WriteMessageData(Message* message, const iovec* vector,
64                                  size_t vector_length) override;
65  Status<FileReference> PushFileHandle(Message* message,
66                                       const LocalHandle& handle) override;
67  Status<FileReference> PushFileHandle(Message* message,
68                                       const BorrowedHandle& handle) override;
69  Status<FileReference> PushFileHandle(Message* message,
70                                       const RemoteHandle& handle) override;
71  Status<ChannelReference> PushChannelHandle(
72      Message* message, const LocalChannelHandle& handle) override;
73  Status<ChannelReference> PushChannelHandle(
74      Message* message, const BorrowedChannelHandle& handle) override;
75  Status<ChannelReference> PushChannelHandle(
76      Message* message, const RemoteChannelHandle& handle) override;
77  LocalHandle GetFileHandle(Message* message, FileReference ref) const override;
78  LocalChannelHandle GetChannelHandle(Message* message,
79                                      ChannelReference ref) const override;
80
81  void* AllocateMessageState() override;
82  void FreeMessageState(void* state) override;
83
84  Status<void> Cancel() override;
85
86  // Open an endpoint at the given path.
87  // Second parameter is unused for UDS, but we have it here for compatibility
88  // in signature with servicefs::Endpoint::Create().
89  // This method uses |endpoint_path| as a relative path to endpoint socket
90  // created by init process.
91  static std::unique_ptr<Endpoint> Create(const std::string& endpoint_path,
92                                          mode_t /*unused_mode*/ = kDefaultMode,
93                                          bool blocking = kDefaultBlocking);
94
95  // Helper method to create an endpoint at the given UDS socket path. This
96  // method physically creates and binds a socket at that path.
97  static std::unique_ptr<Endpoint> CreateAndBindSocket(
98      const std::string& endpoint_path, bool blocking = kDefaultBlocking);
99
100  // Helper method to create an endpoint from an existing socket FD.
101  // Mostly helpful for tests.
102  static std::unique_ptr<Endpoint> CreateFromSocketFd(LocalHandle socket_fd);
103
104  // Test helper method to register a new channel identified by |channel_fd|
105  // socket file descriptor.
106  Status<void> RegisterNewChannelForTests(LocalHandle channel_fd);
107
108  int epoll_fd() const override { return epoll_fd_.Get(); }
109
110 private:
111  struct ChannelData {
112    LocalHandle data_fd;
113    ChannelEventSet event_set;
114    Channel* channel_state{nullptr};
115  };
116
117  // This class must be instantiated using Create() static methods above.
118  Endpoint(const std::string& endpoint_path, bool blocking,
119           bool use_init_socket_fd = true);
120  Endpoint(LocalHandle socket_fd);
121
122  void Init(LocalHandle socket_fd);
123
124  Endpoint(const Endpoint&) = delete;
125  void operator=(const Endpoint&) = delete;
126
127  uint32_t GetNextAvailableMessageId() {
128    return next_message_id_.fetch_add(1, std::memory_order_relaxed);
129  }
130
131  void BuildCloseMessage(int32_t channel_id, Message* message);
132
133  Status<void> AcceptConnection(Message* message);
134  Status<void> ReceiveMessageForChannel(const BorrowedHandle& channel_fd,
135                                        Message* message);
136  Status<void> OnNewChannel(LocalHandle channel_fd);
137  Status<std::pair<int32_t, ChannelData*>> OnNewChannelLocked(
138      LocalHandle channel_fd, Channel* channel_state);
139  Status<void> CloseChannelLocked(int32_t channel_id);
140  Status<void> ReenableEpollEvent(const BorrowedHandle& channel_fd);
141  Channel* GetChannelState(int32_t channel_id);
142  BorrowedHandle GetChannelSocketFd(int32_t channel_id);
143  Status<std::pair<BorrowedHandle, BorrowedHandle>> GetChannelEventFd(
144      int32_t channel_id);
145  int32_t GetChannelId(const BorrowedHandle& channel_fd);
146  Status<void> CreateChannelSocketPair(LocalHandle* local_socket,
147                                       LocalHandle* remote_socket);
148
149  std::string endpoint_path_;
150  bool is_blocking_;
151  LocalHandle socket_fd_;
152  LocalHandle cancel_event_fd_;
153  LocalHandle epoll_fd_;
154
155  mutable std::mutex channel_mutex_;
156  std::map<int32_t, ChannelData> channels_;
157  std::map<int, int32_t> channel_fd_to_id_;
158  int32_t last_channel_id_{0};
159
160  Service* service_{nullptr};
161  std::atomic<uint32_t> next_message_id_;
162};
163
164}  // namespace uds
165}  // namespace pdx
166}  // namespace android
167
168#endif  // ANDROID_PDX_UDS_PDX_SERVICE_ENDPOINT_H_
169