1 /**
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 */
9 enum {
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 */
22 enum stun_af {
23 	STUN_AF_IPv4 = 0x01,  /**< IPv4 Address Family */
24 	STUN_AF_IPv6 = 0x02   /**< IPv6 Address Family */
25 };
26 
27 /** STUN Transport */
28 enum 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 */
35 enum 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 */
46 enum 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 */
54 enum 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 
91 struct stun_change_req {
92 	bool ip;
93 	bool port;
94 };
95 
96 struct stun_errcode {
97 	uint16_t code;
98 	char *reason;
99 };
100 
101 struct stun_unknown_attr {
102 	uint16_t typev[8];
103 	uint32_t typec;
104 };
105 
106 struct stun_even_port {
107 	bool r;
108 };
109 
110 /** Defines a STUN attribute */
111 struct 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 */
158 struct 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 
167 extern const char *stun_software;
168 struct stun;
169 struct stun_msg;
170 struct stun_ctrans;
171 
172 typedef void(stun_resp_h)(int err, uint16_t scode, const char *reason,
173 			  const struct stun_msg *msg, void *arg);
174 typedef void(stun_ind_h)(struct stun_msg *msg, void *arg);
175 typedef bool(stun_attr_h)(const struct stun_attr *attr, void *arg);
176 
177 int  stun_alloc(struct stun **stunp, const struct stun_conf *conf,
178 		stun_ind_h *indh, void *arg);
179 struct stun_conf *stun_conf(struct stun *stun);
180 int  stun_send(int proto, void *sock, const struct sa *dst, struct mbuf *mb);
181 int  stun_recv(struct stun *stun, struct mbuf *mb);
182 int  stun_ctrans_recv(struct stun *stun, const struct stun_msg *msg,
183 		      const struct stun_unknown_attr *ua);
184 struct re_printf;
185 int  stun_debug(struct re_printf *pf, const struct stun *stun);
186 
187 int  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, ...);
191 int  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, ...);
194 int  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, ...);
198 int  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 
202 int  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);
206 int  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, ...);
210 int  stun_msg_decode(struct stun_msg **msgpp, struct mbuf *mb,
211 		     struct stun_unknown_attr *ua);
212 uint16_t stun_msg_type(const struct stun_msg *msg);
213 uint16_t stun_msg_class(const struct stun_msg *msg);
214 uint16_t stun_msg_method(const struct stun_msg *msg);
215 bool stun_msg_mcookie(const struct stun_msg *msg);
216 const uint8_t *stun_msg_tid(const struct stun_msg *msg);
217 struct stun_attr *stun_msg_attr(const struct stun_msg *msg, uint16_t type);
218 struct stun_attr *stun_msg_attr_apply(const struct stun_msg *msg,
219 				      stun_attr_h *h, void *arg);
220 int  stun_msg_chk_mi(const struct stun_msg *msg, const uint8_t *key,
221 		     size_t keylen);
222 int  stun_msg_chk_fingerprint(const struct stun_msg *msg);
223 void stun_msg_dump(const struct stun_msg *msg);
224 
225 const char *stun_class_name(uint16_t cls);
226 const char *stun_method_name(uint16_t method);
227 const char *stun_attr_name(uint16_t type);
228 const char *stun_transp_name(enum stun_transp tp);
229 
230 
231 /* DNS Discovery of a STUN Server */
232 extern const char *stun_proto_udp;
233 extern const char *stun_proto_tcp;
234 
235 extern const char *stun_usage_binding;
236 extern const char *stuns_usage_binding;
237 extern const char *stun_usage_relay;
238 extern const char *stuns_usage_relay;
239 extern const char *stun_usage_behavior;
240 extern 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  */
250 typedef void (stun_dns_h)(int err, const struct sa *srv, void *arg);
251 
252 struct stun_dns;
253 struct dnsc;
254 int  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 */
261 struct 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  */
270 typedef void (stun_mapped_addr_h)(int err, const struct sa *map, void *arg);
271 
272 
273 int  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);
277 void stun_keepalive_enable(struct stun_keepalive *ska, uint32_t interval);
278 
279 
280 /* STUN Reason Phrase */
281 extern const char *stun_reason_300;
282 extern const char *stun_reason_400;
283 extern const char *stun_reason_401;
284 extern const char *stun_reason_403;
285 extern const char *stun_reason_420;
286 extern const char *stun_reason_437;
287 extern const char *stun_reason_438;
288 extern const char *stun_reason_440;
289 extern const char *stun_reason_441;
290 extern const char *stun_reason_442;
291 extern const char *stun_reason_443;
292 extern const char *stun_reason_486;
293 extern const char *stun_reason_500;
294 extern const char *stun_reason_508;
295