Nexus HTTP/3
A QUIC and HTTP/3 library
udp.hpp
1 #pragma once
2 
3 #include <boost/asio/ip/udp.hpp>
4 
5 #include <nexus/error_code.hpp>
6 
7 namespace nexus {
8 
9 using boost::asio::ip::udp;
10 
11 namespace detail {
12 
13 template <int Name4, int Name6>
14 class socket_option {
15  int value;
16  public:
17  constexpr socket_option(bool b) : value(b ? 1 : 0) {}
18 
19  constexpr operator bool() const { return value; }
20 
21  template <typename Protocol>
22  constexpr int level(const Protocol& proto) const {
23  return proto.family() == PF_INET6 ? IPPROTO_IPV6 : IPPROTO_IP;
24  }
25  template <typename Protocol>
26  constexpr int name(const Protocol& proto) const {
27  return proto.family() == PF_INET6 ? Name6 : Name4;
28  }
29  template <typename Protocol>
30  constexpr size_t size(const Protocol&) const {
31  return sizeof(value);
32  }
33  template <typename Protocol>
34  constexpr void* data(const Protocol&) {
35  return &value;
36  }
37  template <typename Protocol>
38  constexpr const void* data(const Protocol&) const {
39  return &value;
40  }
41  template <typename Protocol>
42  constexpr void resize(Protocol&, std::size_t) {}
43 };
44 
45 template <typename Socket, typename Option>
46 error_code set_option(Socket& sock, Option&& option) {
47  error_code ec;
48  sock.set_option(option, ec);
49  return ec;
50 }
51 
52 template <typename Socket, typename ...Options>
53 error_code set_options(Socket& sock, Options&& ...options) {
54  error_code ec;
55  // fold expression calls set_option() on each until one returns an error
56  ((ec = set_option(sock, options)) || ...);
57  return ec;
58 }
59 
60 } // namespace detail
61 
62 using receive_ecn = detail::socket_option<IP_RECVTOS, IPV6_RECVTCLASS>;
63 
64 #ifdef IP_RECVORIGDSTADDR
65 using receive_dstaddr = detail::socket_option<IP_RECVORIGDSTADDR, IPV6_RECVPKTINFO>;
66 #else
67 using receive_dstaddr = detail::socket_option<IP_PKTINFO, IPV6_RECVPKTINFO>;
68 #endif
69 
70 } // namespace nexus
networking
Definition: error_code.hpp:8