1 // Copyright 2019 The Chromium Authors. All rights reserved. 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 PLATFORM_IMPL_STREAM_SOCKET_POSIX_H_ 6 #define PLATFORM_IMPL_STREAM_SOCKET_POSIX_H_ 7 8 #include <atomic> 9 #include <memory> 10 #include <string> 11 12 #include "absl/types/optional.h" 13 #include "platform/base/error.h" 14 #include "platform/base/ip_address.h" 15 #include "platform/impl/socket_address_posix.h" 16 #include "platform/impl/socket_handle_posix.h" 17 #include "platform/impl/stream_socket.h" 18 #include "util/weak_ptr.h" 19 20 namespace openscreen { 21 22 class StreamSocketPosix : public StreamSocket { 23 public: 24 explicit StreamSocketPosix(IPAddress::Version version); 25 explicit StreamSocketPosix(const IPEndpoint& local_endpoint); 26 StreamSocketPosix(SocketAddressPosix local_address, 27 IPEndpoint remote_address, 28 int file_descriptor); 29 30 // StreamSocketPosix is non-copyable, due to directly managing the file 31 // descriptor. 32 StreamSocketPosix(const StreamSocketPosix& other) = delete; 33 StreamSocketPosix(StreamSocketPosix&& other) noexcept; 34 StreamSocketPosix& operator=(const StreamSocketPosix& other) = delete; 35 StreamSocketPosix& operator=(StreamSocketPosix&& other); 36 virtual ~StreamSocketPosix(); 37 38 WeakPtr<StreamSocketPosix> GetWeakPtr() const; 39 40 // StreamSocket overrides. 41 ErrorOr<std::unique_ptr<StreamSocket>> Accept() override; 42 Error Bind() override; 43 Error Close() override; 44 Error Connect(const IPEndpoint& remote_endpoint) override; 45 Error Listen() override; 46 Error Listen(int max_backlog_size) override; 47 48 // StreamSocket getter overrides. socket_handle()49 const SocketHandle& socket_handle() const override { return handle_; } 50 absl::optional<IPEndpoint> remote_address() const override; 51 absl::optional<IPEndpoint> local_address() const override; 52 TcpSocketState state() const override; 53 IPAddress::Version version() const override; 54 55 private: 56 // StreamSocketPosix is lazy initialized on first usage. For simplicitly, 57 // the ensure method returns a boolean of whether or not the socket was 58 // initialized successfully. 59 bool EnsureInitializedAndOpen(); 60 Error Initialize(); 61 62 Error CloseOnError(Error error); 63 Error ReportSocketClosedError(); 64 65 constexpr static int kUnsetHandleFd = -1; 66 67 // This SocketHandle object is expected to persist for the lieftime of this 68 // object. The internal fd may change, but the object may not be destroyed. 69 SocketHandle handle_{kUnsetHandleFd}; 70 71 // last_error_code_ is an Error::Code instead of an Error so it meets 72 // atomic's (trivially) copyable and moveable requirements. 73 Error::Code last_error_code_ = Error::Code::kNone; 74 IPAddress::Version version_; 75 absl::optional<SocketAddressPosix> local_address_; 76 absl::optional<IPEndpoint> remote_address_; 77 78 bool is_bound_ = false; 79 TcpSocketState state_ = TcpSocketState::kNotConnected; 80 81 WeakPtrFactory<StreamSocketPosix> weak_factory_{this}; 82 }; 83 84 } // namespace openscreen 85 86 #endif // PLATFORM_IMPL_STREAM_SOCKET_POSIX_H_ 87