RDK Documentation (Open Sourced RDK Components)
StunClient.h
1 #ifndef STUN_CLIENT_H
2 #define STUN_CLIENT_H
3 
4 #include <array>
5 #include <chrono>
6 #include <cstdint>
7 #include <memory>
8 #include <string>
9 #include <vector>
10 #include <netinet/in.h>
11 
12 namespace stun
13 {
14 
15 class encoder;
16 class decoder;
17 class message;
18 class message_factory;
19 
20 using buffer = std::vector<uint8_t>;
21 
22 enum class network_access_type {
23  udp_blocked,
24  open_internet,
25  symmetric_firewall,
26  full_cone,
27  symmetric_nat,
28  restricted,
29  port_resricted,
30  unknown
31 };
32 
33 namespace message_type {
34  static uint16_t constexpr binding_request = 0x001;
35  static uint16_t constexpr binding_response = 0x0101;
36  static uint16_t constexpr binding_error_response = 0x0111;
37  static uint16_t constexpr shared_secret_request = 0x0002;
38  static uint16_t constexpr shared_secret_response = 0x0102;
39  static uint16_t constexpr shared_secret_error_response = 0x0112;
40 }
41 
42 namespace attribute_type {
43  static uint16_t constexpr mapped_address = 0x001;
44  static uint16_t constexpr response_address = 0x0002;
45  static uint16_t constexpr change_request = 0x0003;
46  static uint16_t constexpr source_address = 0x004;
47  static uint16_t constexpr changed_address = 0x005;
48  static uint16_t constexpr username = 0x0006;
49  static uint16_t constexpr password = 0x0007;
50  static uint16_t constexpr message_integrity = 0x0008;
51  static uint16_t constexpr error_code = 0x0009;
52  static uint16_t constexpr unknown_attributes = 0x000a;
53  static uint16_t constexpr reflected_from = 0x000b;
54 }
55 
56 struct attribute {
57  uint16_t type;
58  uint16_t length;
59  std::vector<uint8_t> value;
60 };
61 
62 namespace attributes {
63  class address {
64  public:
65  address(attribute const & attr);
66  inline sockaddr_storage addr() const {
67  return m_addr;
68  }
69  private:
70  sockaddr_storage m_addr;
71  };
72  struct mapped_address : public address {
73  mapped_address(attribute const & attr) : address(attr) { }
74  };
75  struct source_address : public address {
76  source_address(attribute const & attr) : address(attr) { }
77  };
78  struct changed_address : public address {
79  changed_address(attribute const & attr) : address(attr) { }
80  };
81 }
82 
84  uint16_t message_type;
85  uint16_t message_length;
86  std::array<uint8_t, 16> transaction_id;
87 };
88 
89 class message {
90  friend class encoder;
91  friend class decoder;
92  friend class message_factory;
93 public:
94  buffer encode() const;
95  inline std::vector<attribute> const & attributes() const {
96  return m_attrs;
97  }
98 
99  attribute const * find_attribute(uint16_t attr_type) const;
100 
101 private:
102  message_header m_header;
103  std::vector<attribute> m_attrs;
104 };
105 
106 class message_factory final {
107 public:
108  static message * create_binding_request();
109 };
110 
111 class decoder final {
112 public:
113  static uint16_t decode_u16(buffer const & buff, size_t * offset);
114  static uint32_t decode_u32(buffer const & buff, size_t * offset);
115  static attribute decode_attr(buffer const & buff, size_t * offset);
116  static message * decode_message(buffer const & buff, size_t * offset);
117 };
118 
119 class encoder final {
120 public:
121  static void encode_u16(buffer & buff, uint16_t n);
122  static void encode_u32(buffer & buff, uint32_t n);
123 };
124 
125 struct server {
126  server(std::string const& h, uint16_t p)
127  : hostname(h), port(p)
128  {}
129  std::string hostname;
130  uint16_t port;
131 };
132 
133 enum class protocol {
134  af_inet,
135  af_inet6
136 };
137 
138 struct bind_result {
139  bind_result() : public_ip() {}
140  bool is_valid() { return !public_ip.empty(); }
141  void invalidate() { public_ip.clear(); }
142  std::string public_ip;
143 };
144 
145 class client {
146 public:
147  client();
148  ~client();
149 
150  bool bind(std::string const & hostname,
151  uint16_t port,
152  std::string const & interface,
153  protocol proto,
154  uint16_t bind_timeout,
155  uint16_t cache_timeout,
156  bind_result& result);
157 
158  network_access_type discover_network_access_type(server const & srv);
159 
160  inline void set_verbose(bool b) {
161  m_verbose = b;
162  }
163 private:
164  void verbose(char const * format, ...) __attribute__((format(printf, 2, 3)));
165  void create_udp_socket(int inet_family);
166 
167  std::unique_ptr<message> send_binding_request(std::chrono::milliseconds wait_time);
168 
169  std::unique_ptr<message> send_binding_request(sockaddr_storage const & addr,
170  std::chrono::milliseconds wait_time);
171 
172  message * send_message(sockaddr_storage const & remote_adr, message const & req,
173  std::chrono::milliseconds wait_time, int * local_iface_index = nullptr);
174 
175 private:
176  server m_server;
177  protocol m_protocol;
178  std::string m_interface;
179  uint16_t m_bind_timeout;
180  uint16_t m_cache_timeout;
181  std::chrono::time_point<std::chrono::steady_clock> m_last_cache_time;
182  bind_result m_last_result;
183  bool m_verbose;
184  int m_fd;
185 };
186 
187 std::string sockaddr_to_string(sockaddr_storage const & addr);
188 
189 }
190 
191 #endif
stun::message_header
Definition: StunClient.h:83
stun::attributes::source_address
Definition: StunClient.h:75
stun::attributes::address
Definition: StunClient.h:63
stun::attributes::mapped_address
Definition: StunClient.h:72
stun::message_factory
Definition: StunClient.h:106
stun::decoder
Definition: StunClient.h:111
stun::client
Definition: StunClient.h:145
stun::bind_result
Definition: StunClient.h:138
stun::attributes::changed_address
Definition: StunClient.h:78
stun::encoder
Definition: StunClient.h:119
stun::server
Definition: StunClient.h:125
stun::attribute
Definition: StunClient.h:56
stun::message
Definition: StunClient.h:89