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