media/mtransport/third_party/nICEr/src/ice/ice_ctx.c

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /*
     2 Copyright (c) 2007, Adobe Systems, Incorporated
     3 All rights reserved.
     5 Redistribution and use in source and binary forms, with or without
     6 modification, are permitted provided that the following conditions are
     7 met:
     9 * Redistributions of source code must retain the above copyright
    10   notice, this list of conditions and the following disclaimer.
    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.
    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.
    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 */
    35 static char *RCSSTRING __UNUSED__="$Id: ice_ctx.c,v 1.2 2008/04/28 17:59:01 ekr Exp $";
    37 #include <csi_platform.h>
    38 #include <assert.h>
    39 #include <sys/types.h>
    40 #ifdef WIN32
    41 #include <winsock2.h>
    42 #else
    43 #include <sys/socket.h>
    44 #include <netinet/in.h>
    45 #include <arpa/inet.h>
    46 #endif
    47 #include <sys/queue.h>
    48 #include <string.h>
    49 #include <nr_api.h>
    50 #include <registry.h>
    51 #include "stun.h"
    52 #include "ice_ctx.h"
    53 #include "ice_reg.h"
    54 #include "nr_crypto.h"
    55 #include "async_timer.h"
    56 #include "util.h"
    59 int LOG_ICE = 0;
    61 static int nr_ice_random_string(char *str, int len);
    62 static int nr_ice_fetch_stun_servers(int ct, nr_ice_stun_server **out);
    63 #ifdef USE_TURN
    64 static int nr_ice_fetch_turn_servers(int ct, nr_ice_turn_server **out);
    65 #endif /* USE_TURN */
    66 static void nr_ice_ctx_destroy_cb(NR_SOCKET s, int how, void *cb_arg);
    67 static int nr_ice_ctx_pair_new_trickle_candidates(nr_ice_ctx *ctx, nr_ice_candidate *cand);
    69 int nr_ice_fetch_stun_servers(int ct, nr_ice_stun_server **out)
    70   {
    71     int r,_status;
    72     nr_ice_stun_server *servers = 0;
    73     int i;
    74     NR_registry child;
    75     char *addr=0;
    76     UINT2 port;
    77     in_addr_t addr_int;
    79     if(!(servers=RCALLOC(sizeof(nr_ice_stun_server)*ct)))
    80       ABORT(R_NO_MEMORY);
    82     for(i=0;i<ct;i++){
    83       if(r=NR_reg_get_child_registry(NR_ICE_REG_STUN_SRV_PRFX,i,child))
    84         ABORT(r);
    85       /* Assume we have a v4 addr for now */
    86       if(r=NR_reg_alloc2_string(child,"addr",&addr))
    87         ABORT(r);
    88       addr_int=inet_addr(addr);
    89       if(addr_int==INADDR_NONE){
    90         r_log(LOG_ICE,LOG_ERR,"Invalid address %s;",addr);
    91         ABORT(R_BAD_ARGS);
    92       }
    93       if(r=NR_reg_get2_uint2(child,"port",&port)) {
    94         if (r != R_NOT_FOUND)
    95           ABORT(r);
    96         port = 3478;
    97       }
    98       if(r=nr_ip4_port_to_transport_addr(ntohl(addr_int), port, IPPROTO_UDP,
    99         &servers[i].u.addr))
   100         ABORT(r);
   101       servers[i].index=i;
   102       servers[i].type = NR_ICE_STUN_SERVER_TYPE_ADDR;
   103       RFREE(addr);
   104       addr=0;
   105     }
   107     *out = servers;
   109     _status=0;
   110   abort:
   111     RFREE(addr);
   112     if (_status) RFREE(servers);
   113     return(_status);
   114   }
   116 int nr_ice_ctx_set_stun_servers(nr_ice_ctx *ctx,nr_ice_stun_server *servers,int ct)
   117   {
   118     int _status;
   120     if(ctx->stun_servers){
   121       RFREE(ctx->stun_servers);
   122       ctx->stun_server_ct=0;
   123     }
   125     if (ct) {
   126       if(!(ctx->stun_servers=RCALLOC(sizeof(nr_ice_stun_server)*ct)))
   127         ABORT(R_NO_MEMORY);
   129       memcpy(ctx->stun_servers,servers,sizeof(nr_ice_stun_server)*ct);
   130       ctx->stun_server_ct = ct;
   131     }
   133     _status=0;
   134  abort:
   135     return(_status);
   136   }
   138 int nr_ice_ctx_set_turn_servers(nr_ice_ctx *ctx,nr_ice_turn_server *servers,int ct)
   139   {
   140     int _status;
   142     if(ctx->turn_servers){
   143       RFREE(ctx->turn_servers);
   144       ctx->turn_server_ct=0;
   145     }
   147     if(ct) {
   148       if(!(ctx->turn_servers=RCALLOC(sizeof(nr_ice_turn_server)*ct)))
   149         ABORT(R_NO_MEMORY);
   151       memcpy(ctx->turn_servers,servers,sizeof(nr_ice_turn_server)*ct);
   152       ctx->turn_server_ct = ct;
   153     }
   155     _status=0;
   156  abort:
   157     return(_status);
   158   }
   160 int nr_ice_ctx_set_local_addrs(nr_ice_ctx *ctx,nr_local_addr *addrs,int ct)
   161   {
   162     int _status,i,r;
   164     if(ctx->local_addrs) {
   165       RFREE(ctx->local_addrs);
   166       ctx->local_addr_ct=0;
   167       ctx->local_addrs=0;
   168     }
   170     if (ct) {
   171       if(!(ctx->local_addrs=RCALLOC(sizeof(nr_local_addr)*ct)))
   172         ABORT(R_NO_MEMORY);
   174       for (i=0;i<ct;++i) {
   175         if (r=nr_local_addr_copy(ctx->local_addrs+i,addrs+i)) {
   176           ABORT(r);
   177         }
   178       }
   179       ctx->local_addr_ct = ct;
   180     }
   182     _status=0;
   183    abort:
   184     return(_status);
   185   }
   187 int nr_ice_ctx_set_resolver(nr_ice_ctx *ctx, nr_resolver *resolver)
   188   {
   189     int _status;
   191     if (ctx->resolver) {
   192       ABORT(R_ALREADY);
   193     }
   195     ctx->resolver = resolver;
   197     _status=0;
   198    abort:
   199     return(_status);
   200   }
   202 int nr_ice_ctx_set_interface_prioritizer(nr_ice_ctx *ctx, nr_interface_prioritizer *ip)
   203   {
   204     int _status;
   206     if (ctx->interface_prioritizer) {
   207       ABORT(R_ALREADY);
   208     }
   210     ctx->interface_prioritizer = ip;
   212     _status=0;
   213    abort:
   214     return(_status);
   215   }
   217 #ifdef USE_TURN
   218 int nr_ice_fetch_turn_servers(int ct, nr_ice_turn_server **out)
   219   {
   220     int r,_status;
   221     nr_ice_turn_server *servers = 0;
   222     int i;
   223     NR_registry child;
   224     char *addr=0;
   225     UINT2 port;
   226     in_addr_t addr_int;
   227     Data data={0};
   229     if(!(servers=RCALLOC(sizeof(nr_ice_turn_server)*ct)))
   230       ABORT(R_NO_MEMORY);
   232     for(i=0;i<ct;i++){
   233       if(r=NR_reg_get_child_registry(NR_ICE_REG_TURN_SRV_PRFX,i,child))
   234         ABORT(r);
   235       /* Assume we have a v4 addr for now */
   236       if(r=NR_reg_alloc2_string(child,"addr",&addr))
   237         ABORT(r);
   238       addr_int=inet_addr(addr);
   239       if(addr_int==INADDR_NONE){
   240         r_log(LOG_ICE,LOG_ERR,"Invalid address %s",addr);
   241         ABORT(R_BAD_ARGS);
   242       }
   243       if(r=NR_reg_get2_uint2(child,"port",&port)) {
   244         if (r != R_NOT_FOUND)
   245           ABORT(r);
   246         port = 3478;
   247       }
   248       if(r=nr_ip4_port_to_transport_addr(ntohl(addr_int), port, IPPROTO_UDP,
   249         &servers[i].turn_server.u.addr))
   250         ABORT(r);
   253       if(r=NR_reg_alloc2_string(child,NR_ICE_REG_TURN_SRV_USERNAME,&servers[i].username)){
   254         if(r!=R_NOT_FOUND)
   255           ABORT(r);
   256       }
   258       if(r=NR_reg_alloc2_data(child,NR_ICE_REG_TURN_SRV_PASSWORD,&data)){
   259         if(r!=R_NOT_FOUND)
   260           ABORT(r);
   261       }
   262       else {
   263         servers[i].password=RCALLOC(sizeof(*servers[i].password));
   264         if(!servers[i].password)
   265           ABORT(R_NO_MEMORY);
   266         servers[i].password->data = data.data;
   267         servers[i].password->len = data.len;
   268         data.data=0;
   269       }
   271       servers[i].turn_server.index=i;
   273       RFREE(addr);
   274       addr=0;
   275     }
   277     *out = servers;
   279     _status=0;
   280   abort:
   281     RFREE(data.data);
   282     RFREE(addr);
   283     if (_status) RFREE(servers);
   284     return(_status);
   285   }
   286 #endif /* USE_TURN */
   288 int nr_ice_ctx_create(char *label, UINT4 flags, nr_ice_ctx **ctxp)
   289   {
   290     nr_ice_ctx *ctx=0;
   291     int r,_status;
   292     char buf[100];
   294     if(r=r_log_register("ice", &LOG_ICE))
   295       ABORT(r);
   297     if(!(ctx=RCALLOC(sizeof(nr_ice_ctx))))
   298       ABORT(R_NO_MEMORY);
   300     ctx->flags=flags;
   302     if(!(ctx->label=r_strdup(label)))
   303       ABORT(R_NO_MEMORY);
   305     if(r=nr_ice_random_string(buf,8))
   306       ABORT(r);
   307     if(!(ctx->ufrag=r_strdup(buf)))
   308       ABORT(r);
   309     if(r=nr_ice_random_string(buf,32))
   310       ABORT(r);
   311     if(!(ctx->pwd=r_strdup(buf)))
   312       ABORT(r);
   314     /* Get the STUN servers */
   315     if(r=NR_reg_get_child_count(NR_ICE_REG_STUN_SRV_PRFX,
   316       (unsigned int *)&ctx->stun_server_ct)||ctx->stun_server_ct==0) {
   317       r_log(LOG_ICE,LOG_WARNING,"ICE(%s): No STUN servers specified", ctx->label);
   318       ctx->stun_server_ct=0;
   319     }
   321     /* 255 is the max for our priority algorithm */
   322     if(ctx->stun_server_ct>255){
   323       r_log(LOG_ICE,LOG_WARNING,"ICE(%s): Too many STUN servers specified: max=255", ctx->label);
   324       ctx->stun_server_ct=255;
   325     }
   327     if(ctx->stun_server_ct>0){
   328       if(r=nr_ice_fetch_stun_servers(ctx->stun_server_ct,&ctx->stun_servers)){
   329         r_log(LOG_ICE,LOG_ERR,"ICE(%s): Couldn't load STUN servers from registry", ctx->label);
   330         ctx->stun_server_ct=0;
   331         ABORT(r);
   332       }
   333     }
   335 #ifdef USE_TURN
   336     /* Get the TURN servers */
   337     if(r=NR_reg_get_child_count(NR_ICE_REG_TURN_SRV_PRFX,
   338       (unsigned int *)&ctx->turn_server_ct)||ctx->turn_server_ct==0) {
   339       r_log(LOG_ICE,LOG_NOTICE,"ICE(%s): No TURN servers specified", ctx->label);
   340       ctx->turn_server_ct=0;
   341     }
   342 #else
   343     ctx->turn_server_ct=0;
   344 #endif /* USE_TURN */
   346     ctx->local_addrs=0;
   347     ctx->local_addr_ct=0;
   349     /* 255 is the max for our priority algorithm */
   350     if((ctx->stun_server_ct+ctx->turn_server_ct)>255){
   351       r_log(LOG_ICE,LOG_WARNING,"ICE(%s): Too many STUN/TURN servers specified: max=255", ctx->label);
   352       ctx->turn_server_ct=255-ctx->stun_server_ct;
   353     }
   355 #ifdef USE_TURN
   356     if(ctx->turn_server_ct>0){
   357       if(r=nr_ice_fetch_turn_servers(ctx->turn_server_ct,&ctx->turn_servers)){
   358         ctx->turn_server_ct=0;
   359         r_log(LOG_ICE,LOG_ERR,"ICE(%s): Couldn't load TURN servers from registry", ctx->label);
   360         ABORT(r);
   361       }
   362     }
   363 #endif /* USE_TURN */
   366     ctx->Ta = 20;
   368     STAILQ_INIT(&ctx->streams);
   369     STAILQ_INIT(&ctx->sockets);
   370     STAILQ_INIT(&ctx->foundations);
   371     STAILQ_INIT(&ctx->peers);
   372     STAILQ_INIT(&ctx->ids);
   374     *ctxp=ctx;
   376     _status=0;
   377   abort:
   378     if(_status)
   379       nr_ice_ctx_destroy_cb(0,0,ctx);
   381     return(_status);
   382   }
   384 static void nr_ice_ctx_destroy_cb(NR_SOCKET s, int how, void *cb_arg)
   385   {
   386     nr_ice_ctx *ctx=cb_arg;
   387     nr_ice_foundation *f1,*f2;
   388     nr_ice_media_stream *s1,*s2;
   389     int i;
   390     nr_ice_stun_id *id1,*id2;
   392     RFREE(ctx->label);
   394     RFREE(ctx->stun_servers);
   396     RFREE(ctx->local_addrs);
   398     for (i = 0; i < ctx->turn_server_ct; i++) {
   399         RFREE(ctx->turn_servers[i].username);
   400         r_data_destroy(&ctx->turn_servers[i].password);
   401     }
   402     RFREE(ctx->turn_servers);
   404     f1=STAILQ_FIRST(&ctx->foundations);
   405     while(f1){
   406       f2=STAILQ_NEXT(f1,entry);
   407       RFREE(f1);
   408       f1=f2;
   409     }
   410     RFREE(ctx->pwd);
   411     RFREE(ctx->ufrag);
   413     STAILQ_FOREACH_SAFE(s1, &ctx->streams, entry, s2){
   414       STAILQ_REMOVE(&ctx->streams,s1,nr_ice_media_stream_,entry);
   415       nr_ice_media_stream_destroy(&s1);
   416     }
   418     STAILQ_FOREACH_SAFE(id1, &ctx->ids, entry, id2){
   419       STAILQ_REMOVE(&ctx->ids,id1,nr_ice_stun_id_,entry);
   420       RFREE(id1);
   421     }
   423     nr_resolver_destroy(&ctx->resolver);
   424     nr_interface_prioritizer_destroy(&ctx->interface_prioritizer);
   426     RFREE(ctx);
   427   }
   429 int nr_ice_ctx_destroy(nr_ice_ctx **ctxp)
   430   {
   431     if(!ctxp || !*ctxp)
   432       return(0);
   434     (*ctxp)->done_cb=0;
   435     (*ctxp)->trickle_cb=0;
   437     NR_ASYNC_SCHEDULE(nr_ice_ctx_destroy_cb,*ctxp);
   439     *ctxp=0;
   441     return(0);
   442   }
   444 void nr_ice_initialize_finished_cb(NR_SOCKET s, int h, void *cb_arg)
   445   {
   446     int r,_status;
   447     nr_ice_candidate *cand=cb_arg;
   448     nr_ice_ctx *ctx;
   451     assert(cb_arg);
   452     if (!cb_arg)
   453       return;
   454     ctx = cand->ctx;
   456     ctx->uninitialized_candidates--;
   458     if (cand->state == NR_ICE_CAND_STATE_INITIALIZED) {
   459       int was_pruned = 0;
   461       if (r=nr_ice_component_maybe_prune_candidate(ctx, cand->component,
   462                                                    cand, &was_pruned)) {
   463           r_log(LOG_ICE, LOG_NOTICE, "ICE(%s): Problem pruning candidates",ctx->label);
   464       }
   466       /* If we are initialized, the candidate wasn't pruned,
   467          and we have a trickle ICE callback fire the callback */
   468       if (ctx->trickle_cb && !was_pruned) {
   469         ctx->trickle_cb(ctx->trickle_cb_arg, ctx, cand->stream, cand->component_id, cand);
   471         if (r=nr_ice_ctx_pair_new_trickle_candidates(ctx, cand)) {
   472           r_log(LOG_ICE,LOG_ERR, "ICE(%s): All could not pair new trickle candidate",ctx->label);
   473           /* But continue */
   474         }
   475       }
   476     }
   478     if(ctx->uninitialized_candidates==0){
   479       r_log(LOG_ICE,LOG_DEBUG,"ICE(%s): All candidates initialized",ctx->label);
   480       ctx->state=NR_ICE_STATE_INITIALIZED;
   481       if (ctx->done_cb) {
   482         ctx->done_cb(0,0,ctx->cb_arg);
   483       }
   484       else {
   485         r_log(LOG_ICE,LOG_DEBUG,"ICE(%s): No done_cb. We were probably destroyed.",ctx->label);
   486       }
   487     }
   488     else {
   489       r_log(LOG_ICE,LOG_DEBUG,"ICE(%s): Waiting for %d candidates to be initialized",ctx->label, ctx->uninitialized_candidates);
   490     }
   491   }
   493 static int nr_ice_ctx_pair_new_trickle_candidates(nr_ice_ctx *ctx, nr_ice_candidate *cand)
   494   {
   495     int r,_status;
   496     nr_ice_peer_ctx *pctx;
   498     pctx=STAILQ_FIRST(&ctx->peers);
   499     while(pctx){
   500       if (pctx->state == NR_ICE_PEER_STATE_PAIRED) {
   501         r = nr_ice_peer_ctx_pair_new_trickle_candidate(ctx, pctx, cand);
   502         if (r)
   503           ABORT(r);
   504       }
   506       pctx=STAILQ_NEXT(pctx,entry);
   507     }
   509     _status=0;
   510  abort:
   511     return(_status);
   512   }
   515 #define MAXADDRS 100 // Ridiculously high
   516 int nr_ice_initialize(nr_ice_ctx *ctx, NR_async_cb done_cb, void *cb_arg)
   517   {
   518     int r,_status;
   519     nr_ice_media_stream *stream;
   520     nr_local_addr addrs[MAXADDRS];
   521     int i,addr_ct;
   523     r_log(LOG_ICE,LOG_DEBUG,"ICE(%s): Initializing candidates",ctx->label);
   524     ctx->state=NR_ICE_STATE_INITIALIZING;
   525     ctx->done_cb=done_cb;
   526     ctx->cb_arg=cb_arg;
   528     if(STAILQ_EMPTY(&ctx->streams)) {
   529       r_log(LOG_ICE,LOG_ERR,"ICE(%s): Missing streams to initialize",ctx->label);
   530       ABORT(R_BAD_ARGS);
   531     }
   533     /* First, gather all the local addresses we have */
   534     if(r=nr_stun_find_local_addresses(addrs,MAXADDRS,&addr_ct)) {
   535       r_log(LOG_ICE,LOG_ERR,"ICE(%s): unable to find local addresses",ctx->label);
   536       ABORT(r);
   537     }
   539     /* Sort interfaces by preference */
   540     if(ctx->interface_prioritizer) {
   541       for(i=0;i<addr_ct;i++){
   542         if(r=nr_interface_prioritizer_add_interface(ctx->interface_prioritizer,addrs+i)) {
   543           r_log(LOG_ICE,LOG_ERR,"ICE(%s): unable to add interface ",ctx->label);
   544           ABORT(r);
   545         }
   546       }
   547       if(r=nr_interface_prioritizer_sort_preference(ctx->interface_prioritizer)) {
   548         r_log(LOG_ICE,LOG_ERR,"ICE(%s): unable to sort interface by preference",ctx->label);
   549         ABORT(r);
   550       }
   551     }
   553     if (r=nr_ice_ctx_set_local_addrs(ctx,addrs,addr_ct)) {
   554       ABORT(r);
   555     }
   557     /* Initialize all the media stream/component pairs */
   558     stream=STAILQ_FIRST(&ctx->streams);
   559     while(stream){
   560       if(r=nr_ice_media_stream_initialize(ctx,stream))
   561         ABORT(r);
   563       stream=STAILQ_NEXT(stream,entry);
   564     }
   566     if(ctx->uninitialized_candidates)
   567       ABORT(R_WOULDBLOCK);
   570     _status=0;
   571   abort:
   572     return(_status);
   573   }
   575 int nr_ice_add_media_stream(nr_ice_ctx *ctx,char *label,int components, nr_ice_media_stream **streamp)
   576   {
   577     int r,_status;
   579     if(r=nr_ice_media_stream_create(ctx,label,components,streamp))
   580       ABORT(r);
   582     STAILQ_INSERT_TAIL(&ctx->streams,*streamp,entry);
   584     _status=0;
   585   abort:
   586     return(_status);
   587   }
   589 int nr_ice_get_global_attributes(nr_ice_ctx *ctx,char ***attrsp, int *attrctp)
   590   {
   591     char **attrs=0;
   592     int _status;
   593     char *tmp=0;
   595     if(!(attrs=RCALLOC(sizeof(char *)*2)))
   596       ABORT(R_NO_MEMORY);
   598     if(!(tmp=RMALLOC(100)))
   599       ABORT(R_NO_MEMORY);
   600     snprintf(tmp,100,"ice-ufrag:%s",ctx->ufrag);
   601     attrs[0]=tmp;
   603     if(!(tmp=RMALLOC(100)))
   604       ABORT(R_NO_MEMORY);
   605     snprintf(tmp,100,"ice-pwd:%s",ctx->pwd);
   606     attrs[1]=tmp;
   608     *attrctp=2;
   609     *attrsp=attrs;
   611     _status=0;
   612   abort:
   613     if (_status){
   614       if (attrs){
   615         RFREE(attrs[0]);
   616         RFREE(attrs[1]);
   617       }
   618       RFREE(attrs);
   619     }
   620     return(_status);
   621   }
   623 static int nr_ice_random_string(char *str, int len)
   624   {
   625     unsigned char bytes[100];
   626     int needed;
   627     int r,_status;
   629     if(len%2) ABORT(R_BAD_ARGS);
   630     needed=len/2;
   632     if(needed>sizeof(bytes)) ABORT(R_BAD_ARGS);
   634     //memset(bytes,0,needed);
   636     if(r=nr_crypto_random_bytes(bytes,needed))
   637       ABORT(r);
   639     if(r=nr_bin2hex(bytes,needed,(unsigned char *)str))
   640       ABORT(r);
   642     _status=0;
   643   abort:
   644     return(_status);
   645   }
   647 /* This is incredibly annoying: we now have a datagram but we don't
   648    know which peer it's from, and we need to be able to tell the
   649    API user. So, offer it to each peer and if one bites, assume
   650    the others don't want it
   651 */
   652 int nr_ice_ctx_deliver_packet(nr_ice_ctx *ctx, nr_ice_component *comp, nr_transport_addr *source_addr, UCHAR *data, int len)
   653   {
   654     nr_ice_peer_ctx *pctx;
   655     int r;
   657     pctx=STAILQ_FIRST(&ctx->peers);
   658     while(pctx){
   659       r=nr_ice_peer_ctx_deliver_packet_maybe(pctx, comp, source_addr, data, len);
   660       if(!r)
   661         break;
   663       pctx=STAILQ_NEXT(pctx,entry);
   664     }
   666     if(!pctx)
   667       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);
   669     return(0);
   670   }
   672 int nr_ice_ctx_is_known_id(nr_ice_ctx *ctx, UCHAR id[12])
   673   {
   674     nr_ice_stun_id *xid;
   676     xid=STAILQ_FIRST(&ctx->ids);
   677     while(xid){
   678       if (!memcmp(xid->id, id, 12))
   679           return 1;
   681       xid=STAILQ_NEXT(xid,entry);
   682     }
   684     return 0;
   685   }
   687 int nr_ice_ctx_remember_id(nr_ice_ctx *ctx, nr_stun_message *msg)
   688 {
   689     int _status;
   690     nr_ice_stun_id *xid;
   692     xid = RCALLOC(sizeof(*xid));
   693     if (!xid)
   694         ABORT(R_NO_MEMORY);
   696     assert(sizeof(xid->id) == sizeof(msg->header.id));
   697 #if __STDC_VERSION__ >= 201112L
   698     _Static_assert(sizeof(xid->id) == sizeof(msg->header.id),"Message ID Size Mismatch");
   699 #endif
   700     memcpy(xid->id, &msg->header.id, sizeof(xid->id));
   702     STAILQ_INSERT_TAIL(&ctx->ids,xid,entry);
   704     _status=0;
   705   abort:
   706     return(_status);
   707 }
   710 /* Clean up some of the resources (mostly file descriptors) used
   711    by candidates we didn't choose. Note that this still leaves
   712    a fair amount of non-system stuff floating around. This gets
   713    cleaned up when you destroy the ICE ctx */
   714 int nr_ice_ctx_finalize(nr_ice_ctx *ctx, nr_ice_peer_ctx *pctx)
   715   {
   716     nr_ice_media_stream *lstr,*rstr;
   718     r_log(LOG_ICE,LOG_DEBUG,"Finalizing ICE ctx %s, peer=%s",ctx->label,pctx->label);
   719     /*
   720        First find the peer stream, if any
   721     */
   722     lstr=STAILQ_FIRST(&ctx->streams);
   723     while(lstr){
   724       rstr=STAILQ_FIRST(&pctx->peer_streams);
   726       while(rstr){
   727         if(rstr->local_stream==lstr)
   728           break;
   730         rstr=STAILQ_NEXT(rstr,entry);
   731       }
   733       nr_ice_media_stream_finalize(lstr,rstr);
   735       lstr=STAILQ_NEXT(lstr,entry);
   736     }
   738     return(0);
   739   }
   742 int nr_ice_ctx_set_trickle_cb(nr_ice_ctx *ctx, nr_ice_trickle_candidate_cb cb, void *cb_arg)
   743 {
   744   ctx->trickle_cb = cb;
   745   ctx->trickle_cb_arg = cb_arg;
   747   return 0;
   748 }

mercurial