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