1 // Copyright 2014 The Chromium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef NET_SOCKET_SOCKET_POSIX_H_ 6 #define NET_SOCKET_SOCKET_POSIX_H_ 7 8 #include <memory> 9 10 #include "base/compiler_specific.h" 11 #include "base/memory/raw_ptr.h" 12 #include "base/memory/scoped_refptr.h" 13 #include "base/message_loop/message_pump_for_io.h" 14 #include "base/threading/thread_checker.h" 15 #include "net/base/completion_once_callback.h" 16 #include "net/base/net_export.h" 17 #include "net/socket/socket_descriptor.h" 18 #include "net/traffic_annotation/network_traffic_annotation.h" 19 20 namespace net { 21 22 class IOBuffer; 23 struct SockaddrStorage; 24 25 // Socket class to provide asynchronous read/write operations on top of the 26 // posix socket api. It supports AF_INET, AF_INET6, and AF_UNIX addresses. 27 class NET_EXPORT_PRIVATE SocketPosix 28 : public base::MessagePumpForIO::FdWatcher { 29 public: 30 SocketPosix(); 31 32 SocketPosix(const SocketPosix&) = delete; 33 SocketPosix& operator=(const SocketPosix&) = delete; 34 35 ~SocketPosix() override; 36 37 // Opens a socket and returns net::OK if |address_family| is AF_INET, AF_INET6 38 // or AF_UNIX. Otherwise, it does DCHECK() and returns a net error. 39 int Open(int address_family); 40 41 // Takes ownership of |socket|, which is known to already be connected to the 42 // given peer address. 43 int AdoptConnectedSocket(SocketDescriptor socket, 44 const SockaddrStorage& peer_address); 45 // Takes ownership of |socket|, which may or may not be open, bound, or 46 // listening. The caller must determine the state of the socket based on its 47 // provenance and act accordingly. The socket may have connections waiting 48 // to be accepted, but must not be actually connected. 49 int AdoptUnconnectedSocket(SocketDescriptor socket); 50 51 // Releases ownership of |socket_fd_| to caller. There must be no pending 52 // write. 53 SocketDescriptor ReleaseConnectedSocket(); 54 55 int Bind(const SockaddrStorage& address); 56 57 int Listen(int backlog); 58 int Accept(std::unique_ptr<SocketPosix>* socket, 59 CompletionOnceCallback callback); 60 61 // Connects socket. On non-ERR_IO_PENDING error, sets errno and returns a net 62 // error code. On ERR_IO_PENDING, |callback| is called with a net error code, 63 // not errno, though errno is set if connect event happens with error. 64 // TODO(byungchul): Need more robust way to pass system errno. 65 int Connect(const SockaddrStorage& address, CompletionOnceCallback callback); 66 bool IsConnected() const; 67 bool IsConnectedAndIdle() const; 68 69 // Multiple outstanding requests of the same type are not supported. 70 // Full duplex mode (reading and writing at the same time) is supported. 71 // On error which is not ERR_IO_PENDING, sets errno and returns a net error 72 // code. On ERR_IO_PENDING, |callback| is called with a net error code, not 73 // errno, though errno is set if read or write events happen with error. 74 // TODO(byungchul): Need more robust way to pass system errno. 75 int Read(IOBuffer* buf, int buf_len, CompletionOnceCallback callback); 76 77 // Reads up to |buf_len| bytes into |buf| without blocking. If read is to 78 // be retried later, |callback| will be invoked when data is ready for 79 // reading. This method doesn't hold on to |buf|. 80 // See socket.h for more information. 81 int ReadIfReady(IOBuffer* buf, int buf_len, CompletionOnceCallback callback); 82 int CancelReadIfReady(); 83 int Write(IOBuffer* buf, 84 int buf_len, 85 CompletionOnceCallback callback, 86 const NetworkTrafficAnnotationTag& traffic_annotation); 87 88 // Waits for next write event. This is called by TCPSocketPosix for TCP 89 // fastopen after sending first data. Returns ERR_IO_PENDING if it starts 90 // waiting for write event successfully. Otherwise, returns a net error code. 91 // It must not be called after Write() because Write() calls it internally. 92 int WaitForWrite(IOBuffer* buf, int buf_len, CompletionOnceCallback callback); 93 94 int GetLocalAddress(SockaddrStorage* address) const; 95 int GetPeerAddress(SockaddrStorage* address) const; 96 void SetPeerAddress(const SockaddrStorage& address); 97 // Returns true if peer address has been set regardless of socket state. 98 bool HasPeerAddress() const; 99 100 void Close(); 101 102 // Detachs from the current thread, to allow the socket to be transferred to 103 // a new thread. Should only be called when the object is no longer used by 104 // the old thread. 105 void DetachFromThread(); 106 socket_fd()107 SocketDescriptor socket_fd() const { return socket_fd_; } 108 109 private: 110 // base::MessagePumpForIO::FdWatcher methods. 111 void OnFileCanReadWithoutBlocking(int fd) override; 112 void OnFileCanWriteWithoutBlocking(int fd) override; 113 114 int DoAccept(std::unique_ptr<SocketPosix>* socket); 115 void AcceptCompleted(); 116 117 int DoConnect(); 118 void ConnectCompleted(); 119 120 int DoRead(IOBuffer* buf, int buf_len); 121 void RetryRead(int rv); 122 void ReadCompleted(); 123 124 int DoWrite(IOBuffer* buf, int buf_len); 125 void WriteCompleted(); 126 127 // |close_socket| indicates whether the socket should also be closed. 128 void StopWatchingAndCleanUp(bool close_socket); 129 130 SocketDescriptor socket_fd_; 131 132 base::MessagePumpForIO::FdWatchController accept_socket_watcher_; 133 raw_ptr<std::unique_ptr<SocketPosix>> accept_socket_; 134 CompletionOnceCallback accept_callback_; 135 136 base::MessagePumpForIO::FdWatchController read_socket_watcher_; 137 138 // Non-null when a Read() is in progress. 139 scoped_refptr<IOBuffer> read_buf_; 140 int read_buf_len_ = 0; 141 CompletionOnceCallback read_callback_; 142 143 // Non-null when a ReadIfReady() is in progress. 144 CompletionOnceCallback read_if_ready_callback_; 145 146 base::MessagePumpForIO::FdWatchController write_socket_watcher_; 147 scoped_refptr<IOBuffer> write_buf_; 148 int write_buf_len_ = 0; 149 // External callback; called when write or connect is complete. 150 CompletionOnceCallback write_callback_; 151 152 // A connect operation is pending. In this case, |write_callback_| needs to be 153 // called when connect is complete. 154 bool waiting_connect_ = false; 155 156 std::unique_ptr<SockaddrStorage> peer_address_; 157 158 base::ThreadChecker thread_checker_; 159 }; 160 161 } // namespace net 162 163 #endif // NET_SOCKET_SOCKET_POSIX_H_ 164