1 // Copyright 2018 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_UDP_SOCKET_POSIX_H_ 6 #define PLATFORM_IMPL_UDP_SOCKET_POSIX_H_ 7 8 #include "absl/types/optional.h" 9 #include "platform/api/udp_socket.h" 10 #include "platform/base/macros.h" 11 #include "platform/impl/platform_client_posix.h" 12 #include "platform/impl/socket_handle_posix.h" 13 #include "util/weak_ptr.h" 14 15 namespace openscreen { 16 17 class UdpSocketReaderPosix; 18 19 // Threading: All public methods must be called on the same thread--the one 20 // executing the TaskRunner. All non-public methods, except ReceiveMessage(), 21 // are also assumed to be called on that thread. 22 class UdpSocketPosix : public UdpSocket { 23 public: 24 // Creates a new UdpSocketPosix. The provided client and task_runner must 25 // exist for the duration of this socket's lifetime. 26 UdpSocketPosix(TaskRunner* task_runner, 27 Client* client, 28 SocketHandle handle, 29 const IPEndpoint& local_endpoint, 30 PlatformClientPosix* platform_client = 31 PlatformClientPosix::GetInstance()); 32 33 ~UdpSocketPosix() override; 34 35 // Implementations of UdpSocket methods. 36 bool IsIPv4() const override; 37 bool IsIPv6() const override; 38 IPEndpoint GetLocalEndpoint() const override; 39 void Bind() override; 40 void SetMulticastOutboundInterface(NetworkInterfaceIndex ifindex) override; 41 void JoinMulticastGroup(const IPAddress& address, 42 NetworkInterfaceIndex ifindex) override; 43 void SendMessage(const void* data, 44 size_t length, 45 const IPEndpoint& dest) override; 46 void SetDscp(DscpMode state) override; 47 48 const SocketHandle& GetHandle() const; 49 50 protected: 51 friend class UdpSocketReaderPosix; 52 53 // Called by UdpSocketReaderPosix to perform a non-blocking read on the socket 54 // and then dispatch the packet to this socket's Client. This method is the 55 // only one in this class possibly being called from another thread. 56 void ReceiveMessage(); 57 58 private: 59 // Helper to close the socket if |error| is fatal, in addition to dispatching 60 // an Error to the |client_|. 61 void OnError(Error::Code error); 62 is_closed()63 bool is_closed() const { return handle_.fd < 0; } 64 void Close(); 65 66 // Task runner to use for queuing |client_| callbacks. 67 TaskRunner* const task_runner_; 68 69 // Client to use for callbacks. This can be nullptr if the user does not want 70 // any callbacks (for example, in the send-only case). 71 Client* const client_; 72 73 // Holds the POSIX file descriptor, or -1 if the socket is closed. 74 SocketHandle handle_; 75 76 // Cached value of current local endpoint. This can change (e.g., when the 77 // operating system auto-assigns a free local port when Bind() is called). If 78 // the port is zero, getsockname() is called to try to resolve it. Once the 79 // port is non-zero, it is assumed never to change again. 80 mutable IPEndpoint local_endpoint_; 81 82 WeakPtrFactory<UdpSocketPosix> weak_factory_{this}; 83 84 PlatformClientPosix* const platform_client_; 85 86 OSP_DISALLOW_COPY_AND_ASSIGN(UdpSocketPosix); 87 }; 88 89 } // namespace openscreen 90 91 #endif // PLATFORM_IMPL_UDP_SOCKET_POSIX_H_ 92