1 /*
2 mediastreamer2 library - modular sound and video processing and streaming
3 Copyright (C) 2012-2016 Belledonne Communications
4
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 */
19
20
21 #include <mediastreamer2/stun.h>
22 #include <bctoolbox/crypto.h>
23 #include <bctoolbox/port.h>
24
25
26 #define IANA_PROTOCOL_NUMBERS_UDP 17
27
28 #define STUN_FLAG_CHANGE_IP 0x04
29 #define STUN_FLAG_CHANGE_PORT 0x02
30
31 #define STUN_MESSAGE_HEADER_LENGTH 20
32 #define STUN_MAX_USERNAME_LENGTH 513
33 #define STUN_MAX_REASON_LENGTH 127
34 #define STUN_MAX_SOFTWARE_LENGTH 763 /* Length in bytes, it is supposed to be less than 128 UTF-8 characters (TODO) */
35 #define STUN_MAX_REALM_LENGTH 127
36 #define STUN_MAX_NONCE_LENGTH 127
37
38
39 #define STUN_STR_SETTER(field, value) \
40 if ((field) != NULL) ms_free(field); \
41 (field) = ((value) == NULL) ? NULL : ms_strdup(value)
42
43
44 #if defined(htonq)
45 #elif defined(ORTP_BIGENDIAN)
46 #define htonq(n) n
47 #define ntohq(n) n
48 #else /* little endian */
htonq(uint64_t v)49 static ORTP_INLINE uint64_t htonq(uint64_t v) {
50 return htonl((uint32_t) (v >> 32)) | (uint64_t) htonl((uint32_t) v) << 32;
51 }
ntohq(uint64_t v)52 static ORTP_INLINE uint64_t ntohq (uint64_t v) {
53 return ntohl((uint32_t) (v >> 32)) | (uint64_t) ntohl((uint32_t) v) << 32;
54 }
55 #endif /* little endian */
56
57
58
59 typedef struct {
60 char *buffer;
61 char *ptr;
62 char *lenptr;
63 size_t cursize;
64 size_t remaining;
65 } StunMessageEncoder;
66
67
stun_message_encoder_init(StunMessageEncoder * encoder)68 static void stun_message_encoder_init(StunMessageEncoder *encoder) {
69 memset(encoder, 0, sizeof(StunMessageEncoder));
70 encoder->cursize = 128;
71 encoder->remaining = encoder->cursize;
72 encoder->buffer = ms_malloc(encoder->cursize);
73 encoder->ptr = encoder->buffer;
74 }
75
stun_message_encoder_check_size(StunMessageEncoder * encoder,size_t sz)76 static void stun_message_encoder_check_size(StunMessageEncoder *encoder, size_t sz) {
77 while (encoder->remaining < sz) {
78 size_t offset = encoder->ptr - encoder->buffer;
79 encoder->cursize *= 2;
80 encoder->buffer = ms_realloc(encoder->buffer, encoder->cursize);
81 encoder->ptr = encoder->buffer + offset;
82 encoder->lenptr = encoder->buffer + 2; /* Update pointer to the message length */
83 encoder->remaining = encoder->cursize - offset;
84 }
85 }
86
stun_message_encoder_get_message_length(const StunMessageEncoder * encoder)87 static size_t stun_message_encoder_get_message_length(const StunMessageEncoder *encoder) {
88 return encoder->ptr - encoder->buffer;
89 }
90
stun_message_encoder_memcpy(StunMessageEncoder * encoder,const void * src,size_t len)91 static void stun_message_encoder_memcpy(StunMessageEncoder *encoder, const void *src, size_t len) {
92 stun_message_encoder_check_size(encoder, len);
93 memcpy(encoder->ptr, src, len);
94 encoder->remaining -= len;
95 encoder->ptr += len;
96 }
97
stun_address_xor(MSStunAddress * addr,const UInt96 * tr_id)98 static void stun_address_xor(MSStunAddress *addr, const UInt96 *tr_id) {
99 if (addr->family == MS_STUN_ADDR_FAMILY_IPV4) {
100 addr->ip.v4.addr ^= MS_STUN_MAGIC_COOKIE;
101 addr->ip.v4.port ^= MS_STUN_MAGIC_COOKIE >> 16;
102 } else if (addr->family == MS_STUN_ADDR_FAMILY_IPV6) {
103 int i;
104 uint32_t magic_cookie = htonl(MS_STUN_MAGIC_COOKIE);
105 for (i = 0; i < 4; i++) {
106 addr->ip.v6.addr.octet[i] ^= ((uint8_t *)&magic_cookie)[i];
107 }
108 for (i = 0; i < 12; i++) {
109 addr->ip.v6.addr.octet[i + 4] ^= tr_id->octet[i];
110 }
111 addr->ip.v6.port ^= MS_STUN_MAGIC_COOKIE >> 16;
112 }
113 }
114
encode8(StunMessageEncoder * encoder,uint8_t data)115 static void encode8(StunMessageEncoder *encoder, uint8_t data) {
116 stun_message_encoder_memcpy(encoder, &data, sizeof(data));
117 }
118
encode16(StunMessageEncoder * encoder,uint16_t data)119 static void encode16(StunMessageEncoder *encoder, uint16_t data) {
120 uint16_t ndata = htons(data);
121 stun_message_encoder_memcpy(encoder, &ndata, sizeof(ndata));
122 }
123
encode32(StunMessageEncoder * encoder,uint32_t data)124 static void encode32(StunMessageEncoder *encoder, uint32_t data) {
125 uint32_t ndata = htonl(data);
126 stun_message_encoder_memcpy(encoder, &ndata, sizeof(ndata));
127 }
128
encode64(StunMessageEncoder * encoder,uint64_t data)129 static void encode64(StunMessageEncoder *encoder, uint64_t data) {
130 uint64_t ndata = htonq(data);
131 stun_message_encoder_memcpy(encoder, &ndata, sizeof(ndata));
132 }
133
encode(StunMessageEncoder * encoder,const void * src,size_t len)134 static void encode(StunMessageEncoder *encoder, const void *src, size_t len) {
135 stun_message_encoder_memcpy(encoder, src, len);
136 }
137
encode_message_length(StunMessageEncoder * encoder,size_t len)138 static void encode_message_length(StunMessageEncoder *encoder, size_t len) {
139 uint16_t ndata = htons((uint16_t)len);
140 memcpy(encoder->lenptr, &ndata, sizeof(ndata));
141 }
142
encode_message_header(StunMessageEncoder * encoder,uint16_t type,uint16_t method,const UInt96 * tr_id)143 static void encode_message_header(StunMessageEncoder *encoder, uint16_t type, uint16_t method, const UInt96 *tr_id) {
144 encode16(encoder, type | method);
145 encoder->lenptr = encoder->ptr;
146 encode16(encoder, 0); /* Initialize length to 0, it will be updated later */
147 encode32(encoder, MS_STUN_MAGIC_COOKIE); /* magic cookie */
148 encode(encoder, tr_id, sizeof(UInt96));
149 }
150
encode_addr(StunMessageEncoder * encoder,uint16_t type,const MSStunAddress * addr)151 static void encode_addr(StunMessageEncoder *encoder, uint16_t type, const MSStunAddress *addr) {
152 encode16(encoder, type);
153 if (addr->family == MS_STUN_ADDR_FAMILY_IPV6) {
154 encode16(encoder, 20);
155 } else {
156 encode16(encoder, 8);
157 }
158 encode8(encoder, 0);
159 encode8(encoder, addr->family);
160 if (addr->family == MS_STUN_ADDR_FAMILY_IPV6) {
161 encode16(encoder, addr->ip.v6.port);
162 encode(encoder, &addr->ip.v6.addr, sizeof(UInt128));
163 } else {
164 encode16(encoder, addr->ip.v4.port);
165 encode32(encoder, addr->ip.v4.addr);
166 }
167 }
168
encode_xor_addr(StunMessageEncoder * encoder,uint16_t type,const MSStunAddress * addr,const UInt96 * tr_id)169 static void encode_xor_addr(StunMessageEncoder *encoder, uint16_t type, const MSStunAddress *addr, const UInt96 *tr_id) {
170 MSStunAddress xor_addr = *addr;
171 stun_address_xor(&xor_addr, tr_id);
172 encode_addr(encoder, type, &xor_addr);
173 }
174
encode_change_request(StunMessageEncoder * encoder,uint32_t data)175 static void encode_change_request(StunMessageEncoder *encoder, uint32_t data) {
176 encode16(encoder, MS_STUN_ATTR_CHANGE_REQUEST);
177 encode16(encoder, 4);
178 encode32(encoder, data);
179 }
180
encode_string(StunMessageEncoder * encoder,uint16_t type,const char * data,uint16_t max_length)181 static void encode_string(StunMessageEncoder *encoder, uint16_t type, const char *data, uint16_t max_length) {
182 size_t len = strlen(data);
183 size_t padding;
184
185 if (len > max_length) {
186 len = max_length;
187 ms_warning("STUN encoded string truncated");
188 }
189 padding = 4 - (len % 4);
190 encode16(encoder, type);
191 encode16(encoder, (uint16_t)len);
192 encode(encoder, data, len);
193 if (padding < 4) {
194 size_t i;
195 for (i = 0; i < padding; i++) encode8(encoder, 0);
196 }
197 }
198
encode_error_code(StunMessageEncoder * encoder,uint16_t number,const char * reason)199 static void encode_error_code(StunMessageEncoder *encoder, uint16_t number, const char *reason) {
200 size_t reason_len = 0;
201 size_t padding = 4 - (reason_len % 4);
202 if (reason != NULL) reason_len = strlen(reason);
203 encode16(encoder, MS_STUN_ATTR_ERROR_CODE);
204 encode16(encoder, 4 + (uint16_t)reason_len);
205 encode16(encoder, 0);
206 encode8(encoder, number / 100);
207 encode8(encoder, number - ((number / 100) * 100));
208 if (reason != NULL) encode(encoder, reason, reason_len);
209 if (padding < 4) {
210 size_t i;
211 for (i = 0; i < padding; i++) encode8(encoder, 0);
212 }
213 }
214
encode_priority(StunMessageEncoder * encoder,uint32_t priority)215 static void encode_priority(StunMessageEncoder *encoder, uint32_t priority) {
216 encode16(encoder, MS_ICE_ATTR_PRIORITY);
217 encode16(encoder, 4);
218 encode32(encoder, priority);
219 }
220
encode_use_candidate(StunMessageEncoder * encoder)221 static void encode_use_candidate(StunMessageEncoder *encoder) {
222 encode16(encoder, MS_ICE_ATTR_USE_CANDIDATE);
223 encode16(encoder, 0);
224 }
225
encode_ice_control(StunMessageEncoder * encoder,uint16_t type,uint64_t value)226 static void encode_ice_control(StunMessageEncoder *encoder, uint16_t type, uint64_t value) {
227 encode16(encoder, type);
228 encode16(encoder, 8);
229 encode64(encoder, value);
230 }
231
encode_integrity(StunMessageEncoder * encoder,const char * hmac)232 static void encode_integrity(StunMessageEncoder *encoder, const char *hmac) {
233 encode16(encoder, MS_STUN_ATTR_MESSAGE_INTEGRITY);
234 encode16(encoder, 20);
235 encode(encoder, hmac, 20);
236 }
237
encode_long_term_integrity_from_ha1(StunMessageEncoder * encoder,const char * ha1_text)238 static void encode_long_term_integrity_from_ha1(StunMessageEncoder *encoder, const char *ha1_text) {
239 char *hmac;
240 size_t message_length = stun_message_encoder_get_message_length(encoder);
241 encode_message_length(encoder, message_length - STUN_MESSAGE_HEADER_LENGTH + 24);
242 hmac = ms_stun_calculate_integrity_long_term_from_ha1(encoder->buffer, message_length, ha1_text);
243 encode_integrity(encoder, hmac);
244 ms_free(hmac);
245 }
246
encode_long_term_integrity(StunMessageEncoder * encoder,const char * realm,const char * username,const char * password)247 static void encode_long_term_integrity(StunMessageEncoder *encoder, const char *realm, const char *username, const char *password) {
248 char *hmac;
249 size_t message_length = stun_message_encoder_get_message_length(encoder);
250 encode_message_length(encoder, message_length - STUN_MESSAGE_HEADER_LENGTH + 24);
251 hmac = ms_stun_calculate_integrity_long_term(encoder->buffer, message_length, realm, username, password);
252 encode_integrity(encoder, hmac);
253 ms_free(hmac);
254 }
255
encode_short_term_integrity(StunMessageEncoder * encoder,const char * password,bool_t dummy)256 static void encode_short_term_integrity(StunMessageEncoder *encoder, const char *password, bool_t dummy) {
257 char *hmac;
258 size_t message_length = stun_message_encoder_get_message_length(encoder);
259 encode_message_length(encoder, message_length - STUN_MESSAGE_HEADER_LENGTH + 24);
260 if (dummy) {
261 hmac = ms_strdup("hmac-not-implemented");
262 ms_warning("hmac not implemented by remote, using dummy integrity hash for stun message");
263 } else {
264 hmac = ms_stun_calculate_integrity_short_term(encoder->buffer, message_length, password);
265 }
266 encode_integrity(encoder, hmac);
267 ms_free(hmac);
268 }
269
encode_fingerprint(StunMessageEncoder * encoder)270 static void encode_fingerprint(StunMessageEncoder *encoder) {
271 uint32_t fingerprint;
272 size_t message_length = stun_message_encoder_get_message_length(encoder);
273 encode_message_length(encoder, message_length - STUN_MESSAGE_HEADER_LENGTH + 8);
274 fingerprint = ms_stun_calculate_fingerprint(encoder->buffer, message_length);
275 encode16(encoder, MS_STUN_ATTR_FINGERPRINT);
276 encode16(encoder, 4);
277 fingerprint ^= 0x5354554E;
278 encode32(encoder, fingerprint);
279 }
280
encode_requested_transport(StunMessageEncoder * encoder,uint8_t requested_transport)281 static void encode_requested_transport(StunMessageEncoder *encoder, uint8_t requested_transport) {
282 encode16(encoder, MS_TURN_ATTR_REQUESTED_TRANSPORT);
283 encode16(encoder, 4);
284 encode8(encoder, requested_transport);
285 encode8(encoder, 0);
286 encode16(encoder, 0);
287 }
288
encode_requested_address_family(StunMessageEncoder * encoder,uint8_t family)289 static void encode_requested_address_family(StunMessageEncoder *encoder, uint8_t family) {
290 encode16(encoder, MS_TURN_ATTR_REQUESTED_ADDRESS_FAMILY);
291 encode16(encoder, 4);
292 encode8(encoder, family);
293 encode8(encoder, 0);
294 encode16(encoder, 0);
295 }
296
encode_lifetime(StunMessageEncoder * encoder,uint32_t lifetime)297 static void encode_lifetime(StunMessageEncoder *encoder, uint32_t lifetime) {
298 encode16(encoder, MS_TURN_ATTR_LIFETIME);
299 encode16(encoder, 4);
300 encode32(encoder, lifetime);
301 }
302
encode_channel_number(StunMessageEncoder * encoder,uint16_t channel_number)303 static void encode_channel_number(StunMessageEncoder *encoder, uint16_t channel_number) {
304 encode16(encoder, MS_TURN_ATTR_CHANNEL_NUMBER);
305 encode16(encoder, 4);
306 encode16(encoder, channel_number);
307 encode16(encoder, 0);
308 }
309
encode_data(StunMessageEncoder * encoder,uint8_t * data,uint16_t datalen)310 static void encode_data(StunMessageEncoder *encoder, uint8_t *data, uint16_t datalen) {
311 size_t padding = 4 - (datalen % 4);
312 encode16(encoder, MS_TURN_ATTR_DATA);
313 encode16(encoder, datalen);
314 encode(encoder, data, datalen);
315 if (padding < 4) {
316 size_t i;
317 for (i = 0; i < padding; i++) encode8(encoder, 0);
318 }
319 }
320
321
322 typedef struct {
323 const uint8_t *buffer;
324 const uint8_t *ptr;
325 ssize_t size;
326 ssize_t remaining;
327 bool_t error;
328 } StunMessageDecoder;
329
330
stun_message_decoder_init(StunMessageDecoder * decoder,const uint8_t * buf,ssize_t bufsize)331 static void stun_message_decoder_init(StunMessageDecoder *decoder, const uint8_t *buf, ssize_t bufsize) {
332 decoder->buffer = decoder->ptr = buf;
333 decoder->size = decoder->remaining = bufsize;
334 decoder->error = FALSE;
335 }
336
decode8(StunMessageDecoder * decoder)337 static uint8_t decode8(StunMessageDecoder *decoder) {
338 uint8_t value = *((uint8_t *)decoder->ptr);
339 decoder->ptr += sizeof(uint8_t);
340 decoder->remaining -= sizeof(uint8_t);
341 if (decoder->remaining < 0) decoder->error = TRUE;
342 return value;
343 }
344
decode16(StunMessageDecoder * decoder)345 static uint16_t decode16(StunMessageDecoder *decoder) {
346 uint16_t value = ntohs(*((uint16_t *)decoder->ptr));
347 decoder->ptr += sizeof(uint16_t);
348 decoder->remaining -= sizeof(uint16_t);
349 if (decoder->remaining < 0) decoder->error = TRUE;
350 return value;
351 }
352
decode32(StunMessageDecoder * decoder)353 static uint32_t decode32(StunMessageDecoder *decoder) {
354 uint32_t value = ntohl(*((uint32_t *)decoder->ptr));
355 decoder->ptr += sizeof(uint32_t);
356 decoder->remaining -= sizeof(uint32_t);
357 if (decoder->remaining < 0) decoder->error = TRUE;
358 return value;
359 }
360
decode64(StunMessageDecoder * decoder)361 static uint64_t decode64(StunMessageDecoder *decoder) {
362 uint64_t value = ntohq(*((uint64_t *)decoder->ptr));
363 decoder->ptr += sizeof(uint64_t);
364 decoder->remaining -= sizeof(uint64_t);
365 if (decoder->remaining < 0) decoder->error = TRUE;
366 return value;
367 }
368
decode(StunMessageDecoder * decoder,size_t len)369 static const void * decode(StunMessageDecoder *decoder, size_t len) {
370 const void *value = decoder->ptr;
371 decoder->ptr += len;
372 decoder->remaining -= (ssize_t)len;
373 if (decoder->remaining < 0) decoder->error = TRUE;
374 return value;
375 }
376
decode_message_header(StunMessageDecoder * decoder,MSStunMessage * msg)377 static void decode_message_header(StunMessageDecoder *decoder, MSStunMessage *msg) {
378 uint16_t type = decode16(decoder);
379 uint32_t magic_cookie;
380 UInt96 *tr_id;
381
382 msg->type = type & 0x0110;
383 msg->method = type & 0x3EEF;
384 msg->length = decode16(decoder);
385 magic_cookie = decode32(decoder);
386 if (magic_cookie != MS_STUN_MAGIC_COOKIE) {
387 ms_warning("STUN magic cookie is incorrect");
388 decoder->error = TRUE;
389 return;
390 }
391 tr_id = (UInt96 *)decode(decoder, sizeof(UInt96));
392 ms_stun_message_set_tr_id(msg, *tr_id);
393 }
394
decode_attribute_header(StunMessageDecoder * decoder,uint16_t * type,uint16_t * length)395 static void decode_attribute_header(StunMessageDecoder *decoder, uint16_t *type ,uint16_t *length) {
396 *type = decode16(decoder);
397 *length = decode16(decoder);
398 }
399
decode_addr(StunMessageDecoder * decoder,uint16_t length)400 static MSStunAddress decode_addr(StunMessageDecoder *decoder, uint16_t length) {
401 MSStunAddress stun_addr;
402
403 memset(&stun_addr, 0, sizeof(stun_addr));
404 if ((length != 8) && (length != 20)) {
405 ms_warning("STUN address attribute with wrong length");
406 decoder->error = TRUE;
407 goto error;
408 }
409
410 decode8(decoder);
411 stun_addr.family = decode8(decoder);
412 if (stun_addr.family == MS_STUN_ADDR_FAMILY_IPV6) {
413 stun_addr.ip.v6.port = decode16(decoder);
414 memcpy(&stun_addr.ip.v6.addr, decode(decoder, sizeof(UInt128)), sizeof(UInt128));
415 } else {
416 stun_addr.ip.v4.port = decode16(decoder);
417 stun_addr.ip.v4.addr = decode32(decoder);
418 }
419
420 error:
421 return stun_addr;
422 }
423
decode_xor_addr(StunMessageDecoder * decoder,uint16_t length,UInt96 tr_id)424 static MSStunAddress decode_xor_addr(StunMessageDecoder *decoder, uint16_t length, UInt96 tr_id) {
425 MSStunAddress stun_addr = decode_addr(decoder, length);
426 stun_address_xor(&stun_addr, &tr_id);
427 return stun_addr;
428 }
429
decode_change_request(StunMessageDecoder * decoder,uint16_t length)430 static uint32_t decode_change_request(StunMessageDecoder *decoder, uint16_t length) {
431 if (length != 4) {
432 ms_warning("STUN change address attribute with wrong length");
433 decoder->error = TRUE;
434 return 0;
435 }
436 return decode32(decoder);
437 }
438
decode_string(StunMessageDecoder * decoder,uint16_t length,uint16_t max_length)439 static char * decode_string(StunMessageDecoder *decoder, uint16_t length, uint16_t max_length) {
440 char *str;
441
442 if (length > max_length) {
443 ms_warning("STUN string attribute too long");
444 decoder->error = TRUE;
445 return NULL;
446 }
447 str = ms_malloc(length + 1);
448 memcpy(str, decoder->ptr, length);
449 str[length] = '\0';
450 decoder->ptr += length;
451 decoder->remaining -= length;
452 if (decoder->remaining < 0) decoder->error = TRUE;
453 return str;
454 }
455
decode_error_code(StunMessageDecoder * decoder,uint16_t length,char ** reason)456 static uint16_t decode_error_code(StunMessageDecoder *decoder, uint16_t length, char **reason) {
457 uint16_t number;
458 uint16_t reason_length;
459 uint8_t clazz;
460 uint8_t code;
461
462 if ((length < 4) || (length > (STUN_MAX_REASON_LENGTH + 4))) {
463 ms_warning("STUN error code attribute with wrong length");
464 decoder->error = TRUE;
465 return 0;
466 }
467
468 reason_length = length - 4;
469 decode16(decoder);
470 clazz = decode8(decoder);
471 code = decode8(decoder);
472 number = clazz * 100 + code;
473 if (reason_length > 0) {
474 *reason = ms_malloc(reason_length + 1);
475 memcpy(*reason, decode(decoder, reason_length), reason_length);
476 (*reason)[reason_length] = '\0';
477 }
478 return number;
479 }
480
decode_message_integrity(StunMessageDecoder * decoder,uint16_t length)481 static char * decode_message_integrity(StunMessageDecoder *decoder, uint16_t length) {
482 char *hmac;
483
484 if (length != 20) {
485 ms_warning("STUN message integrity attribute with wrong length");
486 decoder->error = TRUE;
487 return NULL;
488 }
489 hmac = ms_malloc(21);
490 memcpy(hmac, decode(decoder, 20), 20);
491 hmac[20] = '\0';
492 return hmac;
493 }
494
decode_fingerprint(StunMessageDecoder * decoder,uint16_t length)495 static uint32_t decode_fingerprint(StunMessageDecoder *decoder, uint16_t length) {
496 if (length != 4) {
497 ms_warning("STUN fingerprint attribute with wrong length");
498 decoder->error = TRUE;
499 return 0;
500 }
501 return decode32(decoder);
502 }
503
decode_priority(StunMessageDecoder * decoder,uint16_t length)504 static uint32_t decode_priority(StunMessageDecoder *decoder, uint16_t length) {
505 if (length != 4) {
506 ms_warning("STUN priority attribute with wrong length");
507 decoder->error = TRUE;
508 return 0;
509 }
510 return decode32(decoder);
511 }
512
decode_ice_control(StunMessageDecoder * decoder,uint16_t length)513 static uint64_t decode_ice_control(StunMessageDecoder *decoder, uint16_t length) {
514 if (length != 8) {
515 ms_warning("STUN ice-controlled/ice-controlling attribute with wrong length");
516 decoder->error = TRUE;
517 return 0;
518 }
519 return decode64(decoder);
520 }
521
decode_lifetime(StunMessageDecoder * decoder,uint16_t length)522 static uint32_t decode_lifetime(StunMessageDecoder *decoder, uint16_t length) {
523 if (length != 4) {
524 ms_warning("STUN lifetime attribute with wrong length");
525 decoder->error = TRUE;
526 return 0;
527 }
528 return decode32(decoder);
529 }
530
decode_data(StunMessageDecoder * decoder,uint16_t length)531 static uint8_t * decode_data(StunMessageDecoder *decoder, uint16_t length) {
532 uint8_t *data = ms_malloc(length);
533 memcpy(data, decode(decoder, length), length);
534 return data;
535 }
536
537
ms_stun_address_set_port(MSStunAddress * addr,uint16_t port)538 static void ms_stun_address_set_port(MSStunAddress *addr, uint16_t port) {
539 if (addr->family == MS_STUN_ADDR_FAMILY_IPV4) {
540 addr->ip.v4.port = port;
541 } else if (addr->family == MS_STUN_ADDR_FAMILY_IPV6) {
542 addr->ip.v6.port = port;
543 }
544 }
545
ms_compare_stun_addresses(const MSStunAddress * a1,const MSStunAddress * a2)546 bool_t ms_compare_stun_addresses(const MSStunAddress *a1, const MSStunAddress *a2) {
547 if (a1->family != a2->family) return TRUE;
548 if (a1->family == MS_STUN_ADDR_FAMILY_IPV4) {
549 return !((a1->ip.v4.port == a2->ip.v4.port)
550 && (a1->ip.v4.addr == a2->ip.v4.addr));
551 } else if (a1->family == MS_STUN_ADDR_FAMILY_IPV6) {
552 return !((a1->ip.v6.port == a2->ip.v6.port)
553 && (memcmp(&a1->ip.v6.addr, &a2->ip.v6.addr, sizeof(UInt128)) == 0));
554 }
555 return TRUE;
556 }
557
ms_stun_family_to_af(int stun_family)558 int ms_stun_family_to_af(int stun_family) {
559 if (stun_family == MS_STUN_ADDR_FAMILY_IPV4) return AF_INET;
560 else if (stun_family == MS_STUN_ADDR_FAMILY_IPV6) return AF_INET6;
561 else return 0;
562 }
563
ms_stun_address_to_sockaddr(const MSStunAddress * stun_addr,struct sockaddr * addr,socklen_t * addrlen)564 void ms_stun_address_to_sockaddr(const MSStunAddress *stun_addr, struct sockaddr *addr, socklen_t *addrlen) {
565 if (stun_addr->family == MS_STUN_ADDR_FAMILY_IPV4) {
566 struct sockaddr_in *addr_in = (struct sockaddr_in *)addr;
567 addr_in->sin_family = AF_INET;
568 addr_in->sin_port = htons(stun_addr->ip.v4.port);
569 addr_in->sin_addr.s_addr = htonl(stun_addr->ip.v4.addr);
570 *addrlen = sizeof(struct sockaddr_in);
571 } else if (stun_addr->family == MS_STUN_ADDR_FAMILY_IPV6) {
572 struct sockaddr_in6 *addr_in6 = (struct sockaddr_in6 *)addr;
573 addr_in6->sin6_family = AF_INET6;
574 addr_in6->sin6_port = htons(stun_addr->ip.v6.port);
575 memcpy(addr_in6->sin6_addr.s6_addr, &stun_addr->ip.v6.addr, sizeof(UInt128));
576 *addrlen = sizeof(struct sockaddr_in6);
577 } else {
578 memset(addr, 0, *addrlen);
579 }
580 }
581
ms_sockaddr_to_stun_address(const struct sockaddr * addr,MSStunAddress * stun_addr)582 void ms_sockaddr_to_stun_address(const struct sockaddr *addr, MSStunAddress *stun_addr) {
583 if (addr->sa_family == AF_INET) {
584 stun_addr->family = MS_STUN_ADDR_FAMILY_IPV4;
585 stun_addr->ip.v4.port = ntohs(((const struct sockaddr_in *)addr)->sin_port);
586 stun_addr->ip.v4.addr = ntohl(((const struct sockaddr_in *)addr)->sin_addr.s_addr);
587 } else if (addr->sa_family == AF_INET6) {
588 stun_addr->family = MS_STUN_ADDR_FAMILY_IPV6;
589 stun_addr->ip.v6.port = ntohs(((const struct sockaddr_in6 *)addr)->sin6_port);
590 memcpy(&stun_addr->ip.v6.addr, ((const struct sockaddr_in6 *)addr)->sin6_addr.s6_addr, sizeof(UInt128));
591 } else {
592 memset(stun_addr, 0, sizeof(MSStunAddress));
593 }
594 }
595
ms_ip_address_to_stun_address(int ai_family,int socktype,const char * hostname,int port)596 MSStunAddress ms_ip_address_to_stun_address(int ai_family, int socktype, const char *hostname, int port) {
597 MSStunAddress stun_addr;
598 struct addrinfo *res = bctbx_ip_address_to_addrinfo(ai_family, socktype, hostname, port);
599 memset(&stun_addr, 0, sizeof(stun_addr));
600 if (res){
601 ms_sockaddr_to_stun_address(res->ai_addr, &stun_addr);
602 bctbx_freeaddrinfo(res);
603 }
604 return stun_addr;
605 }
606
ms_stun_address_to_ip_address(const MSStunAddress * stun_address,char * ip,size_t ip_size,int * port)607 void ms_stun_address_to_ip_address(const MSStunAddress *stun_address, char *ip, size_t ip_size, int *port) {
608 struct sockaddr_storage addr;
609 socklen_t addrlen = sizeof(addr);
610 memset(&addr, 0, addrlen);
611 ms_stun_address_to_sockaddr(stun_address, (struct sockaddr *)&addr, &addrlen);
612 bctbx_sockaddr_to_ip_address((struct sockaddr *)&addr, addrlen, ip, ip_size, port);
613 }
614
ms_stun_address_to_printable_ip_address(const MSStunAddress * stun_address,char * printable_ip,size_t printable_ip_size)615 void ms_stun_address_to_printable_ip_address(const MSStunAddress *stun_address, char *printable_ip, size_t printable_ip_size) {
616 struct sockaddr_storage addr;
617 socklen_t addrlen = sizeof(addr);
618 memset(&addr, 0, addrlen);
619 ms_stun_address_to_sockaddr(stun_address, (struct sockaddr *)&addr, &addrlen);
620 bctbx_sockaddr_to_printable_ip_address((struct sockaddr *)&addr, addrlen, printable_ip, printable_ip_size);
621 }
622
ms_stun_calculate_integrity_short_term(const char * buf,size_t bufsize,const char * key)623 char * ms_stun_calculate_integrity_short_term(const char *buf, size_t bufsize, const char *key) {
624 char *hmac = ms_malloc(21);
625 memset(hmac, 0, 21);
626 /* SHA1 output length is 20 bytes, get them all */
627 bctbx_hmacSha1((const unsigned char *)key, strlen(key), (const unsigned char *)buf, bufsize, 20, (unsigned char *)hmac);
628 return hmac;
629 }
630
ms_stun_calculate_integrity_long_term_from_ha1(const char * buf,size_t bufsize,const char * ha1_text)631 char * ms_stun_calculate_integrity_long_term_from_ha1(const char *buf, size_t bufsize, const char *ha1_text) {
632 unsigned char ha1[16];
633 unsigned int i, j;
634 char *hmac = ms_malloc(21);
635 memset(hmac, 0, 21);
636 memset(ha1, 0, sizeof(ha1));
637 for (i = 0, j = 0; (i < strlen(ha1_text)) && (j < sizeof(ha1)); i += 2, j++) {
638 char buf[5] = { '0', 'x', ha1_text[i], ha1_text[i + 1], '\0' };
639 ha1[j] = (unsigned char)strtol(buf, NULL, 0);
640 }
641 /* SHA1 output length is 20 bytes, get them all */
642 bctbx_hmacSha1(ha1, sizeof(ha1), (const unsigned char *)buf, bufsize, 20, (unsigned char *)hmac);
643 return hmac;
644 }
645
ms_stun_calculate_integrity_long_term(const char * buf,size_t bufsize,const char * realm,const char * username,const char * password)646 char * ms_stun_calculate_integrity_long_term(const char *buf, size_t bufsize, const char *realm, const char *username, const char *password) {
647 unsigned char ha1[16];
648 char ha1_text[1024];
649 char *hmac = ms_malloc(21);
650 memset(hmac, 0, 21);
651 snprintf(ha1_text, sizeof(ha1_text), "%s:%s:%s", username, realm, password);
652 bctbx_md5((unsigned char *)ha1_text, strlen(ha1_text), ha1);
653 /* SHA1 output length is 20 bytes, get them all */
654 bctbx_hmacSha1(ha1, sizeof(ha1), (const unsigned char *)buf, bufsize, 20, (unsigned char *)hmac);
655 return hmac;
656 }
657
ms_stun_calculate_fingerprint(const char * buf,size_t bufsize)658 uint32_t ms_stun_calculate_fingerprint(const char *buf, size_t bufsize) {
659 /*
660 * COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or
661 * code or tables extracted from it, as desired without restriction.
662 */
663 static uint32_t crc32_tab[] = {
664 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
665 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
666 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
667 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
668 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
669 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
670 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
671 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
672 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
673 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
674 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
675 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
676 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
677 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
678 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
679 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
680 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
681 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
682 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
683 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
684 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
685 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
686 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
687 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
688 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
689 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
690 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
691 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
692 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
693 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
694 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
695 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
696 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
697 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
698 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
699 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
700 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
701 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
702 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
703 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
704 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
705 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
706 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
707 };
708 const uint8_t *p = (uint8_t*)buf;
709 uint32_t crc;
710
711 crc = ~0U;
712 while (bufsize--)
713 crc = crc32_tab[(crc ^ *p++) & 0xFF] ^ (crc >> 8);
714 return crc ^ ~0U;
715 }
716
717
ms_stun_message_create(uint16_t type,uint16_t method)718 MSStunMessage * ms_stun_message_create(uint16_t type, uint16_t method) {
719 MSStunMessage *msg = ms_new0(MSStunMessage, 1);
720 msg->type = type;
721 msg->method = method;
722 ms_stun_message_set_random_tr_id(msg);
723 return msg;
724 }
725
ms_stun_message_create_from_buffer_parsing(const uint8_t * buf,ssize_t bufsize)726 MSStunMessage * ms_stun_message_create_from_buffer_parsing(const uint8_t *buf, ssize_t bufsize) {
727 StunMessageDecoder decoder;
728 MSStunMessage *msg = NULL;
729
730 if (bufsize < STUN_MESSAGE_HEADER_LENGTH) {
731 ms_warning("STUN message too short!");
732 goto error;
733 }
734
735 msg = ms_new0(MSStunMessage, 1);
736 stun_message_decoder_init(&decoder, buf, bufsize);
737 decode_message_header(&decoder, msg);
738 if (decoder.error) goto error;
739 if ((ms_stun_message_get_length(msg) + STUN_MESSAGE_HEADER_LENGTH) != bufsize) {
740 ms_warning("STUN message header length does not match message size: %i - %zd",
741 ms_stun_message_get_length(msg), bufsize);
742 goto error;
743 }
744
745 while (decoder.remaining > 0) {
746 size_t padding;
747 uint16_t type;
748 uint16_t length;
749
750 decode_attribute_header(&decoder, &type, &length);
751 if (length > decoder.remaining) {
752 ms_error("STUN attribute larger than message (attribute type: 0x%4x)", type);
753 decoder.error = TRUE;
754 }
755 if (decoder.error) goto error;
756 switch (type) {
757 case MS_STUN_ATTR_MAPPED_ADDRESS:
758 ms_stun_message_set_mapped_address(msg, decode_addr(&decoder, length));
759 break;
760 case MS_STUN_ATTR_CHANGE_REQUEST:
761 msg->change_request = decode_change_request(&decoder, length);
762 break;
763 case MS_STUN_ATTR_RESPONSE_ADDRESS:
764 case MS_STUN_ATTR_SOURCE_ADDRESS:
765 case MS_STUN_ATTR_CHANGED_ADDRESS:
766 /* Ignore these deprecated attributes. */
767 decode_addr(&decoder, length);
768 break;
769 case MS_STUN_ATTR_USERNAME:
770 {
771 char *username = decode_string(&decoder, length, STUN_MAX_USERNAME_LENGTH);
772 ms_stun_message_set_username(msg, username);
773 if (username != NULL) ms_free(username);
774 }
775 break;
776 case MS_STUN_ATTR_PASSWORD:
777 /* Ignore this deprecated attribute. */
778 {
779 char *password = decode_string(&decoder, length, STUN_MAX_USERNAME_LENGTH);
780 if (password != NULL) ms_free(password);
781 }
782 break;
783 case MS_STUN_ATTR_MESSAGE_INTEGRITY:
784 msg->message_integrity = decode_message_integrity(&decoder, length);
785 msg->has_message_integrity = TRUE;
786 if (strcmp(ms_stun_message_get_message_integrity(msg), "hmac-not-implemented") == 0) msg->has_dummy_message_integrity = TRUE;
787 break;
788 case MS_STUN_ATTR_ERROR_CODE:
789 {
790 char *reason = NULL;
791 uint16_t number = decode_error_code(&decoder, length, &reason);
792 ms_stun_message_set_error_code(msg, number, reason);
793 if (reason != NULL) ms_free(reason);
794 }
795 break;
796 case MS_STUN_ATTR_XOR_MAPPED_ADDRESS:
797 {
798 MSStunAddress stun_addr = decode_xor_addr(&decoder, length, ms_stun_message_get_tr_id(msg));
799 ms_stun_message_set_xor_mapped_address(msg, stun_addr);
800 }
801 break;
802 case MS_STUN_ATTR_SOFTWARE:
803 {
804 char *software = decode_string(&decoder, length, STUN_MAX_SOFTWARE_LENGTH);
805 ms_stun_message_set_software(msg, software);
806 if (software != NULL) ms_free(software);
807 }
808 break;
809 case MS_STUN_ATTR_FINGERPRINT:
810 msg->fingerprint = decode_fingerprint(&decoder, length);
811 msg->has_fingerprint = TRUE;
812 break;
813 case MS_ICE_ATTR_PRIORITY:
814 ms_stun_message_set_priority(msg, decode_priority(&decoder, length));
815 break;
816 case MS_ICE_ATTR_USE_CANDIDATE:
817 ms_stun_message_enable_use_candidate(msg, TRUE);
818 break;
819 case MS_ICE_ATTR_ICE_CONTROLLED:
820 ms_stun_message_set_ice_controlled(msg, decode_ice_control(&decoder, length));
821 break;
822 case MS_ICE_ATTR_ICE_CONTROLLING:
823 ms_stun_message_set_ice_controlling(msg, decode_ice_control(&decoder, length));
824 break;
825 case MS_TURN_ATTR_XOR_PEER_ADDRESS:
826 {
827 MSStunAddress stun_addr = decode_xor_addr(&decoder, length, ms_stun_message_get_tr_id(msg));
828 ms_stun_message_set_xor_peer_address(msg, stun_addr);
829 }
830 break;
831 case MS_TURN_ATTR_XOR_RELAYED_ADDRESS:
832 {
833 MSStunAddress stun_addr = decode_xor_addr(&decoder, length, ms_stun_message_get_tr_id(msg));
834 ms_stun_message_set_xor_relayed_address(msg, stun_addr);
835 }
836 break;
837 case MS_TURN_ATTR_LIFETIME:
838 ms_stun_message_set_lifetime(msg, decode_lifetime(&decoder, length));
839 break;
840 case MS_TURN_ATTR_DATA:
841 ms_stun_message_set_data(msg, decode_data(&decoder, length), length);
842 break;
843 case MS_STUN_ATTR_REALM:
844 {
845 char *realm = decode_string(&decoder, length, STUN_MAX_REALM_LENGTH);
846 ms_stun_message_set_realm(msg, realm);
847 if (realm != NULL) ms_free(realm);
848 }
849 break;
850 case MS_STUN_ATTR_NONCE:
851 {
852 char *nonce = decode_string(&decoder, length, STUN_MAX_NONCE_LENGTH);
853 ms_stun_message_set_nonce(msg, nonce);
854 if (nonce != NULL) ms_free(nonce);
855 }
856 break;
857 default:
858 if (type <= 0x7FFF) {
859 ms_error("STUN unknown Comprehension-Required attribute: 0x%04x", type);
860 goto error;
861 } else {
862 ms_warning("STUN unknown attribute: 0x%04x", type);
863 decode(&decoder, length);
864 }
865 break;
866 }
867 if (decoder.error) goto error;
868 padding = 4 - (length % 4);
869 if (padding < 4) {
870 size_t i;
871 for (i = 0; i < padding; i++) decode8(&decoder);
872 if (decoder.error) goto error;
873 }
874 }
875
876 return msg;
877
878 error:
879 if (msg != NULL) {
880 ms_free(msg);
881 }
882 return NULL;
883 }
884
ms_stun_binding_request_create(void)885 MSStunMessage * ms_stun_binding_request_create(void) {
886 return ms_stun_message_create(MS_STUN_TYPE_REQUEST, MS_STUN_METHOD_BINDING);
887 }
888
ms_stun_binding_success_response_create(void)889 MSStunMessage * ms_stun_binding_success_response_create(void) {
890 return ms_stun_message_create(MS_STUN_TYPE_SUCCESS_RESPONSE, MS_STUN_METHOD_BINDING);
891 }
892
ms_stun_binding_error_response_create(void)893 MSStunMessage * ms_stun_binding_error_response_create(void) {
894 return ms_stun_message_create(MS_STUN_TYPE_ERROR_RESPONSE, MS_STUN_METHOD_BINDING);
895 }
896
ms_stun_binding_indication_create(void)897 MSStunMessage * ms_stun_binding_indication_create(void) {
898 return ms_stun_message_create(MS_STUN_TYPE_INDICATION, MS_STUN_METHOD_BINDING);
899 }
900
ms_stun_message_is_request(const MSStunMessage * msg)901 bool_t ms_stun_message_is_request(const MSStunMessage *msg) {
902 return (((msg->type) & 0x0110) == MS_STUN_TYPE_REQUEST) ? TRUE : FALSE;
903 }
904
ms_stun_message_is_success_response(const MSStunMessage * msg)905 bool_t ms_stun_message_is_success_response(const MSStunMessage *msg) {
906 return (((msg->type) & 0x0110) == MS_STUN_TYPE_SUCCESS_RESPONSE) ? TRUE : FALSE;
907 }
908
ms_stun_message_is_error_response(const MSStunMessage * msg)909 bool_t ms_stun_message_is_error_response(const MSStunMessage *msg) {
910 return (((msg->type) & 0x0110) == MS_STUN_TYPE_ERROR_RESPONSE) ? TRUE : FALSE;
911 }
912
ms_stun_message_is_indication(const MSStunMessage * msg)913 bool_t ms_stun_message_is_indication(const MSStunMessage *msg) {
914 return (((msg->type) & 0x0110) == MS_STUN_TYPE_INDICATION) ? TRUE : FALSE;
915 }
916
ms_stun_message_destroy(MSStunMessage * msg)917 void ms_stun_message_destroy(MSStunMessage *msg) {
918 if (msg->username) ms_free(msg->username);
919 if (msg->password) {
920 memset(msg->password, '\0', strlen(msg->password));
921 ms_free(msg->password);
922 }
923 if (msg->ha1) ms_free(msg->ha1);
924 if (msg->realm) ms_free(msg->realm);
925 if (msg->nonce) ms_free(msg->nonce);
926 if (msg->message_integrity) ms_free(msg->message_integrity);
927 if (msg->software) ms_free(msg->software);
928 if (msg->error_code.reason) ms_free(msg->error_code.reason);
929 if (msg->data) ms_free(msg->data);
930 ms_free(msg);
931 }
932
ms_stun_message_encode(const MSStunMessage * msg,char ** buf)933 size_t ms_stun_message_encode(const MSStunMessage *msg, char **buf) {
934 StunMessageEncoder encoder;
935 const MSStunAddress *stun_addr;
936 size_t message_length;
937
938 stun_message_encoder_init(&encoder);
939 encode_message_header(&encoder, msg->type, msg->method, &msg->tr_id);
940
941 stun_addr = ms_stun_message_get_mapped_address(msg);
942 if (stun_addr != NULL) encode_addr(&encoder, MS_STUN_ATTR_MAPPED_ADDRESS, stun_addr);
943 if (msg->change_request != 0) encode_change_request(&encoder, msg->change_request);
944 if (msg->username != NULL) encode_string(&encoder, MS_STUN_ATTR_USERNAME, msg->username, STUN_MAX_USERNAME_LENGTH);
945 if (msg->realm != NULL) encode_string(&encoder, MS_STUN_ATTR_REALM, msg->realm, STUN_MAX_REALM_LENGTH);
946 if (msg->nonce != NULL) encode_string(&encoder, MS_STUN_ATTR_NONCE, msg->nonce, STUN_MAX_NONCE_LENGTH);
947 if (ms_stun_message_has_error_code(msg)) {
948 char *reason = NULL;
949 uint16_t number = ms_stun_message_get_error_code(msg, &reason);
950 encode_error_code(&encoder, number, reason);
951 }
952 stun_addr = ms_stun_message_get_xor_mapped_address(msg);
953 if (stun_addr != NULL) encode_xor_addr(&encoder, MS_STUN_ATTR_XOR_MAPPED_ADDRESS, stun_addr, &msg->tr_id);
954
955 stun_addr = ms_stun_message_get_xor_peer_address(msg);
956 if (stun_addr != NULL) encode_xor_addr(&encoder, MS_TURN_ATTR_XOR_PEER_ADDRESS, stun_addr, &msg->tr_id);
957 stun_addr = ms_stun_message_get_xor_relayed_address(msg);
958 if (stun_addr != NULL) encode_xor_addr(&encoder, MS_TURN_ATTR_XOR_RELAYED_ADDRESS, stun_addr, &msg->tr_id);
959 if (ms_stun_message_has_requested_transport(msg)) encode_requested_transport(&encoder, ms_stun_message_get_requested_transport(msg));
960 if (ms_stun_message_has_requested_address_family(msg)) encode_requested_address_family(&encoder, ms_stun_message_get_requested_address_family(msg));
961 if (ms_stun_message_has_lifetime(msg)) encode_lifetime(&encoder, ms_stun_message_get_lifetime(msg));
962 if (ms_stun_message_has_channel_number(msg)) encode_channel_number(&encoder, ms_stun_message_get_channel_number(msg));
963 if ((ms_stun_message_get_data(msg) != NULL) && (ms_stun_message_get_data_length(msg) > 0))
964 encode_data(&encoder, ms_stun_message_get_data(msg), ms_stun_message_get_data_length(msg));
965
966 if (ms_stun_message_has_priority(msg)) encode_priority(&encoder, ms_stun_message_get_priority(msg));
967 if (ms_stun_message_use_candidate_enabled(msg)) encode_use_candidate(&encoder);
968 if (ms_stun_message_has_ice_controlled(msg))
969 encode_ice_control(&encoder, MS_ICE_ATTR_ICE_CONTROLLED, ms_stun_message_get_ice_controlled(msg));
970 if (ms_stun_message_has_ice_controlling(msg))
971 encode_ice_control(&encoder, MS_ICE_ATTR_ICE_CONTROLLING, ms_stun_message_get_ice_controlling(msg));
972 if (ms_stun_message_message_integrity_enabled(msg)) {
973 const char *username = ms_stun_message_get_username(msg);
974 const char *password = ms_stun_message_get_password(msg);
975 if (msg->ha1 != NULL) {
976 encode_long_term_integrity_from_ha1(&encoder, msg->ha1);
977 } else if ((username != NULL) && (password != NULL) && (strlen(username) > 0) && (strlen(password) > 0)) {
978 const char *realm = ms_stun_message_get_realm(msg);
979 if ((realm != NULL) && (strlen(realm) > 0)) {
980 encode_long_term_integrity(&encoder, realm, username, password);
981 } else {
982 encode_short_term_integrity(&encoder, password, ms_stun_message_dummy_message_integrity_enabled(msg));
983 }
984 }
985 }
986 if (ms_stun_message_fingerprint_enabled(msg)) encode_fingerprint(&encoder);
987
988 message_length = stun_message_encoder_get_message_length(&encoder);
989 encode_message_length(&encoder, message_length - STUN_MESSAGE_HEADER_LENGTH);
990 *buf = encoder.buffer;
991 return message_length;
992 }
993
ms_stun_message_get_method(const MSStunMessage * msg)994 uint16_t ms_stun_message_get_method(const MSStunMessage *msg) {
995 return msg->method;
996 }
997
ms_stun_message_get_length(const MSStunMessage * msg)998 uint16_t ms_stun_message_get_length(const MSStunMessage *msg) {
999 return msg->length;
1000 }
1001
ms_stun_message_get_tr_id(const MSStunMessage * msg)1002 UInt96 ms_stun_message_get_tr_id(const MSStunMessage *msg) {
1003 return msg->tr_id;
1004 }
1005
ms_stun_message_set_tr_id(MSStunMessage * msg,UInt96 tr_id)1006 void ms_stun_message_set_tr_id(MSStunMessage *msg, UInt96 tr_id) {
1007 msg->tr_id = tr_id;
1008 }
1009
ms_stun_message_set_random_tr_id(MSStunMessage * msg)1010 void ms_stun_message_set_random_tr_id(MSStunMessage *msg) {
1011 UInt96 tr_id;
1012 int i;
1013
1014 for (i = 0; i < 12; i += 4) {
1015 unsigned int r = ortp_random();
1016 tr_id.octet[i + 0] = r >> 0;
1017 tr_id.octet[i + 1] = r >> 8;
1018 tr_id.octet[i + 2] = r >> 16;
1019 tr_id.octet[i + 3] = r >> 24;
1020 }
1021 ms_stun_message_set_tr_id(msg, tr_id);
1022 }
1023
ms_stun_message_get_username(const MSStunMessage * msg)1024 const char * ms_stun_message_get_username(const MSStunMessage *msg) {
1025 return msg->username;
1026 }
1027
ms_stun_message_set_username(MSStunMessage * msg,const char * username)1028 void ms_stun_message_set_username(MSStunMessage *msg, const char *username) {
1029 STUN_STR_SETTER(msg->username, username);
1030 msg->include_username_attribute = TRUE;
1031 }
1032
ms_stun_message_include_username_attribute(MSStunMessage * msg,bool_t include)1033 void ms_stun_message_include_username_attribute(MSStunMessage *msg, bool_t include) {
1034 msg->include_username_attribute = include;
1035 }
1036
ms_stun_message_get_password(const MSStunMessage * msg)1037 const char * ms_stun_message_get_password(const MSStunMessage *msg) {
1038 return msg->password;
1039 }
1040
ms_stun_message_set_password(MSStunMessage * msg,const char * password)1041 void ms_stun_message_set_password(MSStunMessage *msg, const char *password) {
1042 STUN_STR_SETTER(msg->password, password);
1043 }
1044
ms_stun_message_set_ha1(MSStunMessage * msg,const char * ha1)1045 void ms_stun_message_set_ha1(MSStunMessage *msg, const char *ha1) {
1046 STUN_STR_SETTER(msg->ha1, ha1);
1047 }
1048
ms_stun_message_get_realm(const MSStunMessage * msg)1049 const char * ms_stun_message_get_realm(const MSStunMessage *msg) {
1050 return msg->realm;
1051 }
1052
ms_stun_message_set_realm(MSStunMessage * msg,const char * realm)1053 void ms_stun_message_set_realm(MSStunMessage *msg, const char *realm) {
1054 STUN_STR_SETTER(msg->realm, realm);
1055 }
1056
ms_stun_message_get_software(const MSStunMessage * msg)1057 const char * ms_stun_message_get_software(const MSStunMessage *msg) {
1058 return msg->software;
1059 }
1060
ms_stun_message_set_software(MSStunMessage * msg,const char * software)1061 void ms_stun_message_set_software(MSStunMessage *msg, const char *software) {
1062 STUN_STR_SETTER(msg->software, software);
1063 }
1064
ms_stun_message_get_nonce(const MSStunMessage * msg)1065 const char * ms_stun_message_get_nonce(const MSStunMessage *msg) {
1066 return msg->nonce;
1067 }
1068
ms_stun_message_set_nonce(MSStunMessage * msg,const char * nonce)1069 void ms_stun_message_set_nonce(MSStunMessage *msg, const char *nonce) {
1070 STUN_STR_SETTER(msg->nonce, nonce);
1071 }
1072
ms_stun_message_has_error_code(const MSStunMessage * msg)1073 bool_t ms_stun_message_has_error_code(const MSStunMessage *msg) {
1074 return msg->has_error_code;
1075 }
1076
ms_stun_message_get_error_code(const MSStunMessage * msg,char ** reason)1077 uint16_t ms_stun_message_get_error_code(const MSStunMessage *msg, char **reason) {
1078 if (reason != NULL) {
1079 *reason = msg->error_code.reason;
1080 }
1081 return msg->error_code.number;
1082 }
1083
ms_stun_message_set_error_code(MSStunMessage * msg,uint16_t number,const char * reason)1084 void ms_stun_message_set_error_code(MSStunMessage *msg, uint16_t number, const char *reason) {
1085 msg->error_code.number = number;
1086 STUN_STR_SETTER(msg->error_code.reason, reason);
1087 msg->has_error_code = TRUE;
1088 }
1089
ms_stun_message_message_integrity_enabled(const MSStunMessage * msg)1090 bool_t ms_stun_message_message_integrity_enabled(const MSStunMessage *msg) {
1091 return msg->has_message_integrity;
1092 }
1093
ms_stun_message_enable_message_integrity(MSStunMessage * msg,bool_t enable)1094 void ms_stun_message_enable_message_integrity(MSStunMessage *msg, bool_t enable) {
1095 msg->has_message_integrity = enable;
1096 }
1097
ms_stun_message_get_message_integrity(const MSStunMessage * msg)1098 const char * ms_stun_message_get_message_integrity(const MSStunMessage *msg) {
1099 return msg->message_integrity;
1100 }
1101
ms_stun_message_fingerprint_enabled(const MSStunMessage * msg)1102 bool_t ms_stun_message_fingerprint_enabled(const MSStunMessage *msg) {
1103 return msg->has_fingerprint;
1104 }
1105
ms_stun_message_enable_fingerprint(MSStunMessage * msg,bool_t enable)1106 void ms_stun_message_enable_fingerprint(MSStunMessage *msg, bool_t enable) {
1107 msg->has_fingerprint = enable;
1108 }
1109
ms_stun_message_get_mapped_address(const MSStunMessage * msg)1110 const MSStunAddress * ms_stun_message_get_mapped_address(const MSStunMessage *msg) {
1111 if (msg->has_mapped_address) return &msg->mapped_address;
1112 return NULL;
1113 }
1114
ms_stun_message_set_mapped_address(MSStunMessage * msg,MSStunAddress mapped_address)1115 void ms_stun_message_set_mapped_address(MSStunMessage *msg, MSStunAddress mapped_address) {
1116 msg->mapped_address = mapped_address;
1117 msg->has_mapped_address = TRUE;
1118 }
1119
ms_stun_message_get_xor_mapped_address(const MSStunMessage * msg)1120 const MSStunAddress * ms_stun_message_get_xor_mapped_address(const MSStunMessage *msg) {
1121 if (msg->has_xor_mapped_address) return &msg->xor_mapped_address;
1122 return NULL;
1123 }
1124
ms_stun_message_set_xor_mapped_address(MSStunMessage * msg,MSStunAddress xor_mapped_address)1125 void ms_stun_message_set_xor_mapped_address(MSStunMessage *msg, MSStunAddress xor_mapped_address) {
1126 msg->xor_mapped_address = xor_mapped_address;
1127 msg->has_xor_mapped_address = TRUE;
1128 }
1129
ms_stun_message_get_xor_peer_address(const MSStunMessage * msg)1130 const MSStunAddress * ms_stun_message_get_xor_peer_address(const MSStunMessage *msg) {
1131 if (msg->has_xor_peer_address) return &msg->xor_peer_address;
1132 return NULL;
1133 }
1134
ms_stun_message_set_xor_peer_address(MSStunMessage * msg,MSStunAddress xor_peer_address)1135 void ms_stun_message_set_xor_peer_address(MSStunMessage *msg, MSStunAddress xor_peer_address) {
1136 msg->xor_peer_address = xor_peer_address;
1137 msg->has_xor_peer_address = TRUE;
1138 }
1139
ms_stun_message_get_xor_relayed_address(const MSStunMessage * msg)1140 const MSStunAddress * ms_stun_message_get_xor_relayed_address(const MSStunMessage *msg) {
1141 if (msg->has_xor_relayed_address) return &msg->xor_relayed_address;
1142 return NULL;
1143 }
1144
ms_stun_message_set_xor_relayed_address(MSStunMessage * msg,MSStunAddress xor_relayed_address)1145 void ms_stun_message_set_xor_relayed_address(MSStunMessage *msg, MSStunAddress xor_relayed_address) {
1146 msg->xor_relayed_address = xor_relayed_address;
1147 msg->has_xor_relayed_address = TRUE;
1148 }
1149
ms_stun_message_enable_change_ip(MSStunMessage * msg,bool_t enable)1150 void ms_stun_message_enable_change_ip(MSStunMessage *msg, bool_t enable) {
1151 if (enable) msg->change_request |= STUN_FLAG_CHANGE_IP;
1152 else {
1153 uint32_t mask = STUN_FLAG_CHANGE_IP;
1154 msg->change_request &= ~mask;
1155 }
1156 }
1157
ms_stun_message_enable_change_port(MSStunMessage * msg,bool_t enable)1158 void ms_stun_message_enable_change_port(MSStunMessage *msg, bool_t enable) {
1159 if (enable) msg->change_request |= STUN_FLAG_CHANGE_PORT;
1160 else {
1161 uint32_t mask = STUN_FLAG_CHANGE_PORT;
1162 msg->change_request &= ~mask;
1163 }
1164 }
1165
ms_stun_message_has_priority(const MSStunMessage * msg)1166 bool_t ms_stun_message_has_priority(const MSStunMessage *msg) {
1167 return msg->has_priority;
1168 }
1169
ms_stun_message_get_priority(const MSStunMessage * msg)1170 uint32_t ms_stun_message_get_priority(const MSStunMessage *msg) {
1171 return msg->priority;
1172 }
1173
ms_stun_message_set_priority(MSStunMessage * msg,uint32_t priority)1174 void ms_stun_message_set_priority(MSStunMessage *msg, uint32_t priority) {
1175 msg->priority = priority;
1176 msg->has_priority = TRUE;
1177 }
1178
ms_stun_message_use_candidate_enabled(const MSStunMessage * msg)1179 bool_t ms_stun_message_use_candidate_enabled(const MSStunMessage *msg) {
1180 return msg->has_use_candidate;
1181 }
1182
ms_stun_message_enable_use_candidate(MSStunMessage * msg,bool_t enable)1183 void ms_stun_message_enable_use_candidate(MSStunMessage *msg, bool_t enable) {
1184 msg->has_use_candidate = enable;
1185 }
1186
ms_stun_message_has_ice_controlling(const MSStunMessage * msg)1187 bool_t ms_stun_message_has_ice_controlling(const MSStunMessage *msg) {
1188 return msg->has_ice_controlling;
1189 }
1190
ms_stun_message_get_ice_controlling(const MSStunMessage * msg)1191 uint64_t ms_stun_message_get_ice_controlling(const MSStunMessage *msg) {
1192 return msg->ice_controlling;
1193 }
1194
ms_stun_message_set_ice_controlling(MSStunMessage * msg,uint64_t value)1195 void ms_stun_message_set_ice_controlling(MSStunMessage *msg, uint64_t value) {
1196 msg->ice_controlling = value;
1197 msg->has_ice_controlling = TRUE;
1198 }
1199
ms_stun_message_has_ice_controlled(const MSStunMessage * msg)1200 bool_t ms_stun_message_has_ice_controlled(const MSStunMessage *msg) {
1201 return msg->has_ice_controlled;
1202 }
1203
ms_stun_message_get_ice_controlled(const MSStunMessage * msg)1204 uint64_t ms_stun_message_get_ice_controlled(const MSStunMessage *msg) {
1205 return msg->ice_controlled;
1206 }
1207
ms_stun_message_set_ice_controlled(MSStunMessage * msg,uint64_t value)1208 void ms_stun_message_set_ice_controlled(MSStunMessage *msg, uint64_t value) {
1209 msg->ice_controlled = value;
1210 msg->has_ice_controlled = TRUE;
1211 }
1212
ms_stun_message_dummy_message_integrity_enabled(const MSStunMessage * msg)1213 bool_t ms_stun_message_dummy_message_integrity_enabled(const MSStunMessage *msg) {
1214 return msg->has_dummy_message_integrity;
1215 }
1216
ms_stun_message_enable_dummy_message_integrity(MSStunMessage * msg,bool_t enable)1217 void ms_stun_message_enable_dummy_message_integrity(MSStunMessage *msg, bool_t enable) {
1218 msg->has_dummy_message_integrity = enable;
1219 }
1220
ms_turn_allocate_request_create(void)1221 MSStunMessage * ms_turn_allocate_request_create(void) {
1222 MSStunMessage *msg = ms_stun_message_create(MS_STUN_TYPE_REQUEST, MS_TURN_METHOD_ALLOCATE);
1223 msg->requested_transport = IANA_PROTOCOL_NUMBERS_UDP;
1224 msg->has_requested_transport = TRUE;
1225 return msg;
1226 }
1227
ms_turn_refresh_request_create(uint32_t lifetime)1228 MSStunMessage * ms_turn_refresh_request_create(uint32_t lifetime) {
1229 MSStunMessage *msg = ms_stun_message_create(MS_STUN_TYPE_REQUEST, MS_TURN_METHOD_REFRESH);
1230 ms_stun_message_set_lifetime(msg, lifetime);
1231 return msg;
1232 }
1233
ms_turn_create_permission_request_create(MSStunAddress peer_address)1234 MSStunMessage * ms_turn_create_permission_request_create(MSStunAddress peer_address) {
1235 MSStunMessage *msg = ms_stun_message_create(MS_STUN_TYPE_REQUEST, MS_TURN_METHOD_CREATE_PERMISSION);
1236 ms_stun_message_set_xor_peer_address(msg, peer_address);
1237 return msg;
1238 }
1239
ms_turn_send_indication_create(MSStunAddress peer_address)1240 MSStunMessage * ms_turn_send_indication_create(MSStunAddress peer_address) {
1241 MSStunMessage *msg = ms_stun_message_create(MS_STUN_TYPE_INDICATION, MS_TURN_METHOD_SEND);
1242 ms_stun_message_set_xor_peer_address(msg, peer_address);
1243 return msg;
1244 }
1245
ms_turn_channel_bind_request_create(MSStunAddress peer_address,uint16_t channel_number)1246 MSStunMessage * ms_turn_channel_bind_request_create(MSStunAddress peer_address, uint16_t channel_number) {
1247 MSStunMessage *msg = ms_stun_message_create(MS_STUN_TYPE_REQUEST, MS_TURN_METHOD_CHANNEL_BIND);
1248 ms_stun_message_set_xor_peer_address(msg, peer_address);
1249 ms_stun_message_set_channel_number(msg, channel_number);
1250 return msg;
1251 }
1252
ms_stun_message_has_requested_transport(const MSStunMessage * msg)1253 bool_t ms_stun_message_has_requested_transport(const MSStunMessage *msg) {
1254 return msg->has_requested_transport;
1255 }
1256
ms_stun_message_get_requested_transport(const MSStunMessage * msg)1257 uint8_t ms_stun_message_get_requested_transport(const MSStunMessage *msg) {
1258 return msg->requested_transport;
1259 }
1260
ms_stun_message_has_requested_address_family(const MSStunMessage * msg)1261 bool_t ms_stun_message_has_requested_address_family(const MSStunMessage *msg) {
1262 return msg->has_requested_address_family;
1263 }
1264
ms_stun_message_get_requested_address_family(const MSStunMessage * msg)1265 uint8_t ms_stun_message_get_requested_address_family(const MSStunMessage *msg) {
1266 return msg->requested_address_family;
1267 }
1268
ms_stun_message_set_requested_address_family(MSStunMessage * msg,uint8_t family)1269 void ms_stun_message_set_requested_address_family(MSStunMessage *msg, uint8_t family) {
1270 msg->requested_address_family = family;
1271 msg->has_requested_address_family = TRUE;
1272 }
1273
ms_stun_message_has_lifetime(const MSStunMessage * msg)1274 bool_t ms_stun_message_has_lifetime(const MSStunMessage *msg) {
1275 return msg->has_lifetime;
1276 }
1277
ms_stun_message_get_lifetime(const MSStunMessage * msg)1278 uint32_t ms_stun_message_get_lifetime(const MSStunMessage *msg) {
1279 return msg->lifetime;
1280 }
1281
ms_stun_message_set_lifetime(MSStunMessage * msg,uint32_t lifetime)1282 void ms_stun_message_set_lifetime(MSStunMessage *msg, uint32_t lifetime) {
1283 msg->lifetime = lifetime;
1284 msg->has_lifetime = TRUE;
1285 }
1286
ms_stun_message_has_channel_number(const MSStunMessage * msg)1287 bool_t ms_stun_message_has_channel_number(const MSStunMessage *msg) {
1288 return msg->has_channel_number;
1289 }
1290
ms_stun_message_get_channel_number(const MSStunMessage * msg)1291 uint16_t ms_stun_message_get_channel_number(const MSStunMessage *msg) {
1292 return msg->channel_number;
1293 }
1294
ms_stun_message_set_channel_number(MSStunMessage * msg,uint16_t channel_number)1295 void ms_stun_message_set_channel_number(MSStunMessage *msg, uint16_t channel_number) {
1296 msg->channel_number = channel_number;
1297 msg->has_channel_number = TRUE;
1298 }
1299
ms_stun_message_get_data(const MSStunMessage * msg)1300 uint8_t * ms_stun_message_get_data(const MSStunMessage *msg) {
1301 return msg->data;
1302 }
1303
ms_stun_message_get_data_length(const MSStunMessage * msg)1304 uint16_t ms_stun_message_get_data_length(const MSStunMessage *msg) {
1305 return msg->data_length;
1306 }
1307
ms_stun_message_set_data(MSStunMessage * msg,uint8_t * data,uint16_t length)1308 void ms_stun_message_set_data(MSStunMessage *msg, uint8_t *data, uint16_t length) {
1309 if (msg->data != NULL) {
1310 ms_free(msg->data);
1311 msg->data = NULL;
1312 }
1313 msg->data = data;
1314 msg->data_length = length;
1315 }
1316
1317
ms_turn_context_new(MSTurnContextType type,RtpSession * rtp_session)1318 MSTurnContext * ms_turn_context_new(MSTurnContextType type, RtpSession *rtp_session) {
1319 MSTurnContext *context = ms_new0(MSTurnContext, 1);
1320 context->state = MS_TURN_CONTEXT_STATE_IDLE;
1321 context->type = type;
1322 context->rtp_session = rtp_session;
1323 return context;
1324 }
1325
ms_turn_context_destroy(MSTurnContext * context)1326 void ms_turn_context_destroy(MSTurnContext *context) {
1327 if (context->realm != NULL) ms_free(context->realm);
1328 if (context->nonce != NULL) ms_free(context->nonce);
1329 if (context->username != NULL) ms_free(context->username);
1330 if (context->password != NULL) {
1331 memset(context->password, '\0', strlen(context->password));
1332 ms_free(context->password);
1333 }
1334 if (context->ha1 != NULL) ms_free(context->ha1);
1335 if (context->endpoint != NULL) context->endpoint->data = NULL;
1336 bctbx_list_for_each(context->allowed_peer_addresses, (MSIterateFunc)ms_free);
1337 bctbx_list_free(context->allowed_peer_addresses);
1338 ms_free(context);
1339 }
1340
ms_turn_context_set_server_addr(MSTurnContext * context,struct sockaddr * addr,socklen_t addrlen)1341 void ms_turn_context_set_server_addr(MSTurnContext *context, struct sockaddr *addr, socklen_t addrlen) {
1342 context->turn_server_addr = addr;
1343 context->turn_server_addrlen = addrlen;
1344 }
1345
ms_turn_context_get_state(const MSTurnContext * context)1346 MSTurnContextState ms_turn_context_get_state(const MSTurnContext *context) {
1347 return context->state;
1348 }
1349
ms_turn_context_set_state(MSTurnContext * context,MSTurnContextState state)1350 void ms_turn_context_set_state(MSTurnContext *context, MSTurnContextState state) {
1351 context->state = state;
1352 if (state == MS_TURN_CONTEXT_STATE_ALLOCATION_CREATED) context->stats.nb_successful_allocate++;
1353 else if (state == MS_TURN_CONTEXT_STATE_CHANNEL_BOUND) context->stats.nb_successful_channel_bind++;
1354 }
1355
ms_turn_context_get_realm(const MSTurnContext * context)1356 const char * ms_turn_context_get_realm(const MSTurnContext *context) {
1357 return context->realm;
1358 }
1359
ms_turn_context_set_realm(MSTurnContext * context,const char * realm)1360 void ms_turn_context_set_realm(MSTurnContext *context, const char *realm) {
1361 STUN_STR_SETTER(context->realm, realm);
1362 }
1363
ms_turn_context_get_nonce(const MSTurnContext * context)1364 const char * ms_turn_context_get_nonce(const MSTurnContext *context) {
1365 return context->nonce;
1366 }
1367
ms_turn_context_set_nonce(MSTurnContext * context,const char * nonce)1368 void ms_turn_context_set_nonce(MSTurnContext *context, const char *nonce) {
1369 STUN_STR_SETTER(context->nonce, nonce);
1370 }
1371
ms_turn_context_get_username(const MSTurnContext * context)1372 const char * ms_turn_context_get_username(const MSTurnContext *context) {
1373 return context->username;
1374 }
1375
ms_turn_context_set_username(MSTurnContext * context,const char * username)1376 void ms_turn_context_set_username(MSTurnContext *context, const char *username) {
1377 STUN_STR_SETTER(context->username, username);
1378 }
1379
ms_turn_context_get_password(const MSTurnContext * context)1380 const char * ms_turn_context_get_password(const MSTurnContext *context) {
1381 return context->password;
1382 }
1383
ms_turn_context_set_password(MSTurnContext * context,const char * password)1384 void ms_turn_context_set_password(MSTurnContext *context, const char *password) {
1385 STUN_STR_SETTER(context->password, password);
1386 }
1387
ms_turn_context_get_ha1(const MSTurnContext * context)1388 const char * ms_turn_context_get_ha1(const MSTurnContext *context) {
1389 return context->ha1;
1390 }
1391
ms_turn_context_set_ha1(MSTurnContext * context,const char * ha1)1392 void ms_turn_context_set_ha1(MSTurnContext *context, const char *ha1) {
1393 STUN_STR_SETTER(context->ha1, ha1);
1394 }
1395
ms_turn_context_get_lifetime(const MSTurnContext * context)1396 uint32_t ms_turn_context_get_lifetime(const MSTurnContext *context) {
1397 return context->lifetime;
1398 }
1399
ms_turn_context_set_lifetime(MSTurnContext * context,uint32_t lifetime)1400 void ms_turn_context_set_lifetime(MSTurnContext *context, uint32_t lifetime) {
1401 context->lifetime = lifetime;
1402 }
1403
ms_turn_context_get_channel_number(const MSTurnContext * context)1404 uint16_t ms_turn_context_get_channel_number(const MSTurnContext *context) {
1405 return context->channel_number;
1406 }
1407
ms_turn_context_set_channel_number(MSTurnContext * context,uint16_t channel_number)1408 void ms_turn_context_set_channel_number(MSTurnContext *context, uint16_t channel_number) {
1409 context->channel_number = channel_number;
1410 }
1411
ms_turn_context_set_allocated_relay_addr(MSTurnContext * context,MSStunAddress relay_addr)1412 void ms_turn_context_set_allocated_relay_addr(MSTurnContext *context, MSStunAddress relay_addr) {
1413 context->relay_addr = relay_addr;
1414 }
1415
ms_turn_context_set_force_rtp_sending_via_relay(MSTurnContext * context,bool_t force)1416 void ms_turn_context_set_force_rtp_sending_via_relay(MSTurnContext *context, bool_t force) {
1417 context->force_rtp_sending_via_relay = force;
1418 }
1419
ms_turn_context_peer_address_allowed(const MSTurnContext * context,const MSStunAddress * peer_address)1420 bool_t ms_turn_context_peer_address_allowed(const MSTurnContext *context, const MSStunAddress *peer_address) {
1421 bctbx_list_t *elem = context->allowed_peer_addresses;
1422 while (elem != NULL) {
1423 MSStunAddress *allowed_peer = (MSStunAddress *)elem->data;
1424 if (ms_compare_stun_addresses(allowed_peer, peer_address) == FALSE) return TRUE;
1425 elem = elem->next;
1426 }
1427 return FALSE;
1428 }
1429
ms_turn_context_allow_peer_address(MSTurnContext * context,const MSStunAddress * peer_address)1430 void ms_turn_context_allow_peer_address(MSTurnContext *context, const MSStunAddress *peer_address) {
1431 if (!ms_turn_context_peer_address_allowed(context, peer_address)) {
1432 MSStunAddress *new_peer = ms_malloc(sizeof(MSStunAddress));
1433 memcpy(new_peer, peer_address, sizeof(MSStunAddress));
1434 context->allowed_peer_addresses = bctbx_list_append(context->allowed_peer_addresses, new_peer);
1435 context->stats.nb_successful_create_permission++;
1436 }
1437 }
1438
ms_turn_rtp_endpoint_recvfrom(RtpTransport * rtptp,mblk_t * msg,int flags,struct sockaddr * from,socklen_t * fromlen)1439 static int ms_turn_rtp_endpoint_recvfrom(RtpTransport *rtptp, mblk_t *msg, int flags, struct sockaddr *from, socklen_t *fromlen) {
1440 MSTurnContext *context = (MSTurnContext *)rtptp->data;
1441 int msgsize = 0;
1442
1443 if ((context != NULL) && (context->rtp_session != NULL)) {
1444 msgsize = rtp_session_recvfrom(context->rtp_session, context->type == MS_TURN_CONTEXT_TYPE_RTP, msg, flags, from, fromlen);
1445 if ((msgsize >= RTP_FIXED_HEADER_SIZE) && (rtp_get_version(msg) != 2)) {
1446 /* This is not a RTP packet, try to see if it is a TURN ChannelData message */
1447 if ((ms_turn_context_get_state(context) >= MS_TURN_CONTEXT_STATE_BINDING_CHANNEL) && (*msg->b_rptr & 0x40)) {
1448 uint16_t channel = ntohs(*((uint16_t *)msg->b_rptr));
1449 uint16_t datasize = ntohs(*(((uint16_t *)msg->b_rptr) + 1));
1450 if ((channel == ms_turn_context_get_channel_number(context)) && (msgsize >= (datasize + 4))) {
1451 msg->b_rptr += 4; /* Unpack the TURN ChannelData message */
1452 context->stats.nb_received_channel_msg++;
1453 }
1454 } else {
1455 /* This is not a RTP packet and not a TURN ChannelData message, try to see if it is a STUN one */
1456 uint16_t stunlen = ntohs(*((uint16_t*)(msg->b_rptr + sizeof(uint16_t))));
1457 if (msgsize == (stunlen + 20)) {
1458 /* It seems to be a STUN packet */
1459 MSStunMessage *stun_msg = ms_stun_message_create_from_buffer_parsing(msg->b_rptr, msgsize);
1460 if (stun_msg != NULL) {
1461 if (ms_stun_message_is_indication(stun_msg)
1462 && (ms_stun_message_get_data(stun_msg) != NULL) && (ms_stun_message_get_data_length(stun_msg) > 0)) {
1463 /* This is TURN data indication */
1464 const MSStunAddress *stun_addr = ms_stun_message_get_xor_peer_address(stun_msg);
1465 if (stun_addr != NULL) {
1466 MSStunAddress permission_addr = *stun_addr;
1467 ms_stun_address_set_port(&permission_addr, 0);
1468 if (ms_turn_context_peer_address_allowed(context, &permission_addr) == TRUE) {
1469 struct sockaddr_storage relay_ss;
1470 struct sockaddr *relay_sa = (struct sockaddr *)&relay_ss;
1471 socklen_t relay_sa_len = sizeof(relay_ss);
1472 memset(relay_sa, 0, relay_sa_len);
1473 /* Copy the data of the TURN data indication in the mblk_t so that it contains the unpacked data */
1474 msgsize = ms_stun_message_get_data_length(stun_msg);
1475 memcpy(msg->b_rptr, ms_stun_message_get_data(stun_msg), msgsize);
1476 /* Overwrite the ortp_recv_addr of the mblk_t so that ICE source address is correct */
1477 ms_stun_address_to_sockaddr(&context->relay_addr, relay_sa, &relay_sa_len);
1478 msg->recv_addr.family = relay_sa->sa_family;
1479 if (relay_sa->sa_family == AF_INET) {
1480 msg->recv_addr.addr.ipi_addr = ((struct sockaddr_in *)relay_sa)->sin_addr;
1481 msg->recv_addr.port = ((struct sockaddr_in *)relay_sa)->sin_port;
1482 } else if (relay_sa->sa_family == AF_INET6) {
1483 memcpy(&msg->recv_addr.addr.ipi6_addr, &((struct sockaddr_in6 *)relay_sa)->sin6_addr, sizeof(struct in6_addr));
1484 msg->recv_addr.port = ((struct sockaddr_in6 *)relay_sa)->sin6_port;
1485 } else {
1486 ms_warning("turn: Unknown address family in relay_addr");
1487 msgsize = 0;
1488 }
1489 /* Overwrite the source address of the packet so that it uses the peer address instead of the TURN server one */
1490 ms_stun_address_to_sockaddr(stun_addr, from, fromlen);
1491 if (msgsize > 0) context->stats.nb_data_indication++;
1492 }
1493 }
1494 }
1495 ms_stun_message_destroy(stun_msg);
1496 }
1497 }
1498 }
1499 }
1500 }
1501 return msgsize;
1502 }
1503
ms_turn_rtp_endpoint_send_via_turn_server(MSTurnContext * context,const struct sockaddr * from,socklen_t fromlen)1504 static bool_t ms_turn_rtp_endpoint_send_via_turn_server(MSTurnContext *context, const struct sockaddr *from, socklen_t fromlen) {
1505 struct sockaddr_storage relay_ss;
1506 struct sockaddr *relay_sa = (struct sockaddr *)&relay_ss;
1507 socklen_t relay_sa_len = sizeof(relay_ss);
1508
1509 memset(relay_sa, 0, relay_sa_len);
1510 ms_stun_address_to_sockaddr(&context->relay_addr, relay_sa, &relay_sa_len);
1511 if (relay_sa->sa_family != from->sa_family) return FALSE;
1512 if (relay_sa->sa_family == AF_INET) {
1513 struct sockaddr_in *relay_sa_in = (struct sockaddr_in *)relay_sa;
1514 struct sockaddr_in *from_in = (struct sockaddr_in *)from;
1515 return (relay_sa_in->sin_port == from_in->sin_port) && (relay_sa_in->sin_addr.s_addr == from_in->sin_addr.s_addr);
1516 } else if (relay_sa->sa_family == AF_INET6) {
1517 struct sockaddr_in6 *relay_sa_in6 = (struct sockaddr_in6 *)relay_sa;
1518 struct sockaddr_in6 *from_in6 = (struct sockaddr_in6 *)from;
1519 return (relay_sa_in6->sin6_port == from_in6->sin6_port) && (memcmp(&relay_sa_in6->sin6_addr, &from_in6->sin6_addr, sizeof(struct in6_addr)) == 0);
1520 } else return FALSE;
1521 }
1522
ms_turn_rtp_endpoint_sendto(RtpTransport * rtptp,mblk_t * msg,int flags,const struct sockaddr * to,socklen_t tolen)1523 static int ms_turn_rtp_endpoint_sendto(RtpTransport *rtptp, mblk_t *msg, int flags, const struct sockaddr *to, socklen_t tolen) {
1524 MSTurnContext *context = (MSTurnContext *)rtptp->data;
1525 MSStunMessage *stun_msg = NULL;
1526 bool_t rtp_packet = FALSE;
1527 int ret = 0;
1528 mblk_t *new_msg = NULL;
1529
1530 if ((context != NULL) && (context->rtp_session != NULL)) {
1531 if ((msgdsize(msg) >= RTP_FIXED_HEADER_SIZE) && (rtp_get_version(msg) == 2)) rtp_packet = TRUE;
1532 if ((rtp_packet && context->force_rtp_sending_via_relay) || ms_turn_rtp_endpoint_send_via_turn_server(context, (struct sockaddr *)&msg->net_addr, msg->net_addrlen)) {
1533 if (ms_turn_context_get_state(context) >= MS_TURN_CONTEXT_STATE_CHANNEL_BOUND) {
1534 /* Use a TURN ChannelData message */
1535 new_msg = allocb(4, 0);
1536 *((uint16_t *)new_msg->b_wptr) = htons(ms_turn_context_get_channel_number(context));
1537 new_msg->b_wptr += 2;
1538 *((uint16_t *)new_msg->b_wptr) = htons((uint16_t)msgdsize(msg));
1539 new_msg->b_wptr += 2;
1540 mblk_meta_copy(msg, new_msg);
1541 concatb(new_msg, dupmsg(msg));
1542 msg = new_msg;
1543 context->stats.nb_sent_channel_msg++;
1544 } else {
1545 /* Use a TURN send indication to encapsulate the data to be sent */
1546 struct sockaddr_storage realto;
1547 socklen_t realtolen = sizeof(realto);
1548 MSStunAddress stun_addr;
1549 char *buf = NULL;
1550 size_t len;
1551 uint8_t *data;
1552 uint16_t datalen;
1553 msgpullup(msg, -1);
1554 datalen = (uint16_t)(msg->b_wptr - msg->b_rptr);
1555 bctbx_sockaddr_ipv6_to_ipv4(to, (struct sockaddr *)&realto, &realtolen);
1556 ms_sockaddr_to_stun_address((struct sockaddr *)&realto, &stun_addr);
1557 stun_msg = ms_turn_send_indication_create(stun_addr);
1558 data = ms_malloc(datalen);
1559 memcpy(data, msg->b_rptr, datalen);
1560 ms_stun_message_set_data(stun_msg, data, datalen);
1561 msg->b_rptr = msg->b_wptr;
1562 len = ms_stun_message_encode(stun_msg, &buf);
1563 msgappend(msg, buf, len, FALSE);
1564 ms_free(buf);
1565 context->stats.nb_send_indication++;
1566 }
1567 to = (const struct sockaddr *)context->turn_server_addr;
1568 tolen = context->turn_server_addrlen;
1569 }
1570 ret = rtp_session_sendto(context->rtp_session, context->type == MS_TURN_CONTEXT_TYPE_RTP, msg, flags, to, tolen);
1571 }
1572 if (stun_msg != NULL) ms_stun_message_destroy(stun_msg);
1573 if (new_msg != NULL) {
1574 freemsg(new_msg);
1575 }
1576 return ret;
1577 }
1578
ms_turn_rtp_endpoint_close(RtpTransport * rtptp)1579 static void ms_turn_rtp_endpoint_close(RtpTransport *rtptp) {
1580 MSTurnContext *context = (MSTurnContext *)rtptp->data;
1581 if (context != NULL) context->rtp_session = NULL;
1582 }
1583
ms_turn_rtp_endpoint_destroy(RtpTransport * rtptp)1584 static void ms_turn_rtp_endpoint_destroy(RtpTransport *rtptp) {
1585 ms_free(rtptp);
1586 }
1587
ms_turn_context_create_endpoint(MSTurnContext * context)1588 RtpTransport * ms_turn_context_create_endpoint(MSTurnContext *context) {
1589 RtpTransport *rtptp = ms_new0(RtpTransport, 1);
1590 rtptp->t_getsocket = NULL;
1591 rtptp->t_recvfrom = ms_turn_rtp_endpoint_recvfrom;
1592 rtptp->t_sendto = ms_turn_rtp_endpoint_sendto;
1593 rtptp->t_close = ms_turn_rtp_endpoint_close;
1594 rtptp->t_destroy = ms_turn_rtp_endpoint_destroy;
1595 rtptp->data = context;
1596 context->endpoint = rtptp;
1597 return rtptp;
1598 }
1599