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