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