• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_API_UDP_SOCKET_H_
6 #define PLATFORM_API_UDP_SOCKET_H_
7 
8 #include <stddef.h>  // size_t
9 #include <stdint.h>  // uint8_t
10 
11 #include <memory>
12 
13 #include "platform/api/network_interface.h"
14 #include "platform/base/error.h"
15 #include "platform/base/ip_address.h"
16 #include "platform/base/udp_packet.h"
17 
18 namespace openscreen {
19 
20 class TaskRunner;
21 
22 // An open UDP socket for sending/receiving datagrams to/from either specific
23 // endpoints or over IP multicast.
24 //
25 // Usage: The socket is created and opened by calling the Create() method. This
26 // returns a unique pointer that auto-closes/destroys the socket when it goes
27 // out-of-scope.
28 class UdpSocket {
29  public:
30   // Client for the UdpSocket class.
31   class Client {
32    public:
33 
34     // Method called when the UDP socket is bound. Default implementation
35     // does nothing, as clients may not care about the socket bind state.
OnBound(UdpSocket * socket)36     virtual void OnBound(UdpSocket* socket) {}
37 
38     // Method called on socket configuration operations when an error occurs.
39     // These specific APIs are:
40     //   UdpSocket::Bind()
41     //   UdpSocket::SetMulticastOutboundInterface(...)
42     //   UdpSocket::JoinMulticastGroup(...)
43     //   UdpSocket::SetDscp(...)
44     virtual void OnError(UdpSocket* socket, Error error) = 0;
45 
46     // Method called when an error occurs during a SendMessage call.
47     virtual void OnSendError(UdpSocket* socket, Error error) = 0;
48 
49     // Method called when a packet is read.
50     virtual void OnRead(UdpSocket* socket, ErrorOr<UdpPacket> packet) = 0;
51 
52    protected:
53     virtual ~Client();
54   };
55 
56   // Constants used to specify how we want packets sent from this socket.
57   enum class DscpMode : uint8_t {
58     // Default value set by the system on creation of a new socket.
59     kUnspecified = 0x0,
60 
61     // Mode for Audio only.
62     kAudioOnly = 0xb8,
63 
64     // Mode for Audio + Video.
65     kAudioVideo = 0x88,
66 
67     // Mode for low priority operations such as trace log data.
68     kLowPriority = 0x20
69   };
70 
71   using Version = IPAddress::Version;
72 
73   // Creates a new, scoped UdpSocket within the IPv4 or IPv6 family.
74   // |local_endpoint| may be zero (see comments for Bind()). This method must be
75   // defined in the platform-level implementation. All |client| methods called
76   // will be queued on the provided |task_runner|. For this reason, the provided
77   // TaskRunner and Client must exist for the duration of the created socket's
78   // lifetime.
79   static ErrorOr<std::unique_ptr<UdpSocket>> Create(
80       TaskRunner* task_runner,
81       Client* client,
82       const IPEndpoint& local_endpoint);
83 
84   virtual ~UdpSocket();
85 
86   // Returns true if |socket| belongs to the IPv4/IPv6 address family.
87   virtual bool IsIPv4() const = 0;
88   virtual bool IsIPv6() const = 0;
89 
90   // Returns the current local endpoint's address and port. Initially, this will
91   // be the same as the value that was passed into Create(). However, it can
92   // later change after certain operations, such as Bind(), are executed.
93   virtual IPEndpoint GetLocalEndpoint() const = 0;
94 
95   // Binds to the address specified in the constructor. If the local endpoint's
96   // address is zero, the operating system will bind to all interfaces. If the
97   // local endpoint's port is zero, the operating system will automatically find
98   // a free local port and bind to it. Future calls to GetLocalEndpoint() will
99   // reflect the resolved port.
100   virtual void Bind() = 0;
101 
102   // Sets the device to use for outgoing multicast packets on the socket.
103   virtual void SetMulticastOutboundInterface(NetworkInterfaceIndex ifindex) = 0;
104 
105   // Joins to the multicast group at the given address, using the specified
106   // interface.
107   virtual void JoinMulticastGroup(const IPAddress& address,
108                                   NetworkInterfaceIndex ifindex) = 0;
109 
110   // Sends a message. If the message is not sent, Client::OnSendError() will be
111   // called to indicate this. Error::Code::kAgain indicates the operation would
112   // block, which can be expected during normal operation.
113   virtual void SendMessage(const void* data,
114                            size_t length,
115                            const IPEndpoint& dest) = 0;
116 
117   // Sets the DSCP value to use for all messages sent from this socket.
118   virtual void SetDscp(DscpMode state) = 0;
119 
120  protected:
121   UdpSocket();
122 };
123 
124 }  // namespace openscreen
125 
126 #endif  // PLATFORM_API_UDP_SOCKET_H_
127