media/mtransport/third_party/nICEr/upstream.diff

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/media/mtransport/third_party/nICEr/upstream.diff	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,2449 @@
     1.4 +diff -U10 -r /Users/ekr/dev/mtransport-import-references/nICEr/src/ice/ice_candidate.c src/ice/ice_candidate.c
     1.5 +--- /Users/ekr/dev/mtransport-import-references/nICEr/src/ice/ice_candidate.c	2012-09-16 16:26:08.000000000 -0700
     1.6 ++++ src/ice/ice_candidate.c	2012-10-06 08:30:22.000000000 -0700
     1.7 +@@ -54,36 +54,38 @@
     1.8 + 
     1.9 + #include "stun_client_ctx.h"
    1.10 + #include "stun_server_ctx.h"
    1.11 + #include "turn_client_ctx.h"
    1.12 + #include "ice_ctx.h"
    1.13 + #include "ice_candidate.h"
    1.14 + #include "ice_reg.h"
    1.15 + #include "ice_util.h"
    1.16 + #include "nr_socket_turn.h"
    1.17 + 
    1.18 ++static int next_automatic_preference = 224;
    1.19 ++
    1.20 + static int nr_ice_get_foundation(nr_ice_ctx *ctx,nr_ice_candidate *cand);
    1.21 + static int nr_ice_srvrflx_start_stun(nr_ice_candidate *cand, NR_async_cb ready_cb, void *cb_arg);
    1.22 +-static void nr_ice_srvrflx_stun_finished_cb(int sock, int how, void *cb_arg);
    1.23 ++static void nr_ice_srvrflx_stun_finished_cb(NR_SOCKET sock, int how, void *cb_arg);
    1.24 + #ifdef USE_TURN
    1.25 + static int nr_ice_start_relay_turn(nr_ice_candidate *cand, NR_async_cb ready_cb, void *cb_arg);
    1.26 +-static void nr_ice_turn_allocated_cb(int sock, int how, void *cb_arg);
    1.27 ++static void nr_ice_turn_allocated_cb(NR_SOCKET sock, int how, void *cb_arg);
    1.28 + #endif /* USE_TURN */
    1.29 + 
    1.30 + char *nr_ice_candidate_type_names[]={0,"host","srflx","prflx","relay",0};
    1.31 + 
    1.32 + int nr_ice_candidate_create(nr_ice_ctx *ctx,char *label,nr_ice_component *comp,nr_ice_socket *isock, nr_socket *osock, nr_ice_candidate_type ctype, nr_ice_stun_server *stun_server, UCHAR component_id, nr_ice_candidate **candp)
    1.33 +   {
    1.34 +     nr_ice_candidate *cand=0;
    1.35 +     nr_ice_candidate *tmp=0;
    1.36 +     int r,_status;
    1.37 +- 
    1.38 ++
    1.39 +     if(!(cand=RCALLOC(sizeof(nr_ice_candidate))))
    1.40 +       ABORT(R_NO_MEMORY);
    1.41 +     if(!(cand->label=r_strdup(label)))
    1.42 +       ABORT(R_NO_MEMORY);
    1.43 +     cand->state=NR_ICE_CAND_STATE_CREATED;
    1.44 +     cand->ctx=ctx;
    1.45 +     cand->isock=isock;
    1.46 +     cand->osock=osock;
    1.47 +     cand->type=ctype;
    1.48 +     cand->stun_server=stun_server;
    1.49 +@@ -189,21 +191,21 @@
    1.50 +     if(cand->delay_timer)
    1.51 +       NR_async_timer_cancel(cand->delay_timer);
    1.52 + 
    1.53 +     RFREE(cand->foundation);
    1.54 +     RFREE(cand->label);
    1.55 +     RFREE(cand);
    1.56 +     
    1.57 +     return(0);
    1.58 +   }
    1.59 + 
    1.60 +-void nr_ice_candidate_destroy_cb(int s, int h, void *cb_arg)
    1.61 ++void nr_ice_candidate_destroy_cb(NR_SOCKET s, int h, void *cb_arg)
    1.62 +   {
    1.63 +     nr_ice_candidate *cand=cb_arg;
    1.64 +     nr_ice_candidate_destroy(&cand);
    1.65 +   }
    1.66 + 
    1.67 + /* This algorithm is not super-fast, but I don't think we need a hash
    1.68 +    table just yet and it produces a small foundation string */
    1.69 + static int nr_ice_get_foundation(nr_ice_ctx *ctx,nr_ice_candidate *cand)
    1.70 +   {
    1.71 +     nr_ice_foundation *foundation;
    1.72 +@@ -276,22 +278,38 @@
    1.73 +         break;
    1.74 +       default:
    1.75 +         ABORT(R_INTERNAL);
    1.76 +     }
    1.77 + 
    1.78 +     if(type_preference > 126)
    1.79 +       r_log(LOG_ICE,LOG_ERR,"Illegal type preference %d",type_preference);
    1.80 + 
    1.81 +       
    1.82 +     if(r=NR_reg_get2_uchar(NR_ICE_REG_PREF_INTERFACE_PRFX,cand->base.ifname,
    1.83 +-      &interface_preference))
    1.84 +-      ABORT(r);
    1.85 ++      &interface_preference)) {
    1.86 ++      if (r==R_NOT_FOUND) {
    1.87 ++        if (next_automatic_preference == 1) {
    1.88 ++          r_log(LOG_ICE,LOG_DEBUG,"Out of preference values. Can't assign one for interface %s",cand->base.ifname);
    1.89 ++          ABORT(R_NOT_FOUND);
    1.90 ++        }
    1.91 ++        r_log(LOG_ICE,LOG_DEBUG,"Automatically assigning preference for interface %s->%d",cand->base.ifname,
    1.92 ++          next_automatic_preference);
    1.93 ++        if (r=NR_reg_set2_uchar(NR_ICE_REG_PREF_INTERFACE_PRFX,cand->base.ifname,next_automatic_preference)){
    1.94 ++          ABORT(r);
    1.95 ++        }
    1.96 ++        interface_preference=next_automatic_preference;
    1.97 ++        next_automatic_preference--;
    1.98 ++      }
    1.99 ++      else {
   1.100 ++        ABORT(r);
   1.101 ++      }
   1.102 ++    }
   1.103 + 
   1.104 +     cand->priority=
   1.105 +       (type_preference << 24) |
   1.106 +       (interface_preference << 16) |
   1.107 +       (stun_priority << 8) |
   1.108 +       (256 - cand->component_id);
   1.109 + 
   1.110 +     /* S 4.1.2 */    
   1.111 +     assert(cand->priority>=1&&cand->priority<=2147483647);
   1.112 + 
   1.113 +@@ -306,21 +324,22 @@
   1.114 + 
   1.115 +     cand->done_cb=ready_cb;
   1.116 +     cand->cb_arg=cb_arg;
   1.117 + 
   1.118 +     switch(cand->type){
   1.119 +       case HOST:
   1.120 +         if(r=nr_socket_getaddr(cand->isock->sock,&cand->addr))
   1.121 +           ABORT(r);
   1.122 +         cand->osock=cand->isock->sock;
   1.123 +         cand->state=NR_ICE_CAND_STATE_INITIALIZED;
   1.124 +-        ready_cb(0,0,cb_arg);
   1.125 ++        // Post this so that it doesn't happen in-line
   1.126 ++        NR_ASYNC_SCHEDULE(ready_cb,cb_arg);
   1.127 +         break;
   1.128 + #ifdef USE_TURN
   1.129 +       case RELAYED:
   1.130 +         if(r=nr_ice_start_relay_turn(cand,ready_cb,cb_arg))
   1.131 +           ABORT(r);
   1.132 +         ABORT(R_WOULDBLOCK);
   1.133 +         break;
   1.134 + #endif /* USE_TURN */
   1.135 +       case SERVER_REFLEXIVE:
   1.136 +         /* Need to start stun */
   1.137 +@@ -333,21 +352,21 @@
   1.138 +         ABORT(R_INTERNAL);
   1.139 +     }
   1.140 + 
   1.141 +     _status=0;
   1.142 +   abort:
   1.143 +     if(_status && _status!=R_WOULDBLOCK)
   1.144 +       cand->state=NR_ICE_CAND_STATE_FAILED;
   1.145 +     return(_status);
   1.146 +   }
   1.147 + 
   1.148 +-static void nr_ice_srvrflx_start_stun_timer_cb(int s, int how, void *cb_arg)
   1.149 ++static void nr_ice_srvrflx_start_stun_timer_cb(NR_SOCKET s, int how, void *cb_arg)
   1.150 +   {
   1.151 +     nr_ice_candidate *cand=cb_arg;
   1.152 +     int r,_status;
   1.153 + 
   1.154 +     cand->delay_timer=0;
   1.155 + 
   1.156 + /* TODO: if the response is a BINDING-ERROR-RESPONSE, then restart
   1.157 +  * TODO: using NR_STUN_CLIENT_MODE_BINDING_REQUEST because the
   1.158 +  * TODO: server may not have understood the 0.96-style request */
   1.159 +     if(r=nr_stun_client_start(cand->u.srvrflx.stun, NR_STUN_CLIENT_MODE_BINDING_REQUEST_STUND_0_96, nr_ice_srvrflx_stun_finished_cb, cand))
   1.160 +@@ -387,21 +406,21 @@
   1.161 + 
   1.162 +     _status=0;
   1.163 +   abort:
   1.164 +     if(_status){
   1.165 +       cand->state=NR_ICE_CAND_STATE_FAILED;
   1.166 +     }
   1.167 +     return(_status);
   1.168 +   }
   1.169 + 
   1.170 + #ifdef USE_TURN
   1.171 +-static void nr_ice_start_relay_turn_timer_cb(int s, int how, void *cb_arg)
   1.172 ++static void nr_ice_start_relay_turn_timer_cb(NR_SOCKET s, int how, void *cb_arg)
   1.173 +   {
   1.174 +     nr_ice_candidate *cand=cb_arg;
   1.175 +     int r,_status;
   1.176 +     int i;
   1.177 + 
   1.178 +     cand->delay_timer=0;
   1.179 + 
   1.180 +     if(r=nr_turn_client_allocate(cand->u.relayed.turn, cand->u.relayed.server->username, cand->u.relayed.server->password, cand->u.relayed.server->bandwidth_kbps, cand->u.relayed.server->lifetime_secs, nr_ice_turn_allocated_cb, cand))
   1.181 +       ABORT(r);
   1.182 + 
   1.183 +@@ -443,21 +462,21 @@
   1.184 + 
   1.185 +     _status=0;
   1.186 +   abort:
   1.187 +     if(_status){
   1.188 +       cand->state=NR_ICE_CAND_STATE_FAILED;
   1.189 +     }
   1.190 +     return(_status);
   1.191 +   }
   1.192 + #endif /* USE_TURN */
   1.193 + 
   1.194 +-static void nr_ice_srvrflx_stun_finished_cb(int sock, int how, void *cb_arg)
   1.195 ++static void nr_ice_srvrflx_stun_finished_cb(NR_SOCKET sock, int how, void *cb_arg)
   1.196 +   {
   1.197 +     int _status;
   1.198 +     nr_ice_candidate *cand=cb_arg;
   1.199 + 
   1.200 +     /* Deregister to suppress duplicates */
   1.201 +     if(cand->u.srvrflx.stun_handle){ /* This test because we might have failed before CB registered */
   1.202 +       nr_ice_socket_deregister(cand->isock,cand->u.srvrflx.stun_handle);
   1.203 +       cand->u.srvrflx.stun_handle=0;
   1.204 +     }
   1.205 + 
   1.206 +@@ -481,40 +500,40 @@
   1.207 +     }
   1.208 +     _status = 0;
   1.209 +   abort:
   1.210 +     if(_status){
   1.211 +       cand->state=NR_ICE_CAND_STATE_FAILED;
   1.212 +       cand->done_cb(0,0,cand->cb_arg);
   1.213 +     }
   1.214 +   }
   1.215 + 
   1.216 + #ifdef USE_TURN
   1.217 +-static void nr_ice_turn_allocated_cb(int s, int how, void *cb_arg)
   1.218 ++static void nr_ice_turn_allocated_cb(NR_SOCKET s, int how, void *cb_arg)
   1.219 +   {
   1.220 +     int r,_status;
   1.221 +     nr_ice_candidate *cand=cb_arg;
   1.222 +     nr_turn_client_ctx *turn=cand->u.relayed.turn;
   1.223 +     int i;
   1.224 +     char *label;
   1.225 + 
   1.226 +     /* Deregister to suppress duplicates */
   1.227 +     if(cand->u.relayed.turn_handle){ /* This test because we might have failed before CB registered */
   1.228 +       nr_ice_socket_deregister(cand->isock,cand->u.relayed.turn_handle);
   1.229 +       cand->u.relayed.turn_handle=0;
   1.230 +     }
   1.231 + 
   1.232 +     switch(turn->state){
   1.233 +     /* OK, we should have a mapped address */
   1.234 +     case NR_TURN_CLIENT_STATE_ALLOCATED:
   1.235 +         /* switch candidate from TURN mode to STUN mode */
   1.236 + 
   1.237 +-        if(r=nr_concat_strings(&label,"turn-relay(",cand->base.as_string,"|",turn->relay_addr.as_string,")",0))
   1.238 ++        if(r=nr_concat_strings(&label,"turn-relay(",cand->base.as_string,"|",turn->relay_addr.as_string,")",NULL))
   1.239 +           ABORT(r);
   1.240 + 
   1.241 +         r_log(LOG_ICE,LOG_DEBUG,"ICE(%s): Switching from TURN (%s) to RELAY (%s)",cand->u.relayed.turn->label,cand->label,label);
   1.242 + 
   1.243 +         /* Copy out mapped address and relay address */
   1.244 +         nr_transport_addr_copy(&turn->relay_addr, &cand->u.relayed.turn->stun_ctx[NR_TURN_CLIENT_PHASE_ALLOCATE_REQUEST2]->results.allocate_response2.relay_addr);
   1.245 +         nr_transport_addr_copy(&cand->addr, &turn->relay_addr);
   1.246 + 
   1.247 +         r_log(LOG_ICE,LOG_DEBUG,"ICE-CANDIDATE(%s): base=%s, candidate=%s", cand->label, cand->base.as_string, cand->addr.as_string);
   1.248 + 
   1.249 +diff -U10 -r /Users/ekr/dev/mtransport-import-references/nICEr/src/ice/ice_candidate.h src/ice/ice_candidate.h
   1.250 +--- /Users/ekr/dev/mtransport-import-references/nICEr/src/ice/ice_candidate.h	2012-09-16 16:26:08.000000000 -0700
   1.251 ++++ src/ice/ice_candidate.h	2012-10-06 08:30:22.000000000 -0700
   1.252 +@@ -41,21 +41,22 @@
   1.253 + 
   1.254 + typedef enum {HOST=1, SERVER_REFLEXIVE, PEER_REFLEXIVE, RELAYED} nr_ice_candidate_type;
   1.255 + 
   1.256 + struct nr_ice_candidate_ {
   1.257 +   char *label;
   1.258 +   int state;
   1.259 + #define NR_ICE_CAND_STATE_CREATED          1
   1.260 + #define NR_ICE_CAND_STATE_INITIALIZING     2
   1.261 + #define NR_ICE_CAND_STATE_INITIALIZED      3
   1.262 + #define NR_ICE_CAND_STATE_FAILED           4
   1.263 +-#define NR_ICE_CAND_PEER_CANDIDATE         10
   1.264 ++#define NR_ICE_CAND_PEER_CANDIDATE_UNPAIRED 9
   1.265 ++#define NR_ICE_CAND_PEER_CANDIDATE_PAIRED   10
   1.266 +   struct nr_ice_ctx_ *ctx;
   1.267 +   nr_ice_socket *isock;               /* The socket to read from
   1.268 +                                          (it contains all other candidates
   1.269 +                                          on this socket) */
   1.270 +   nr_socket *osock;                   /* The socket to write to */
   1.271 +   nr_ice_media_stream *stream;        /* The media stream this is associated with */
   1.272 +   nr_ice_component *component;        /* The component this is associated with */
   1.273 +   nr_ice_candidate_type type;         /* The type of the candidate (S 4.1.1) */
   1.274 +   UCHAR component_id;                 /* The component id (S 4.1.2.1) */
   1.275 +   nr_transport_addr addr;             /* The advertised address;
   1.276 +@@ -89,21 +90,21 @@
   1.277 +   TAILQ_ENTRY(nr_ice_candidate_) entry_comp;
   1.278 + };
   1.279 + 
   1.280 + extern char *nr_ice_candidate_type_names[];
   1.281 + 
   1.282 + 
   1.283 + int nr_ice_candidate_create(struct nr_ice_ctx_ *ctx,char *label, nr_ice_component *component, nr_ice_socket *isock, nr_socket *osock, nr_ice_candidate_type ctype, nr_ice_stun_server *stun_server, UCHAR component_id, nr_ice_candidate **candp);
   1.284 + int nr_ice_candidate_initialize(nr_ice_candidate *cand, NR_async_cb ready_cb, void *cb_arg);
   1.285 + int nr_ice_candidate_process_stun(nr_ice_candidate *cand, UCHAR *msg, int len, nr_transport_addr *faddr);
   1.286 + int nr_ice_candidate_destroy(nr_ice_candidate **candp);
   1.287 +-void nr_ice_candidate_destroy_cb(int s, int h, void *cb_arg);
   1.288 ++void nr_ice_candidate_destroy_cb(NR_SOCKET s, int h, void *cb_arg);
   1.289 + int nr_ice_format_candidate_attribute(nr_ice_candidate *cand, char *attr, int maxlen);
   1.290 + int nr_ice_peer_candidate_from_attribute(nr_ice_ctx *ctx,char *attr,nr_ice_media_stream *stream,nr_ice_candidate **candp);
   1.291 + int nr_ice_peer_peer_rflx_candidate_create(nr_ice_ctx *ctx,char *label, nr_ice_component *comp,nr_transport_addr *addr, nr_ice_candidate **candp);
   1.292 + int nr_ice_candidate_compute_priority(nr_ice_candidate *cand);
   1.293 + 
   1.294 + #ifdef __cplusplus
   1.295 + }
   1.296 + #endif /* __cplusplus */
   1.297 + #endif
   1.298 + 
   1.299 +diff -U10 -r /Users/ekr/dev/mtransport-import-references/nICEr/src/ice/ice_candidate_pair.c src/ice/ice_candidate_pair.c
   1.300 +--- /Users/ekr/dev/mtransport-import-references/nICEr/src/ice/ice_candidate_pair.c	2012-09-16 16:26:08.000000000 -0700
   1.301 ++++ src/ice/ice_candidate_pair.c	2012-10-06 08:30:22.000000000 -0700
   1.302 +@@ -37,21 +37,21 @@
   1.303 + #include <assert.h>
   1.304 + #include <string.h>
   1.305 + #include <nr_api.h>
   1.306 + #include "ice_ctx.h"
   1.307 + #include "ice_util.h"
   1.308 + #include "ice_codeword.h"
   1.309 + #include "stun.h"
   1.310 + 
   1.311 + static char *nr_ice_cand_pair_states[]={"UNKNOWN","FROZEN","WAITING","IN_PROGRESS","FAILED","SUCCEEDED","CANCELLED"};
   1.312 + 
   1.313 +-static void nr_ice_candidate_pair_restart_stun_controlled_cb(int s, int how, void *cb_arg);
   1.314 ++static void nr_ice_candidate_pair_restart_stun_controlled_cb(NR_SOCKET s, int how, void *cb_arg);
   1.315 + static void nr_ice_candidate_pair_compute_codeword(nr_ice_cand_pair *pair,
   1.316 +   nr_ice_candidate *lcand, nr_ice_candidate *rcand);
   1.317 + 
   1.318 + int nr_ice_candidate_pair_create(nr_ice_peer_ctx *pctx, nr_ice_candidate *lcand,nr_ice_candidate *rcand,nr_ice_cand_pair **pairp)
   1.319 +   {
   1.320 +     nr_ice_cand_pair *pair=0;
   1.321 +     UINT8 o_priority, a_priority;
   1.322 +     char *lufrag,*rufrag;
   1.323 +     char *lpwd,*rpwd;
   1.324 +     char *l2ruser=0,*r2lpass=0;
   1.325 +@@ -61,21 +61,21 @@
   1.326 +     UINT8 t_priority;
   1.327 + 
   1.328 +     if(!(pair=RCALLOC(sizeof(nr_ice_cand_pair))))
   1.329 +       ABORT(R_NO_MEMORY);
   1.330 +     
   1.331 +     pair->pctx=pctx;
   1.332 +     
   1.333 +     nr_ice_candidate_pair_compute_codeword(pair,lcand,rcand);
   1.334 +     
   1.335 +     if(r=nr_concat_strings(&pair->as_string,pair->codeword,"|",lcand->addr.as_string,"|",
   1.336 +-         rcand->addr.as_string,"(",lcand->label,"|",rcand->label,")",0))
   1.337 ++        rcand->addr.as_string,"(",lcand->label,"|",rcand->label,")", NULL))
   1.338 +       ABORT(r);
   1.339 + 
   1.340 +     nr_ice_candidate_pair_set_state(pctx,pair,NR_ICE_PAIR_STATE_FROZEN);
   1.341 +     pair->local=lcand;
   1.342 +     pair->remote=rcand;
   1.343 + 
   1.344 +     /* Priority computation S 5.7.2 */
   1.345 +     if(pctx->ctx->flags & NR_ICE_CTX_FLAGS_OFFERER)
   1.346 +     {
   1.347 +       assert(!(pctx->ctx->flags & NR_ICE_CTX_FLAGS_ANSWERER));
   1.348 +@@ -87,21 +87,21 @@
   1.349 +       o_priority=rcand->priority;
   1.350 +       a_priority=lcand->priority;
   1.351 +     }
   1.352 +     pair->priority=(MIN(o_priority, a_priority))<<32 | 
   1.353 +       (MAX(o_priority, a_priority))<<1 | (o_priority > a_priority?0:1);
   1.354 +     
   1.355 +     r_log(LOG_ICE,LOG_DEBUG,"ICE(%s): Pairing candidate %s (%x):%s (%x) priority=%llu (%llx) codeword=%s",pctx->ctx->label,lcand->addr.as_string,lcand->priority,rcand->addr.as_string,rcand->priority,pair->priority,pair->priority,pair->codeword);
   1.356 + 
   1.357 +     /* Foundation */
   1.358 +     if(r=nr_concat_strings(&pair->foundation,lcand->foundation,"|",
   1.359 +-      rcand->foundation,0))
   1.360 ++      rcand->foundation,NULL))
   1.361 +       ABORT(r);
   1.362 + 
   1.363 + 
   1.364 +     /* OK, now the STUN data */
   1.365 +     lufrag=lcand->stream->ufrag?lcand->stream->ufrag:pctx->ctx->ufrag;
   1.366 +     lpwd=lcand->stream->pwd?lcand->stream->pwd:pctx->ctx->pwd;
   1.367 +     rufrag=rcand->stream->ufrag?rcand->stream->ufrag:pctx->peer_ufrag;
   1.368 +     rpwd=rcand->stream->pwd?rcand->stream->pwd:pctx->peer_pwd;
   1.369 + 
   1.370 + 
   1.371 +@@ -110,39 +110,39 @@
   1.372 + 
   1.373 +     /* Make a bogus candidate to compute a theoretical peer reflexive
   1.374 +      * priority per S 7.1.1.1 */
   1.375 +     memcpy(&tmpcand, lcand, sizeof(tmpcand));
   1.376 +     tmpcand.type = PEER_REFLEXIVE;
   1.377 +     if (r=nr_ice_candidate_compute_priority(&tmpcand))
   1.378 +       ABORT(r);
   1.379 +     t_priority = tmpcand.priority;
   1.380 + 
   1.381 +     /* Our sending context */
   1.382 +-    if(r=nr_concat_strings(&l2ruser,lufrag,":",rufrag,0))
   1.383 ++    if(r=nr_concat_strings(&l2ruser,lufrag,":",rufrag,NULL))
   1.384 +       ABORT(r);
   1.385 +     if(r=nr_stun_client_ctx_create(pair->as_string,
   1.386 +       lcand->osock,
   1.387 +       &rcand->addr,RTO,&pair->stun_client))
   1.388 +       ABORT(r);
   1.389 +     if(!(pair->stun_client->params.ice_binding_request.username=r_strdup(l2ruser)))
   1.390 +       ABORT(R_NO_MEMORY);
   1.391 +     if(r=r_data_make(&pair->stun_client->params.ice_binding_request.password,(UCHAR *)lpwd,strlen(lpwd)))
   1.392 +       ABORT(r);
   1.393 +     pair->stun_client->params.ice_binding_request.priority=t_priority;
   1.394 +     pair->stun_client->params.ice_binding_request.control = pctx->controlling?
   1.395 +       NR_ICE_CONTROLLING:NR_ICE_CONTROLLED;
   1.396 + 
   1.397 +     pair->stun_client->params.ice_binding_request.tiebreaker=pctx->tiebreaker;
   1.398 + 
   1.399 +     /* Our receiving username/passwords. Stash these for later 
   1.400 +        injection into the stun server ctx*/
   1.401 +-    if(r=nr_concat_strings(&pair->r2l_user,rufrag,":",lufrag,0))
   1.402 ++    if(r=nr_concat_strings(&pair->r2l_user,rufrag,":",lufrag,NULL))
   1.403 +       ABORT(r);
   1.404 +     if(!(r2lpass=r_strdup(rpwd)))
   1.405 +       ABORT(R_NO_MEMORY);
   1.406 +     INIT_DATA(pair->r2l_pwd,(UCHAR *)r2lpass,strlen(r2lpass));
   1.407 +     
   1.408 +     *pairp=pair;
   1.409 + 
   1.410 +     _status=0;
   1.411 +   abort:
   1.412 +     RFREE(l2ruser);
   1.413 +@@ -178,21 +178,21 @@
   1.414 + 
   1.415 + int nr_ice_candidate_pair_unfreeze(nr_ice_peer_ctx *pctx, nr_ice_cand_pair *pair)
   1.416 +   {
   1.417 +     assert(pair->state==NR_ICE_PAIR_STATE_FROZEN);
   1.418 +     
   1.419 +     nr_ice_candidate_pair_set_state(pctx,pair,NR_ICE_PAIR_STATE_WAITING);
   1.420 +     
   1.421 +     return(0);
   1.422 +   }
   1.423 + 
   1.424 +-static void nr_ice_candidate_pair_stun_cb(int s, int how, void *cb_arg)
   1.425 ++static void nr_ice_candidate_pair_stun_cb(NR_SOCKET s, int how, void *cb_arg)
   1.426 +   {
   1.427 +     int r,_status;
   1.428 +     nr_ice_cand_pair *pair=cb_arg,*orig_pair;
   1.429 +     nr_ice_candidate *cand=0;
   1.430 +     nr_stun_message *sres;
   1.431 +     nr_transport_addr *request_src;
   1.432 +     nr_transport_addr *request_dst;
   1.433 +     nr_transport_addr *response_src;
   1.434 +     nr_transport_addr response_dst;
   1.435 +     nr_stun_message_attribute *attr;
   1.436 +@@ -457,32 +457,47 @@
   1.437 +   abort:
   1.438 +     return(_status);
   1.439 +  }
   1.440 + 
   1.441 + int nr_ice_candidate_pair_set_state(nr_ice_peer_ctx *pctx, nr_ice_cand_pair *pair, int state)
   1.442 +   {
   1.443 +     int r,_status;
   1.444 + 
   1.445 +     r_log(LOG_ICE,LOG_DEBUG,"ICE-PEER(%s): setting pair %s to %s",
   1.446 +       pctx->label,pair->as_string,nr_ice_cand_pair_states[state]);
   1.447 +-    pair->state=state;
   1.448 + 
   1.449 +-    if(pctx->state!=NR_ICE_PAIR_STATE_WAITING){
   1.450 ++    /* NOTE: This function used to reference pctx->state instead of
   1.451 ++       pair->state and the assignment to pair->state was at the top
   1.452 ++       of this function. Because pctx->state was never changed, this seems to have
   1.453 ++       been a typo. The natural logic is "if the state changed
   1.454 ++       decrement the counter" so this implies we should be checking
   1.455 ++       the pair state rather than the pctx->state.
   1.456 ++
   1.457 ++       This didn't cause big problems because waiting_pairs was only
   1.458 ++       used for pacing, so the pacing just was kind of broken.
   1.459 ++       
   1.460 ++       This note is here as a reminder until we do more testing
   1.461 ++       and make sure that in fact this was a typo.
   1.462 ++    */
   1.463 ++    if(pair->state!=NR_ICE_PAIR_STATE_WAITING){
   1.464 +       if(state==NR_ICE_PAIR_STATE_WAITING)
   1.465 +         pctx->waiting_pairs++;
   1.466 +     }
   1.467 +     else{
   1.468 +       if(state!=NR_ICE_PAIR_STATE_WAITING)
   1.469 +         pctx->waiting_pairs--;
   1.470 + 
   1.471 +       assert(pctx->waiting_pairs>=0);
   1.472 +     }
   1.473 ++    pair->state=state;
   1.474 ++
   1.475 ++
   1.476 +     if(pair->state==NR_ICE_PAIR_STATE_FAILED){
   1.477 +       if(r=nr_ice_component_failed_pair(pair->remote->component, pair))
   1.478 +         ABORT(r);
   1.479 +     }
   1.480 + 
   1.481 +     _status=0;
   1.482 +   abort:
   1.483 +     return(_status);
   1.484 +   }
   1.485 + 
   1.486 +@@ -505,42 +520,42 @@
   1.487 +         break;
   1.488 +       }
   1.489 +         
   1.490 +       c1=TAILQ_NEXT(c1,entry);
   1.491 +     }
   1.492 +     if(!c1) TAILQ_INSERT_TAIL(head,pair,entry);
   1.493 + 
   1.494 +     return(0);
   1.495 +   }
   1.496 + 
   1.497 +-void nr_ice_candidate_pair_restart_stun_nominated_cb(int s, int how, void *cb_arg)
   1.498 ++void nr_ice_candidate_pair_restart_stun_nominated_cb(NR_SOCKET s, int how, void *cb_arg)
   1.499 +   {
   1.500 +     nr_ice_cand_pair *pair=cb_arg;
   1.501 +     int r,_status;
   1.502 + 
   1.503 +     r_log(LOG_ICE,LOG_DEBUG,"ICE-PEER(%s)/STREAM(%s):%d: Restarting pair %s as nominated",pair->pctx->label,pair->local->stream->label,pair->remote->component->component_id,pair->as_string);
   1.504 + 
   1.505 +     nr_stun_client_reset(pair->stun_client);
   1.506 +     pair->stun_client->params.ice_binding_request.control=NR_ICE_CONTROLLING;
   1.507 + 
   1.508 +     if(r=nr_stun_client_start(pair->stun_client,NR_ICE_CLIENT_MODE_USE_CANDIDATE,nr_ice_candidate_pair_stun_cb,pair))
   1.509 +       ABORT(r);
   1.510 + 
   1.511 +     if(r=nr_ice_ctx_remember_id(pair->pctx->ctx, pair->stun_client->request))
   1.512 +       ABORT(r);
   1.513 + 
   1.514 +     _status=0;
   1.515 +   abort:
   1.516 +     return;
   1.517 +   }
   1.518 + 
   1.519 +-static void nr_ice_candidate_pair_restart_stun_controlled_cb(int s, int how, void *cb_arg)
   1.520 ++static void nr_ice_candidate_pair_restart_stun_controlled_cb(NR_SOCKET s, int how, void *cb_arg)
   1.521 +   {
   1.522 +     nr_ice_cand_pair *pair=cb_arg;
   1.523 +     int r,_status;
   1.524 + 
   1.525 +     r_log(LOG_ICE,LOG_DEBUG,"ICE-PEER(%s)/STREAM(%s):%d: Restarting pair %s as CONTROLLED",pair->pctx->label,pair->local->stream->label,pair->remote->component->component_id,pair->as_string);
   1.526 + 
   1.527 +     nr_stun_client_reset(pair->stun_client);
   1.528 +     pair->stun_client->params.ice_binding_request.control=NR_ICE_CONTROLLED;
   1.529 + 
   1.530 +     if(r=nr_stun_client_start(pair->stun_client,NR_ICE_CLIENT_MODE_BINDING_REQUEST,nr_ice_candidate_pair_stun_cb,pair))
   1.531 +@@ -556,21 +571,21 @@
   1.532 + 
   1.533 + 
   1.534 + 
   1.535 + static void nr_ice_candidate_pair_compute_codeword(nr_ice_cand_pair *pair,
   1.536 +   nr_ice_candidate *lcand, nr_ice_candidate *rcand)
   1.537 +   {
   1.538 +     int r,_status;
   1.539 +     char *as_string=0;
   1.540 + 
   1.541 +     if(r=nr_concat_strings(&as_string,lcand->addr.as_string,"|",
   1.542 +-      rcand->addr.as_string,"(",lcand->label,"|",rcand->label,")",0))
   1.543 ++      rcand->addr.as_string,"(",lcand->label,"|",rcand->label,")",NULL))
   1.544 +       ABORT(r);
   1.545 + 
   1.546 +     nr_ice_compute_codeword(as_string,strlen(as_string),pair->codeword);
   1.547 + 
   1.548 +     _status=0;
   1.549 +       abort:
   1.550 +     RFREE(as_string);
   1.551 + return;
   1.552 +   }
   1.553 + 
   1.554 +diff -U10 -r /Users/ekr/dev/mtransport-import-references/nICEr/src/ice/ice_candidate_pair.h src/ice/ice_candidate_pair.h
   1.555 +--- /Users/ekr/dev/mtransport-import-references/nICEr/src/ice/ice_candidate_pair.h	2012-09-16 16:26:08.000000000 -0700
   1.556 ++++ src/ice/ice_candidate_pair.h	2012-10-06 08:30:22.000000000 -0700
   1.557 +@@ -72,18 +72,18 @@
   1.558 + 
   1.559 + int nr_ice_candidate_pair_create(nr_ice_peer_ctx *pctx, nr_ice_candidate *lcand,nr_ice_candidate *rcand,nr_ice_cand_pair **pairp);
   1.560 + int nr_ice_candidate_pair_unfreeze(nr_ice_peer_ctx *pctx, nr_ice_cand_pair *pair);
   1.561 + int nr_ice_candidate_pair_start(nr_ice_peer_ctx *pctx, nr_ice_cand_pair *pair);
   1.562 + int nr_ice_candidate_pair_set_state(nr_ice_peer_ctx *pctx, nr_ice_cand_pair *pair, int state);
   1.563 + int nr_ice_candidate_pair_dump_state(nr_ice_cand_pair *pair, FILE *out);
   1.564 + int nr_ice_candidate_pair_cancel(nr_ice_peer_ctx *pctx,nr_ice_cand_pair *pair);
   1.565 + int nr_ice_candidate_pair_select(nr_ice_cand_pair *pair);
   1.566 + int nr_ice_candidate_pair_do_triggered_check(nr_ice_peer_ctx *pctx, nr_ice_cand_pair *pair);
   1.567 + int nr_ice_candidate_pair_insert(nr_ice_cand_pair_head *head,nr_ice_cand_pair *pair);
   1.568 +-void nr_ice_candidate_pair_restart_stun_nominated_cb(int s, int how, void *cb_arg);
   1.569 ++void nr_ice_candidate_pair_restart_stun_nominated_cb(NR_SOCKET s, int how, void *cb_arg);
   1.570 + int nr_ice_candidate_pair_destroy(nr_ice_cand_pair **pairp);
   1.571 + 
   1.572 + #ifdef __cplusplus
   1.573 + }
   1.574 + #endif /* __cplusplus */
   1.575 + #endif
   1.576 + 
   1.577 +diff -U10 -r /Users/ekr/dev/mtransport-import-references/nICEr/src/ice/ice_component.c src/ice/ice_component.c
   1.578 +--- /Users/ekr/dev/mtransport-import-references/nICEr/src/ice/ice_component.c	2012-09-16 16:26:08.000000000 -0700
   1.579 ++++ src/ice/ice_component.c	2012-10-06 08:30:22.000000000 -0700
   1.580 +@@ -451,21 +451,21 @@
   1.581 +         if(r=nr_ice_peer_peer_rflx_candidate_create(comp->stream->pctx->ctx,"prflx",comp,&req->src_addr,&pcand)) {
   1.582 +           *error=(r==R_NO_MEMORY)?500:400;
   1.583 +           ABORT(r);
   1.584 +         }
   1.585 +         if(!nr_stun_message_has_attribute(sreq,NR_STUN_ATTR_PRIORITY,&attr)){
   1.586 +           r_log(LOG_ICE,LOG_ERR,"ICE-PEER(%s): Rejecting stun request without priority",comp->stream->pctx->label);
   1.587 +           *error=487;
   1.588 +           ABORT(R_BAD_DATA);
   1.589 +         }
   1.590 +         pcand->priority=attr->u.priority;
   1.591 +-        pcand->state=NR_ICE_CAND_PEER_CANDIDATE;
   1.592 ++        pcand->state=NR_ICE_CAND_PEER_CANDIDATE_PAIRED;;
   1.593 +         TAILQ_INSERT_TAIL(&comp->candidates,pcand,entry_comp);
   1.594 + 
   1.595 +         if(r=nr_ice_candidate_pair_create(comp->stream->pctx,cand,pcand,
   1.596 +              &pair)) {
   1.597 +           *error=(r==R_NO_MEMORY)?500:400;
   1.598 +           ABORT(r);
   1.599 +         }
   1.600 +         nr_ice_candidate_pair_set_state(pair->pctx,pair,NR_ICE_PAIR_STATE_FROZEN);        
   1.601 +       
   1.602 +         if(r=nr_ice_candidate_pair_insert(&comp->stream->check_list,pair)) {
   1.603 +@@ -563,30 +563,38 @@
   1.604 +           break;
   1.605 +       }
   1.606 +       
   1.607 +       /* PAIR with each peer*/
   1.608 +       if(TAILQ_EMPTY(&pcomp->candidates)) {
   1.609 +           /* can happen if our peer proposes no (or all bogus) candidates */
   1.610 +           goto next_cand;
   1.611 +       }
   1.612 +       pcand=TAILQ_FIRST(&pcomp->candidates);
   1.613 +       while(pcand){
   1.614 +-        nr_ice_compute_codeword(pcand->label,strlen(pcand->label),codeword);
   1.615 +-        r_log(LOG_ICE,LOG_DEBUG,"Examining peer candidate %s:%s",codeword,pcand->label);
   1.616 +-
   1.617 +-        if(r=nr_ice_candidate_pair_create(pctx,lcand,pcand,&pair))
   1.618 +-          ABORT(r);
   1.619 +-        
   1.620 +-        if(r=nr_ice_candidate_pair_insert(&pcomp->stream->check_list,
   1.621 +-          pair))
   1.622 +-          ABORT(r);
   1.623 ++        /* Only pair peer candidates which have not yet been paired.
   1.624 ++           This allows "trickle ICE". (Not yet standardized, but
   1.625 ++           part of WebRTC).
   1.626 ++
   1.627 ++           TODO(ekr@rtfm.com): Add refernece to the spec when there
   1.628 ++           is one.
   1.629 ++         */
   1.630 ++        if (pcand->state = NR_ICE_CAND_PEER_CANDIDATE_UNPAIRED) {
   1.631 ++          nr_ice_compute_codeword(pcand->label,strlen(pcand->label),codeword);
   1.632 ++          r_log(LOG_ICE,LOG_DEBUG,"Examining peer candidate %s:%s",codeword,pcand->label);
   1.633 ++          
   1.634 ++          if(r=nr_ice_candidate_pair_create(pctx,lcand,pcand,&pair))
   1.635 ++            ABORT(r);
   1.636 +           
   1.637 ++          if(r=nr_ice_candidate_pair_insert(&pcomp->stream->check_list,
   1.638 ++              pair))
   1.639 ++            ABORT(r);
   1.640 ++        }
   1.641 +         pcand=TAILQ_NEXT(pcand,entry_comp);
   1.642 +       }
   1.643 +     
   1.644 +       if(!pair)
   1.645 +         ABORT(R_INTERNAL);
   1.646 + 
   1.647 +       /* Add the stun username/password pair from the last pair (any 
   1.648 +          would do) to the stun contexts */
   1.649 +       isock=STAILQ_FIRST(&lcomp->sockets);
   1.650 +       while(isock){
   1.651 +@@ -594,20 +602,28 @@
   1.652 +            pair->r2l_user,&pair->r2l_pwd,nr_ice_component_stun_server_cb,pcomp))
   1.653 +           ABORT(r);
   1.654 + 
   1.655 +         isock=STAILQ_NEXT(isock,entry);
   1.656 +       }
   1.657 + 
   1.658 +     next_cand:
   1.659 +       lcand=TAILQ_NEXT(lcand,entry_comp);
   1.660 +     } 
   1.661 + 
   1.662 ++    /* Mark all peer candidates as paired */
   1.663 ++    pcand=TAILQ_FIRST(&pcomp->candidates);
   1.664 ++    while(pcand){
   1.665 ++      pcand->state = NR_ICE_CAND_PEER_CANDIDATE_PAIRED;
   1.666 ++      
   1.667 ++      pcand=TAILQ_NEXT(pcand,entry_comp);
   1.668 ++    }
   1.669 ++
   1.670 +     _status=0;
   1.671 +   abort:
   1.672 +     return(_status);
   1.673 +   }
   1.674 + 
   1.675 + int nr_ice_component_nominated_pair(nr_ice_component *comp, nr_ice_cand_pair *pair)
   1.676 +   {
   1.677 +     int r,_status;
   1.678 +     int fire_cb=0;
   1.679 +     nr_ice_cand_pair *p2;
   1.680 +@@ -616,32 +632,32 @@
   1.681 +       fire_cb=1;
   1.682 + 
   1.683 +     /* Are we changing what the nominated pair is? */
   1.684 +     if(comp->nominated){
   1.685 +       if(comp->nominated->priority > pair->priority)
   1.686 +         return(0);
   1.687 +       r_log(LOG_ICE,LOG_DEBUG,"ICE-PEER(%s)/STREAM(%s)/comp(%d): replacing pair %s with pair %s",comp->stream->pctx->label,comp->stream->label,comp->component_id,comp->nominated->as_string,pair->as_string);
   1.688 +     }
   1.689 + 
   1.690 +     /* Set the new nominated pair */
   1.691 +-    r_log(LOG_ICE,LOG_DEBUG,"ICE-PEER(%s)/STREAM(%s)/comp(%d): nominated pair is %s (0x%x)",comp->stream->pctx->label,comp->stream->label,comp->component_id,pair->as_string,(int)pair);
   1.692 ++    r_log(LOG_ICE,LOG_DEBUG,"ICE-PEER(%s)/STREAM(%s)/comp(%d): nominated pair is %s (0x%p)",comp->stream->pctx->label,comp->stream->label,comp->component_id,pair->as_string,pair);
   1.693 +     comp->state=NR_ICE_COMPONENT_NOMINATED;
   1.694 +     comp->nominated=pair;
   1.695 +     comp->active=pair;
   1.696 + 
   1.697 +-    r_log(LOG_ICE,LOG_DEBUG,"ICE-PEER(%s)/STREAM(%s)/comp(%d): cancelling all pairs but %s (0x%x)",comp->stream->pctx->label,comp->stream->label,comp->component_id,pair->as_string,(int)pair);
   1.698 ++    r_log(LOG_ICE,LOG_DEBUG,"ICE-PEER(%s)/STREAM(%s)/comp(%d): cancelling all pairs but %s (0x%p)",comp->stream->pctx->label,comp->stream->label,comp->component_id,pair->as_string,pair);
   1.699 + 
   1.700 +     /* OK, we need to cancel off everything on this component */
   1.701 +     p2=TAILQ_FIRST(&comp->stream->check_list);
   1.702 +     while(p2){
   1.703 +       if((p2 != pair) && (p2->remote->component->component_id == comp->component_id)){
   1.704 +-        r_log(LOG_ICE,LOG_DEBUG,"ICE-PEER(%s)/STREAM(%s)/comp(%d): cancelling pair %s (0x%x)",comp->stream->pctx->label,comp->stream->label,comp->component_id,p2->as_string,(int)p2);
   1.705 ++        r_log(LOG_ICE,LOG_DEBUG,"ICE-PEER(%s)/STREAM(%s)/comp(%d): cancelling pair %s (0x%p)",comp->stream->pctx->label,comp->stream->label,comp->component_id,p2->as_string,p2);
   1.706 +         
   1.707 +         if(r=nr_ice_candidate_pair_cancel(pair->pctx,p2))
   1.708 +           ABORT(r);
   1.709 +       }
   1.710 + 
   1.711 +       p2=TAILQ_NEXT(p2,entry);
   1.712 +     }
   1.713 +     r_log(LOG_ICE,LOG_DEBUG,"ICE-PEER(%s)/STREAM(%s)/comp(%d): cancelling done",comp->stream->pctx->label,comp->stream->label,comp->component_id);
   1.714 + 
   1.715 +     if(r=nr_ice_media_stream_component_nominated(comp->stream,comp))
   1.716 +@@ -734,21 +750,21 @@
   1.717 +         ABORT(r);
   1.718 +     }
   1.719 + 
   1.720 +     _status=0;
   1.721 +   abort:
   1.722 +     RFREE(pairs);
   1.723 +     return(_status);
   1.724 +   }
   1.725 + 
   1.726 + 
   1.727 +-static void nr_ice_component_keepalive_cb(int s, int how, void *cb_arg)
   1.728 ++static void nr_ice_component_keepalive_cb(NR_SOCKET s, int how, void *cb_arg)
   1.729 +   {
   1.730 +     nr_ice_component *comp=cb_arg;
   1.731 +     UINT4 keepalive_timeout;
   1.732 + 
   1.733 +     assert(comp->keepalive_ctx);
   1.734 + 
   1.735 +     if(NR_reg_get_uint4(NR_ICE_REG_KEEPALIVE_TIMER,&keepalive_timeout)){
   1.736 +       keepalive_timeout=15000; /* Default */
   1.737 +     }
   1.738 + 
   1.739 +diff -U10 -r /Users/ekr/dev/mtransport-import-references/nICEr/src/ice/ice_ctx.c src/ice/ice_ctx.c
   1.740 +--- /Users/ekr/dev/mtransport-import-references/nICEr/src/ice/ice_ctx.c	2012-09-16 16:26:08.000000000 -0700
   1.741 ++++ src/ice/ice_ctx.c	2012-10-06 08:30:22.000000000 -0700
   1.742 +@@ -56,21 +56,21 @@
   1.743 + #include "util.h"
   1.744 + 
   1.745 + 
   1.746 + int LOG_ICE = 0;
   1.747 + 
   1.748 + static int nr_ice_random_string(char *str, int len);
   1.749 + static int nr_ice_fetch_stun_servers(int ct, nr_ice_stun_server **out);
   1.750 + #ifdef USE_TURN
   1.751 + static int nr_ice_fetch_turn_servers(int ct, nr_ice_turn_server **out);
   1.752 + #endif /* USE_TURN */
   1.753 +-static void nr_ice_ctx_destroy_cb(int s, int how, void *cb_arg);
   1.754 ++static void nr_ice_ctx_destroy_cb(NR_SOCKET s, int how, void *cb_arg);
   1.755 + 
   1.756 + int nr_ice_fetch_stun_servers(int ct, nr_ice_stun_server **out)
   1.757 +   {
   1.758 +     int r,_status;
   1.759 +     nr_ice_stun_server *servers = 0;
   1.760 +     int i;
   1.761 +     NR_registry child;
   1.762 +     char *addr=0;
   1.763 +     UINT2 port;
   1.764 +     in_addr_t addr_int;
   1.765 +@@ -271,21 +271,21 @@
   1.766 +     *ctxp=ctx;
   1.767 + 
   1.768 +     _status=0;
   1.769 +   abort:
   1.770 +     if(_status)
   1.771 +       nr_ice_ctx_destroy_cb(0,0,ctx);
   1.772 + 
   1.773 +     return(_status);
   1.774 +   }
   1.775 + 
   1.776 +-static void nr_ice_ctx_destroy_cb(int s, int how, void *cb_arg)
   1.777 ++static void nr_ice_ctx_destroy_cb(NR_SOCKET s, int how, void *cb_arg)
   1.778 +   {
   1.779 +     nr_ice_ctx *ctx=cb_arg;
   1.780 +     nr_ice_foundation *f1,*f2;
   1.781 +     nr_ice_media_stream *s1,*s2;
   1.782 +     int i;
   1.783 +     nr_ice_stun_id *id1,*id2;
   1.784 + 
   1.785 +     RFREE(ctx->label);
   1.786 + 
   1.787 +     RFREE(ctx->stun_servers);
   1.788 +@@ -323,21 +323,21 @@
   1.789 +     if(!ctxp || !*ctxp)
   1.790 +       return(0);
   1.791 + 
   1.792 +     NR_ASYNC_SCHEDULE(nr_ice_ctx_destroy_cb,*ctxp);
   1.793 + 
   1.794 +     *ctxp=0;
   1.795 +     
   1.796 +     return(0);
   1.797 +   }
   1.798 + 
   1.799 +-void nr_ice_initialize_finished_cb(int s, int h, void *cb_arg)
   1.800 ++void nr_ice_initialize_finished_cb(NR_SOCKET s, int h, void *cb_arg)
   1.801 +   {
   1.802 +     nr_ice_ctx *ctx=cb_arg;
   1.803 + 
   1.804 + /*    r_log(LOG_ICE,LOG_DEBUG,"ICE(%s): Candidate %s %s",ctx->label,
   1.805 +       cand->label, cand->state==NR_ICE_CAND_STATE_INITIALIZED?"INITIALIZED":"FAILED");
   1.806 + */
   1.807 +     ctx->uninitialized_candidates--;
   1.808 + 
   1.809 +     if(ctx->uninitialized_candidates==0){
   1.810 +       r_log(LOG_ICE,LOG_DEBUG,"ICE(%s): All candidates initialized",ctx->label);
   1.811 +@@ -368,21 +368,22 @@
   1.812 +     stream=STAILQ_FIRST(&ctx->streams);
   1.813 +     while(stream){
   1.814 +       if(r=nr_ice_media_stream_initialize(ctx,stream))
   1.815 +         ABORT(r);
   1.816 +       
   1.817 +       stream=STAILQ_NEXT(stream,entry);
   1.818 +     }
   1.819 + 
   1.820 +     if(ctx->uninitialized_candidates)
   1.821 +       ABORT(R_WOULDBLOCK);
   1.822 +-
   1.823 ++    
   1.824 ++    
   1.825 +     _status=0;
   1.826 +   abort:
   1.827 +     return(_status);
   1.828 +   }
   1.829 + 
   1.830 + int nr_ice_add_media_stream(nr_ice_ctx *ctx,char *label,int components, nr_ice_media_stream **streamp)
   1.831 +   {
   1.832 +     int r,_status;
   1.833 + 
   1.834 +     if(r=nr_ice_media_stream_create(ctx,label,components,streamp))
   1.835 +diff -U10 -r /Users/ekr/dev/mtransport-import-references/nICEr/src/ice/ice_ctx.h src/ice/ice_ctx.h
   1.836 +--- /Users/ekr/dev/mtransport-import-references/nICEr/src/ice/ice_ctx.h	2012-09-16 16:26:08.000000000 -0700
   1.837 ++++ src/ice/ice_ctx.h	2012-10-06 08:30:22.000000000 -0700
   1.838 +@@ -92,23 +92,23 @@
   1.839 +   UCHAR id[12];
   1.840 + 
   1.841 +   STAILQ_ENTRY(nr_ice_stun_id_) entry;
   1.842 + } nr_ice_stun_id;
   1.843 + 
   1.844 + typedef STAILQ_HEAD(nr_ice_stun_id_head_,nr_ice_stun_id_) nr_ice_stun_id_head;
   1.845 + 
   1.846 + struct nr_ice_ctx_ {
   1.847 +   UINT4 flags;
   1.848 +   int state;
   1.849 +-#define NR_ICE_STATE_CREATED      1
   1.850 +-#define NR_ICE_STATE_INITIALIZING 2
   1.851 +-#define NR_ICE_STATE_INITIALIZED  3
   1.852 ++#define NR_ICE_STATE_CREATED          1
   1.853 ++#define NR_ICE_STATE_INITIALIZING     2
   1.854 ++#define NR_ICE_STATE_INITIALIZED      3
   1.855 +   char *label;
   1.856 +   
   1.857 +   char *ufrag;
   1.858 +   char *pwd;
   1.859 + 
   1.860 +   UINT4 Ta;
   1.861 + 
   1.862 +   nr_ice_stun_server *stun_servers;           /* The list of stun servers */
   1.863 +   int stun_server_ct;
   1.864 +   nr_ice_turn_server *turn_servers;           /* The list of turn servers */
   1.865 +@@ -133,21 +133,21 @@
   1.866 + 
   1.867 + int nr_ice_ctx_create(char *label, UINT4 flags, nr_ice_ctx **ctxp);
   1.868 + #define NR_ICE_CTX_FLAGS_OFFERER                           1
   1.869 + #define NR_ICE_CTX_FLAGS_ANSWERER                          (1<<1)
   1.870 + #define NR_ICE_CTX_FLAGS_AGGRESSIVE_NOMINATION             (1<<2)
   1.871 + #define NR_ICE_CTX_FLAGS_LITE                              (1<<3)
   1.872 + 
   1.873 + int nr_ice_ctx_destroy(nr_ice_ctx **ctxp);
   1.874 + int nr_ice_initialize(nr_ice_ctx *ctx, NR_async_cb done_cb, void *cb_arg);
   1.875 + int nr_ice_add_candidate(nr_ice_ctx *ctx, nr_ice_candidate *cand);
   1.876 +-void nr_ice_initialize_finished_cb(int s, int h, void *cb_arg);
   1.877 ++void nr_ice_initialize_finished_cb(NR_SOCKET s, int h, void *cb_arg);
   1.878 + int nr_ice_add_media_stream(nr_ice_ctx *ctx,char *label,int components, nr_ice_media_stream **streamp);
   1.879 + int nr_ice_get_global_attributes(nr_ice_ctx *ctx,char ***attrsp, int *attrctp);
   1.880 + int nr_ice_ctx_deliver_packet(nr_ice_ctx *ctx, nr_ice_component *comp, nr_transport_addr *source_addr, UCHAR *data, int len);
   1.881 + int nr_ice_ctx_is_known_id(nr_ice_ctx *ctx, UCHAR id[12]);
   1.882 + int nr_ice_ctx_remember_id(nr_ice_ctx *ctx, nr_stun_message *msg);
   1.883 + int nr_ice_ctx_finalize(nr_ice_ctx *ctx, nr_ice_peer_ctx *pctx);
   1.884 + 
   1.885 + extern int LOG_ICE;
   1.886 + 
   1.887 + #ifdef __cplusplus
   1.888 +diff -U10 -r /Users/ekr/dev/mtransport-import-references/nICEr/src/ice/ice_media_stream.c src/ice/ice_media_stream.c
   1.889 +--- /Users/ekr/dev/mtransport-import-references/nICEr/src/ice/ice_media_stream.c	2012-09-16 16:26:08.000000000 -0700
   1.890 ++++ src/ice/ice_media_stream.c	2012-10-06 08:30:22.000000000 -0700
   1.891 +@@ -35,21 +35,21 @@
   1.892 + static char *RCSSTRING __UNUSED__="$Id: ice_media_stream.c,v 1.2 2008/04/28 17:59:01 ekr Exp $";
   1.893 + 
   1.894 + #include <string.h>
   1.895 + #include <assert.h>
   1.896 + #include <nr_api.h>
   1.897 + #include <r_assoc.h>
   1.898 + #include <async_timer.h>
   1.899 + #include "ice_ctx.h"
   1.900 + 
   1.901 + static char *nr_ice_media_stream_states[]={"INVALID",
   1.902 +-  "FROZEN","ACTIVE","COMPLETED","FAILED"
   1.903 ++  "UNPAIRED","FROZEN","ACTIVE","COMPLETED","FAILED"
   1.904 + };
   1.905 + 
   1.906 + int nr_ice_media_stream_set_state(nr_ice_media_stream *str, int state);
   1.907 + 
   1.908 + int nr_ice_media_stream_create(nr_ice_ctx *ctx,char *label,int components, nr_ice_media_stream **streamp)
   1.909 +   {
   1.910 +     int r,_status;
   1.911 +     nr_ice_media_stream *stream=0;
   1.912 +     nr_ice_component *comp=0;
   1.913 +     int i;
   1.914 +@@ -66,29 +66,29 @@
   1.915 +     for(i=0;i<components;i++){
   1.916 +       /* component-id must be > 0, so increment by 1 */
   1.917 +       if(r=nr_ice_component_create(stream, i+1, &comp))
   1.918 +         ABORT(r);
   1.919 + 
   1.920 +     }
   1.921 + 
   1.922 +     TAILQ_INIT(&stream->check_list);
   1.923 + 
   1.924 +     stream->component_ct=components;
   1.925 +-    
   1.926 ++    stream->ice_state = NR_ICE_MEDIA_STREAM_UNPAIRED;
   1.927 +     *streamp=stream;
   1.928 + 
   1.929 +     _status=0;
   1.930 +   abort:
   1.931 +     if(_status){
   1.932 +       nr_ice_media_stream_destroy(&stream);
   1.933 +     }
   1.934 +-    return(_status);            
   1.935 ++    return(_status);
   1.936 +   }
   1.937 + 
   1.938 + int nr_ice_media_stream_destroy(nr_ice_media_stream **streamp)
   1.939 +   {
   1.940 +     nr_ice_media_stream *stream;
   1.941 +     nr_ice_component *c1,*c2;
   1.942 +     nr_ice_cand_pair *p1,*p2;
   1.943 +     if(!streamp || !*streamp)
   1.944 +       return(0);
   1.945 + 
   1.946 +@@ -200,85 +200,148 @@
   1.947 +       if(attrs){
   1.948 +         for(index=0;index<attrct;index++){
   1.949 +           RFREE(attrs[index]);
   1.950 +         }
   1.951 +         RFREE(attrs);
   1.952 +       }
   1.953 +     }
   1.954 +     return(_status);
   1.955 +   }
   1.956 + 
   1.957 ++
   1.958 ++/* Get a default candidate per 4.1.4 */
   1.959 ++int nr_ice_media_stream_get_default_candidate(nr_ice_media_stream *stream, int component, nr_ice_candidate **candp)
   1.960 ++  {
   1.961 ++    int _status;
   1.962 ++    nr_ice_component *comp;
   1.963 ++    nr_ice_candidate *cand;
   1.964 ++    nr_ice_candidate *best_cand = NULL;
   1.965 ++
   1.966 ++    comp=STAILQ_FIRST(&stream->components);
   1.967 ++    while(comp){
   1.968 ++      if (comp->component_id == component)
   1.969 ++        break;
   1.970 ++      
   1.971 ++      comp=STAILQ_NEXT(comp,entry);
   1.972 ++    }
   1.973 ++    
   1.974 ++    if (!comp)
   1.975 ++      ABORT(R_NOT_FOUND);
   1.976 ++
   1.977 ++    /* We have the component. Now find the "best" candidate, making 
   1.978 ++       use of the fact that more "reliable" candidate types have
   1.979 ++       higher numbers. So, we sort by type and then priority within
   1.980 ++       type
   1.981 ++    */
   1.982 ++    cand=TAILQ_FIRST(&comp->candidates);
   1.983 ++    while(cand){
   1.984 ++      if (!best_cand) {
   1.985 ++        best_cand = cand;
   1.986 ++      }
   1.987 ++      else {
   1.988 ++        if (best_cand->type < cand->type) {
   1.989 ++          best_cand = cand;
   1.990 ++        } else if (best_cand->type == cand->type) { 
   1.991 ++          if (best_cand->priority < cand->priority)
   1.992 ++            best_cand = cand;
   1.993 ++        }
   1.994 ++      }
   1.995 ++
   1.996 ++      cand=TAILQ_NEXT(cand,entry_comp);
   1.997 ++    }
   1.998 ++    
   1.999 ++    /* No candidates */
  1.1000 ++    if (!best_cand)
  1.1001 ++      ABORT(R_NOT_FOUND);
  1.1002 ++
  1.1003 ++    *candp = best_cand;
  1.1004 ++
  1.1005 ++    _status=0;
  1.1006 ++  abort:
  1.1007 ++    return(_status);
  1.1008 ++  }
  1.1009 ++
  1.1010 ++
  1.1011 + int nr_ice_media_stream_pair_candidates(nr_ice_peer_ctx *pctx,nr_ice_media_stream *lstream,nr_ice_media_stream *pstream)
  1.1012 +   {
  1.1013 +     int r,_status;
  1.1014 +     nr_ice_component *pcomp,*lcomp;
  1.1015 + 
  1.1016 +     pcomp=STAILQ_FIRST(&pstream->components);
  1.1017 +     lcomp=STAILQ_FIRST(&lstream->components);
  1.1018 +     while(pcomp){
  1.1019 +       if(r=nr_ice_component_pair_candidates(pctx,lcomp,pcomp))
  1.1020 +         ABORT(r);
  1.1021 +-      
  1.1022 ++
  1.1023 +       lcomp=STAILQ_NEXT(lcomp,entry);
  1.1024 +       pcomp=STAILQ_NEXT(pcomp,entry);
  1.1025 +     };
  1.1026 + 
  1.1027 ++    if (pstream->ice_state == NR_ICE_MEDIA_STREAM_UNPAIRED) {
  1.1028 ++      r_log(LOG_ICE,LOG_DEBUG,"ICE-PEER(%s): unfreezing stream %s",pstream->pctx->label,pstream->label);
  1.1029 ++      pstream->ice_state = NR_ICE_MEDIA_STREAM_CHECKS_FROZEN;
  1.1030 ++    }
  1.1031 ++
  1.1032 +     _status=0;
  1.1033 +   abort:
  1.1034 +     return(_status);
  1.1035 +   }
  1.1036 + 
  1.1037 + /* S 5.8 -- run the highest priority WAITING pair or if not available
  1.1038 +    FROZEN pair */
  1.1039 +-static void nr_ice_media_stream_check_timer_cb(int s, int h, void *cb_arg)
  1.1040 ++static void nr_ice_media_stream_check_timer_cb(NR_SOCKET s, int h, void *cb_arg)
  1.1041 +   {
  1.1042 +     int r,_status;
  1.1043 +     nr_ice_media_stream *stream=cb_arg;
  1.1044 +     nr_ice_cand_pair *pair;
  1.1045 +     int timer_val;
  1.1046 + 
  1.1047 +     assert(stream->pctx->active_streams!=0);
  1.1048 + 
  1.1049 +     timer_val=stream->pctx->ctx->Ta*stream->pctx->active_streams;
  1.1050 + 
  1.1051 ++    if (stream->ice_state == NR_ICE_MEDIA_STREAM_CHECKS_COMPLETED) {
  1.1052 ++      r_log(LOG_ICE,LOG_DEBUG,"ICE-PEER(%s): bogus state for stream %s",stream->pctx->label,stream->label);
  1.1053 ++    }
  1.1054 +     assert(stream->ice_state != NR_ICE_MEDIA_STREAM_CHECKS_COMPLETED);
  1.1055 +     
  1.1056 +     r_log(LOG_ICE,LOG_DEBUG,"ICE-PEER(%s): check timer expired for media stream %s",stream->pctx->label,stream->label);
  1.1057 +     stream->timer=0;
  1.1058 + 
  1.1059 +-
  1.1060 +     /* Find the highest priority WAITING check and move it to RUNNING */
  1.1061 +     pair=TAILQ_FIRST(&stream->check_list);
  1.1062 +     while(pair){
  1.1063 +       if(pair->state==NR_ICE_PAIR_STATE_WAITING)
  1.1064 +         break;
  1.1065 +       pair=TAILQ_NEXT(pair,entry);
  1.1066 +     }
  1.1067 + 
  1.1068 +     /* Hmmm... No WAITING. Let's look for FROZEN */
  1.1069 +     if(!pair){
  1.1070 +       pair=TAILQ_FIRST(&stream->check_list);
  1.1071 +-      
  1.1072 ++
  1.1073 +       while(pair){
  1.1074 +         if(pair->state==NR_ICE_PAIR_STATE_FROZEN){
  1.1075 +           if(r=nr_ice_candidate_pair_unfreeze(stream->pctx,pair))
  1.1076 +             ABORT(r);
  1.1077 +           break;
  1.1078 +         }
  1.1079 +         pair=TAILQ_NEXT(pair,entry);
  1.1080 +       }
  1.1081 +     }
  1.1082 + 
  1.1083 +     if(pair){
  1.1084 +       nr_ice_candidate_pair_start(pair->pctx,pair); /* Ignore failures */
  1.1085 +       NR_ASYNC_TIMER_SET(timer_val,nr_ice_media_stream_check_timer_cb,cb_arg,&stream->timer);
  1.1086 +     }
  1.1087 ++    /* TODO(ekr@rtfm.com): Report on the special case where there are no checks to
  1.1088 ++       run at all */
  1.1089 +     _status=0;
  1.1090 +   abort:
  1.1091 +     return;
  1.1092 +   }
  1.1093 + 
  1.1094 + 
  1.1095 + /* Start checks for this media stream (aka check list) */
  1.1096 + int nr_ice_media_stream_start_checks(nr_ice_peer_ctx *pctx, nr_ice_media_stream *stream)
  1.1097 +   {
  1.1098 +     assert(stream->ice_state==NR_ICE_MEDIA_STREAM_CHECKS_FROZEN);
  1.1099 +@@ -476,21 +539,23 @@
  1.1100 +     /* All done... */
  1.1101 +     r_log(LOG_ICE,LOG_INFO,"ICE-PEER(%s)/ICE-STREAM(%s): all components have nominated candidate pairs",stream->pctx->label,stream->label);
  1.1102 +     nr_ice_media_stream_set_state(stream,NR_ICE_MEDIA_STREAM_CHECKS_COMPLETED);
  1.1103 +     
  1.1104 +     /* Cancel our timer */
  1.1105 +     if(stream->timer){
  1.1106 +       NR_async_timer_cancel(stream->timer);
  1.1107 +       stream->timer=0;
  1.1108 +     }
  1.1109 + 
  1.1110 +-    stream->pctx->handler->vtbl->stream_ready(stream->pctx->handler->obj,stream->local_stream);
  1.1111 ++    if (stream->pctx->handler) {
  1.1112 ++      stream->pctx->handler->vtbl->stream_ready(stream->pctx->handler->obj,stream->local_stream);
  1.1113 ++    }
  1.1114 + 
  1.1115 +     /* Now tell the peer_ctx that we're done */
  1.1116 +     if(r=nr_ice_peer_ctx_stream_done(stream->pctx,stream))
  1.1117 +       ABORT(r);
  1.1118 +     
  1.1119 +   done:
  1.1120 +     _status=0;
  1.1121 +   abort:
  1.1122 +     return(_status);
  1.1123 +   }
  1.1124 +@@ -515,21 +580,23 @@
  1.1125 +       
  1.1126 +       p2=TAILQ_NEXT(p2,entry);
  1.1127 +     }
  1.1128 + 
  1.1129 +     /* Cancel our timer */
  1.1130 +     if(stream->timer){
  1.1131 +       NR_async_timer_cancel(stream->timer);
  1.1132 +       stream->timer=0;
  1.1133 +     }
  1.1134 + 
  1.1135 +-    stream->pctx->handler->vtbl->stream_failed(stream->pctx->handler->obj,stream->local_stream);
  1.1136 ++    if (stream->pctx->handler) {
  1.1137 ++      stream->pctx->handler->vtbl->stream_failed(stream->pctx->handler->obj,stream->local_stream);
  1.1138 ++    }
  1.1139 + 
  1.1140 +     /* Now tell the peer_ctx that we're done */
  1.1141 +     if(r=nr_ice_peer_ctx_stream_done(stream->pctx,stream))
  1.1142 +       ABORT(r);
  1.1143 + 
  1.1144 +     _status=0;
  1.1145 +   abort:
  1.1146 +     return(_status);
  1.1147 +   }
  1.1148 + 
  1.1149 +diff -U10 -r /Users/ekr/dev/mtransport-import-references/nICEr/src/ice/ice_media_stream.h src/ice/ice_media_stream.h
  1.1150 +--- /Users/ekr/dev/mtransport-import-references/nICEr/src/ice/ice_media_stream.h	2012-09-16 16:26:08.000000000 -0700
  1.1151 ++++ src/ice/ice_media_stream.h	2012-10-06 08:30:22.000000000 -0700
  1.1152 +@@ -45,40 +45,43 @@
  1.1153 +   struct nr_ice_peer_ctx_ *pctx;
  1.1154 + 
  1.1155 +   struct nr_ice_media_stream_ *local_stream; /* used when this is a peer */
  1.1156 +   int component_ct;
  1.1157 +   nr_ice_component_head components;
  1.1158 + 
  1.1159 +   char *ufrag;    /* ICE username */
  1.1160 +   char *pwd;    /* ICE password */
  1.1161 + 
  1.1162 +   int ice_state;
  1.1163 +-#define NR_ICE_MEDIA_STREAM_CHECKS_FROZEN      1
  1.1164 +-#define NR_ICE_MEDIA_STREAM_CHECKS_ACTIVE      2
  1.1165 +-#define NR_ICE_MEDIA_STREAM_CHECKS_COMPLETED   3
  1.1166 +-#define NR_ICE_MEDIA_STREAM_CHECKS_FAILED      4
  1.1167 ++
  1.1168 ++#define NR_ICE_MEDIA_STREAM_UNPAIRED           1
  1.1169 ++#define NR_ICE_MEDIA_STREAM_CHECKS_FROZEN      2
  1.1170 ++#define NR_ICE_MEDIA_STREAM_CHECKS_ACTIVE      3
  1.1171 ++#define NR_ICE_MEDIA_STREAM_CHECKS_COMPLETED   4
  1.1172 ++#define NR_ICE_MEDIA_STREAM_CHECKS_FAILED      5
  1.1173 + 
  1.1174 +   nr_ice_cand_pair_head check_list;
  1.1175 +   void *timer;  /* Check list periodic timer */
  1.1176 + 
  1.1177 + //  nr_ice_cand_pair_head valid_list;
  1.1178 +-  
  1.1179 ++
  1.1180 +   STAILQ_ENTRY(nr_ice_media_stream_) entry;
  1.1181 + };
  1.1182 + 
  1.1183 + typedef STAILQ_HEAD(nr_ice_media_stream_head_,nr_ice_media_stream_) nr_ice_media_stream_head;
  1.1184 + 
  1.1185 + int nr_ice_media_stream_create(struct nr_ice_ctx_ *ctx,char *label, int components, nr_ice_media_stream **streamp);
  1.1186 + int nr_ice_media_stream_destroy(nr_ice_media_stream **streamp);
  1.1187 + int nr_ice_media_stream_finalize(nr_ice_media_stream *lstr,nr_ice_media_stream *rstr);
  1.1188 + int nr_ice_media_stream_initialize(struct nr_ice_ctx_ *ctx, nr_ice_media_stream *stream);
  1.1189 + int nr_ice_media_stream_get_attributes(nr_ice_media_stream *stream, char ***attrsp,int *attrctp);
  1.1190 ++int nr_ice_media_stream_get_default_candidate(nr_ice_media_stream *stream, int component, nr_ice_candidate **candp);
  1.1191 + int nr_ice_media_stream_pair_candidates(nr_ice_peer_ctx *pctx,nr_ice_media_stream *lstream,nr_ice_media_stream *pstream);
  1.1192 + int nr_ice_media_stream_start_checks(nr_ice_peer_ctx *pctx, nr_ice_media_stream *stream);
  1.1193 + int nr_ice_media_stream_unfreeze_pairs(nr_ice_peer_ctx *pctx, nr_ice_media_stream *stream);
  1.1194 + int nr_ice_media_stream_unfreeze_pairs_foundation(nr_ice_media_stream *stream, char *foundation);
  1.1195 + int nr_ice_media_stream_dump_state(nr_ice_peer_ctx *pctx, nr_ice_media_stream *stream,FILE *out);
  1.1196 + int nr_ice_media_stream_component_nominated(nr_ice_media_stream *stream,nr_ice_component *component);
  1.1197 + int nr_ice_media_stream_component_failed(nr_ice_media_stream *stream,nr_ice_component *component);
  1.1198 + int nr_ice_media_stream_set_state(nr_ice_media_stream *str, int state);
  1.1199 + int nr_ice_media_stream_get_best_candidate(nr_ice_media_stream *str, int component, nr_ice_candidate **candp);
  1.1200 + int nr_ice_media_stream_send(nr_ice_peer_ctx *pctx,nr_ice_media_stream *str, int component, UCHAR *data, int len);
  1.1201 +diff -U10 -r /Users/ekr/dev/mtransport-import-references/nICEr/src/ice/ice_parser.c src/ice/ice_parser.c
  1.1202 +--- /Users/ekr/dev/mtransport-import-references/nICEr/src/ice/ice_parser.c	2012-09-16 16:26:08.000000000 -0700
  1.1203 ++++ src/ice/ice_parser.c	2012-10-06 08:30:22.000000000 -0700
  1.1204 +@@ -35,20 +35,21 @@
  1.1205 + static char *RCSSTRING __UNUSED__="$Id: ice_parser.c,v 1.2 2008/04/28 17:59:01 ekr Exp $";
  1.1206 + 
  1.1207 + #include <csi_platform.h>
  1.1208 + #include <sys/types.h>
  1.1209 + #ifdef WIN32
  1.1210 + #include <winsock2.h>
  1.1211 + #else
  1.1212 + #include <sys/socket.h>
  1.1213 + #include <netinet/in.h>
  1.1214 + #include <arpa/inet.h>
  1.1215 ++#include <strings.h>
  1.1216 + #endif
  1.1217 + #include <string.h>
  1.1218 + #include <assert.h>
  1.1219 + #include <ctype.h>
  1.1220 + #include "nr_api.h"
  1.1221 + #include "ice_ctx.h"
  1.1222 + #include "ice_candidate.h"
  1.1223 + #include "ice_reg.h"
  1.1224 + 
  1.1225 + static void
  1.1226 +@@ -125,21 +126,21 @@
  1.1227 +     char *rel_addr=0;
  1.1228 + 
  1.1229 +     if(!(cand=RCALLOC(sizeof(nr_ice_candidate))))
  1.1230 +         ABORT(R_NO_MEMORY);
  1.1231 + 
  1.1232 +     if(!(cand->label=r_strdup(orig)))
  1.1233 +         ABORT(R_NO_MEMORY);
  1.1234 + 
  1.1235 +     cand->ctx=ctx;
  1.1236 +     cand->isock=0;
  1.1237 +-    cand->state=NR_ICE_CAND_PEER_CANDIDATE;
  1.1238 ++    cand->state=NR_ICE_CAND_PEER_CANDIDATE_UNPAIRED;
  1.1239 +     cand->stream=stream;
  1.1240 +     skip_whitespace(&str);
  1.1241 + 
  1.1242 +     /* Candidate attr */
  1.1243 +     if (strncasecmp(str, "candidate:", 10))
  1.1244 +         ABORT(R_BAD_DATA);
  1.1245 + 
  1.1246 +     fast_forward(&str, 10);
  1.1247 +     if (*str == '\0')
  1.1248 +         ABORT(R_BAD_DATA);
  1.1249 +@@ -311,26 +312,31 @@
  1.1250 +         /* it's expected to be at EOD at this point */
  1.1251 + 
  1.1252 +         break;
  1.1253 +     default:
  1.1254 +         ABORT(R_INTERNAL);
  1.1255 +         break;
  1.1256 +     }
  1.1257 + 
  1.1258 +     skip_whitespace(&str);
  1.1259 + 
  1.1260 +-    assert(strlen(str) == 0);
  1.1261 +-
  1.1262 ++    /* This used to be an assert, but we don't want to exit on invalid
  1.1263 ++       remote data */
  1.1264 ++    if (strlen(str) != 0) {
  1.1265 ++      ABORT(R_BAD_DATA);
  1.1266 ++    }
  1.1267 ++      
  1.1268 +     *candp=cand;
  1.1269 + 
  1.1270 +     _status=0;
  1.1271 +   abort:
  1.1272 ++    /* TODO(ekr@rtfm.com): Fix memory leak if we have a parse error */
  1.1273 +     if (_status)
  1.1274 +         r_log(LOG_ICE,LOG_WARNING,"ICE(%s): Error parsing attribute: %s",ctx->label,orig);
  1.1275 + 
  1.1276 +     RFREE(connection_address);
  1.1277 +     RFREE(rel_addr);
  1.1278 +     return(_status);
  1.1279 + }
  1.1280 + 
  1.1281 + 
  1.1282 + int
  1.1283 +diff -U10 -r /Users/ekr/dev/mtransport-import-references/nICEr/src/ice/ice_peer_ctx.c src/ice/ice_peer_ctx.c
  1.1284 +--- /Users/ekr/dev/mtransport-import-references/nICEr/src/ice/ice_peer_ctx.c	2012-09-16 16:26:08.000000000 -0700
  1.1285 ++++ src/ice/ice_peer_ctx.c	2012-10-06 08:30:22.000000000 -0700
  1.1286 +@@ -35,33 +35,35 @@
  1.1287 + static char *RCSSTRING __UNUSED__="$Id: ice_peer_ctx.c,v 1.2 2008/04/28 17:59:01 ekr Exp $";
  1.1288 + 
  1.1289 + #include <string.h>
  1.1290 + #include <assert.h>
  1.1291 + #include <nr_api.h>
  1.1292 + #include "ice_ctx.h"
  1.1293 + #include "ice_peer_ctx.h"
  1.1294 + #include "nr_crypto.h"
  1.1295 + #include "async_timer.h"
  1.1296 + 
  1.1297 +-static void nr_ice_peer_ctx_destroy_cb(int s, int how, void *cb_arg);
  1.1298 ++static void nr_ice_peer_ctx_destroy_cb(NR_SOCKET s, int how, void *cb_arg);
  1.1299 ++static int nr_ice_peer_ctx_parse_stream_attributes_int(nr_ice_peer_ctx *pctx, nr_ice_media_stream *stream, nr_ice_media_stream *pstream, char **attrs, int attr_ct);
  1.1300 ++static int nr_ice_ctx_parse_candidate(nr_ice_peer_ctx *pctx, nr_ice_media_stream *pstream, char *candidate);
  1.1301 + 
  1.1302 + int nr_ice_peer_ctx_create(nr_ice_ctx *ctx, nr_ice_handler *handler,char *label, nr_ice_peer_ctx **pctxp)
  1.1303 +   {
  1.1304 +     int r,_status;
  1.1305 +     nr_ice_peer_ctx *pctx=0;
  1.1306 + 
  1.1307 +     if(!(pctx=RCALLOC(sizeof(nr_ice_peer_ctx))))
  1.1308 +       ABORT(R_NO_MEMORY);
  1.1309 + 
  1.1310 +     if(!(pctx->label=r_strdup(label)))
  1.1311 +       ABORT(R_NO_MEMORY);
  1.1312 +-    
  1.1313 ++
  1.1314 +     pctx->ctx=ctx;
  1.1315 +     pctx->handler=handler;
  1.1316 + 
  1.1317 +     /* Decide controlling vs. controlled */
  1.1318 +     if(ctx->flags & NR_ICE_CTX_FLAGS_LITE){
  1.1319 +       if(pctx->peer_lite){
  1.1320 +         r_log(LOG_ICE,LOG_ERR,"Both sides are ICE-Lite");
  1.1321 +         ABORT(R_BAD_DATA);
  1.1322 +       }
  1.1323 +         
  1.1324 +@@ -88,85 +90,177 @@
  1.1325 +       nr_ice_peer_ctx_destroy_cb(0,0,pctx);
  1.1326 +     }
  1.1327 +     return(_status);
  1.1328 +   }
  1.1329 + 
  1.1330 + 
  1.1331 + 
  1.1332 + int nr_ice_peer_ctx_parse_stream_attributes(nr_ice_peer_ctx *pctx, nr_ice_media_stream *stream, char **attrs, int attr_ct)
  1.1333 +   {
  1.1334 +     nr_ice_media_stream *pstream=0;
  1.1335 +-    nr_ice_candidate *cand=0;
  1.1336 +     nr_ice_component *comp,*comp2;
  1.1337 +     int r,_status;
  1.1338 +-    int i,j;
  1.1339 + 
  1.1340 +-    /* Note: use component_ct from our own stream since components other
  1.1341 +-       than this offered by the other side are unusable */
  1.1342 ++    /*
  1.1343 ++      Note: use component_ct from our own stream since components other
  1.1344 ++      than this offered by the other side are unusable */
  1.1345 +     if(r=nr_ice_media_stream_create(pctx->ctx,stream->label,stream->component_ct,&pstream))
  1.1346 +       ABORT(r);
  1.1347 +-    
  1.1348 +-    /* Match up the local and remote components */ 
  1.1349 ++
  1.1350 ++    /* Match up the local and remote components */
  1.1351 +     comp=STAILQ_FIRST(&stream->components);
  1.1352 +     comp2=STAILQ_FIRST(&pstream->components);
  1.1353 +     while(comp){
  1.1354 +       comp2->local_component=comp;
  1.1355 + 
  1.1356 +       comp=STAILQ_NEXT(comp,entry);
  1.1357 +       comp2=STAILQ_NEXT(comp2,entry);
  1.1358 +     }
  1.1359 +-        
  1.1360 + 
  1.1361 +-    pstream->ice_state=NR_ICE_MEDIA_STREAM_CHECKS_FROZEN;
  1.1362 +     pstream->local_stream=stream;
  1.1363 +     pstream->pctx=pctx;
  1.1364 + 
  1.1365 ++    if (r=nr_ice_peer_ctx_parse_stream_attributes_int(pctx,stream,pstream,attrs,attr_ct))
  1.1366 ++      ABORT(r);
  1.1367 ++
  1.1368 ++
  1.1369 ++    STAILQ_INSERT_TAIL(&pctx->peer_streams,pstream,entry);
  1.1370 ++
  1.1371 ++    _status=0;
  1.1372 ++  abort:
  1.1373 ++    return(_status);
  1.1374 ++  }
  1.1375 ++
  1.1376 ++static int nr_ice_peer_ctx_parse_stream_attributes_int(nr_ice_peer_ctx *pctx, nr_ice_media_stream *stream, nr_ice_media_stream *pstream, char **attrs, int attr_ct)
  1.1377 ++  {
  1.1378 ++    int r;
  1.1379 ++    int i;
  1.1380 ++
  1.1381 +     for(i=0;i<attr_ct;i++){
  1.1382 +       if(!strncmp(attrs[i],"ice-",4)){
  1.1383 +-        if(r=nr_ice_peer_ctx_parse_media_stream_attribute(pctx,pstream,attrs[i]))
  1.1384 ++        if(r=nr_ice_peer_ctx_parse_media_stream_attribute(pctx,pstream,attrs[i])) {
  1.1385 ++          r_log(LOG_ICE,LOG_ERR,"ICE(%s): peer (%s) specified bogus ICE attribute",pctx->ctx->label,pctx->label);
  1.1386 +           continue;
  1.1387 +-        continue;
  1.1388 ++        }
  1.1389 +       }
  1.1390 +-        
  1.1391 +-      if(r=nr_ice_peer_candidate_from_attribute(pctx->ctx,attrs[i],pstream,&cand))
  1.1392 +-        continue;
  1.1393 +-      if(cand->component_id-1>=pstream->component_ct){
  1.1394 +-        r_log(LOG_ICE,LOG_ERR,"ICE(%s): peer (%s) specified too many components",pctx->ctx->label,pctx->label);
  1.1395 +-        continue;
  1.1396 ++      else if (!strncmp(attrs[i],"candidate",9)){
  1.1397 ++        if(r=nr_ice_ctx_parse_candidate(pctx,pstream,attrs[i])) {
  1.1398 ++          r_log(LOG_ICE,LOG_ERR,"ICE(%s): peer (%s) specified bogus candidate",pctx->ctx->label,pctx->label);
  1.1399 ++          continue;
  1.1400 ++        }
  1.1401 ++      }
  1.1402 ++      else {
  1.1403 ++        r_log(LOG_ICE,LOG_ERR,"ICE(%s): peer (%s) specified bogus attribute",pctx->ctx->label,pctx->label);
  1.1404 +       }
  1.1405 ++    }
  1.1406 + 
  1.1407 +-      /* Not the fastest way to find a component, but it's what we got */
  1.1408 +-      j=1;
  1.1409 +-      for(comp=STAILQ_FIRST(&pstream->components);comp;comp=STAILQ_NEXT(comp,entry)){
  1.1410 +-        if(j==cand->component_id)
  1.1411 +-          break;
  1.1412 ++    /* Doesn't fail because we just skip errors */
  1.1413 ++    return(0);
  1.1414 ++  }
  1.1415 + 
  1.1416 +-        j++;
  1.1417 +-      }
  1.1418 +-      
  1.1419 +-      if(!comp){
  1.1420 +-        r_log(LOG_ICE,LOG_ERR,"Peer answered with more components than we offered");
  1.1421 +-        ABORT(R_BAD_DATA);
  1.1422 +-      }
  1.1423 +-      
  1.1424 +-      cand->component=comp;
  1.1425 ++static int nr_ice_ctx_parse_candidate(nr_ice_peer_ctx *pctx, nr_ice_media_stream *pstream, char *candidate)
  1.1426 ++  {
  1.1427 ++    nr_ice_candidate *cand=0;
  1.1428 ++    nr_ice_component *comp;
  1.1429 ++    int j;
  1.1430 ++    int r, _status;
  1.1431 + 
  1.1432 +-      TAILQ_INSERT_TAIL(&comp->candidates,cand,entry_comp);
  1.1433 ++    if(r=nr_ice_peer_candidate_from_attribute(pctx->ctx,candidate,pstream,&cand))
  1.1434 ++      ABORT(r);
  1.1435 ++    if(cand->component_id-1>=pstream->component_ct){
  1.1436 ++      r_log(LOG_ICE,LOG_ERR,"ICE(%s): peer (%s) specified too many components",pctx->ctx->label,pctx->label);
  1.1437 ++      ABORT(R_BAD_DATA);
  1.1438 +     }
  1.1439 + 
  1.1440 +-    STAILQ_INSERT_TAIL(&pctx->peer_streams,pstream,entry);
  1.1441 ++    /* Not the fastest way to find a component, but it's what we got */
  1.1442 ++    j=1;
  1.1443 ++    for(comp=STAILQ_FIRST(&pstream->components);comp;comp=STAILQ_NEXT(comp,entry)){
  1.1444 ++      if(j==cand->component_id)
  1.1445 ++        break;
  1.1446 ++
  1.1447 ++      j++;
  1.1448 ++    }
  1.1449 ++
  1.1450 ++    if(!comp){
  1.1451 ++      r_log(LOG_ICE,LOG_ERR,"Peer answered with more components than we offered");
  1.1452 ++      ABORT(R_BAD_DATA);
  1.1453 ++    }
  1.1454 ++
  1.1455 ++    cand->component=comp;
  1.1456 ++
  1.1457 ++    TAILQ_INSERT_TAIL(&comp->candidates,cand,entry_comp);
  1.1458 + 
  1.1459 +     _status=0;
  1.1460 +-  abort:
  1.1461 ++ abort:
  1.1462 ++    if (_status) {
  1.1463 ++      nr_ice_candidate_destroy(&cand);
  1.1464 ++    }
  1.1465 +     return(_status);
  1.1466 +   }
  1.1467 + 
  1.1468 ++
  1.1469 ++
  1.1470 ++int nr_ice_peer_ctx_parse_trickle_candidate(nr_ice_peer_ctx *pctx, nr_ice_media_stream *stream, char *candidate)
  1.1471 ++  {
  1.1472 ++    /* First need to find the stream. Because we don't have forward pointers,
  1.1473 ++       iterate through all the peer streams to find one that matches us */
  1.1474 ++    nr_ice_media_stream *pstream;
  1.1475 ++    int r,_status;
  1.1476 ++    int needs_pairing = 0;
  1.1477 ++
  1.1478 ++    pstream=STAILQ_FIRST(&pctx->peer_streams);
  1.1479 ++    while(pstream) {
  1.1480 ++      if (pstream->local_stream == stream)
  1.1481 ++        break;
  1.1482 ++      
  1.1483 ++      pstream = STAILQ_NEXT(pstream, entry);
  1.1484 ++    }
  1.1485 ++    if (!pstream) {
  1.1486 ++      r_log(LOG_ICE,LOG_ERR,"ICE(%s): peer (%s) has no stream matching stream %s",pctx->ctx->label,pctx->label,stream->label);
  1.1487 ++      ABORT(R_NOT_FOUND);
  1.1488 ++    }
  1.1489 ++
  1.1490 ++    switch(pstream->ice_state) {
  1.1491 ++      case NR_ICE_MEDIA_STREAM_UNPAIRED:
  1.1492 ++        break;
  1.1493 ++      case NR_ICE_MEDIA_STREAM_CHECKS_FROZEN:
  1.1494 ++      case NR_ICE_MEDIA_STREAM_CHECKS_ACTIVE:
  1.1495 ++        needs_pairing = 1;
  1.1496 ++        break;
  1.1497 ++      default:
  1.1498 ++        r_log(LOG_ICE,LOG_ERR,"ICE(%s): peer (%s), stream(%s) tried to trickle ICE in inappropriate state %d",pctx->ctx->label,pctx->label,stream->label,pstream->ice_state);
  1.1499 ++        ABORT(R_ALREADY);
  1.1500 ++        break;
  1.1501 ++    }
  1.1502 ++
  1.1503 ++    if(r=nr_ice_ctx_parse_candidate(pctx,pstream,candidate)){
  1.1504 ++      ABORT(r);
  1.1505 ++    }
  1.1506 ++
  1.1507 ++    /* If ICE is running (i.e., we are in FROZEN or ACTIVE states)
  1.1508 ++       then we need to pair this new candidate. For now we
  1.1509 ++       just re-pair the stream which is inefficient but still
  1.1510 ++       fine because we suppress duplicate pairing */
  1.1511 ++    if (needs_pairing) {
  1.1512 ++      if(r=nr_ice_media_stream_pair_candidates(pctx, stream, pstream)) {
  1.1513 ++        r_log(LOG_ICE,LOG_ERR,"ICE(%s): peer (%s), stream(%s) failed to pair trickle ICE candidates",pctx->ctx->label,pctx->label,stream->label);
  1.1514 ++        ABORT(r);
  1.1515 ++      }
  1.1516 ++    }
  1.1517 ++
  1.1518 ++    _status =0;
  1.1519 ++ abort:
  1.1520 ++    return(_status);
  1.1521 ++
  1.1522 ++  }
  1.1523 ++
  1.1524 ++
  1.1525 + int nr_ice_peer_ctx_pair_candidates(nr_ice_peer_ctx *pctx)
  1.1526 +   {
  1.1527 +     nr_ice_media_stream *stream;
  1.1528 +     int r,_status;
  1.1529 + 
  1.1530 +     if(STAILQ_EMPTY(&pctx->peer_streams)) {
  1.1531 +         r_log(LOG_ICE,LOG_ERR,"ICE(%s): peer (%s) received no media stream attribributes",pctx->ctx->label,pctx->label);
  1.1532 +         ABORT(R_FAILED);
  1.1533 +     }
  1.1534 + 
  1.1535 +@@ -177,21 +271,21 @@
  1.1536 +         ABORT(r);
  1.1537 + 
  1.1538 +       stream=STAILQ_NEXT(stream,entry);
  1.1539 +     }   
  1.1540 + 
  1.1541 +     _status=0;
  1.1542 +   abort:
  1.1543 +     return(_status);
  1.1544 +   }
  1.1545 + 
  1.1546 +-static void nr_ice_peer_ctx_destroy_cb(int s, int how, void *cb_arg)
  1.1547 ++static void nr_ice_peer_ctx_destroy_cb(NR_SOCKET s, int how, void *cb_arg)
  1.1548 +   {
  1.1549 +     nr_ice_peer_ctx *pctx=cb_arg;
  1.1550 +     nr_ice_media_stream *str1,*str2;
  1.1551 + 
  1.1552 +     RFREE(pctx->label);
  1.1553 +     RFREE(pctx->peer_ufrag);
  1.1554 +     RFREE(pctx->peer_pwd);
  1.1555 +     
  1.1556 +     STAILQ_FOREACH_SAFE(str1, &pctx->peer_streams, entry, str2){
  1.1557 +       STAILQ_REMOVE(&pctx->peer_streams,str1,nr_ice_media_stream_,entry);
  1.1558 +@@ -199,44 +293,79 @@
  1.1559 +     }
  1.1560 + 
  1.1561 +     RFREE(pctx);
  1.1562 +   }
  1.1563 + 
  1.1564 + int nr_ice_peer_ctx_destroy(nr_ice_peer_ctx **pctxp)
  1.1565 +   {
  1.1566 + 
  1.1567 +     if(!pctxp || !*pctxp)
  1.1568 +       return(0);
  1.1569 +-    
  1.1570 ++
  1.1571 ++    /* Stop calling the handler */
  1.1572 ++    (*pctxp)->handler = 0;
  1.1573 ++
  1.1574 +     NR_ASYNC_SCHEDULE(nr_ice_peer_ctx_destroy_cb,*pctxp);
  1.1575 + 
  1.1576 +     *pctxp=0;
  1.1577 + 
  1.1578 +     return(0);
  1.1579 +   }
  1.1580 + 
  1.1581 ++
  1.1582 + /* Start the checks for the first media stream (S 5.7)
  1.1583 +    The rest remain FROZEN */
  1.1584 + int nr_ice_peer_ctx_start_checks(nr_ice_peer_ctx *pctx)
  1.1585 +   {
  1.1586 ++    return nr_ice_peer_ctx_start_checks2(pctx, 0);
  1.1587 ++  }
  1.1588 ++
  1.1589 ++/* Start checks for some media stream.
  1.1590 ++
  1.1591 ++   If allow_non_first == 0, then we only look at the first stream,
  1.1592 ++   which is 5245-complaint.
  1.1593 ++
  1.1594 ++   If allow_non_first == 1 then we find the first non-empty stream
  1.1595 ++   This is not compliant with RFC 5245 but is necessary to make trickle ICE
  1.1596 ++   work plausibly
  1.1597 ++*/
  1.1598 ++int nr_ice_peer_ctx_start_checks2(nr_ice_peer_ctx *pctx, int allow_non_first)
  1.1599 ++  {
  1.1600 +     int r,_status;
  1.1601 +     nr_ice_media_stream *stream;
  1.1602 + 
  1.1603 +     stream=STAILQ_FIRST(&pctx->peer_streams);
  1.1604 +     if(!stream)
  1.1605 +       ABORT(R_FAILED);
  1.1606 + 
  1.1607 ++    while (stream) {
  1.1608 ++      if(!TAILQ_EMPTY(&stream->check_list))
  1.1609 ++        break;
  1.1610 ++
  1.1611 ++      if(!allow_non_first){
  1.1612 ++        r_log(LOG_ICE,LOG_ERR,"ICE(%s): peer (%s) first stream has empty check list",pctx->ctx->label,pctx->label);
  1.1613 ++        ABORT(R_FAILED);
  1.1614 ++      }
  1.1615 ++
  1.1616 ++      stream=STAILQ_NEXT(stream, entry);
  1.1617 ++    }
  1.1618 ++
  1.1619 ++    if (!stream) {
  1.1620 ++      r_log(LOG_ICE,LOG_ERR,"ICE(%s): peer (%s) no streams with non-empty check lists",pctx->ctx->label,pctx->label);
  1.1621 ++      ABORT(R_NOT_FOUND);
  1.1622 ++    }
  1.1623 ++
  1.1624 +     if (stream->ice_state == NR_ICE_MEDIA_STREAM_CHECKS_FROZEN) {
  1.1625 +-        if(r=nr_ice_media_stream_unfreeze_pairs(pctx,stream))
  1.1626 +-          ABORT(r);
  1.1627 +-        if(r=nr_ice_media_stream_start_checks(pctx,stream))
  1.1628 +-          ABORT(r);
  1.1629 ++      if(r=nr_ice_media_stream_unfreeze_pairs(pctx,stream))
  1.1630 ++        ABORT(r);
  1.1631 ++      if(r=nr_ice_media_stream_start_checks(pctx,stream))
  1.1632 ++        ABORT(r);
  1.1633 +     }
  1.1634 + 
  1.1635 +     _status=0;
  1.1636 +   abort:
  1.1637 +     return(_status);
  1.1638 +   }
  1.1639 + 
  1.1640 + #ifndef NDEBUG
  1.1641 + int nr_ice_peer_ctx_dump_state(nr_ice_peer_ctx *pctx,FILE *out)
  1.1642 +   {
  1.1643 +@@ -253,26 +382,28 @@
  1.1644 +       stream=STAILQ_NEXT(stream,entry);
  1.1645 +     }
  1.1646 +     fprintf(out,"==========================================\n");
  1.1647 + 
  1.1648 +     _status=0;
  1.1649 +   abort:
  1.1650 +     return(_status);
  1.1651 +   }
  1.1652 + #endif
  1.1653 + 
  1.1654 +-static void nr_ice_peer_ctx_fire_done(int s, int how, void *cb_arg)
  1.1655 ++static void nr_ice_peer_ctx_fire_done(NR_SOCKET s, int how, void *cb_arg)
  1.1656 +   {
  1.1657 +     nr_ice_peer_ctx *pctx=cb_arg;
  1.1658 + 
  1.1659 +     /* Fire the handler callback to say we're done */
  1.1660 +-    pctx->handler->vtbl->ice_completed(pctx->handler->obj, pctx);
  1.1661 ++    if (pctx->handler) {
  1.1662 ++      pctx->handler->vtbl->ice_completed(pctx->handler->obj, pctx);
  1.1663 ++    }
  1.1664 +   }
  1.1665 + 
  1.1666 + 
  1.1667 + /* OK, a stream just went ready. Examine all the streams to see if we're
  1.1668 +    maybe miraculously done */
  1.1669 + int nr_ice_peer_ctx_stream_done(nr_ice_peer_ctx *pctx, nr_ice_media_stream *stream)
  1.1670 +   {
  1.1671 +     int _status;
  1.1672 +     nr_ice_media_stream *str;
  1.1673 +     int failed=0;
  1.1674 +@@ -365,21 +496,24 @@
  1.1675 +         NR_TRANSPORT_ADDR_CMP_MODE_ALL))
  1.1676 +         break;
  1.1677 + 
  1.1678 +       cand=TAILQ_NEXT(cand,entry_comp);
  1.1679 +     }
  1.1680 + 
  1.1681 +     if(!cand)
  1.1682 +       ABORT(R_REJECTED);
  1.1683 + 
  1.1684 +     /* OK, there's a match. Call the handler */
  1.1685 +-    r_log(LOG_ICE,LOG_DEBUG,"ICE-PEER(%s): Delivering data", pctx->label);
  1.1686 + 
  1.1687 +-    pctx->handler->vtbl->msg_recvd(pctx->handler->obj,
  1.1688 +-      pctx,comp->stream,comp->component_id,data,len);
  1.1689 ++    if (pctx->handler) {
  1.1690 ++      r_log(LOG_ICE,LOG_DEBUG,"ICE-PEER(%s): Delivering data", pctx->label);
  1.1691 ++
  1.1692 ++      pctx->handler->vtbl->msg_recvd(pctx->handler->obj,
  1.1693 ++        pctx,comp->stream,comp->component_id,data,len);
  1.1694 ++    }
  1.1695 + 
  1.1696 +     _status=0;
  1.1697 +   abort:
  1.1698 +     return(_status);
  1.1699 +   }
  1.1700 + 
  1.1701 + 
  1.1702 +diff -U10 -r /Users/ekr/dev/mtransport-import-references/nICEr/src/ice/ice_peer_ctx.h src/ice/ice_peer_ctx.h
  1.1703 +--- /Users/ekr/dev/mtransport-import-references/nICEr/src/ice/ice_peer_ctx.h	2012-09-16 16:26:08.000000000 -0700
  1.1704 ++++ src/ice/ice_peer_ctx.h	2012-10-06 08:30:22.000000000 -0700
  1.1705 +@@ -33,23 +33,21 @@
  1.1706 + 
  1.1707 + 
  1.1708 + #ifndef _ice_peer_ctx_h
  1.1709 + #define _ice_peer_ctx_h
  1.1710 + #ifdef __cplusplus
  1.1711 + using namespace std;
  1.1712 + extern "C" {
  1.1713 + #endif /* __cplusplus */
  1.1714 + 
  1.1715 + struct nr_ice_peer_ctx_ {
  1.1716 +-  int state;
  1.1717 +   char *label;
  1.1718 +-  
  1.1719 +   nr_ice_ctx *ctx;
  1.1720 +   nr_ice_handler *handler;
  1.1721 + 
  1.1722 +   UCHAR controlling; /* 1 for controlling, 0 for controlled */
  1.1723 +   UINT8 tiebreaker;
  1.1724 + 
  1.1725 +   char *peer_ufrag;
  1.1726 +   char *peer_pwd;
  1.1727 +   int peer_lite;
  1.1728 +   int peer_ice_mismatch;
  1.1729 +@@ -59,23 +57,26 @@
  1.1730 +   int waiting_pairs;
  1.1731 + 
  1.1732 +   STAILQ_ENTRY(nr_ice_peer_ctx_) entry;
  1.1733 + };
  1.1734 + 
  1.1735 + typedef STAILQ_HEAD(nr_ice_peer_ctx_head_, nr_ice_peer_ctx_) nr_ice_peer_ctx_head;
  1.1736 + 
  1.1737 + int nr_ice_peer_ctx_create(nr_ice_ctx *ctx, nr_ice_handler *handler,char *label, nr_ice_peer_ctx **pctxp);
  1.1738 + int nr_ice_peer_ctx_destroy(nr_ice_peer_ctx **pctxp);
  1.1739 + int nr_ice_peer_ctx_parse_stream_attributes(nr_ice_peer_ctx *pctx, nr_ice_media_stream *stream, char **attrs, int attr_ct);
  1.1740 ++int nr_ice_peer_ctx_parse_trickle_candidate(nr_ice_peer_ctx *pctx, nr_ice_media_stream *stream, char *cand);
  1.1741 ++
  1.1742 + int nr_ice_peer_ctx_pair_candidates(nr_ice_peer_ctx *pctx);
  1.1743 + int nr_ice_peer_ctx_parse_global_attributes(nr_ice_peer_ctx *pctx, char **attrs, int attr_ct);
  1.1744 + int nr_ice_peer_ctx_start_checks(nr_ice_peer_ctx *pctx);
  1.1745 ++int nr_ice_peer_ctx_start_checks2(nr_ice_peer_ctx *pctx, int allow_non_first);
  1.1746 + int nr_ice_peer_ctx_dump_state(nr_ice_peer_ctx *pctx,FILE *out);
  1.1747 + int nr_ice_peer_ctx_log_state(nr_ice_peer_ctx *pctx);
  1.1748 + int nr_ice_peer_ctx_stream_done(nr_ice_peer_ctx *pctx, nr_ice_media_stream *stream);
  1.1749 + int nr_ice_peer_ctx_find_component(nr_ice_peer_ctx *pctx, nr_ice_media_stream *str, int component_id, nr_ice_component **compp);
  1.1750 + int nr_ice_peer_ctx_deliver_packet_maybe(nr_ice_peer_ctx *pctx, nr_ice_component *comp, nr_transport_addr *source_addr, UCHAR *data, int len);
  1.1751 + #ifdef __cplusplus
  1.1752 + }
  1.1753 + #endif /* __cplusplus */
  1.1754 + #endif
  1.1755 + 
  1.1756 +diff -U10 -r /Users/ekr/dev/mtransport-import-references/nICEr/src/ice/ice_socket.c src/ice/ice_socket.c
  1.1757 +--- /Users/ekr/dev/mtransport-import-references/nICEr/src/ice/ice_socket.c	2012-09-16 16:26:08.000000000 -0700
  1.1758 ++++ src/ice/ice_socket.c	2012-10-06 08:30:22.000000000 -0700
  1.1759 +@@ -216,28 +216,34 @@
  1.1760 +       RFREE(s1);
  1.1761 +     }
  1.1762 + 
  1.1763 +     RFREE(isock);
  1.1764 +     
  1.1765 +     return(0);
  1.1766 +   }
  1.1767 + 
  1.1768 + int nr_ice_socket_close(nr_ice_socket *isock)
  1.1769 +   {
  1.1770 ++#ifdef NR_SOCKET_IS_VOID_PTR
  1.1771 ++    NR_SOCKET fd=NULL;
  1.1772 ++    NR_SOCKET no_socket = NULL;
  1.1773 ++#else
  1.1774 +     NR_SOCKET fd=-1;
  1.1775 ++    NR_SOCKET no_socket = -1;
  1.1776 ++#endif
  1.1777 + 
  1.1778 +     if (!isock||!isock->sock)
  1.1779 +       return(0);
  1.1780 + 
  1.1781 +     nr_socket_getfd(isock->sock,&fd);
  1.1782 +     assert(isock->sock!=0);
  1.1783 +-    if(fd!=-1){
  1.1784 ++    if(fd != no_socket){
  1.1785 +       NR_ASYNC_CANCEL(fd,NR_ASYNC_WAIT_READ);
  1.1786 +       NR_ASYNC_CANCEL(fd,NR_ASYNC_WAIT_WRITE);
  1.1787 +       nr_socket_destroy(&isock->sock);
  1.1788 +     }
  1.1789 +     
  1.1790 +     return(0);
  1.1791 +   }
  1.1792 + 
  1.1793 + int nr_ice_socket_register_stun_client(nr_ice_socket *sock, nr_stun_client_ctx *srv,void **handle)
  1.1794 +   {
  1.1795 +diff -U10 -r /Users/ekr/dev/mtransport-import-references/nICEr/src/net/nr_socket.h src/net/nr_socket.h
  1.1796 +--- /Users/ekr/dev/mtransport-import-references/nICEr/src/net/nr_socket.h	2012-09-16 16:26:09.000000000 -0700
  1.1797 ++++ src/net/nr_socket.h	2012-10-06 08:30:22.000000000 -0700
  1.1798 +@@ -38,21 +38,23 @@
  1.1799 + #include <sys/types.h>
  1.1800 + #ifdef WIN32
  1.1801 + #include <winsock2.h>
  1.1802 + #include <ws2tcpip.h>
  1.1803 + #else
  1.1804 + #include <sys/socket.h>
  1.1805 + #endif
  1.1806 + 
  1.1807 + #include "transport_addr.h"
  1.1808 + 
  1.1809 +-#ifdef WIN32
  1.1810 ++#ifdef __cplusplus
  1.1811 ++#define restrict
  1.1812 ++#elif defined(WIN32)
  1.1813 + #define restrict __restrict
  1.1814 + #endif
  1.1815 + 
  1.1816 + typedef struct nr_socket_vtbl_ {
  1.1817 +   int (*destroy)(void **obj);
  1.1818 +   int (*ssendto)(void *obj,const void *msg, size_t len, int flags,
  1.1819 +     nr_transport_addr *addr);
  1.1820 +   int (*srecvfrom)(void *obj,void * restrict buf, size_t maxlen, size_t *len, int flags,
  1.1821 +     nr_transport_addr *addr);
  1.1822 +   int (*getfd)(void *obj, NR_SOCKET *fd);
  1.1823 +diff -U10 -r /Users/ekr/dev/mtransport-import-references/nICEr/src/net/transport_addr_reg.c src/net/transport_addr_reg.c
  1.1824 +--- /Users/ekr/dev/mtransport-import-references/nICEr/src/net/transport_addr_reg.c	2012-09-16 16:26:09.000000000 -0700
  1.1825 ++++ src/net/transport_addr_reg.c	2012-10-06 08:30:22.000000000 -0700
  1.1826 +@@ -29,25 +29,27 @@
  1.1827 + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  1.1828 + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  1.1829 + */
  1.1830 + 
  1.1831 + 
  1.1832 + 
  1.1833 + static char *RCSSTRING __UNUSED__="$Id: transport_addr_reg.c,v 1.2 2008/04/28 17:59:03 ekr Exp $";
  1.1834 + 
  1.1835 + #include <csi_platform.h>
  1.1836 + #include <stdio.h>
  1.1837 ++#include <string.h>
  1.1838 + #include <memory.h>
  1.1839 + #include <sys/types.h>
  1.1840 + #ifdef WIN32
  1.1841 + #include <winsock2.h>
  1.1842 + #else
  1.1843 ++#include <strings.h>
  1.1844 + #include <unistd.h>
  1.1845 + #include <sys/socket.h>
  1.1846 + #include <netinet/in.h>
  1.1847 + #include <arpa/inet.h>
  1.1848 + #endif
  1.1849 + #include <assert.h>
  1.1850 + #include "nr_api.h"
  1.1851 + #include "transport_addr.h"
  1.1852 + #include "transport_addr_reg.h"
  1.1853 + 
  1.1854 +@@ -83,20 +85,22 @@
  1.1855 + 
  1.1856 +     if ((r=NR_reg_get2_uint2(prefix, "port", &port))) {
  1.1857 +         if (r != R_NOT_FOUND)
  1.1858 +             ABORT(r);
  1.1859 +         port = 0;
  1.1860 +     }
  1.1861 + 
  1.1862 +     if ((r=NR_reg_alloc2_string(prefix, "protocol", &protocol))) {
  1.1863 +         if (r != R_NOT_FOUND)
  1.1864 +             ABORT(r);
  1.1865 ++        p = IPPROTO_UDP;
  1.1866 ++
  1.1867 +         protocol = 0;
  1.1868 +     }
  1.1869 +     else {
  1.1870 +         if (!strcasecmp("tcp", protocol))
  1.1871 +             p = IPPROTO_TCP;
  1.1872 +         else if (!strcasecmp("udp", protocol))
  1.1873 +             p = IPPROTO_UDP;
  1.1874 +         else
  1.1875 +             ABORT(R_BAD_DATA);
  1.1876 +     }
  1.1877 +diff -U10 -r /Users/ekr/dev/mtransport-import-references/nICEr/src/stun/addrs.c src/stun/addrs.c
  1.1878 +--- /Users/ekr/dev/mtransport-import-references/nICEr/src/stun/addrs.c	2012-09-16 16:26:10.000000000 -0700
  1.1879 ++++ src/stun/addrs.c	2012-10-06 09:42:43.000000000 -0700
  1.1880 +@@ -46,20 +46,22 @@
  1.1881 + #include <sys/sysctl.h>
  1.1882 + #include <sys/param.h>
  1.1883 + #include <sys/socket.h>
  1.1884 + #include <sys/syslog.h>
  1.1885 + #include <net/if.h>
  1.1886 + #ifndef LINUX
  1.1887 + #include <net/if_var.h>
  1.1888 + #include <net/if_dl.h>
  1.1889 + #include <net/if_types.h>
  1.1890 + #include <sys/sockio.h>
  1.1891 ++#else
  1.1892 ++#include <linux/if.h>
  1.1893 + #endif
  1.1894 + #include <net/route.h>
  1.1895 + 
  1.1896 + /* IP */
  1.1897 + #include <netinet/in.h>
  1.1898 + #ifdef LINUX
  1.1899 + #include "sys/ioctl.h"
  1.1900 + #else
  1.1901 + #include <netinet/in_var.h>
  1.1902 + #endif
  1.1903 +@@ -105,20 +107,23 @@
  1.1904 +  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  1.1905 +  * SUCH DAMAGE.
  1.1906 +  */
  1.1907 + 
  1.1908 + #include <err.h>
  1.1909 + 
  1.1910 + static void stun_rt_xaddrs(caddr_t, caddr_t, struct rt_addrinfo *);
  1.1911 + static int stun_grab_addrs(char *name, int addrcount,
  1.1912 +                struct ifa_msghdr *ifam,
  1.1913 +                nr_transport_addr addrs[], int maxaddrs, int *count);
  1.1914 ++static int
  1.1915 ++nr_stun_is_duplicate_addr(nr_transport_addr addrs[], int count, nr_transport_addr *addr);
  1.1916 ++
  1.1917 + 
  1.1918 + /*
  1.1919 +  * Expand the compacted form of addresses as returned via the
  1.1920 +  * configuration read via sysctl().
  1.1921 +  */
  1.1922 + #define ROUNDUP(a) \
  1.1923 +     ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
  1.1924 + #define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len))
  1.1925 + 
  1.1926 + static void
  1.1927 +@@ -135,21 +140,21 @@
  1.1928 +             continue;
  1.1929 +         rtinfo->rti_info[i] = sa = (struct sockaddr *)cp;
  1.1930 +         ADVANCE(cp, sa);
  1.1931 +     }
  1.1932 + }
  1.1933 + 
  1.1934 + static int
  1.1935 + stun_grab_addrs(char *name, int addrcount, struct ifa_msghdr *ifam, nr_transport_addr addrs[], int maxaddrs, int *count)
  1.1936 + {
  1.1937 +     int r,_status;
  1.1938 +-    NR_SOCKET s = -1;
  1.1939 ++    int s = -1;
  1.1940 +     struct ifreq ifr;
  1.1941 +     struct rt_addrinfo info;
  1.1942 +     struct sockaddr_in *sin;
  1.1943 + 
  1.1944 +     ifr.ifr_addr.sa_family = AF_INET;
  1.1945 +     strncpy(ifr.ifr_name, name, sizeof ifr.ifr_name);
  1.1946 + 
  1.1947 +     if ((s = socket(ifr.ifr_addr.sa_family, SOCK_DGRAM, 0)) < 0) {
  1.1948 +       r_log(NR_LOG_STUN, LOG_WARNING, "unable to obtain addresses from socket");
  1.1949 +       ABORT(R_FAILED);
  1.1950 +@@ -180,21 +185,20 @@
  1.1951 +         addrcount--;
  1.1952 + 
  1.1953 +         if (*count >= maxaddrs) {
  1.1954 +             r_log(NR_LOG_STUN, LOG_WARNING, "Address list truncated at %d out of entries", maxaddrs, maxaddrs+addrcount);
  1.1955 +             break;
  1.1956 +         }
  1.1957 + 
  1.1958 +         ifam = (struct ifa_msghdr *)((char *)ifam + ifam->ifam_msglen);
  1.1959 +     }
  1.1960 + 
  1.1961 +-
  1.1962 +     _status = 0;
  1.1963 +   abort:
  1.1964 +     if (s != -1) close(s);
  1.1965 +     return _status;
  1.1966 + }
  1.1967 + 
  1.1968 + static int
  1.1969 + stun_get_mib_addrs(nr_transport_addr addrs[], int maxaddrs, int *count)
  1.1970 + {
  1.1971 +     int _status;
  1.1972 +@@ -551,44 +555,48 @@
  1.1973 + #else
  1.1974 + 
  1.1975 + static int
  1.1976 + stun_get_siocgifconf_addrs(nr_transport_addr addrs[], int maxaddrs, int *count)
  1.1977 + {
  1.1978 +    struct ifconf ifc;
  1.1979 +    int _status;
  1.1980 +    int s = socket( AF_INET, SOCK_DGRAM, 0 );
  1.1981 +    int len = 100 * sizeof(struct ifreq);
  1.1982 +    int r;
  1.1983 ++   int e;
  1.1984 ++   char *ptr;
  1.1985 ++   int tl;
  1.1986 ++   int n;
  1.1987 ++   struct ifreq ifr2;
  1.1988 + 
  1.1989 +    char buf[ len ];
  1.1990 + 
  1.1991 +    ifc.ifc_len = len;
  1.1992 +    ifc.ifc_buf = buf;
  1.1993 + 
  1.1994 +-   int e = ioctl(s,SIOCGIFCONF,&ifc);
  1.1995 +-   char *ptr = buf;
  1.1996 +-   int tl = ifc.ifc_len;
  1.1997 +-   int n=0;
  1.1998 ++   e = ioctl(s,SIOCGIFCONF,&ifc);
  1.1999 ++   ptr = buf;
  1.2000 ++   tl = ifc.ifc_len;
  1.2001 ++   n=0;
  1.2002 + 
  1.2003 +    while ( (tl > 0) && ( n < maxaddrs) )
  1.2004 +    {
  1.2005 +       struct ifreq* ifr = (struct ifreq *)ptr;
  1.2006 + 
  1.2007 + #ifdef LINUX
  1.2008 +-      int si = sizeof(ifr->ifr_name) + sizeof(ifr->ifr_addr);
  1.2009 ++      int si = sizeof(struct ifreq);
  1.2010 + #else
  1.2011 +       int si = sizeof(ifr->ifr_name) + MAX(ifr->ifr_addr.sa_len, sizeof(ifr->ifr_addr));
  1.2012 + #endif
  1.2013 +       tl -= si;
  1.2014 +       ptr += si;
  1.2015 + 
  1.2016 +-      struct ifreq ifr2;
  1.2017 +       ifr2 = *ifr;
  1.2018 + 
  1.2019 +       e = ioctl(s,SIOCGIFADDR,&ifr2);
  1.2020 +       if ( e == -1 )
  1.2021 +       {
  1.2022 +           continue;
  1.2023 +       }
  1.2024 + 
  1.2025 +       //r_log(NR_LOG_STUN, LOG_ERR, "ioctl addr e = %d",e);
  1.2026 + 
  1.2027 +@@ -603,21 +611,21 @@
  1.2028 + 
  1.2029 +    close(s);
  1.2030 + 
  1.2031 +    *count = n;
  1.2032 + 
  1.2033 +     _status = 0;
  1.2034 +     return _status;
  1.2035 + }
  1.2036 + #endif
  1.2037 + 
  1.2038 +-int
  1.2039 ++static int
  1.2040 + nr_stun_is_duplicate_addr(nr_transport_addr addrs[], int count, nr_transport_addr *addr)
  1.2041 + {
  1.2042 +     int i;
  1.2043 +     int different;
  1.2044 + 
  1.2045 +     for (i = 0; i < count; ++i) {
  1.2046 +         different = nr_transport_addr_cmp(&addrs[i], addr, NR_TRANSPORT_ADDR_CMP_MODE_ALL);
  1.2047 +         if (!different) 
  1.2048 +             return 1;  /* duplicate */
  1.2049 +     }
  1.2050 +diff -U10 -r /Users/ekr/dev/mtransport-import-references/nICEr/src/stun/nr_socket_turn.c src/stun/nr_socket_turn.c
  1.2051 +--- /Users/ekr/dev/mtransport-import-references/nICEr/src/stun/nr_socket_turn.c	2012-09-16 16:26:10.000000000 -0700
  1.2052 ++++ src/stun/nr_socket_turn.c	2012-10-06 08:30:22.000000000 -0700
  1.2053 +@@ -246,17 +246,19 @@
  1.2054 +     default:
  1.2055 +         assert(0);
  1.2056 +         break;
  1.2057 +     }
  1.2058 + 
  1.2059 +     return R_FAILED;
  1.2060 +   }
  1.2061 + 
  1.2062 + static int nr_socket_turn_close(void *obj)
  1.2063 +   {
  1.2064 ++#ifndef NDEBUG
  1.2065 +     nr_socket_turn *sturn=obj;
  1.2066 +     assert(sturn->magic_cookie == nr_socket_turn_magic_cookie);
  1.2067 ++#endif
  1.2068 + 
  1.2069 +     return 0;
  1.2070 +   }
  1.2071 + 
  1.2072 + #endif /* USE_TURN */
  1.2073 +diff -U10 -r /Users/ekr/dev/mtransport-import-references/nICEr/src/stun/stun_client_ctx.c src/stun/stun_client_ctx.c
  1.2074 +--- /Users/ekr/dev/mtransport-import-references/nICEr/src/stun/stun_client_ctx.c	2012-09-16 16:26:10.000000000 -0700
  1.2075 ++++ src/stun/stun_client_ctx.c	2012-10-06 08:30:22.000000000 -0700
  1.2076 +@@ -38,21 +38,22 @@
  1.2077 + #include <string.h>
  1.2078 + 
  1.2079 + #include <nr_api.h>
  1.2080 + #include "stun.h"
  1.2081 + #include "async_timer.h"
  1.2082 + #include "registry.h"
  1.2083 + #include "stun_reg.h"
  1.2084 + #include "r_time.h"
  1.2085 + 
  1.2086 + static int nr_stun_client_send_request(nr_stun_client_ctx *ctx);
  1.2087 +-static void nr_stun_client_timer_expired_cb(int a, int b, void *cb_arg);
  1.2088 ++static void nr_stun_client_timer_expired_cb(NR_SOCKET s, int b, void *cb_arg);
  1.2089 ++static int nr_stun_client_get_password(void *arg, nr_stun_message *msg, Data **password);
  1.2090 + 
  1.2091 + int nr_stun_client_ctx_create(char *label, nr_socket *sock, nr_transport_addr *peer, UINT4 RTO, nr_stun_client_ctx **ctxp)
  1.2092 +   {
  1.2093 +     nr_stun_client_ctx *ctx=0;
  1.2094 +     int r,_status;
  1.2095 + 
  1.2096 +     if ((r=nr_stun_startup()))
  1.2097 +       ABORT(r);
  1.2098 + 
  1.2099 +     if(!(ctx=RCALLOC(sizeof(nr_stun_client_ctx))))
  1.2100 +@@ -185,21 +186,21 @@
  1.2101 +     ctx->finished_cb   = 0;
  1.2102 +     ctx->cb_arg        = 0;
  1.2103 +     ctx->request_ct    = 0;
  1.2104 +     ctx->timeout_ms    = 0;
  1.2105 + 
  1.2106 +     ctx->state = NR_STUN_CLIENT_STATE_INITTED;
  1.2107 + 
  1.2108 +     return 0;
  1.2109 + }
  1.2110 + 
  1.2111 +-static void nr_stun_client_timer_expired_cb(int a, int b, void *cb_arg)
  1.2112 ++static void nr_stun_client_timer_expired_cb(NR_SOCKET s, int b, void *cb_arg)
  1.2113 +   {
  1.2114 +     int _status;
  1.2115 +     nr_stun_client_ctx *ctx=cb_arg;
  1.2116 +     struct timeval now;
  1.2117 +     INT8 ms_waited;
  1.2118 + 
  1.2119 +     /* Prevent this timer from being cancelled later */
  1.2120 +     ctx->timer_handle=0;
  1.2121 + 
  1.2122 +     /* Shouldn't happen */
  1.2123 +@@ -387,21 +388,21 @@
  1.2124 +     }
  1.2125 +    
  1.2126 +     _status=0;
  1.2127 +   abort:
  1.2128 +     if (_status) {
  1.2129 +       ctx->state=NR_STUN_CLIENT_STATE_FAILED;
  1.2130 +     }
  1.2131 +     return(_status);
  1.2132 +   }
  1.2133 + 
  1.2134 +-int nr_stun_client_get_password(void *arg, nr_stun_message *msg, Data **password)
  1.2135 ++static int nr_stun_client_get_password(void *arg, nr_stun_message *msg, Data **password)
  1.2136 + {
  1.2137 +     *password = (Data*)arg;
  1.2138 +     if (!arg)
  1.2139 +         return(R_NOT_FOUND);
  1.2140 +     return(0);
  1.2141 + }
  1.2142 + 
  1.2143 + int nr_stun_client_process_response(nr_stun_client_ctx *ctx, UCHAR *msg, int len, nr_transport_addr *peer_addr)
  1.2144 +   {
  1.2145 +     int r,_status;
  1.2146 +diff -U10 -r /Users/ekr/dev/mtransport-import-references/nICEr/src/stun/stun_codec.c src/stun/stun_codec.c
  1.2147 +--- /Users/ekr/dev/mtransport-import-references/nICEr/src/stun/stun_codec.c	2012-09-16 16:26:10.000000000 -0700
  1.2148 ++++ src/stun/stun_codec.c	2012-10-06 08:30:22.000000000 -0700
  1.2149 +@@ -73,20 +73,22 @@
  1.2150 + static int nr_stun_decode_htonll(UCHAR *buf, int buflen, int *offset, UINT8 *data);
  1.2151 + static int nr_stun_decode(int length, UCHAR *buf, int buflen, int *offset, UCHAR *data);
  1.2152 + 
  1.2153 + static int nr_stun_attr_string_illegal(nr_stun_attr_info *attr_info, int len, void *data, int max_bytes, int max_chars);
  1.2154 + 
  1.2155 + static int nr_stun_attr_error_code_illegal(nr_stun_attr_info *attr_info, int attrlen, void *data);
  1.2156 + static int nr_stun_attr_nonce_illegal(nr_stun_attr_info *attr_info, int attrlen, void *data);
  1.2157 + static int nr_stun_attr_realm_illegal(nr_stun_attr_info *attr_info, int attrlen, void *data);
  1.2158 + static int nr_stun_attr_server_illegal(nr_stun_attr_info *attr_info, int attrlen, void *data);
  1.2159 + static int nr_stun_attr_username_illegal(nr_stun_attr_info *attr_info, int attrlen, void *data);
  1.2160 ++static int
  1.2161 ++nr_stun_attr_codec_fingerprint_decode(nr_stun_attr_info *attr_info, int attrlen, UCHAR *buf, int offset, int buflen, void *data);
  1.2162 + 
  1.2163 + 
  1.2164 + int
  1.2165 + nr_stun_encode_htons(UINT2 data, int buflen, UCHAR *buf, int *offset)
  1.2166 + {
  1.2167 +    UINT2 d = htons(data);
  1.2168 + 
  1.2169 +    if (*offset + sizeof(d) >= buflen) {
  1.2170 +       r_log(NR_LOG_STUN, LOG_WARNING, "Attempted buffer overrun: %d + %d >= %d", *offset, sizeof(d), buflen);
  1.2171 +       return R_BAD_DATA;
  1.2172 +@@ -632,21 +634,21 @@
  1.2173 +     }
  1.2174 + 
  1.2175 +     fingerprint->checksum = checksum ^ 0x5354554e;
  1.2176 + 
  1.2177 +     r_log(NR_LOG_STUN, LOG_DEBUG, "Computed FINGERPRINT %08x", fingerprint->checksum);
  1.2178 + 
  1.2179 +     fingerprint->valid = 1;
  1.2180 +     return nr_stun_attr_codec_UINT4.encode(attr_info, &fingerprint->checksum, offset, buflen, buf, attrlen);
  1.2181 + }
  1.2182 + 
  1.2183 +-int
  1.2184 ++static int
  1.2185 + nr_stun_attr_codec_fingerprint_decode(nr_stun_attr_info *attr_info, int attrlen, UCHAR *buf, int offset, int buflen, void *data)
  1.2186 + {
  1.2187 +     int r,_status;
  1.2188 +     nr_stun_attr_fingerprint *fingerprint = data;
  1.2189 +     nr_stun_message_header *header = (nr_stun_message_header*)buf;
  1.2190 +     int length;
  1.2191 +     UINT4 checksum;
  1.2192 + 
  1.2193 +     if ((r=nr_stun_attr_codec_UINT4.decode(attr_info, attrlen, buf, offset, buflen, &fingerprint->checksum)))
  1.2194 +         ABORT(r);
  1.2195 +diff -U10 -r /Users/ekr/dev/mtransport-import-references/nICEr/src/stun/stun_proc.c src/stun/stun_proc.c
  1.2196 +--- /Users/ekr/dev/mtransport-import-references/nICEr/src/stun/stun_proc.c	2012-09-16 16:26:10.000000000 -0700
  1.2197 ++++ src/stun/stun_proc.c	2012-10-06 08:30:22.000000000 -0700
  1.2198 +@@ -43,20 +43,22 @@
  1.2199 + #include <time.h>
  1.2200 + #else   /* UNIX */
  1.2201 + #include <string.h>
  1.2202 + #endif  /* end UNIX */
  1.2203 + #include <assert.h>
  1.2204 + 
  1.2205 + #include "stun.h"
  1.2206 + #include "stun_reg.h"
  1.2207 + #include "registry.h"
  1.2208 + 
  1.2209 ++static int
  1.2210 ++nr_stun_add_realm_and_nonce(int new_nonce, nr_stun_server_client *clnt, nr_stun_message *res);
  1.2211 + 
  1.2212 + /* draft-ietf-behave-rfc3489bis-10.txt S 7.3 */
  1.2213 + int
  1.2214 + nr_stun_receive_message(nr_stun_message *req, nr_stun_message *msg)
  1.2215 + {
  1.2216 +     int _status;
  1.2217 +     nr_stun_message_attribute *attr;
  1.2218 + 
  1.2219 + #ifdef USE_RFC_3489_BACKWARDS_COMPATIBLE
  1.2220 +     /* if this message was generated by an RFC 3489 impementation,
  1.2221 +@@ -371,21 +373,21 @@
  1.2222 +         /* nothing to check in this case */
  1.2223 +         break;
  1.2224 + #endif /* USE_STUND_0_96 */
  1.2225 +     }
  1.2226 + 
  1.2227 +    _status=0;
  1.2228 +  abort:
  1.2229 +      return _status;
  1.2230 + }
  1.2231 + 
  1.2232 +-int
  1.2233 ++static int
  1.2234 + nr_stun_add_realm_and_nonce(int new_nonce, nr_stun_server_client *clnt, nr_stun_message *res)
  1.2235 + {
  1.2236 +     int r,_status;
  1.2237 +     char *realm = 0;
  1.2238 +     char *nonce;
  1.2239 +     UINT2 size;
  1.2240 + 
  1.2241 +     if ((r=NR_reg_alloc_string(NR_STUN_REG_PREF_SERVER_REALM, &realm)))
  1.2242 +         ABORT(r);
  1.2243 + 
  1.2244 +diff -U10 -r /Users/ekr/dev/mtransport-import-references/nICEr/src/stun/stun_server_ctx.c src/stun/stun_server_ctx.c
  1.2245 +--- /Users/ekr/dev/mtransport-import-references/nICEr/src/stun/stun_server_ctx.c	2012-09-16 16:26:10.000000000 -0700
  1.2246 ++++ src/stun/stun_server_ctx.c	2012-10-06 08:30:22.000000000 -0700
  1.2247 +@@ -114,21 +114,21 @@
  1.2248 +     STAILQ_INSERT_TAIL(&ctx->clients,clnt,entry);
  1.2249 +     
  1.2250 +     _status=0;
  1.2251 +   abort:
  1.2252 +     if(_status){
  1.2253 +       nr_stun_server_destroy_client(clnt);
  1.2254 +     }
  1.2255 +     return(_status);
  1.2256 +   }
  1.2257 + 
  1.2258 +-int nr_stun_server_get_password(void *arg, nr_stun_message *msg, Data **password)
  1.2259 ++static int nr_stun_server_get_password(void *arg, nr_stun_message *msg, Data **password)
  1.2260 +   {
  1.2261 +     int _status;
  1.2262 +     nr_stun_server_ctx *ctx = (nr_stun_server_ctx*)arg;
  1.2263 +     nr_stun_server_client *clnt = 0;
  1.2264 +     nr_stun_message_attribute *username_attribute;
  1.2265 + 
  1.2266 +     if ((nr_stun_get_message_client(ctx, msg, &clnt))) {
  1.2267 +         if (! nr_stun_message_has_attribute(msg, NR_STUN_ATTR_USERNAME, &username_attribute)) {
  1.2268 +            r_log(NR_LOG_STUN,LOG_NOTICE,"STUN-SERVER(%s): Missing Username",ctx->label);
  1.2269 +            ABORT(R_NOT_FOUND);
  1.2270 +diff -U10 -r /Users/ekr/dev/mtransport-import-references/nICEr/src/stun/stun_util.c src/stun/stun_util.c
  1.2271 +--- /Users/ekr/dev/mtransport-import-references/nICEr/src/stun/stun_util.c	2012-09-16 16:26:10.000000000 -0700
  1.2272 ++++ src/stun/stun_util.c	2012-10-06 08:30:22.000000000 -0700
  1.2273 +@@ -94,21 +94,20 @@
  1.2274 +     _status = 0;
  1.2275 +   abort:
  1.2276 +     return _status;
  1.2277 + }
  1.2278 + 
  1.2279 + int
  1.2280 + nr_stun_find_local_addresses(nr_transport_addr addrs[], int maxaddrs, int *count)
  1.2281 + {
  1.2282 +     int r,_status;
  1.2283 +     NR_registry *children = 0;
  1.2284 +-    int i;
  1.2285 + 
  1.2286 +     if ((r=NR_reg_get_child_count(NR_STUN_REG_PREF_ADDRESS_PRFX, (unsigned int*)count)))
  1.2287 +         if (r == R_NOT_FOUND)
  1.2288 +             *count = 0;
  1.2289 +         else
  1.2290 +             ABORT(r);
  1.2291 + 
  1.2292 +     if (*count == 0) {
  1.2293 +         if ((r=nr_stun_get_addrs(addrs, maxaddrs, 1, count)))
  1.2294 +             ABORT(r);
  1.2295 +diff -U10 -r /Users/ekr/dev/mtransport-import-references/nICEr/src/stun/turn_client_ctx.c src/stun/turn_client_ctx.c
  1.2296 +--- /Users/ekr/dev/mtransport-import-references/nICEr/src/stun/turn_client_ctx.c	2012-09-16 16:26:10.000000000 -0700
  1.2297 ++++ src/stun/turn_client_ctx.c	2012-10-06 08:30:22.000000000 -0700
  1.2298 +@@ -55,21 +55,24 @@
  1.2299 + };
  1.2300 + 
  1.2301 + static int TURN_PHASE_MODE[NUMBER_OF_STUN_CTX] = {
  1.2302 +     NR_TURN_CLIENT_MODE_ALLOCATE_REQUEST1,
  1.2303 +     NR_TURN_CLIENT_MODE_ALLOCATE_REQUEST2,
  1.2304 +     NR_TURN_CLIENT_MODE_SET_ACTIVE_DEST_REQUEST
  1.2305 + };
  1.2306 + 
  1.2307 + 
  1.2308 + static int nr_turn_client_next_action(nr_turn_client_ctx *ctx, int stun_ctx_state);
  1.2309 +-static void nr_turn_client_cb(int s, int how, void *cb_arg);
  1.2310 ++static void nr_turn_client_cb(NR_SOCKET s, int how, void *cb_arg);
  1.2311 ++static int
  1.2312 ++nr_turn_client_prepare_start(nr_turn_client_ctx *ctx, char *username, Data *password, UINT4 bandwidth_kbps, UINT4 lifetime_secs, NR_async_cb finished_cb, void *cb_arg);
  1.2313 ++
  1.2314 + 
  1.2315 + int
  1.2316 + nr_turn_client_next_action(nr_turn_client_ctx *ctx, int stun_ctx_state)
  1.2317 + {
  1.2318 +     int r,_status;
  1.2319 + 
  1.2320 +     assert(ctx->phase >= -1 && ctx->phase < NUMBER_OF_STUN_CTX);
  1.2321 + 
  1.2322 +     switch (ctx->state) {
  1.2323 +     //case NR_TURN_CLIENT_STATE_ALLOCATING:
  1.2324 +@@ -147,21 +150,21 @@
  1.2325 +              * because as a side effect this ctx may be operated on in the
  1.2326 +              * callback */
  1.2327 +             finished_cb(0,0,ctx->cb_arg);
  1.2328 +         }
  1.2329 +     }
  1.2330 + 
  1.2331 +     return(_status);
  1.2332 + }
  1.2333 + 
  1.2334 + void
  1.2335 +-nr_turn_client_cb(int s, int how, void *cb_arg)
  1.2336 ++nr_turn_client_cb(NR_SOCKET s, int how, void *cb_arg)
  1.2337 + {
  1.2338 +     int r,_status;
  1.2339 +     nr_turn_client_ctx *ctx = (nr_turn_client_ctx*)cb_arg;
  1.2340 +     nr_stun_client_ctx *stun_ctx = ctx->stun_ctx[ctx->phase];
  1.2341 + 
  1.2342 +     assert(ctx->phase >= 0);
  1.2343 + 
  1.2344 +     if ((r=nr_turn_client_next_action(ctx, stun_ctx->state)))
  1.2345 +         ABORT(r);
  1.2346 + 
  1.2347 +@@ -234,21 +237,21 @@
  1.2348 + 
  1.2349 +     RFREE(ctx->username);
  1.2350 +     r_data_destroy(&ctx->password);
  1.2351 + 
  1.2352 +     RFREE(ctx->label);
  1.2353 +     RFREE(ctx);
  1.2354 + 
  1.2355 +     return(0);
  1.2356 + }
  1.2357 + 
  1.2358 +-int
  1.2359 ++static int
  1.2360 + nr_turn_client_prepare_start(nr_turn_client_ctx *ctx, char *username, Data *password, UINT4 bandwidth_kbps, UINT4 lifetime_secs, NR_async_cb finished_cb, void *cb_arg)
  1.2361 + {
  1.2362 +     int r,_status;
  1.2363 +     nr_stun_client_allocate_request1_params          *allocate_request1 = 0;
  1.2364 +     nr_stun_client_allocate_request2_params          *allocate_request2 = 0;
  1.2365 +     nr_stun_client_allocate_response1_results        *allocate_response1 = 0;
  1.2366 + //    nr_stun_client_allocate_response2_results        *allocate_response2;
  1.2367 + 
  1.2368 +     if (ctx->state != NR_TURN_CLIENT_STATE_INITTED)
  1.2369 +         ABORT(R_NOT_PERMITTED);
  1.2370 +diff -U10 -r /Users/ekr/dev/mtransport-import-references/nICEr/src/util/ice_util.c src/util/ice_util.c
  1.2371 +--- /Users/ekr/dev/mtransport-import-references/nICEr/src/util/ice_util.c	2012-09-16 16:26:10.000000000 -0700
  1.2372 ++++ src/util/ice_util.c	2012-10-06 08:30:22.000000000 -0700
  1.2373 +@@ -31,20 +31,21 @@
  1.2374 + */
  1.2375 + 
  1.2376 + #include <stdarg.h>
  1.2377 + 
  1.2378 + 
  1.2379 + static char *RCSSTRING __UNUSED__="$Id: ice_util.c,v 1.2 2008/04/28 17:59:05 ekr Exp $";
  1.2380 + 
  1.2381 + #include <stdarg.h>
  1.2382 + #include <string.h>
  1.2383 + #include "nr_api.h"
  1.2384 ++#include "ice_util.h"
  1.2385 + 
  1.2386 + int nr_concat_strings(char **outp,...)
  1.2387 +   {
  1.2388 +     va_list ap;
  1.2389 +     char *s,*out=0;
  1.2390 +     int len=0;
  1.2391 +     int _status;
  1.2392 + 
  1.2393 +     va_start(ap,outp);
  1.2394 +     while(s=va_arg(ap,char *)){
  1.2395 +diff -U10 -r /Users/ekr/dev/mtransport-import-references/nICEr/src/util/mbslen.c src/util/mbslen.c
  1.2396 +--- /Users/ekr/dev/mtransport-import-references/nICEr/src/util/mbslen.c	2012-09-16 16:26:10.000000000 -0700
  1.2397 ++++ src/util/mbslen.c	2012-10-06 08:31:01.000000000 -0700
  1.2398 +@@ -56,21 +56,21 @@
  1.2399 + {
  1.2400 + #ifdef DARWIN
  1.2401 +     static locale_t loc = 0;
  1.2402 +     static int initialized = 0;
  1.2403 + #endif /* DARWIN */
  1.2404 + #ifdef WIN32
  1.2405 +     char *my_locale=0;
  1.2406 +     unsigned int i;
  1.2407 + #endif  /* WIN32 */
  1.2408 +     int _status;
  1.2409 +-    int nbytes;
  1.2410 ++    size_t nbytes;
  1.2411 +     int nchars;
  1.2412 +     mbstate_t mbs;
  1.2413 + 
  1.2414 + #ifdef DARWIN
  1.2415 +     if (! initialized) {
  1.2416 +         initialized = 1;
  1.2417 +         loc = newlocale(LC_CTYPE_MASK, "UTF-8", LC_GLOBAL_LOCALE);
  1.2418 +     }
  1.2419 + 
  1.2420 +     if (loc == 0) {
  1.2421 +@@ -102,25 +102,28 @@
  1.2422 + 
  1.2423 +     memset(&mbs, 0, sizeof(mbs));
  1.2424 +     nchars = 0;
  1.2425 + 
  1.2426 + #ifdef DARWIN
  1.2427 +     while (*s != '\0' && (nbytes = mbrlen_l(s, strlen(s), &mbs, loc)) != 0)
  1.2428 + #else
  1.2429 +     while (*s != '\0' && (nbytes = mbrlen(s, strlen(s), &mbs)) != 0)
  1.2430 + #endif /* DARWIN */
  1.2431 +     {
  1.2432 +-        assert(nbytes >= 0);
  1.2433 +-        if (nbytes == (size_t)-1)   /* should never happen */
  1.2434 ++        if (nbytes == (size_t)-1)   /* should never happen */ {
  1.2435 ++	    assert(0);
  1.2436 +             ABORT(R_INTERNAL);
  1.2437 +-        if (nbytes == (size_t)-2)   /* encoding error */
  1.2438 ++	}
  1.2439 ++        if (nbytes == (size_t)-2)   /* encoding error */ {
  1.2440 ++	    assert(0);
  1.2441 +             ABORT(R_BAD_DATA);
  1.2442 ++	}
  1.2443 +  
  1.2444 +         s += nbytes;
  1.2445 +         ++nchars;
  1.2446 +     }
  1.2447 + 
  1.2448 +     *ncharsp = nchars;
  1.2449 + 
  1.2450 +     _status = 0;
  1.2451 +   abort:
  1.2452 + #ifdef WIN32

mercurial