blob: 363989170d7243365cec007aa4de9aa0f9faa5f6 [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
Ryan Keanedeb48b32019-06-28 16:24:40 -070059 // Creates a new, scoped UdpSocket within the IPv4 or IPv6 family. This method
60 // must be defined in the platform-level implementation.
Jordan Bayles5c473922019-07-26 12:44:15 -070061 static ErrorOr<UdpSocketUniquePtr> Create(const IPEndpoint& endpoint);
btolsch9ccfa782018-07-26 00:16:08 -070062
Yuri Wiitala10dea9f2019-02-04 20:19:17 -080063 // Returns true if |socket| belongs to the IPv4/IPv6 address family.
Ryan Keanedeb48b32019-06-28 16:24:40 -070064 virtual bool IsIPv4() const = 0;
65 virtual bool IsIPv6() const = 0;
Yuri Wiitala10dea9f2019-02-04 20:19:17 -080066
Jordan Bayles5c473922019-07-26 12:44:15 -070067 // Binds to the address specified in the constructor.
68 virtual Error Bind() = 0;
Yuri Wiitala10dea9f2019-02-04 20:19:17 -080069
70 // Sets the device to use for outgoing multicast packets on the socket.
Ryan Keanedeb48b32019-06-28 16:24:40 -070071 virtual Error SetMulticastOutboundInterface(
72 NetworkInterfaceIndex ifindex) = 0;
Yuri Wiitala10dea9f2019-02-04 20:19:17 -080073
74 // Joins to the multicast group at the given address, using the specified
75 // interface.
Ryan Keanedeb48b32019-06-28 16:24:40 -070076 virtual Error JoinMulticastGroup(const IPAddress& address,
77 NetworkInterfaceIndex ifindex) = 0;
Yuri Wiitala10dea9f2019-02-04 20:19:17 -080078
79 // Performs a non-blocking read on the socket, returning the number of bytes
80 // received. Note that a non-Error return value of 0 is a valid result,
81 // indicating an empty message has been received. Also note that
82 // Error::Code::kAgain might be returned if there is no message currently
Max Yakimakha04362e22019-07-22 17:54:45 -070083 // ready for receive, which can be expected during normal operation.
84 virtual ErrorOr<UdpPacket> ReceiveMessage() = 0;
Yuri Wiitala10dea9f2019-02-04 20:19:17 -080085
86 // Sends a message and returns the number of bytes sent, on success.
87 // Error::Code::kAgain might be returned to indicate the operation would
88 // block, which can be expected during normal operation.
Ryan Keanedeb48b32019-06-28 16:24:40 -070089 virtual Error SendMessage(const void* data,
90 size_t length,
91 const IPEndpoint& dest) = 0;
Yuri Wiitala10dea9f2019-02-04 20:19:17 -080092
Ryan Keane8f1c9252019-05-06 11:03:38 -070093 // Sets the DSCP value to use for all messages sent from this socket.
Ryan Keanedeb48b32019-06-28 16:24:40 -070094 virtual Error SetDscp(DscpMode state) = 0;
95
96 // Sets the callback that should be called upon deletion of this socket. This
97 // allows other objects to observe the socket's destructor and act when it is
98 // called.
99 void SetDeletionCallback(std::function<void(UdpSocket*)> callback);
Ryan Keane8f1c9252019-05-06 11:03:38 -0700100
Yuri Wiitala10dea9f2019-02-04 20:19:17 -0800101 protected:
102 UdpSocket();
Yuri Wiitala10dea9f2019-02-04 20:19:17 -0800103
104 private:
Ryan Keanedeb48b32019-06-28 16:24:40 -0700105 // This callback allows other objects to observe the socket's destructor and
106 // act when it is called.
107 std::function<void(UdpSocket*)> deletion_callback_;
108
Jordan Baylesf1e4bb72019-05-01 12:38:39 -0700109 OSP_DISALLOW_COPY_AND_ASSIGN(UdpSocket);
Yuri Wiitala10dea9f2019-02-04 20:19:17 -0800110};
btolsch9ccfa782018-07-26 00:16:08 -0700111
112} // namespace platform
113} // namespace openscreen
114
Jordan Baylesad2d2cd2019-05-22 14:49:40 -0700115#endif // PLATFORM_API_UDP_SOCKET_H_