blob: e6481241491cd33e58328b4f5c47207d1acce9e3 [file] [log] [blame]
btolsch9ccfa782018-07-26 00:16:08 -07001// 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
Jordan Baylesad2d2cd2019-05-22 14:49:40 -07005#ifndef PLATFORM_API_UDP_SOCKET_H_
6#define PLATFORM_API_UDP_SOCKET_H_
btolsch9ccfa782018-07-26 00:16:08 -07007
Yuri Wiitala10dea9f2019-02-04 20:19:17 -08008#include <cstdint>
Ryan Keanedeb48b32019-06-28 16:24:40 -07009#include <functional>
Yuri Wiitala10dea9f2019-02-04 20:19:17 -080010#include <memory>
11
Jordan Baylesf1e4bb72019-05-01 12:38:39 -070012#include "osp_base/error.h"
13#include "osp_base/ip_address.h"
14#include "osp_base/macros.h"
Yuri Wiitala82edd202018-10-31 18:42:58 -070015#include "platform/api/network_interface.h"
btolsch9ccfa782018-07-26 00:16:08 -070016
17namespace openscreen {
18namespace platform {
19
Yuri Wiitala10dea9f2019-02-04 20:19:17 -080020class UdpSocket;
btolsch9ccfa782018-07-26 00:16:08 -070021
Ryan Keanedeb48b32019-06-28 16:24:40 -070022using UdpSocketUniquePtr = std::unique_ptr<UdpSocket>;
Yuri Wiitalab94f12e2018-10-31 18:28:53 -070023
Yuri Wiitala10dea9f2019-02-04 20:19:17 -080024// An open UDP socket for sending/receiving datagrams to/from either specific
25// endpoints or over IP multicast.
26//
27// Usage: The socket is created and opened by calling the Create() method. This
28// returns a unique pointer that auto-closes/destroys the socket when it goes
29// out-of-scope.
30//
31// Platform implementation note: There must only be one platform-specific
32// implementation of UdpSocket linked into the library/application. For that
33// reason, none of the methods here are declared virtual (i.e., the overhead is
34// pure waste). However, UdpSocket can be subclassed to include all extra
35// private state, such as OS-specific handles. See UdpSocketPosix for a
36// reference implementation.
37class UdpSocket {
38 public:
Ryan Keanedeb48b32019-06-28 16:24:40 -070039 virtual ~UdpSocket();
40
Ryan Keane8f1c9252019-05-06 11:03:38 -070041 // Constants used to specify how we want packets sent from this socket.
42 enum class DscpMode : uint8_t {
43 // Default value set by the system on creation of a new socket.
44 kUnspecified = 0x0,
45
46 // Mode for Audio only.
47 kAudioOnly = 0xb8,
48
49 // Mode for Audio + Video.
50 kAudioVideo = 0x88,
51
52 // Mode for low priority operations such as trace log data.
53 kLowPriority = 0x20
54 };
55
Yuri Wiitala10dea9f2019-02-04 20:19:17 -080056 using Version = IPAddress::Version;
btolsch9ccfa782018-07-26 00:16:08 -070057
Ryan Keanedeb48b32019-06-28 16:24:40 -070058 // Creates a new, scoped UdpSocket within the IPv4 or IPv6 family. This method
59 // must be defined in the platform-level implementation.
Yuri Wiitala10dea9f2019-02-04 20:19:17 -080060 static ErrorOr<UdpSocketUniquePtr> Create(Version version);
btolsch9ccfa782018-07-26 00:16:08 -070061
Yuri Wiitala10dea9f2019-02-04 20:19:17 -080062 // Returns true if |socket| belongs to the IPv4/IPv6 address family.
Ryan Keanedeb48b32019-06-28 16:24:40 -070063 virtual bool IsIPv4() const = 0;
64 virtual bool IsIPv6() const = 0;
Yuri Wiitala10dea9f2019-02-04 20:19:17 -080065
66 // Sets the socket for address reuse, binds to the address/port.
Ryan Keanedeb48b32019-06-28 16:24:40 -070067 virtual Error Bind(const IPEndpoint& local_endpoint) = 0;
Yuri Wiitala10dea9f2019-02-04 20:19:17 -080068
69 // Sets the device to use for outgoing multicast packets on the socket.
Ryan Keanedeb48b32019-06-28 16:24:40 -070070 virtual Error SetMulticastOutboundInterface(
71 NetworkInterfaceIndex ifindex) = 0;
Yuri Wiitala10dea9f2019-02-04 20:19:17 -080072
73 // Joins to the multicast group at the given address, using the specified
74 // interface.
Ryan Keanedeb48b32019-06-28 16:24:40 -070075 virtual Error JoinMulticastGroup(const IPAddress& address,
76 NetworkInterfaceIndex ifindex) = 0;
Yuri Wiitala10dea9f2019-02-04 20:19:17 -080077
78 // Performs a non-blocking read on the socket, returning the number of bytes
79 // received. Note that a non-Error return value of 0 is a valid result,
80 // indicating an empty message has been received. Also note that
81 // Error::Code::kAgain might be returned if there is no message currently
82 // ready for receive, which can be expected during normal operation. |src| and
83 // |original_destination| are optional output arguments that provide the
84 // source of the message and its intended destination, respectively.
Ryan Keanedeb48b32019-06-28 16:24:40 -070085 virtual ErrorOr<size_t> ReceiveMessage(void* data,
86 size_t length,
87 IPEndpoint* src,
88 IPEndpoint* original_destination) = 0;
Yuri Wiitala10dea9f2019-02-04 20:19:17 -080089
90 // Sends a message and returns the number of bytes sent, on success.
91 // Error::Code::kAgain might be returned to indicate the operation would
92 // block, which can be expected during normal operation.
Ryan Keanedeb48b32019-06-28 16:24:40 -070093 virtual Error SendMessage(const void* data,
94 size_t length,
95 const IPEndpoint& dest) = 0;
Yuri Wiitala10dea9f2019-02-04 20:19:17 -080096
Ryan Keane8f1c9252019-05-06 11:03:38 -070097 // Sets the DSCP value to use for all messages sent from this socket.
Ryan Keanedeb48b32019-06-28 16:24:40 -070098 virtual Error SetDscp(DscpMode state) = 0;
99
100 // Sets the callback that should be called upon deletion of this socket. This
101 // allows other objects to observe the socket's destructor and act when it is
102 // called.
103 void SetDeletionCallback(std::function<void(UdpSocket*)> callback);
Ryan Keane8f1c9252019-05-06 11:03:38 -0700104
Yuri Wiitala10dea9f2019-02-04 20:19:17 -0800105 protected:
106 UdpSocket();
Yuri Wiitala10dea9f2019-02-04 20:19:17 -0800107
108 private:
Ryan Keanedeb48b32019-06-28 16:24:40 -0700109 // This callback allows other objects to observe the socket's destructor and
110 // act when it is called.
111 std::function<void(UdpSocket*)> deletion_callback_;
112
Jordan Baylesf1e4bb72019-05-01 12:38:39 -0700113 OSP_DISALLOW_COPY_AND_ASSIGN(UdpSocket);
Yuri Wiitala10dea9f2019-02-04 20:19:17 -0800114};
btolsch9ccfa782018-07-26 00:16:08 -0700115
116} // namespace platform
117} // namespace openscreen
118
Jordan Baylesad2d2cd2019-05-22 14:49:40 -0700119#endif // PLATFORM_API_UDP_SOCKET_H_