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