userver: userver/engine/io/multicast_membership.hpp Source File
Loading...
Searching...
No Matches
multicast_membership.hpp
Go to the documentation of this file.
1#pragma once
2
3/// @file userver/engine/io/multicast_membership.hpp
4/// @brief @copybrief engine::io::IpMreq
5
6#include <netinet/in.h>
7#include <sys/socket.h>
8#include <sys/types.h>
9
10#include <stdexcept>
11
12USERVER_NAMESPACE_BEGIN
13
14namespace engine::io {
15
16/// Multicast request related exceptions
17class IpMulticastRequestException : public std::runtime_error {
18public:
19 using std::runtime_error::runtime_error;
20};
21
22class Socket;
23
24/// Native ip multicast request wrapper
25/// @snippet src/engine/io/socket_test.cpp multicast socket creation sample
26class IpMreq final {
27public:
28 /// @brief Creates a structure storing multicast group membership request information. The resulting object may be
29 /// passed to @ref engine::io::AddMembership() and @ref engine::io::DropMembership() functions.
30 /// @note IP version is chosen automatically from ip_multiaddr value.
31 /// @param ip_multiaddr IP multicast group address (e.g. 239.255.0.1" or "ff02::1")
32 /// @param interface_index Interface index (0 for default);
33 IpMreq(const char* ip_multiaddr, unsigned int interface_index);
34
35 /// @brief Native multicast request structure pointer.
36 void* Data() { return &data_; }
37
38 /// @brief Native multicast request structure pointer.
39 const void* Data() const { return &data_; }
40
41 /// @brief Returns socket option level.
42 int GetSocketOptionLevel() const noexcept { return (family_ == AF_INET ? IPPROTO_IP : IPPROTO_IPV6); }
43
44 /// @brief Returns socket option name for joining multicast group.
45 int GetJoinSocketOptionName() const noexcept { return (family_ == AF_INET ? IP_ADD_MEMBERSHIP : IPV6_JOIN_GROUP); }
46
47 /// @brief Returns socket option name for leaving multicast group.
48 int GetLeaveSocketOption() const noexcept { return (family_ == AF_INET ? IP_DROP_MEMBERSHIP : IPV6_LEAVE_GROUP); }
49
50 /// Returns appropriate size for setsockopt based on address family.
51 /// @param domain Socket domain (AF_INET or AF_INET6)
52 size_t Size() const noexcept { return (family_ == AF_INET ? sizeof(struct ip_mreqn) : sizeof(struct ipv6_mreq)); }
53
54private:
55 union Storage {
56 struct ip_mreqn ip_req;
57 struct ipv6_mreq ipv6_req;
58 } data_;
59 int family_;
60};
61
62/// @brief Joins multicast group for given socket to receive multicast datagrams.
63void AddMembership(Socket& socket, const IpMreq& mreq);
64
65/// @brief Leaves multicast group for given socket previously joined with AddMembership.
66void DropMembership(Socket& socket, const IpMreq& mreq);
67
68} // namespace engine::io
69
70USERVER_NAMESPACE_END