blob: 4b8092a099d6fe39138ee8fac9c99b870bd958ca [file] [log] [blame]
James Kuszmaul82f6c042021-01-17 11:30:16 -08001/**
2 * @file re_stun.h Session Traversal Utilities for (NAT) (STUN)
3 *
4 * Copyright (C) 2010 Creytiv.com
5 */
6
7
8/** STUN Protocol values */
9enum {
10 STUN_PORT = 3478, /**< STUN Port number */
11 STUNS_PORT = 5349, /**< STUNS Port number */
12 STUN_HEADER_SIZE = 20, /**< Number of bytes in header */
13 STUN_ATTR_HEADER_SIZE = 4, /**< Size of attribute header */
14 STUN_TID_SIZE = 12, /**< Number of bytes in transaction ID */
15 STUN_DEFAULT_RTO = 500, /**< Default Retrans Timeout in [ms] */
16 STUN_DEFAULT_RC = 7, /**< Default number of retransmits */
17 STUN_DEFAULT_RM = 16, /**< Wait time after last request is sent */
18 STUN_DEFAULT_TI = 39500 /**< Reliable timeout */
19};
20
21/** STUN Address Family */
22enum stun_af {
23 STUN_AF_IPv4 = 0x01, /**< IPv4 Address Family */
24 STUN_AF_IPv6 = 0x02 /**< IPv6 Address Family */
25};
26
27/** STUN Transport */
28enum stun_transp {
29 STUN_TRANSP_UDP = IPPROTO_UDP, /**< UDP-transport (struct udp_sock) */
30 STUN_TRANSP_TCP = IPPROTO_TCP, /**< TCP-transport (struct tcp_conn) */
31 STUN_TRANSP_DTLS, /**< DTLS-transport (struct tls_conn) */
32};
33
34/** STUN Methods */
35enum stun_method {
36 STUN_METHOD_BINDING = 0x001,
37 STUN_METHOD_ALLOCATE = 0x003,
38 STUN_METHOD_REFRESH = 0x004,
39 STUN_METHOD_SEND = 0x006,
40 STUN_METHOD_DATA = 0x007,
41 STUN_METHOD_CREATEPERM = 0x008,
42 STUN_METHOD_CHANBIND = 0x009,
43};
44
45/** STUN Message class */
46enum stun_msg_class {
47 STUN_CLASS_REQUEST = 0x0, /**< STUN Request */
48 STUN_CLASS_INDICATION = 0x1, /**< STUN Indication */
49 STUN_CLASS_SUCCESS_RESP = 0x2, /**< STUN Success Response */
50 STUN_CLASS_ERROR_RESP = 0x3 /**< STUN Error Response */
51};
52
53/** STUN Attributes */
54enum stun_attrib {
55 /* Comprehension-required range (0x0000-0x7FFF) */
56 STUN_ATTR_MAPPED_ADDR = 0x0001,
57 STUN_ATTR_CHANGE_REQ = 0x0003,
58 STUN_ATTR_USERNAME = 0x0006,
59 STUN_ATTR_MSG_INTEGRITY = 0x0008,
60 STUN_ATTR_ERR_CODE = 0x0009,
61 STUN_ATTR_UNKNOWN_ATTR = 0x000a,
62 STUN_ATTR_CHANNEL_NUMBER = 0x000c,
63 STUN_ATTR_LIFETIME = 0x000d,
64 STUN_ATTR_XOR_PEER_ADDR = 0x0012,
65 STUN_ATTR_DATA = 0x0013,
66 STUN_ATTR_REALM = 0x0014,
67 STUN_ATTR_NONCE = 0x0015,
68 STUN_ATTR_XOR_RELAY_ADDR = 0x0016,
69 STUN_ATTR_REQ_ADDR_FAMILY = 0x0017,
70 STUN_ATTR_EVEN_PORT = 0x0018,
71 STUN_ATTR_REQ_TRANSPORT = 0x0019,
72 STUN_ATTR_DONT_FRAGMENT = 0x001a,
73 STUN_ATTR_XOR_MAPPED_ADDR = 0x0020,
74 STUN_ATTR_RSV_TOKEN = 0x0022,
75 STUN_ATTR_PRIORITY = 0x0024,
76 STUN_ATTR_USE_CAND = 0x0025,
77 STUN_ATTR_PADDING = 0x0026,
78 STUN_ATTR_RESP_PORT = 0x0027,
79
80 /* Comprehension-optional range (0x8000-0xFFFF) */
81 STUN_ATTR_SOFTWARE = 0x8022,
82 STUN_ATTR_ALT_SERVER = 0x8023,
83 STUN_ATTR_FINGERPRINT = 0x8028,
84 STUN_ATTR_CONTROLLED = 0x8029,
85 STUN_ATTR_CONTROLLING = 0x802a,
86 STUN_ATTR_RESP_ORIGIN = 0x802b,
87 STUN_ATTR_OTHER_ADDR = 0x802c,
88};
89
90
91struct stun_change_req {
92 bool ip;
93 bool port;
94};
95
96struct stun_errcode {
97 uint16_t code;
98 char *reason;
99};
100
101struct stun_unknown_attr {
102 uint16_t typev[8];
103 uint32_t typec;
104};
105
106struct stun_even_port {
107 bool r;
108};
109
110/** Defines a STUN attribute */
111struct stun_attr {
112 struct le le;
113 uint16_t type;
114 union {
115 /* generic types */
116 struct sa sa;
117 char *str;
118 uint64_t uint64;
119 uint32_t uint32;
120 uint16_t uint16;
121 uint8_t uint8;
122 struct mbuf mb;
123
124 /* actual attributes */
125 struct sa mapped_addr;
126 struct stun_change_req change_req;
127 char *username;
128 uint8_t msg_integrity[20];
129 struct stun_errcode err_code;
130 struct stun_unknown_attr unknown_attr;
131 uint16_t channel_number;
132 uint32_t lifetime;
133 struct sa xor_peer_addr;
134 struct mbuf data;
135 char *realm;
136 char *nonce;
137 struct sa xor_relay_addr;
138 uint8_t req_addr_family;
139 struct stun_even_port even_port;
140 uint8_t req_transport;
141 struct sa xor_mapped_addr;
142 uint64_t rsv_token;
143 uint32_t priority;
144 struct mbuf padding;
145 uint16_t resp_port;
146 char *software;
147 struct sa alt_server;
148 uint32_t fingerprint;
149 uint64_t controlled;
150 uint64_t controlling;
151 struct sa resp_origin;
152 struct sa other_addr;
153 } v;
154};
155
156
157/** STUN Configuration */
158struct stun_conf {
159 uint32_t rto; /**< RTO Retransmission TimeOut [ms] */
160 uint32_t rc; /**< Rc Retransmission count (default 7) */
161 uint32_t rm; /**< Rm Max retransmissions (default 16) */
162 uint32_t ti; /**< Ti Timeout for reliable transport [ms] */
163 uint8_t tos; /**< Type-of-service field */
164};
165
166
167extern const char *stun_software;
168struct stun;
169struct stun_msg;
170struct stun_ctrans;
171
172typedef void(stun_resp_h)(int err, uint16_t scode, const char *reason,
173 const struct stun_msg *msg, void *arg);
174typedef void(stun_ind_h)(struct stun_msg *msg, void *arg);
175typedef bool(stun_attr_h)(const struct stun_attr *attr, void *arg);
176
177int stun_alloc(struct stun **stunp, const struct stun_conf *conf,
178 stun_ind_h *indh, void *arg);
179struct stun_conf *stun_conf(struct stun *stun);
180int stun_send(int proto, void *sock, const struct sa *dst, struct mbuf *mb);
181int stun_recv(struct stun *stun, struct mbuf *mb);
182int stun_ctrans_recv(struct stun *stun, const struct stun_msg *msg,
183 const struct stun_unknown_attr *ua);
184struct re_printf;
185int stun_debug(struct re_printf *pf, const struct stun *stun);
186
187int stun_request(struct stun_ctrans **ctp, struct stun *stun, int proto,
188 void *sock, const struct sa *dst, size_t presz,
189 uint16_t method, const uint8_t *key, size_t keylen, bool fp,
190 stun_resp_h *resph, void *arg, uint32_t attrc, ...);
191int stun_reply(int proto, void *sock, const struct sa *dst, size_t presz,
192 const struct stun_msg *req, const uint8_t *key,
193 size_t keylen, bool fp, uint32_t attrc, ...);
194int stun_ereply(int proto, void *sock, const struct sa *dst, size_t presz,
195 const struct stun_msg *req, uint16_t scode,
196 const char *reason, const uint8_t *key, size_t keylen,
197 bool fp, uint32_t attrc, ...);
198int stun_indication(int proto, void *sock, const struct sa *dst, size_t presz,
199 uint16_t method, const uint8_t *key, size_t keylen,
200 bool fp, uint32_t attrc, ...);
201
202int stun_msg_vencode(struct mbuf *mb, uint16_t method, uint8_t cls,
203 const uint8_t *tid, const struct stun_errcode *ec,
204 const uint8_t *key, size_t keylen, bool fp,
205 uint8_t padding, uint32_t attrc, va_list ap);
206int stun_msg_encode(struct mbuf *mb, uint16_t method, uint8_t cls,
207 const uint8_t *tid, const struct stun_errcode *ec,
208 const uint8_t *key, size_t keylen, bool fp,
209 uint8_t padding, uint32_t attrc, ...);
210int stun_msg_decode(struct stun_msg **msgpp, struct mbuf *mb,
211 struct stun_unknown_attr *ua);
212uint16_t stun_msg_type(const struct stun_msg *msg);
213uint16_t stun_msg_class(const struct stun_msg *msg);
214uint16_t stun_msg_method(const struct stun_msg *msg);
215bool stun_msg_mcookie(const struct stun_msg *msg);
216const uint8_t *stun_msg_tid(const struct stun_msg *msg);
217struct stun_attr *stun_msg_attr(const struct stun_msg *msg, uint16_t type);
218struct stun_attr *stun_msg_attr_apply(const struct stun_msg *msg,
219 stun_attr_h *h, void *arg);
220int stun_msg_chk_mi(const struct stun_msg *msg, const uint8_t *key,
221 size_t keylen);
222int stun_msg_chk_fingerprint(const struct stun_msg *msg);
223void stun_msg_dump(const struct stun_msg *msg);
224
225const char *stun_class_name(uint16_t cls);
226const char *stun_method_name(uint16_t method);
227const char *stun_attr_name(uint16_t type);
228const char *stun_transp_name(enum stun_transp tp);
229
230
231/* DNS Discovery of a STUN Server */
232extern const char *stun_proto_udp;
233extern const char *stun_proto_tcp;
234
235extern const char *stun_usage_binding;
236extern const char *stuns_usage_binding;
237extern const char *stun_usage_relay;
238extern const char *stuns_usage_relay;
239extern const char *stun_usage_behavior;
240extern const char *stuns_usage_behavior;
241
242
243/**
244 * Defines the STUN Server Discovery handler
245 *
246 * @param err Errorcode
247 * @param srv IP Address and port of STUN Server
248 * @param arg Handler argument
249 */
250typedef void (stun_dns_h)(int err, const struct sa *srv, void *arg);
251
252struct stun_dns;
253struct dnsc;
254int stun_server_discover(struct stun_dns **dnsp, struct dnsc *dnsc,
255 const char *service, const char *proto,
256 int af, const char *domain, uint16_t port,
257 stun_dns_h *dnsh, void *arg);
258
259
260/* NAT Keepalives */
261struct stun_keepalive;
262
263/**
264 * Defines the STUN Keepalive Mapped-Address handler
265 *
266 * @param err Errorcode
267 * @param map Mapped Address
268 * @param arg Handler argument
269 */
270typedef void (stun_mapped_addr_h)(int err, const struct sa *map, void *arg);
271
272
273int stun_keepalive_alloc(struct stun_keepalive **skap,
274 int proto, void *sock, int layer,
275 const struct sa *dst, const struct stun_conf *conf,
276 stun_mapped_addr_h *mah, void *arg);
277void stun_keepalive_enable(struct stun_keepalive *ska, uint32_t interval);
278
279
280/* STUN Reason Phrase */
281extern const char *stun_reason_300;
282extern const char *stun_reason_400;
283extern const char *stun_reason_401;
284extern const char *stun_reason_403;
285extern const char *stun_reason_420;
286extern const char *stun_reason_437;
287extern const char *stun_reason_438;
288extern const char *stun_reason_440;
289extern const char *stun_reason_441;
290extern const char *stun_reason_442;
291extern const char *stun_reason_443;
292extern const char *stun_reason_486;
293extern const char *stun_reason_500;
294extern const char *stun_reason_508;