1 // Copyright (C) 2021 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 #pragma once
15 #include <stdint.h>     // for uint64_t, uint8_t
16 #include <sys/types.h>  // for ssize_t
17 
18 #include <atomic>  // for atomic_bool
19 
20 #include "net/async_data_channel.h"  // for AsyncDataChannel, ReadCallback
21 
22 namespace rootcanal {
23 class AsyncManager;
24 }  // namespace rootcanal
25 
26 namespace android {
27 namespace net {
28 
29 using rootcanal::AsyncManager;
30 
31 // A Posix compliant implementation of the AsyncDataChannel interface.
32 //
33 // Supports both Darwin and Linux.
34 class PosixAsyncSocket : public AsyncDataChannel {
35  public:
36   // The AsyncManager must support the following:
37   //
38   // - If a callback happens on thread t, and
39   //   am->StopWatchingFileDescriptor(fd)
40   //   is called from t then am will never fire an event for fd upon return.
41   PosixAsyncSocket(int fd, AsyncManager* am);
42   PosixAsyncSocket(const PosixAsyncSocket& other) = delete;
43   PosixAsyncSocket(PosixAsyncSocket&& other);
44 
45   // Make sure to close the socket before hand.
46   ~PosixAsyncSocket();
47 
48   // Receive data in the given buffer. Returns the number of bytes read,
49   // or a negative number in case of failure. Check the errno variable to
50   // learn why the call failed.
51   ssize_t Recv(uint8_t* buffer, uint64_t bufferSize) override;
52 
53   // Send data in the given buffer. Returns the number of bytes read,
54   // or a negative number in case of failure. Check the errno variable to
55   // learn why the call failed. Note: This can be EAGAIN if we cannot
56   // write to the socket at this time as it would block.
57   ssize_t Send(const uint8_t* buffer, uint64_t bufferSize) override;
58 
59   // True if this socket is connected
60   bool Connected() override;
61 
62   // Closes this socket. You must call this before deleting the socket.
63   //
64   // - On Linux, the socket is always closed when this function returns
65   // - On OS X, whether the socket the underlying fd becomes available seems
66   //   pretty much random! (You might want to drain the socket first.)
67   void Close() override;
68 
69   // Registers the given callback to be invoked when a recv call can be made
70   // to read data from this socket.
71   // Only one callback can be registered per socket.
72   bool WatchForNonBlockingRead(
73       const ReadCallback& on_read_ready_callback) override;
74 
75   void StopWatching() override;
76 
fd()77   int fd() const { return fd_; }
78 
79  private:
80   void OnReadCallback();
81 
82   int fd_;
83   AsyncManager* am_;
84   std::atomic_bool watching_;
85 };
86 }  // namespace net
87 }  // namespace android
88 
89 // Re-run |fn| system call until the system call doesn't cause EINTR.
90 #define REPEAT_UNTIL_NO_INTR(fn) \
91   do {                           \
92   } while ((fn) == -1 && errno == EINTR)
93