blob: 22e7061b4ca753776f1628345481d9e63659eb3d [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
5#ifndef PLATFORM_API_SOCKET_H_
6#define PLATFORM_API_SOCKET_H_
7
Yuri Wiitala10dea9f2019-02-04 20:19:17 -08008#include <cstdint>
9#include <memory>
10
Jordan Baylesf1e4bb72019-05-01 12:38:39 -070011#include "osp_base/error.h"
12#include "osp_base/ip_address.h"
13#include "osp_base/macros.h"
Yuri Wiitala82edd202018-10-31 18:42:58 -070014#include "platform/api/network_interface.h"
btolsch9ccfa782018-07-26 00:16:08 -070015
16namespace openscreen {
17namespace platform {
18
Yuri Wiitala10dea9f2019-02-04 20:19:17 -080019class UdpSocket;
btolsch9ccfa782018-07-26 00:16:08 -070020
Yuri Wiitala10dea9f2019-02-04 20:19:17 -080021// Platform-specific deleter of a UdpSocket instance returned by
22// UdpSocket::Create().
23struct UdpSocketDeleter {
24 void operator()(UdpSocket* socket) const;
25};
btolsch9ccfa782018-07-26 00:16:08 -070026
Yuri Wiitala10dea9f2019-02-04 20:19:17 -080027using UdpSocketUniquePtr = std::unique_ptr<UdpSocket, UdpSocketDeleter>;
Yuri Wiitalab94f12e2018-10-31 18:28:53 -070028
Yuri Wiitala10dea9f2019-02-04 20:19:17 -080029// An open UDP socket for sending/receiving datagrams to/from either specific
30// endpoints or over IP multicast.
31//
32// Usage: The socket is created and opened by calling the Create() method. This
33// returns a unique pointer that auto-closes/destroys the socket when it goes
34// out-of-scope.
35//
36// Platform implementation note: There must only be one platform-specific
37// implementation of UdpSocket linked into the library/application. For that
38// reason, none of the methods here are declared virtual (i.e., the overhead is
39// pure waste). However, UdpSocket can be subclassed to include all extra
40// private state, such as OS-specific handles. See UdpSocketPosix for a
41// reference implementation.
42class UdpSocket {
43 public:
44 using Version = IPAddress::Version;
btolsch9ccfa782018-07-26 00:16:08 -070045
Yuri Wiitala10dea9f2019-02-04 20:19:17 -080046 // Creates a new, scoped UdpSocket within the IPv4 or IPv6 family.
47 static ErrorOr<UdpSocketUniquePtr> Create(Version version);
btolsch9ccfa782018-07-26 00:16:08 -070048
Yuri Wiitala10dea9f2019-02-04 20:19:17 -080049 // Returns true if |socket| belongs to the IPv4/IPv6 address family.
50 bool IsIPv4() const;
51 bool IsIPv6() const;
52
53 // Sets the socket for address reuse, binds to the address/port.
54 Error Bind(const IPEndpoint& local_endpoint);
55
56 // Sets the device to use for outgoing multicast packets on the socket.
57 Error SetMulticastOutboundInterface(NetworkInterfaceIndex ifindex);
58
59 // Joins to the multicast group at the given address, using the specified
60 // interface.
61 Error JoinMulticastGroup(const IPAddress& address,
62 NetworkInterfaceIndex ifindex);
63
64 // Performs a non-blocking read on the socket, returning the number of bytes
65 // received. Note that a non-Error return value of 0 is a valid result,
66 // indicating an empty message has been received. Also note that
67 // Error::Code::kAgain might be returned if there is no message currently
68 // ready for receive, which can be expected during normal operation. |src| and
69 // |original_destination| are optional output arguments that provide the
70 // source of the message and its intended destination, respectively.
71 ErrorOr<size_t> ReceiveMessage(void* data,
72 size_t length,
73 IPEndpoint* src,
74 IPEndpoint* original_destination);
75
76 // Sends a message and returns the number of bytes sent, on success.
77 // Error::Code::kAgain might be returned to indicate the operation would
78 // block, which can be expected during normal operation.
79 Error SendMessage(const void* data, size_t length, const IPEndpoint& dest);
80
81 protected:
82 UdpSocket();
83 ~UdpSocket();
84
85 private:
Jordan Baylesf1e4bb72019-05-01 12:38:39 -070086 OSP_DISALLOW_COPY_AND_ASSIGN(UdpSocket);
Yuri Wiitala10dea9f2019-02-04 20:19:17 -080087};
btolsch9ccfa782018-07-26 00:16:08 -070088
89} // namespace platform
90} // namespace openscreen
91
btolscha21e8ed2018-08-30 15:13:48 -070092#endif // PLATFORM_API_SOCKET_H_