blob: aeee300fcd1b55ee6489baaaaf31c5762d4d16fe [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
Yuri Wiitala82edd202018-10-31 18:42:58 -070012#include "platform/api/network_interface.h"
Max Yakimakha04362e22019-07-22 17:54:45 -070013#include "platform/api/udp_read_callback.h"
Jordan Baylesa26582d2019-07-10 14:44:58 -070014#include "platform/base/error.h"
15#include "platform/base/ip_address.h"
16#include "platform/base/macros.h"
btolsch9ccfa782018-07-26 00:16:08 -070017
18namespace openscreen {
19namespace platform {
20
Yuri Wiitala10dea9f2019-02-04 20:19:17 -080021class UdpSocket;
btolsch9ccfa782018-07-26 00:16:08 -070022
Ryan Keanedeb48b32019-06-28 16:24:40 -070023using UdpSocketUniquePtr = std::unique_ptr<UdpSocket>;
Yuri Wiitalab94f12e2018-10-31 18:28:53 -070024
Yuri Wiitala10dea9f2019-02-04 20:19:17 -080025// An open UDP socket for sending/receiving datagrams to/from either specific
26// endpoints or over IP multicast.
27//
28// Usage: The socket is created and opened by calling the Create() method. This
29// returns a unique pointer that auto-closes/destroys the socket when it goes
30// out-of-scope.
31//
32// Platform implementation note: There must only be one platform-specific
33// implementation of UdpSocket linked into the library/application. For that
34// reason, none of the methods here are declared virtual (i.e., the overhead is
35// pure waste). However, UdpSocket can be subclassed to include all extra
36// private state, such as OS-specific handles. See UdpSocketPosix for a
37// reference implementation.
38class UdpSocket {
39 public:
Ryan Keanedeb48b32019-06-28 16:24:40 -070040 virtual ~UdpSocket();
41
Ryan Keane8f1c9252019-05-06 11:03:38 -070042 // Constants used to specify how we want packets sent from this socket.
43 enum class DscpMode : uint8_t {
44 // Default value set by the system on creation of a new socket.
45 kUnspecified = 0x0,
46
47 // Mode for Audio only.
48 kAudioOnly = 0xb8,
49
50 // Mode for Audio + Video.
51 kAudioVideo = 0x88,
52
53 // Mode for low priority operations such as trace log data.
54 kLowPriority = 0x20
55 };
56
Yuri Wiitala10dea9f2019-02-04 20:19:17 -080057 using Version = IPAddress::Version;
btolsch9ccfa782018-07-26 00:16:08 -070058
Yuri Wiitalade01e532019-08-06 18:12:02 -070059 // Creates a new, scoped UdpSocket within the IPv4 or IPv6 family.
60 // |local_endpoint| may be zero (see comments for Bind()). This method must be
61 // defined in the platform-level implementation.
62 static ErrorOr<UdpSocketUniquePtr> Create(const IPEndpoint& local_endpoint);
btolsch9ccfa782018-07-26 00:16:08 -070063
Yuri Wiitala10dea9f2019-02-04 20:19:17 -080064 // Returns true if |socket| belongs to the IPv4/IPv6 address family.
Ryan Keanedeb48b32019-06-28 16:24:40 -070065 virtual bool IsIPv4() const = 0;
66 virtual bool IsIPv6() const = 0;
Yuri Wiitala10dea9f2019-02-04 20:19:17 -080067
Yuri Wiitalade01e532019-08-06 18:12:02 -070068 // Returns the current local endpoint's address and port. Initially, this will
69 // be the same as the value that was passed into Create(). However, it can
70 // later change after certain operations, such as Bind(), are executed.
71 virtual IPEndpoint GetLocalEndpoint() const = 0;
72
73 // Binds to the address specified in the constructor. If the local endpoint's
74 // address is zero, the operating system will bind to all interfaces. If the
75 // local endpoint's port is zero, the operating system will automatically find
76 // a free local port and bind to it. Future calls to local_endpoint() will
77 // reflect the resolved port.
Jordan Bayles5c473922019-07-26 12:44:15 -070078 virtual Error Bind() = 0;
Yuri Wiitala10dea9f2019-02-04 20:19:17 -080079
80 // Sets the device to use for outgoing multicast packets on the socket.
Ryan Keanedeb48b32019-06-28 16:24:40 -070081 virtual Error SetMulticastOutboundInterface(
82 NetworkInterfaceIndex ifindex) = 0;
Yuri Wiitala10dea9f2019-02-04 20:19:17 -080083
84 // Joins to the multicast group at the given address, using the specified
85 // interface.
Ryan Keanedeb48b32019-06-28 16:24:40 -070086 virtual Error JoinMulticastGroup(const IPAddress& address,
87 NetworkInterfaceIndex ifindex) = 0;
Yuri Wiitala10dea9f2019-02-04 20:19:17 -080088
89 // Performs a non-blocking read on the socket, returning the number of bytes
90 // received. Note that a non-Error return value of 0 is a valid result,
91 // indicating an empty message has been received. Also note that
92 // Error::Code::kAgain might be returned if there is no message currently
Max Yakimakha04362e22019-07-22 17:54:45 -070093 // ready for receive, which can be expected during normal operation.
94 virtual ErrorOr<UdpPacket> ReceiveMessage() = 0;
Yuri Wiitala10dea9f2019-02-04 20:19:17 -080095
96 // Sends a message and returns the number of bytes sent, on success.
97 // Error::Code::kAgain might be returned to indicate the operation would
98 // block, which can be expected during normal operation.
Ryan Keanedeb48b32019-06-28 16:24:40 -070099 virtual Error SendMessage(const void* data,
100 size_t length,
101 const IPEndpoint& dest) = 0;
Yuri Wiitala10dea9f2019-02-04 20:19:17 -0800102
Ryan Keane8f1c9252019-05-06 11:03:38 -0700103 // Sets the DSCP value to use for all messages sent from this socket.
Ryan Keanedeb48b32019-06-28 16:24:40 -0700104 virtual Error SetDscp(DscpMode state) = 0;
105
106 // Sets the callback that should be called upon deletion of this socket. This
107 // allows other objects to observe the socket's destructor and act when it is
108 // called.
109 void SetDeletionCallback(std::function<void(UdpSocket*)> callback);
Ryan Keane8f1c9252019-05-06 11:03:38 -0700110
Yuri Wiitala10dea9f2019-02-04 20:19:17 -0800111 protected:
112 UdpSocket();
Yuri Wiitala10dea9f2019-02-04 20:19:17 -0800113
114 private:
Ryan Keanedeb48b32019-06-28 16:24:40 -0700115 // This callback allows other objects to observe the socket's destructor and
116 // act when it is called.
117 std::function<void(UdpSocket*)> deletion_callback_;
118
Jordan Baylesf1e4bb72019-05-01 12:38:39 -0700119 OSP_DISALLOW_COPY_AND_ASSIGN(UdpSocket);
Yuri Wiitala10dea9f2019-02-04 20:19:17 -0800120};
btolsch9ccfa782018-07-26 00:16:08 -0700121
122} // namespace platform
123} // namespace openscreen
124
Jordan Baylesad2d2cd2019-05-22 14:49:40 -0700125#endif // PLATFORM_API_UDP_SOCKET_H_