1 /*
2 Copyright (c) 2007, Adobe Systems, Incorporated
3 All rights reserved.
4
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are
7 met:
8
9 * Redistributions of source code must retain the above copyright
10 notice, this list of conditions and the following disclaimer.
11
12 * Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in the
14 documentation and/or other materials provided with the distribution.
15
16 * Neither the name of Adobe Systems, Network Resonance nor the names of its
17 contributors may be used to endorse or promote products derived from
18 this software without specific prior written permission.
19
20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33 #include <csi_platform.h>
34 #include <assert.h>
35 #include <sys/types.h>
36 #ifdef WIN32
37 #include <winsock2.h>
38 #else
39 #include <sys/socket.h>
40 #include <netinet/in.h>
41 #include <arpa/inet.h>
42 #endif
43 #include <sys/queue.h>
44 #include <string.h>
45 #include <nr_api.h>
46 #include <registry.h>
47 #include "stun.h"
48 #include "ice_ctx.h"
49 #include "ice_reg.h"
50 #include "nr_crypto.h"
51 #include "async_timer.h"
52 #include "util.h"
53 #include "nr_socket_local.h"
54
55 #define ICE_UFRAG_LEN 8
56 #define ICE_PWD_LEN 32
57
58 int LOG_ICE = 0;
59
60 static int nr_ice_random_string(char *str, int len);
61 static int nr_ice_fetch_stun_servers(int ct, nr_ice_stun_server **out);
62 #ifdef USE_TURN
63 static int nr_ice_fetch_turn_servers(int ct, nr_ice_turn_server **out);
64 #endif /* USE_TURN */
65 static int nr_ice_ctx_pair_new_trickle_candidates(nr_ice_ctx *ctx, nr_ice_candidate *cand);
no_op(void ** obj)66 static int no_op(void **obj) {
67 return 0;
68 }
69
70 static nr_socket_factory_vtbl default_socket_factory_vtbl = {
71 nr_socket_local_create,
72 no_op
73 };
74
nr_ice_fetch_stun_servers(int ct,nr_ice_stun_server ** out)75 int nr_ice_fetch_stun_servers(int ct, nr_ice_stun_server **out)
76 {
77 int r,_status;
78 nr_ice_stun_server *servers = 0;
79 int i;
80 NR_registry child;
81 char *addr=0;
82 UINT2 port;
83 in_addr_t addr_int;
84
85 if(!(servers=RCALLOC(sizeof(nr_ice_stun_server)*ct)))
86 ABORT(R_NO_MEMORY);
87
88 for(i=0;i<ct;i++){
89 if(r=NR_reg_get_child_registry(NR_ICE_REG_STUN_SRV_PRFX,i,child))
90 ABORT(r);
91 /* Assume we have a v4 addr for now */
92 if(r=NR_reg_alloc2_string(child,"addr",&addr))
93 ABORT(r);
94 addr_int=inet_addr(addr);
95 if(addr_int==INADDR_NONE){
96 r_log(LOG_ICE,LOG_ERR,"Invalid address %s;",addr);
97 ABORT(R_BAD_ARGS);
98 }
99 if(r=NR_reg_get2_uint2(child,"port",&port)) {
100 if (r != R_NOT_FOUND)
101 ABORT(r);
102 port = 3478;
103 }
104 if (r = nr_ip4_port_to_transport_addr(ntohl(addr_int), port, IPPROTO_UDP,
105 &servers[i].addr))
106 ABORT(r);
107 RFREE(addr);
108 addr=0;
109 }
110
111 *out = servers;
112
113 _status=0;
114 abort:
115 RFREE(addr);
116 if (_status) RFREE(servers);
117 return(_status);
118 }
119
nr_ice_ctx_set_stun_servers(nr_ice_ctx * ctx,nr_ice_stun_server * servers,int ct)120 int nr_ice_ctx_set_stun_servers(nr_ice_ctx *ctx,nr_ice_stun_server *servers,int ct)
121 {
122 int _status;
123
124 if(ctx->stun_servers_cfg){
125 RFREE(ctx->stun_servers_cfg);
126 ctx->stun_servers_cfg=NULL;
127 ctx->stun_server_ct_cfg=0;
128 }
129
130 if (ct) {
131 if(!(ctx->stun_servers_cfg=RCALLOC(sizeof(nr_ice_stun_server)*ct)))
132 ABORT(R_NO_MEMORY);
133
134 memcpy(ctx->stun_servers_cfg,servers,sizeof(nr_ice_stun_server)*ct);
135 ctx->stun_server_ct_cfg = ct;
136 }
137
138 _status=0;
139 abort:
140 return(_status);
141 }
142
nr_ice_ctx_set_turn_servers(nr_ice_ctx * ctx,nr_ice_turn_server * servers,int ct)143 int nr_ice_ctx_set_turn_servers(nr_ice_ctx *ctx,nr_ice_turn_server *servers,int ct)
144 {
145 int _status;
146
147 if(ctx->turn_servers_cfg){
148 for (int i = 0; i < ctx->turn_server_ct_cfg; i++) {
149 RFREE(ctx->turn_servers_cfg[i].username);
150 r_data_destroy(&ctx->turn_servers_cfg[i].password);
151 }
152 RFREE(ctx->turn_servers_cfg);
153 ctx->turn_servers_cfg=NULL;
154 ctx->turn_server_ct_cfg=0;
155 }
156
157 if(ct) {
158 if(!(ctx->turn_servers_cfg=RCALLOC(sizeof(nr_ice_turn_server)*ct)))
159 ABORT(R_NO_MEMORY);
160
161 memcpy(ctx->turn_servers_cfg,servers,sizeof(nr_ice_turn_server)*ct);
162 ctx->turn_server_ct_cfg = ct;
163 }
164
165 _status=0;
166 abort:
167 return(_status);
168 }
169
nr_ice_ctx_copy_turn_servers(nr_ice_ctx * ctx,nr_ice_turn_server * servers,int ct)170 int nr_ice_ctx_copy_turn_servers(nr_ice_ctx *ctx, nr_ice_turn_server *servers, int ct)
171 {
172 int _status, i, r;
173
174 if (r = nr_ice_ctx_set_turn_servers(ctx, servers, ct)) {
175 ABORT(r);
176 }
177
178 // make copies of the username and password so they aren't freed twice
179 for (i = 0; i < ct; ++i) {
180 if (!(ctx->turn_servers_cfg[i].username = r_strdup(servers[i].username))) {
181 ABORT(R_NO_MEMORY);
182 }
183 if (r = r_data_create(&ctx->turn_servers_cfg[i].password,
184 servers[i].password->data,
185 servers[i].password->len)) {
186 ABORT(r);
187 }
188 }
189
190 _status=0;
191 abort:
192 return(_status);
193 }
194
nr_ice_ctx_set_local_addrs(nr_ice_ctx * ctx,nr_local_addr * addrs,int ct)195 static int nr_ice_ctx_set_local_addrs(nr_ice_ctx *ctx,nr_local_addr *addrs,int ct)
196 {
197 int _status,i,r;
198
199 if(ctx->local_addrs) {
200 RFREE(ctx->local_addrs);
201 ctx->local_addr_ct=0;
202 ctx->local_addrs=0;
203 }
204
205 if (ct) {
206 if(!(ctx->local_addrs=RCALLOC(sizeof(nr_local_addr)*ct)))
207 ABORT(R_NO_MEMORY);
208
209 for (i=0;i<ct;++i) {
210 if (r=nr_local_addr_copy(ctx->local_addrs+i,addrs+i)) {
211 ABORT(r);
212 }
213 }
214 ctx->local_addr_ct = ct;
215 }
216
217 _status=0;
218 abort:
219 return(_status);
220 }
221
nr_ice_ctx_set_resolver(nr_ice_ctx * ctx,nr_resolver * resolver)222 int nr_ice_ctx_set_resolver(nr_ice_ctx *ctx, nr_resolver *resolver)
223 {
224 int _status;
225
226 if (ctx->resolver) {
227 ABORT(R_ALREADY);
228 }
229
230 ctx->resolver = resolver;
231
232 _status=0;
233 abort:
234 return(_status);
235 }
236
nr_ice_ctx_set_interface_prioritizer(nr_ice_ctx * ctx,nr_interface_prioritizer * ip)237 int nr_ice_ctx_set_interface_prioritizer(nr_ice_ctx *ctx, nr_interface_prioritizer *ip)
238 {
239 int _status;
240
241 if (ctx->interface_prioritizer) {
242 ABORT(R_ALREADY);
243 }
244
245 ctx->interface_prioritizer = ip;
246
247 _status=0;
248 abort:
249 return(_status);
250 }
251
nr_ice_ctx_set_socket_factory(nr_ice_ctx * ctx,nr_socket_factory * factory)252 void nr_ice_ctx_set_socket_factory(nr_ice_ctx *ctx, nr_socket_factory *factory)
253 {
254 nr_socket_factory_destroy(&ctx->socket_factory);
255 ctx->socket_factory = factory;
256 }
257
258 #ifdef USE_TURN
nr_ice_fetch_turn_servers(int ct,nr_ice_turn_server ** out)259 int nr_ice_fetch_turn_servers(int ct, nr_ice_turn_server **out)
260 {
261 int r,_status;
262 nr_ice_turn_server *servers = 0;
263 int i;
264 NR_registry child;
265 char *addr=0;
266 UINT2 port;
267 in_addr_t addr_int;
268 Data data={0};
269
270 if(!(servers=RCALLOC(sizeof(nr_ice_turn_server)*ct)))
271 ABORT(R_NO_MEMORY);
272
273 for(i=0;i<ct;i++){
274 if(r=NR_reg_get_child_registry(NR_ICE_REG_TURN_SRV_PRFX,i,child))
275 ABORT(r);
276 /* Assume we have a v4 addr for now */
277 if(r=NR_reg_alloc2_string(child,"addr",&addr))
278 ABORT(r);
279 addr_int=inet_addr(addr);
280 if(addr_int==INADDR_NONE){
281 r_log(LOG_ICE,LOG_ERR,"Invalid address %s",addr);
282 ABORT(R_BAD_ARGS);
283 }
284 if(r=NR_reg_get2_uint2(child,"port",&port)) {
285 if (r != R_NOT_FOUND)
286 ABORT(r);
287 port = 3478;
288 }
289 if (r = nr_ip4_port_to_transport_addr(ntohl(addr_int), port, IPPROTO_UDP,
290 &servers[i].turn_server.addr))
291 ABORT(r);
292
293
294 if(r=NR_reg_alloc2_string(child,NR_ICE_REG_TURN_SRV_USERNAME,&servers[i].username)){
295 if(r!=R_NOT_FOUND)
296 ABORT(r);
297 }
298
299 if(r=NR_reg_alloc2_data(child,NR_ICE_REG_TURN_SRV_PASSWORD,&data)){
300 if(r!=R_NOT_FOUND)
301 ABORT(r);
302 }
303 else {
304 servers[i].password=RCALLOC(sizeof(*servers[i].password));
305 if(!servers[i].password)
306 ABORT(R_NO_MEMORY);
307 servers[i].password->data = data.data;
308 servers[i].password->len = data.len;
309 data.data=0;
310 }
311
312 RFREE(addr);
313 addr=0;
314 }
315
316 *out = servers;
317
318 _status=0;
319 abort:
320 RFREE(data.data);
321 RFREE(addr);
322 if (_status) RFREE(servers);
323 return(_status);
324 }
325 #endif /* USE_TURN */
326
327 #define MAXADDRS 100 /* Ridiculously high */
nr_ice_ctx_create(char * label,UINT4 flags,nr_ice_ctx ** ctxp)328 int nr_ice_ctx_create(char *label, UINT4 flags, nr_ice_ctx **ctxp)
329 {
330 nr_ice_ctx *ctx=0;
331 int r,_status;
332
333 if(r=r_log_register("ice", &LOG_ICE))
334 ABORT(r);
335
336 if(!(ctx=RCALLOC(sizeof(nr_ice_ctx))))
337 ABORT(R_NO_MEMORY);
338
339 ctx->flags=flags;
340
341 if(!(ctx->label=r_strdup(label)))
342 ABORT(R_NO_MEMORY);
343
344 /* Get the STUN servers */
345 if(r=NR_reg_get_child_count(NR_ICE_REG_STUN_SRV_PRFX,
346 (unsigned int *)&ctx->stun_server_ct_cfg)||ctx->stun_server_ct_cfg==0) {
347 r_log(LOG_ICE,LOG_DEBUG,"ICE(%s): No STUN servers specified in nICEr registry", ctx->label);
348 ctx->stun_server_ct_cfg=0;
349 }
350
351 /* 31 is the max for our priority algorithm */
352 if(ctx->stun_server_ct_cfg>31){
353 r_log(LOG_ICE,LOG_WARNING,"ICE(%s): Too many STUN servers specified: max=31", ctx->label);
354 ctx->stun_server_ct_cfg=31;
355 }
356
357 if(ctx->stun_server_ct_cfg>0){
358 if(r=nr_ice_fetch_stun_servers(ctx->stun_server_ct_cfg,&ctx->stun_servers_cfg)){
359 r_log(LOG_ICE,LOG_ERR,"ICE(%s): Couldn't load STUN servers from registry", ctx->label);
360 ctx->stun_server_ct_cfg=0;
361 ABORT(r);
362 }
363 }
364
365 #ifdef USE_TURN
366 /* Get the TURN servers */
367 if(r=NR_reg_get_child_count(NR_ICE_REG_TURN_SRV_PRFX,
368 (unsigned int *)&ctx->turn_server_ct_cfg)||ctx->turn_server_ct_cfg==0) {
369 r_log(LOG_ICE,LOG_DEBUG,"ICE(%s): No TURN servers specified in nICEr registry", ctx->label);
370 ctx->turn_server_ct_cfg=0;
371 }
372 #else
373 ctx->turn_server_ct_cfg=0;
374 #endif /* USE_TURN */
375
376 ctx->local_addrs=0;
377 ctx->local_addr_ct=0;
378
379 /* 31 is the max for our priority algorithm */
380 if((ctx->stun_server_ct_cfg+ctx->turn_server_ct_cfg)>31){
381 r_log(LOG_ICE,LOG_WARNING,"ICE(%s): Too many STUN/TURN servers specified: max=31", ctx->label);
382 ctx->turn_server_ct_cfg=31-ctx->stun_server_ct_cfg;
383 }
384
385 #ifdef USE_TURN
386 if(ctx->turn_server_ct_cfg>0){
387 if(r=nr_ice_fetch_turn_servers(ctx->turn_server_ct_cfg,&ctx->turn_servers_cfg)){
388 ctx->turn_server_ct_cfg=0;
389 r_log(LOG_ICE,LOG_ERR,"ICE(%s): Couldn't load TURN servers from registry", ctx->label);
390 ABORT(r);
391 }
392 }
393 #endif /* USE_TURN */
394
395
396 ctx->Ta = 20;
397
398 ctx->test_timer_divider = 0;
399
400 if (r=nr_socket_factory_create_int(NULL, &default_socket_factory_vtbl, &ctx->socket_factory))
401 ABORT(r);
402
403 if ((r=NR_reg_get_string((char *)NR_ICE_REG_PREF_FORCE_INTERFACE_NAME, ctx->force_net_interface, sizeof(ctx->force_net_interface)))) {
404 if (r == R_NOT_FOUND) {
405 ctx->force_net_interface[0] = 0;
406 } else {
407 ABORT(r);
408 }
409 }
410
411 ctx->target_for_default_local_address_lookup=0;
412
413 STAILQ_INIT(&ctx->streams);
414 STAILQ_INIT(&ctx->sockets);
415 STAILQ_INIT(&ctx->foundations);
416 STAILQ_INIT(&ctx->peers);
417 STAILQ_INIT(&ctx->ids);
418
419 *ctxp=ctx;
420
421 _status=0;
422 abort:
423 if (_status && ctx) nr_ice_ctx_destroy(&ctx);
424
425 return(_status);
426 }
427
nr_ice_ctx_add_flags(nr_ice_ctx * ctx,UINT4 flags)428 void nr_ice_ctx_add_flags(nr_ice_ctx* ctx, UINT4 flags) {
429 ctx->flags |= flags;
430 }
431
nr_ice_ctx_remove_flags(nr_ice_ctx * ctx,UINT4 flags)432 void nr_ice_ctx_remove_flags(nr_ice_ctx* ctx, UINT4 flags) {
433 ctx->flags &= ~flags;
434 }
435
nr_ice_ctx_destroy(nr_ice_ctx ** ctxp)436 void nr_ice_ctx_destroy(nr_ice_ctx** ctxp) {
437 if (!ctxp || !*ctxp) return;
438
439 nr_ice_ctx* ctx = *ctxp;
440 nr_ice_foundation *f1,*f2;
441 nr_ice_media_stream *s1,*s2;
442 int i;
443 nr_ice_stun_id *id1,*id2;
444
445 ctx->done_cb = 0;
446 ctx->trickle_cb = 0;
447
448 STAILQ_FOREACH_SAFE(s1, &ctx->streams, entry, s2){
449 STAILQ_REMOVE(&ctx->streams,s1,nr_ice_media_stream_,entry);
450 nr_ice_media_stream_destroy(&s1);
451 }
452
453 RFREE(ctx->label);
454
455 RFREE(ctx->stun_servers_cfg);
456
457 RFREE(ctx->local_addrs);
458
459 RFREE(ctx->target_for_default_local_address_lookup);
460
461 for (i = 0; i < ctx->turn_server_ct_cfg; i++) {
462 RFREE(ctx->turn_servers_cfg[i].username);
463 r_data_destroy(&ctx->turn_servers_cfg[i].password);
464 }
465 RFREE(ctx->turn_servers_cfg);
466
467 f1=STAILQ_FIRST(&ctx->foundations);
468 while(f1){
469 f2=STAILQ_NEXT(f1,entry);
470 RFREE(f1);
471 f1=f2;
472 }
473
474 STAILQ_FOREACH_SAFE(id1, &ctx->ids, entry, id2){
475 STAILQ_REMOVE(&ctx->ids,id1,nr_ice_stun_id_,entry);
476 RFREE(id1);
477 }
478
479 nr_resolver_destroy(&ctx->resolver);
480 nr_interface_prioritizer_destroy(&ctx->interface_prioritizer);
481 nr_socket_factory_destroy(&ctx->socket_factory);
482
483 RFREE(ctx);
484
485 *ctxp=0;
486 }
487
nr_ice_gather_finished_cb(NR_SOCKET s,int h,void * cb_arg)488 void nr_ice_gather_finished_cb(NR_SOCKET s, int h, void *cb_arg)
489 {
490 int r;
491 nr_ice_candidate *cand=cb_arg;
492 nr_ice_ctx *ctx;
493 nr_ice_media_stream *stream;
494 int component_id;
495
496 assert(cb_arg);
497 if (!cb_arg)
498 return;
499 ctx = cand->ctx;
500 stream = cand->stream;
501 component_id = cand->component_id;
502
503 ctx->uninitialized_candidates--;
504 if (cand->state == NR_ICE_CAND_STATE_FAILED) {
505 r_log(LOG_ICE, LOG_WARNING,
506 "ICE(%s)/CAND(%s): failed to initialize, %d remaining", ctx->label,
507 cand->label, ctx->uninitialized_candidates);
508 } else {
509 r_log(LOG_ICE, LOG_DEBUG, "ICE(%s)/CAND(%s): initialized, %d remaining",
510 ctx->label, cand->label, ctx->uninitialized_candidates);
511 }
512
513 /* Avoid the need for yet another initialization function */
514 if (cand->state == NR_ICE_CAND_STATE_INITIALIZING && cand->type == HOST)
515 cand->state = NR_ICE_CAND_STATE_INITIALIZED;
516
517 if (cand->state == NR_ICE_CAND_STATE_INITIALIZED) {
518 int was_pruned = 0;
519
520 if (r=nr_ice_component_maybe_prune_candidate(ctx, cand->component,
521 cand, &was_pruned)) {
522 r_log(LOG_ICE, LOG_NOTICE, "ICE(%s): Problem pruning candidates",ctx->label);
523 }
524
525 if (was_pruned) {
526 cand = NULL;
527 }
528
529 /* If we are initialized, the candidate wasn't pruned,
530 and we have a trickle ICE callback fire the callback */
531 if (ctx->trickle_cb && cand &&
532 !nr_ice_ctx_hide_candidate(ctx, cand)) {
533 ctx->trickle_cb(ctx->trickle_cb_arg, ctx, cand->stream, cand->component_id, cand);
534
535 if (nr_ice_ctx_pair_new_trickle_candidates(ctx, cand)) {
536 r_log(LOG_ICE,LOG_ERR, "ICE(%s): All could not pair new trickle candidate",ctx->label);
537 /* But continue */
538 }
539 }
540 }
541
542 if (nr_ice_media_stream_is_done_gathering(stream) &&
543 ctx->trickle_cb) {
544 ctx->trickle_cb(ctx->trickle_cb_arg, ctx, stream, component_id, NULL);
545 }
546
547 if(ctx->uninitialized_candidates==0){
548 r_log(LOG_ICE, LOG_INFO, "ICE(%s): All candidates initialized",
549 ctx->label);
550 if (ctx->done_cb) {
551 ctx->done_cb(0,0,ctx->cb_arg);
552 }
553 else {
554 r_log(LOG_ICE, LOG_INFO,
555 "ICE(%s): No done_cb. We were probably destroyed.", ctx->label);
556 }
557 }
558 else {
559 r_log(LOG_ICE,LOG_DEBUG,"ICE(%s): Waiting for %d candidates to be initialized",ctx->label, ctx->uninitialized_candidates);
560 }
561 }
562
nr_ice_ctx_pair_new_trickle_candidates(nr_ice_ctx * ctx,nr_ice_candidate * cand)563 static int nr_ice_ctx_pair_new_trickle_candidates(nr_ice_ctx *ctx, nr_ice_candidate *cand)
564 {
565 int r,_status;
566 nr_ice_peer_ctx *pctx;
567
568 pctx=STAILQ_FIRST(&ctx->peers);
569 while(pctx){
570 if (pctx->state == NR_ICE_PEER_STATE_PAIRED) {
571 r = nr_ice_peer_ctx_pair_new_trickle_candidate(ctx, pctx, cand);
572 if (r)
573 ABORT(r);
574 }
575
576 pctx=STAILQ_NEXT(pctx,entry);
577 }
578
579 _status=0;
580 abort:
581 return(_status);
582 }
583
584 /* Get the default address by creating a UDP socket, binding it to a wildcard
585 address, and connecting it to the remote IP. Because this is UDP, no packets
586 are sent. This lets us query the local address assigned to the socket by the
587 kernel.
588
589 If the context's remote address is NULL, then the application wasn't loaded
590 over the network, and we can fall back on connecting to a known public
591 address (namely Google's):
592
593 IPv4: 8.8.8.8
594 IPv6: 2001:4860:4860::8888
595 */
nr_ice_get_default_address(nr_ice_ctx * ctx,int ip_version,nr_transport_addr * addrp)596 static int nr_ice_get_default_address(nr_ice_ctx *ctx, int ip_version, nr_transport_addr* addrp)
597 {
598 int r,_status;
599 nr_transport_addr addr, known_remote_addr;
600 nr_transport_addr *remote_addr=ctx->target_for_default_local_address_lookup;
601 nr_socket *sock=0;
602
603 switch(ip_version) {
604 case NR_IPV4:
605 if ((r=nr_str_port_to_transport_addr("0.0.0.0", 0, IPPROTO_UDP, &addr)))
606 ABORT(r);
607 if (!remote_addr || nr_transport_addr_is_loopback(remote_addr)) {
608 if ((r=nr_str_port_to_transport_addr("8.8.8.8", 53, IPPROTO_UDP, &known_remote_addr)))
609 ABORT(r);
610 remote_addr=&known_remote_addr;
611 }
612 break;
613 case NR_IPV6:
614 if ((r=nr_str_port_to_transport_addr("::0", 0, IPPROTO_UDP, &addr)))
615 ABORT(r);
616 if (!remote_addr || nr_transport_addr_is_loopback(remote_addr)) {
617 if ((r=nr_str_port_to_transport_addr("2001:4860:4860::8888", 53, IPPROTO_UDP, &known_remote_addr)))
618 ABORT(r);
619 remote_addr=&known_remote_addr;
620 }
621 break;
622 default:
623 assert(0);
624 ABORT(R_INTERNAL);
625 }
626
627 if ((r=nr_socket_factory_create_socket(ctx->socket_factory, &addr, &sock)))
628 ABORT(r);
629 if ((r=nr_socket_connect(sock, remote_addr)))
630 ABORT(r);
631 if ((r=nr_socket_getaddr(sock, addrp)))
632 ABORT(r);
633
634 r_log(LOG_GENERIC, LOG_DEBUG, "Default address: %s", addrp->as_string);
635
636 _status=0;
637 abort:
638 nr_socket_destroy(&sock);
639 return(_status);
640 }
641
nr_ice_get_default_local_address(nr_ice_ctx * ctx,int ip_version,nr_local_addr * addrs,int addr_ct,nr_local_addr * addrp)642 static int nr_ice_get_default_local_address(nr_ice_ctx *ctx, int ip_version, nr_local_addr* addrs, int addr_ct, nr_local_addr *addrp)
643 {
644 int r,_status;
645 nr_transport_addr default_addr;
646 int i;
647
648 if ((r=nr_ice_get_default_address(ctx, ip_version, &default_addr)))
649 ABORT(r);
650
651 for (i=0; i < addr_ct; ++i) {
652 // if default addr is found in local addrs, copy the more fully
653 // complete local addr to the output arg. Don't need to worry
654 // about comparing ports here.
655 if (!nr_transport_addr_cmp(&default_addr, &addrs[i].addr,
656 NR_TRANSPORT_ADDR_CMP_MODE_ADDR)) {
657 if ((r=nr_local_addr_copy(addrp, &addrs[i])))
658 ABORT(r);
659 break;
660 }
661 }
662
663 // if default addr is not in local addrs, just copy the transport addr
664 // to output arg.
665 if (i == addr_ct) {
666 if ((r=nr_transport_addr_copy(&addrp->addr, &default_addr)))
667 ABORT(r);
668 (void)strlcpy(addrp->addr.ifname, "default route", sizeof(addrp->addr.ifname));
669 }
670
671 _status=0;
672 abort:
673 return(_status);
674 }
675
676 /* if handed a IPv4 default_local_addr, looks for IPv6 address on same interface
677 if handed a IPv6 default_local_addr, looks for IPv4 address on same interface
678 */
nr_ice_get_assoc_interface_address(nr_local_addr * default_local_addr,nr_local_addr * local_addrs,int addr_ct,nr_local_addr * assoc_addrp)679 static int nr_ice_get_assoc_interface_address(nr_local_addr* default_local_addr,
680 nr_local_addr* local_addrs, int addr_ct,
681 nr_local_addr* assoc_addrp)
682 {
683 int r, _status;
684 int i, ip_version;
685
686 if (!default_local_addr || !local_addrs || !addr_ct) {
687 ABORT(R_BAD_ARGS);
688 }
689
690 /* set _status to R_EOD in case we don't find an associated address */
691 _status = R_EOD;
692
693 /* look for IPv6 if we have IPv4, look for IPv4 if we have IPv6 */
694 ip_version = (NR_IPV4 == default_local_addr->addr.ip_version?NR_IPV6:NR_IPV4);
695
696 for (i=0; i<addr_ct; ++i) {
697 /* if we find the ip_version we're looking for on the matching interface,
698 copy it to assoc_addrp.
699 */
700 if (local_addrs[i].addr.ip_version == ip_version &&
701 !strcmp(local_addrs[i].addr.ifname, default_local_addr->addr.ifname)) {
702 if (r=nr_local_addr_copy(assoc_addrp, &local_addrs[i])) {
703 ABORT(r);
704 }
705 _status = 0;
706 break;
707 }
708 }
709
710 abort:
711 return(_status);
712 }
713
nr_ice_set_local_addresses(nr_ice_ctx * ctx,nr_local_addr * stun_addrs,int stun_addr_ct)714 int nr_ice_set_local_addresses(nr_ice_ctx *ctx,
715 nr_local_addr* stun_addrs, int stun_addr_ct)
716 {
717 int r,_status;
718 nr_local_addr local_addrs[MAXADDRS];
719 nr_local_addr *addrs = 0;
720 int i,addr_ct;
721 nr_local_addr default_addrs[2];
722 int default_addr_ct = 0;
723
724 if (!stun_addrs || !stun_addr_ct) {
725 r_log(LOG_ICE,LOG_ERR,"ICE(%s): no stun addrs provided",ctx->label);
726 ABORT(R_BAD_ARGS);
727 }
728
729 addr_ct = MIN(stun_addr_ct, MAXADDRS);
730 r_log(LOG_ICE, LOG_DEBUG, "ICE(%s): copy %d pre-fetched stun addrs", ctx->label, addr_ct);
731 for (i=0; i<addr_ct; ++i) {
732 if (r=nr_local_addr_copy(&local_addrs[i], &stun_addrs[i])) {
733 ABORT(r);
734 }
735 }
736
737 // removes duplicates and, based on prefs, loopback and link_local addrs
738 if (r=nr_stun_filter_local_addresses(local_addrs, &addr_ct)) {
739 ABORT(r);
740 }
741
742 if (ctx->force_net_interface[0] && addr_ct) {
743 /* Limit us to only addresses on a single interface */
744 int force_addr_ct = 0;
745 for(i=0;i<addr_ct;i++){
746 if (!strcmp(local_addrs[i].addr.ifname, ctx->force_net_interface)) {
747 // copy it down in the array, if needed
748 if (i != force_addr_ct) {
749 if (r=nr_local_addr_copy(&local_addrs[force_addr_ct], &local_addrs[i])) {
750 ABORT(r);
751 }
752 }
753 force_addr_ct++;
754 }
755 }
756 addr_ct = force_addr_ct;
757 }
758
759 r_log(LOG_ICE, LOG_DEBUG,
760 "ICE(%s): use only default local addresses: %s\n",
761 ctx->label,
762 (char*)(ctx->flags & NR_ICE_CTX_FLAGS_ONLY_DEFAULT_ADDRS?"yes":"no"));
763 if ((!addr_ct) || (ctx->flags & NR_ICE_CTX_FLAGS_ONLY_DEFAULT_ADDRS)) {
764 if (ctx->target_for_default_local_address_lookup) {
765 /* Get just the default IPv4 or IPv6 addr */
766 if(!nr_ice_get_default_local_address(
767 ctx, ctx->target_for_default_local_address_lookup->ip_version,
768 local_addrs, addr_ct, &default_addrs[default_addr_ct])) {
769 nr_local_addr *new_addr = &default_addrs[default_addr_ct];
770
771 ++default_addr_ct;
772
773 /* If we have a default target address, check for an associated
774 address on the same interface. For example, if the default
775 target address is IPv6, this will find an associated IPv4
776 address on the same interface.
777 This makes ICE w/ dual stacks work better - Bug 1609124.
778 */
779 if(!nr_ice_get_assoc_interface_address(
780 new_addr, local_addrs, addr_ct,
781 &default_addrs[default_addr_ct])) {
782 ++default_addr_ct;
783 }
784 }
785 } else {
786 /* Get just the default IPv4 and IPv6 addrs */
787 if(!nr_ice_get_default_local_address(ctx, NR_IPV4, local_addrs, addr_ct,
788 &default_addrs[default_addr_ct])) {
789 ++default_addr_ct;
790 }
791 if(!nr_ice_get_default_local_address(ctx, NR_IPV6, local_addrs, addr_ct,
792 &default_addrs[default_addr_ct])) {
793 ++default_addr_ct;
794 }
795 }
796 if (!default_addr_ct) {
797 r_log(LOG_ICE,LOG_ERR,"ICE(%s): failed to find default addresses",ctx->label);
798 ABORT(R_FAILED);
799 }
800 addrs = default_addrs;
801 addr_ct = default_addr_ct;
802 }
803 else {
804 addrs = local_addrs;
805 }
806
807 /* Sort interfaces by preference */
808 if(ctx->interface_prioritizer) {
809 for(i=0;i<addr_ct;i++){
810 if((r=nr_interface_prioritizer_add_interface(ctx->interface_prioritizer,addrs+i)) && (r!=R_ALREADY)) {
811 r_log(LOG_ICE,LOG_ERR,"ICE(%s): unable to add interface ",ctx->label);
812 ABORT(r);
813 }
814 }
815 if(r=nr_interface_prioritizer_sort_preference(ctx->interface_prioritizer)) {
816 r_log(LOG_ICE,LOG_ERR,"ICE(%s): unable to sort interface by preference",ctx->label);
817 ABORT(r);
818 }
819 }
820
821 if (r=nr_ice_ctx_set_local_addrs(ctx,addrs,addr_ct)) {
822 ABORT(r);
823 }
824
825 _status=0;
826 abort:
827 return(_status);
828 }
829
nr_ice_set_target_for_default_local_address_lookup(nr_ice_ctx * ctx,const char * target_ip,UINT2 target_port)830 int nr_ice_set_target_for_default_local_address_lookup(nr_ice_ctx *ctx, const char *target_ip, UINT2 target_port)
831 {
832 int r,_status;
833
834 if (ctx->target_for_default_local_address_lookup) {
835 RFREE(ctx->target_for_default_local_address_lookup);
836 ctx->target_for_default_local_address_lookup=0;
837 }
838
839 if (!(ctx->target_for_default_local_address_lookup=RCALLOC(sizeof(nr_transport_addr))))
840 ABORT(R_NO_MEMORY);
841
842 if ((r=nr_str_port_to_transport_addr(target_ip, target_port, IPPROTO_UDP, ctx->target_for_default_local_address_lookup))) {
843 RFREE(ctx->target_for_default_local_address_lookup);
844 ctx->target_for_default_local_address_lookup=0;
845 ABORT(r);
846 }
847
848 _status=0;
849 abort:
850 return(_status);
851 }
852
nr_ice_gather(nr_ice_ctx * ctx,NR_async_cb done_cb,void * cb_arg)853 int nr_ice_gather(nr_ice_ctx *ctx, NR_async_cb done_cb, void *cb_arg)
854 {
855 int r,_status;
856 nr_ice_media_stream *stream;
857 nr_local_addr stun_addrs[MAXADDRS];
858 int stun_addr_ct;
859
860 if (!ctx->local_addrs) {
861 if((r=nr_stun_find_local_addresses(stun_addrs,MAXADDRS,&stun_addr_ct))) {
862 ABORT(r);
863 }
864 if((r=nr_ice_set_local_addresses(ctx,stun_addrs,stun_addr_ct))) {
865 ABORT(r);
866 }
867 }
868
869 if(STAILQ_EMPTY(&ctx->streams)) {
870 r_log(LOG_ICE,LOG_ERR,"ICE(%s): Missing streams to initialize",ctx->label);
871 ABORT(R_BAD_ARGS);
872 }
873
874 r_log(LOG_ICE,LOG_DEBUG,"ICE(%s): Initializing candidates",ctx->label);
875 ctx->done_cb=done_cb;
876 ctx->cb_arg=cb_arg;
877
878 /* Initialize all the media stream/component pairs */
879 stream=STAILQ_FIRST(&ctx->streams);
880 while(stream){
881 if(!stream->obsolete) {
882 if(r=nr_ice_media_stream_initialize(ctx,stream)) {
883 r_log(LOG_ICE,LOG_ERR,"ICE(%s): Failed to initialize a stream; this might not be an unrecoverable error, if this stream will be marked obsolete soon due to an ICE restart.",ctx->label);
884 }
885 }
886
887 stream=STAILQ_NEXT(stream,entry);
888 }
889
890 if(ctx->uninitialized_candidates)
891 ABORT(R_WOULDBLOCK);
892
893 _status=0;
894 abort:
895 return(_status);
896 }
897
nr_ice_add_media_stream(nr_ice_ctx * ctx,const char * label,const char * ufrag,const char * pwd,int components,nr_ice_media_stream ** streamp)898 int nr_ice_add_media_stream(nr_ice_ctx *ctx,const char *label,const char *ufrag,const char *pwd,int components, nr_ice_media_stream **streamp)
899 {
900 int r,_status;
901
902 if(r=nr_ice_media_stream_create(ctx,label,ufrag,pwd,components,streamp))
903 ABORT(r);
904
905 STAILQ_INSERT_TAIL(&ctx->streams,*streamp,entry);
906
907 _status=0;
908 abort:
909 return(_status);
910 }
911
nr_ice_remove_media_stream(nr_ice_ctx * ctx,nr_ice_media_stream ** streamp)912 int nr_ice_remove_media_stream(nr_ice_ctx *ctx,nr_ice_media_stream **streamp)
913 {
914 int r,_status;
915 nr_ice_peer_ctx *pctx;
916 nr_ice_media_stream *peer_stream;
917
918 pctx=STAILQ_FIRST(&ctx->peers);
919 while(pctx){
920 if(!nr_ice_peer_ctx_find_pstream(pctx, *streamp, &peer_stream)) {
921 if(r=nr_ice_peer_ctx_remove_pstream(pctx, &peer_stream)) {
922 ABORT(r);
923 }
924 }
925
926 pctx=STAILQ_NEXT(pctx,entry);
927 }
928
929 STAILQ_REMOVE(&ctx->streams,*streamp,nr_ice_media_stream_,entry);
930 if(r=nr_ice_media_stream_destroy(streamp)) {
931 ABORT(r);
932 }
933
934 _status=0;
935 abort:
936 return(_status);
937 }
938
nr_ice_get_global_attributes(nr_ice_ctx * ctx,char *** attrsp,int * attrctp)939 int nr_ice_get_global_attributes(nr_ice_ctx *ctx,char ***attrsp, int *attrctp)
940 {
941 *attrctp=0;
942 *attrsp=0;
943 return(0);
944 }
945
nr_ice_random_string(char * str,int len)946 static int nr_ice_random_string(char *str, int len)
947 {
948 unsigned char bytes[100];
949 size_t needed;
950 int r,_status;
951
952 if(len%2) ABORT(R_BAD_ARGS);
953 needed=len/2;
954
955 if(needed>sizeof(bytes)) ABORT(R_BAD_ARGS);
956
957 if(r=nr_crypto_random_bytes(bytes,needed))
958 ABORT(r);
959
960 if(r=nr_bin2hex(bytes,needed,(unsigned char *)str))
961 ABORT(r);
962
963 _status=0;
964 abort:
965 return(_status);
966 }
967
968 /* This is incredibly annoying: we now have a datagram but we don't
969 know which peer it's from, and we need to be able to tell the
970 API user. So, offer it to each peer and if one bites, assume
971 the others don't want it
972 */
nr_ice_ctx_deliver_packet(nr_ice_ctx * ctx,nr_ice_component * comp,nr_transport_addr * source_addr,UCHAR * data,int len)973 int nr_ice_ctx_deliver_packet(nr_ice_ctx *ctx, nr_ice_component *comp, nr_transport_addr *source_addr, UCHAR *data, int len)
974 {
975 nr_ice_peer_ctx *pctx;
976 int r;
977
978 pctx=STAILQ_FIRST(&ctx->peers);
979 while(pctx){
980 r=nr_ice_peer_ctx_deliver_packet_maybe(pctx, comp, source_addr, data, len);
981 if(!r)
982 break;
983
984 pctx=STAILQ_NEXT(pctx,entry);
985 }
986
987 if(!pctx)
988 r_log(LOG_ICE,LOG_WARNING,"ICE(%s): Packet received from %s which doesn't match any known peer",ctx->label,source_addr->as_string);
989
990 return(0);
991 }
992
nr_ice_ctx_is_known_id(nr_ice_ctx * ctx,UCHAR id[12])993 int nr_ice_ctx_is_known_id(nr_ice_ctx *ctx, UCHAR id[12])
994 {
995 nr_ice_stun_id *xid;
996
997 xid=STAILQ_FIRST(&ctx->ids);
998 while(xid){
999 if (!memcmp(xid->id, id, 12))
1000 return 1;
1001
1002 xid=STAILQ_NEXT(xid,entry);
1003 }
1004
1005 return 0;
1006 }
1007
nr_ice_ctx_remember_id(nr_ice_ctx * ctx,nr_stun_message * msg)1008 int nr_ice_ctx_remember_id(nr_ice_ctx *ctx, nr_stun_message *msg)
1009 {
1010 int _status;
1011 nr_ice_stun_id *xid;
1012
1013 xid = RCALLOC(sizeof(*xid));
1014 if (!xid)
1015 ABORT(R_NO_MEMORY);
1016
1017 assert(sizeof(xid->id) == sizeof(msg->header.id));
1018 #if __STDC_VERSION__ >= 201112L
1019 _Static_assert(sizeof(xid->id) == sizeof(msg->header.id),"Message ID Size Mismatch");
1020 #endif
1021 memcpy(xid->id, &msg->header.id, sizeof(xid->id));
1022
1023 STAILQ_INSERT_TAIL(&ctx->ids,xid,entry);
1024
1025 _status=0;
1026 abort:
1027 return(_status);
1028 }
1029
1030
1031 /* Clean up some of the resources (mostly file descriptors) used
1032 by candidates we didn't choose. Note that this still leaves
1033 a fair amount of non-system stuff floating around. This gets
1034 cleaned up when you destroy the ICE ctx */
nr_ice_ctx_finalize(nr_ice_ctx * ctx,nr_ice_peer_ctx * pctx)1035 int nr_ice_ctx_finalize(nr_ice_ctx *ctx, nr_ice_peer_ctx *pctx)
1036 {
1037 nr_ice_media_stream *lstr,*rstr;
1038
1039 r_log(LOG_ICE,LOG_DEBUG,"Finalizing ICE ctx %s, peer=%s",ctx->label,pctx->label);
1040 /*
1041 First find the peer stream, if any
1042 */
1043 lstr=STAILQ_FIRST(&ctx->streams);
1044 while(lstr){
1045 rstr=STAILQ_FIRST(&pctx->peer_streams);
1046
1047 while(rstr){
1048 if(rstr->local_stream==lstr)
1049 break;
1050
1051 rstr=STAILQ_NEXT(rstr,entry);
1052 }
1053
1054 nr_ice_media_stream_finalize(lstr,rstr);
1055
1056 lstr=STAILQ_NEXT(lstr,entry);
1057 }
1058
1059 return(0);
1060 }
1061
1062
nr_ice_ctx_set_trickle_cb(nr_ice_ctx * ctx,nr_ice_trickle_candidate_cb cb,void * cb_arg)1063 int nr_ice_ctx_set_trickle_cb(nr_ice_ctx *ctx, nr_ice_trickle_candidate_cb cb, void *cb_arg)
1064 {
1065 ctx->trickle_cb = cb;
1066 ctx->trickle_cb_arg = cb_arg;
1067
1068 return 0;
1069 }
1070
nr_ice_ctx_hide_candidate(nr_ice_ctx * ctx,nr_ice_candidate * cand)1071 int nr_ice_ctx_hide_candidate(nr_ice_ctx *ctx, nr_ice_candidate *cand)
1072 {
1073 if (cand->state != NR_ICE_CAND_STATE_INITIALIZED) {
1074 return 1;
1075 }
1076
1077 if (ctx->flags & NR_ICE_CTX_FLAGS_HIDE_HOST_CANDIDATES) {
1078 if (cand->type == HOST)
1079 return 1;
1080 }
1081
1082 if (cand->stream->obsolete) {
1083 return 1;
1084 }
1085
1086 return 0;
1087 }
1088
nr_ice_get_new_ice_ufrag(char ** ufrag)1089 int nr_ice_get_new_ice_ufrag(char** ufrag)
1090 {
1091 int r,_status;
1092 char buf[ICE_UFRAG_LEN+1];
1093
1094 if(r=nr_ice_random_string(buf,ICE_UFRAG_LEN))
1095 ABORT(r);
1096 if(!(*ufrag=r_strdup(buf)))
1097 ABORT(r);
1098
1099 _status=0;
1100 abort:
1101 if(_status) {
1102 RFREE(*ufrag);
1103 *ufrag = 0;
1104 }
1105 return(_status);
1106 }
1107
nr_ice_get_new_ice_pwd(char ** pwd)1108 int nr_ice_get_new_ice_pwd(char** pwd)
1109 {
1110 int r,_status;
1111 char buf[ICE_PWD_LEN+1];
1112
1113 if(r=nr_ice_random_string(buf,ICE_PWD_LEN))
1114 ABORT(r);
1115 if(!(*pwd=r_strdup(buf)))
1116 ABORT(r);
1117
1118 _status=0;
1119 abort:
1120 if(_status) {
1121 RFREE(*pwd);
1122 *pwd = 0;
1123 }
1124 return(_status);
1125 }
1126