1diff -U10 -r /Users/ekr/dev/mtransport-import-references/nICEr/src/ice/ice_candidate.c src/ice/ice_candidate.c 2--- /Users/ekr/dev/mtransport-import-references/nICEr/src/ice/ice_candidate.c 2012-09-16 16:26:08.000000000 -0700 3+++ src/ice/ice_candidate.c 2012-10-06 08:30:22.000000000 -0700 4@@ -54,36 +54,38 @@ 5 6 #include "stun_client_ctx.h" 7 #include "stun_server_ctx.h" 8 #include "turn_client_ctx.h" 9 #include "ice_ctx.h" 10 #include "ice_candidate.h" 11 #include "ice_reg.h" 12 #include "ice_util.h" 13 #include "nr_socket_turn.h" 14 15+static int next_automatic_preference = 224; 16+ 17 static int nr_ice_get_foundation(nr_ice_ctx *ctx,nr_ice_candidate *cand); 18 static int nr_ice_srvrflx_start_stun(nr_ice_candidate *cand, NR_async_cb ready_cb, void *cb_arg); 19-static void nr_ice_srvrflx_stun_finished_cb(int sock, int how, void *cb_arg); 20+static void nr_ice_srvrflx_stun_finished_cb(NR_SOCKET sock, int how, void *cb_arg); 21 #ifdef USE_TURN 22 static int nr_ice_start_relay_turn(nr_ice_candidate *cand, NR_async_cb ready_cb, void *cb_arg); 23-static void nr_ice_turn_allocated_cb(int sock, int how, void *cb_arg); 24+static void nr_ice_turn_allocated_cb(NR_SOCKET sock, int how, void *cb_arg); 25 #endif /* USE_TURN */ 26 27 char *nr_ice_candidate_type_names[]={0,"host","srflx","prflx","relay",0}; 28 29 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) 30 { 31 nr_ice_candidate *cand=0; 32 nr_ice_candidate *tmp=0; 33 int r,_status; 34- 35+ 36 if(!(cand=RCALLOC(sizeof(nr_ice_candidate)))) 37 ABORT(R_NO_MEMORY); 38 if(!(cand->label=r_strdup(label))) 39 ABORT(R_NO_MEMORY); 40 cand->state=NR_ICE_CAND_STATE_CREATED; 41 cand->ctx=ctx; 42 cand->isock=isock; 43 cand->osock=osock; 44 cand->type=ctype; 45 cand->stun_server=stun_server; 46@@ -189,21 +191,21 @@ 47 if(cand->delay_timer) 48 NR_async_timer_cancel(cand->delay_timer); 49 50 RFREE(cand->foundation); 51 RFREE(cand->label); 52 RFREE(cand); 53 54 return(0); 55 } 56 57-void nr_ice_candidate_destroy_cb(int s, int h, void *cb_arg) 58+void nr_ice_candidate_destroy_cb(NR_SOCKET s, int h, void *cb_arg) 59 { 60 nr_ice_candidate *cand=cb_arg; 61 nr_ice_candidate_destroy(&cand); 62 } 63 64 /* This algorithm is not super-fast, but I don't think we need a hash 65 table just yet and it produces a small foundation string */ 66 static int nr_ice_get_foundation(nr_ice_ctx *ctx,nr_ice_candidate *cand) 67 { 68 nr_ice_foundation *foundation; 69@@ -276,22 +278,38 @@ 70 break; 71 default: 72 ABORT(R_INTERNAL); 73 } 74 75 if(type_preference > 126) 76 r_log(LOG_ICE,LOG_ERR,"Illegal type preference %d",type_preference); 77 78 79 if(r=NR_reg_get2_uchar(NR_ICE_REG_PREF_INTERFACE_PRFX,cand->base.ifname, 80- &interface_preference)) 81- ABORT(r); 82+ &interface_preference)) { 83+ if (r==R_NOT_FOUND) { 84+ if (next_automatic_preference == 1) { 85+ r_log(LOG_ICE,LOG_DEBUG,"Out of preference values. Can't assign one for interface %s",cand->base.ifname); 86+ ABORT(R_NOT_FOUND); 87+ } 88+ r_log(LOG_ICE,LOG_DEBUG,"Automatically assigning preference for interface %s->%d",cand->base.ifname, 89+ next_automatic_preference); 90+ if (r=NR_reg_set2_uchar(NR_ICE_REG_PREF_INTERFACE_PRFX,cand->base.ifname,next_automatic_preference)){ 91+ ABORT(r); 92+ } 93+ interface_preference=next_automatic_preference; 94+ next_automatic_preference--; 95+ } 96+ else { 97+ ABORT(r); 98+ } 99+ } 100 101 cand->priority= 102 (type_preference << 24) | 103 (interface_preference << 16) | 104 (stun_priority << 8) | 105 (256 - cand->component_id); 106 107 /* S 4.1.2 */ 108 assert(cand->priority>=1&&cand->priority<=2147483647); 109 110@@ -306,21 +324,22 @@ 111 112 cand->done_cb=ready_cb; 113 cand->cb_arg=cb_arg; 114 115 switch(cand->type){ 116 case HOST: 117 if(r=nr_socket_getaddr(cand->isock->sock,&cand->addr)) 118 ABORT(r); 119 cand->osock=cand->isock->sock; 120 cand->state=NR_ICE_CAND_STATE_INITIALIZED; 121- ready_cb(0,0,cb_arg); 122+ // Post this so that it doesn't happen in-line 123+ NR_ASYNC_SCHEDULE(ready_cb,cb_arg); 124 break; 125 #ifdef USE_TURN 126 case RELAYED: 127 if(r=nr_ice_start_relay_turn(cand,ready_cb,cb_arg)) 128 ABORT(r); 129 ABORT(R_WOULDBLOCK); 130 break; 131 #endif /* USE_TURN */ 132 case SERVER_REFLEXIVE: 133 /* Need to start stun */ 134@@ -333,21 +352,21 @@ 135 ABORT(R_INTERNAL); 136 } 137 138 _status=0; 139 abort: 140 if(_status && _status!=R_WOULDBLOCK) 141 cand->state=NR_ICE_CAND_STATE_FAILED; 142 return(_status); 143 } 144 145-static void nr_ice_srvrflx_start_stun_timer_cb(int s, int how, void *cb_arg) 146+static void nr_ice_srvrflx_start_stun_timer_cb(NR_SOCKET s, int how, void *cb_arg) 147 { 148 nr_ice_candidate *cand=cb_arg; 149 int r,_status; 150 151 cand->delay_timer=0; 152 153 /* TODO: if the response is a BINDING-ERROR-RESPONSE, then restart 154 * TODO: using NR_STUN_CLIENT_MODE_BINDING_REQUEST because the 155 * TODO: server may not have understood the 0.96-style request */ 156 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)) 157@@ -387,21 +406,21 @@ 158 159 _status=0; 160 abort: 161 if(_status){ 162 cand->state=NR_ICE_CAND_STATE_FAILED; 163 } 164 return(_status); 165 } 166 167 #ifdef USE_TURN 168-static void nr_ice_start_relay_turn_timer_cb(int s, int how, void *cb_arg) 169+static void nr_ice_start_relay_turn_timer_cb(NR_SOCKET s, int how, void *cb_arg) 170 { 171 nr_ice_candidate *cand=cb_arg; 172 int r,_status; 173 int i; 174 175 cand->delay_timer=0; 176 177 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)) 178 ABORT(r); 179 180@@ -443,21 +462,21 @@ 181 182 _status=0; 183 abort: 184 if(_status){ 185 cand->state=NR_ICE_CAND_STATE_FAILED; 186 } 187 return(_status); 188 } 189 #endif /* USE_TURN */ 190 191-static void nr_ice_srvrflx_stun_finished_cb(int sock, int how, void *cb_arg) 192+static void nr_ice_srvrflx_stun_finished_cb(NR_SOCKET sock, int how, void *cb_arg) 193 { 194 int _status; 195 nr_ice_candidate *cand=cb_arg; 196 197 /* Deregister to suppress duplicates */ 198 if(cand->u.srvrflx.stun_handle){ /* This test because we might have failed before CB registered */ 199 nr_ice_socket_deregister(cand->isock,cand->u.srvrflx.stun_handle); 200 cand->u.srvrflx.stun_handle=0; 201 } 202 203@@ -481,40 +500,40 @@ 204 } 205 _status = 0; 206 abort: 207 if(_status){ 208 cand->state=NR_ICE_CAND_STATE_FAILED; 209 cand->done_cb(0,0,cand->cb_arg); 210 } 211 } 212 213 #ifdef USE_TURN 214-static void nr_ice_turn_allocated_cb(int s, int how, void *cb_arg) 215+static void nr_ice_turn_allocated_cb(NR_SOCKET s, int how, void *cb_arg) 216 { 217 int r,_status; 218 nr_ice_candidate *cand=cb_arg; 219 nr_turn_client_ctx *turn=cand->u.relayed.turn; 220 int i; 221 char *label; 222 223 /* Deregister to suppress duplicates */ 224 if(cand->u.relayed.turn_handle){ /* This test because we might have failed before CB registered */ 225 nr_ice_socket_deregister(cand->isock,cand->u.relayed.turn_handle); 226 cand->u.relayed.turn_handle=0; 227 } 228 229 switch(turn->state){ 230 /* OK, we should have a mapped address */ 231 case NR_TURN_CLIENT_STATE_ALLOCATED: 232 /* switch candidate from TURN mode to STUN mode */ 233 234- if(r=nr_concat_strings(&label,"turn-relay(",cand->base.as_string,"|",turn->relay_addr.as_string,")",0)) 235+ if(r=nr_concat_strings(&label,"turn-relay(",cand->base.as_string,"|",turn->relay_addr.as_string,")",NULL)) 236 ABORT(r); 237 238 r_log(LOG_ICE,LOG_DEBUG,"ICE(%s): Switching from TURN (%s) to RELAY (%s)",cand->u.relayed.turn->label,cand->label,label); 239 240 /* Copy out mapped address and relay address */ 241 nr_transport_addr_copy(&turn->relay_addr, &cand->u.relayed.turn->stun_ctx[NR_TURN_CLIENT_PHASE_ALLOCATE_REQUEST2]->results.allocate_response2.relay_addr); 242 nr_transport_addr_copy(&cand->addr, &turn->relay_addr); 243 244 r_log(LOG_ICE,LOG_DEBUG,"ICE-CANDIDATE(%s): base=%s, candidate=%s", cand->label, cand->base.as_string, cand->addr.as_string); 245 246diff -U10 -r /Users/ekr/dev/mtransport-import-references/nICEr/src/ice/ice_candidate.h src/ice/ice_candidate.h 247--- /Users/ekr/dev/mtransport-import-references/nICEr/src/ice/ice_candidate.h 2012-09-16 16:26:08.000000000 -0700 248+++ src/ice/ice_candidate.h 2012-10-06 08:30:22.000000000 -0700 249@@ -41,21 +41,22 @@ 250 251 typedef enum {HOST=1, SERVER_REFLEXIVE, PEER_REFLEXIVE, RELAYED} nr_ice_candidate_type; 252 253 struct nr_ice_candidate_ { 254 char *label; 255 int state; 256 #define NR_ICE_CAND_STATE_CREATED 1 257 #define NR_ICE_CAND_STATE_INITIALIZING 2 258 #define NR_ICE_CAND_STATE_INITIALIZED 3 259 #define NR_ICE_CAND_STATE_FAILED 4 260-#define NR_ICE_CAND_PEER_CANDIDATE 10 261+#define NR_ICE_CAND_PEER_CANDIDATE_UNPAIRED 9 262+#define NR_ICE_CAND_PEER_CANDIDATE_PAIRED 10 263 struct nr_ice_ctx_ *ctx; 264 nr_ice_socket *isock; /* The socket to read from 265 (it contains all other candidates 266 on this socket) */ 267 nr_socket *osock; /* The socket to write to */ 268 nr_ice_media_stream *stream; /* The media stream this is associated with */ 269 nr_ice_component *component; /* The component this is associated with */ 270 nr_ice_candidate_type type; /* The type of the candidate (S 4.1.1) */ 271 UCHAR component_id; /* The component id (S 4.1.2.1) */ 272 nr_transport_addr addr; /* The advertised address; 273@@ -89,21 +90,21 @@ 274 TAILQ_ENTRY(nr_ice_candidate_) entry_comp; 275 }; 276 277 extern char *nr_ice_candidate_type_names[]; 278 279 280 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); 281 int nr_ice_candidate_initialize(nr_ice_candidate *cand, NR_async_cb ready_cb, void *cb_arg); 282 int nr_ice_candidate_process_stun(nr_ice_candidate *cand, UCHAR *msg, int len, nr_transport_addr *faddr); 283 int nr_ice_candidate_destroy(nr_ice_candidate **candp); 284-void nr_ice_candidate_destroy_cb(int s, int h, void *cb_arg); 285+void nr_ice_candidate_destroy_cb(NR_SOCKET s, int h, void *cb_arg); 286 int nr_ice_format_candidate_attribute(nr_ice_candidate *cand, char *attr, int maxlen); 287 int nr_ice_peer_candidate_from_attribute(nr_ice_ctx *ctx,char *attr,nr_ice_media_stream *stream,nr_ice_candidate **candp); 288 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); 289 int nr_ice_candidate_compute_priority(nr_ice_candidate *cand); 290 291 #ifdef __cplusplus 292 } 293 #endif /* __cplusplus */ 294 #endif 295 296diff -U10 -r /Users/ekr/dev/mtransport-import-references/nICEr/src/ice/ice_candidate_pair.c src/ice/ice_candidate_pair.c 297--- /Users/ekr/dev/mtransport-import-references/nICEr/src/ice/ice_candidate_pair.c 2012-09-16 16:26:08.000000000 -0700 298+++ src/ice/ice_candidate_pair.c 2012-10-06 08:30:22.000000000 -0700 299@@ -37,21 +37,21 @@ 300 #include <assert.h> 301 #include <string.h> 302 #include <nr_api.h> 303 #include "ice_ctx.h" 304 #include "ice_util.h" 305 #include "ice_codeword.h" 306 #include "stun.h" 307 308 static char *nr_ice_cand_pair_states[]={"UNKNOWN","FROZEN","WAITING","IN_PROGRESS","FAILED","SUCCEEDED","CANCELLED"}; 309 310-static void nr_ice_candidate_pair_restart_stun_controlled_cb(int s, int how, void *cb_arg); 311+static void nr_ice_candidate_pair_restart_stun_controlled_cb(NR_SOCKET s, int how, void *cb_arg); 312 static void nr_ice_candidate_pair_compute_codeword(nr_ice_cand_pair *pair, 313 nr_ice_candidate *lcand, nr_ice_candidate *rcand); 314 315 int nr_ice_candidate_pair_create(nr_ice_peer_ctx *pctx, nr_ice_candidate *lcand,nr_ice_candidate *rcand,nr_ice_cand_pair **pairp) 316 { 317 nr_ice_cand_pair *pair=0; 318 UINT8 o_priority, a_priority; 319 char *lufrag,*rufrag; 320 char *lpwd,*rpwd; 321 char *l2ruser=0,*r2lpass=0; 322@@ -61,21 +61,21 @@ 323 UINT8 t_priority; 324 325 if(!(pair=RCALLOC(sizeof(nr_ice_cand_pair)))) 326 ABORT(R_NO_MEMORY); 327 328 pair->pctx=pctx; 329 330 nr_ice_candidate_pair_compute_codeword(pair,lcand,rcand); 331 332 if(r=nr_concat_strings(&pair->as_string,pair->codeword,"|",lcand->addr.as_string,"|", 333- rcand->addr.as_string,"(",lcand->label,"|",rcand->label,")",0)) 334+ rcand->addr.as_string,"(",lcand->label,"|",rcand->label,")", NULL)) 335 ABORT(r); 336 337 nr_ice_candidate_pair_set_state(pctx,pair,NR_ICE_PAIR_STATE_FROZEN); 338 pair->local=lcand; 339 pair->remote=rcand; 340 341 /* Priority computation S 5.7.2 */ 342 if(pctx->ctx->flags & NR_ICE_CTX_FLAGS_OFFERER) 343 { 344 assert(!(pctx->ctx->flags & NR_ICE_CTX_FLAGS_ANSWERER)); 345@@ -87,21 +87,21 @@ 346 o_priority=rcand->priority; 347 a_priority=lcand->priority; 348 } 349 pair->priority=(MIN(o_priority, a_priority))<<32 | 350 (MAX(o_priority, a_priority))<<1 | (o_priority > a_priority?0:1); 351 352 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); 353 354 /* Foundation */ 355 if(r=nr_concat_strings(&pair->foundation,lcand->foundation,"|", 356- rcand->foundation,0)) 357+ rcand->foundation,NULL)) 358 ABORT(r); 359 360 361 /* OK, now the STUN data */ 362 lufrag=lcand->stream->ufrag?lcand->stream->ufrag:pctx->ctx->ufrag; 363 lpwd=lcand->stream->pwd?lcand->stream->pwd:pctx->ctx->pwd; 364 rufrag=rcand->stream->ufrag?rcand->stream->ufrag:pctx->peer_ufrag; 365 rpwd=rcand->stream->pwd?rcand->stream->pwd:pctx->peer_pwd; 366 367 368@@ -110,39 +110,39 @@ 369 370 /* Make a bogus candidate to compute a theoretical peer reflexive 371 * priority per S 7.1.1.1 */ 372 memcpy(&tmpcand, lcand, sizeof(tmpcand)); 373 tmpcand.type = PEER_REFLEXIVE; 374 if (r=nr_ice_candidate_compute_priority(&tmpcand)) 375 ABORT(r); 376 t_priority = tmpcand.priority; 377 378 /* Our sending context */ 379- if(r=nr_concat_strings(&l2ruser,lufrag,":",rufrag,0)) 380+ if(r=nr_concat_strings(&l2ruser,lufrag,":",rufrag,NULL)) 381 ABORT(r); 382 if(r=nr_stun_client_ctx_create(pair->as_string, 383 lcand->osock, 384 &rcand->addr,RTO,&pair->stun_client)) 385 ABORT(r); 386 if(!(pair->stun_client->params.ice_binding_request.username=r_strdup(l2ruser))) 387 ABORT(R_NO_MEMORY); 388 if(r=r_data_make(&pair->stun_client->params.ice_binding_request.password,(UCHAR *)lpwd,strlen(lpwd))) 389 ABORT(r); 390 pair->stun_client->params.ice_binding_request.priority=t_priority; 391 pair->stun_client->params.ice_binding_request.control = pctx->controlling? 392 NR_ICE_CONTROLLING:NR_ICE_CONTROLLED; 393 394 pair->stun_client->params.ice_binding_request.tiebreaker=pctx->tiebreaker; 395 396 /* Our receiving username/passwords. Stash these for later 397 injection into the stun server ctx*/ 398- if(r=nr_concat_strings(&pair->r2l_user,rufrag,":",lufrag,0)) 399+ if(r=nr_concat_strings(&pair->r2l_user,rufrag,":",lufrag,NULL)) 400 ABORT(r); 401 if(!(r2lpass=r_strdup(rpwd))) 402 ABORT(R_NO_MEMORY); 403 INIT_DATA(pair->r2l_pwd,(UCHAR *)r2lpass,strlen(r2lpass)); 404 405 *pairp=pair; 406 407 _status=0; 408 abort: 409 RFREE(l2ruser); 410@@ -178,21 +178,21 @@ 411 412 int nr_ice_candidate_pair_unfreeze(nr_ice_peer_ctx *pctx, nr_ice_cand_pair *pair) 413 { 414 assert(pair->state==NR_ICE_PAIR_STATE_FROZEN); 415 416 nr_ice_candidate_pair_set_state(pctx,pair,NR_ICE_PAIR_STATE_WAITING); 417 418 return(0); 419 } 420 421-static void nr_ice_candidate_pair_stun_cb(int s, int how, void *cb_arg) 422+static void nr_ice_candidate_pair_stun_cb(NR_SOCKET s, int how, void *cb_arg) 423 { 424 int r,_status; 425 nr_ice_cand_pair *pair=cb_arg,*orig_pair; 426 nr_ice_candidate *cand=0; 427 nr_stun_message *sres; 428 nr_transport_addr *request_src; 429 nr_transport_addr *request_dst; 430 nr_transport_addr *response_src; 431 nr_transport_addr response_dst; 432 nr_stun_message_attribute *attr; 433@@ -457,32 +457,47 @@ 434 abort: 435 return(_status); 436 } 437 438 int nr_ice_candidate_pair_set_state(nr_ice_peer_ctx *pctx, nr_ice_cand_pair *pair, int state) 439 { 440 int r,_status; 441 442 r_log(LOG_ICE,LOG_DEBUG,"ICE-PEER(%s): setting pair %s to %s", 443 pctx->label,pair->as_string,nr_ice_cand_pair_states[state]); 444- pair->state=state; 445 446- if(pctx->state!=NR_ICE_PAIR_STATE_WAITING){ 447+ /* NOTE: This function used to reference pctx->state instead of 448+ pair->state and the assignment to pair->state was at the top 449+ of this function. Because pctx->state was never changed, this seems to have 450+ been a typo. The natural logic is "if the state changed 451+ decrement the counter" so this implies we should be checking 452+ the pair state rather than the pctx->state. 453+ 454+ This didn't cause big problems because waiting_pairs was only 455+ used for pacing, so the pacing just was kind of broken. 456+ 457+ This note is here as a reminder until we do more testing 458+ and make sure that in fact this was a typo. 459+ */ 460+ if(pair->state!=NR_ICE_PAIR_STATE_WAITING){ 461 if(state==NR_ICE_PAIR_STATE_WAITING) 462 pctx->waiting_pairs++; 463 } 464 else{ 465 if(state!=NR_ICE_PAIR_STATE_WAITING) 466 pctx->waiting_pairs--; 467 468 assert(pctx->waiting_pairs>=0); 469 } 470+ pair->state=state; 471+ 472+ 473 if(pair->state==NR_ICE_PAIR_STATE_FAILED){ 474 if(r=nr_ice_component_failed_pair(pair->remote->component, pair)) 475 ABORT(r); 476 } 477 478 _status=0; 479 abort: 480 return(_status); 481 } 482 483@@ -505,42 +520,42 @@ 484 break; 485 } 486 487 c1=TAILQ_NEXT(c1,entry); 488 } 489 if(!c1) TAILQ_INSERT_TAIL(head,pair,entry); 490 491 return(0); 492 } 493 494-void nr_ice_candidate_pair_restart_stun_nominated_cb(int s, int how, void *cb_arg) 495+void nr_ice_candidate_pair_restart_stun_nominated_cb(NR_SOCKET s, int how, void *cb_arg) 496 { 497 nr_ice_cand_pair *pair=cb_arg; 498 int r,_status; 499 500 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); 501 502 nr_stun_client_reset(pair->stun_client); 503 pair->stun_client->params.ice_binding_request.control=NR_ICE_CONTROLLING; 504 505 if(r=nr_stun_client_start(pair->stun_client,NR_ICE_CLIENT_MODE_USE_CANDIDATE,nr_ice_candidate_pair_stun_cb,pair)) 506 ABORT(r); 507 508 if(r=nr_ice_ctx_remember_id(pair->pctx->ctx, pair->stun_client->request)) 509 ABORT(r); 510 511 _status=0; 512 abort: 513 return; 514 } 515 516-static void nr_ice_candidate_pair_restart_stun_controlled_cb(int s, int how, void *cb_arg) 517+static void nr_ice_candidate_pair_restart_stun_controlled_cb(NR_SOCKET s, int how, void *cb_arg) 518 { 519 nr_ice_cand_pair *pair=cb_arg; 520 int r,_status; 521 522 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); 523 524 nr_stun_client_reset(pair->stun_client); 525 pair->stun_client->params.ice_binding_request.control=NR_ICE_CONTROLLED; 526 527 if(r=nr_stun_client_start(pair->stun_client,NR_ICE_CLIENT_MODE_BINDING_REQUEST,nr_ice_candidate_pair_stun_cb,pair)) 528@@ -556,21 +571,21 @@ 529 530 531 532 static void nr_ice_candidate_pair_compute_codeword(nr_ice_cand_pair *pair, 533 nr_ice_candidate *lcand, nr_ice_candidate *rcand) 534 { 535 int r,_status; 536 char *as_string=0; 537 538 if(r=nr_concat_strings(&as_string,lcand->addr.as_string,"|", 539- rcand->addr.as_string,"(",lcand->label,"|",rcand->label,")",0)) 540+ rcand->addr.as_string,"(",lcand->label,"|",rcand->label,")",NULL)) 541 ABORT(r); 542 543 nr_ice_compute_codeword(as_string,strlen(as_string),pair->codeword); 544 545 _status=0; 546 abort: 547 RFREE(as_string); 548 return; 549 } 550 551diff -U10 -r /Users/ekr/dev/mtransport-import-references/nICEr/src/ice/ice_candidate_pair.h src/ice/ice_candidate_pair.h 552--- /Users/ekr/dev/mtransport-import-references/nICEr/src/ice/ice_candidate_pair.h 2012-09-16 16:26:08.000000000 -0700 553+++ src/ice/ice_candidate_pair.h 2012-10-06 08:30:22.000000000 -0700 554@@ -72,18 +72,18 @@ 555 556 int nr_ice_candidate_pair_create(nr_ice_peer_ctx *pctx, nr_ice_candidate *lcand,nr_ice_candidate *rcand,nr_ice_cand_pair **pairp); 557 int nr_ice_candidate_pair_unfreeze(nr_ice_peer_ctx *pctx, nr_ice_cand_pair *pair); 558 int nr_ice_candidate_pair_start(nr_ice_peer_ctx *pctx, nr_ice_cand_pair *pair); 559 int nr_ice_candidate_pair_set_state(nr_ice_peer_ctx *pctx, nr_ice_cand_pair *pair, int state); 560 int nr_ice_candidate_pair_dump_state(nr_ice_cand_pair *pair, FILE *out); 561 int nr_ice_candidate_pair_cancel(nr_ice_peer_ctx *pctx,nr_ice_cand_pair *pair); 562 int nr_ice_candidate_pair_select(nr_ice_cand_pair *pair); 563 int nr_ice_candidate_pair_do_triggered_check(nr_ice_peer_ctx *pctx, nr_ice_cand_pair *pair); 564 int nr_ice_candidate_pair_insert(nr_ice_cand_pair_head *head,nr_ice_cand_pair *pair); 565-void nr_ice_candidate_pair_restart_stun_nominated_cb(int s, int how, void *cb_arg); 566+void nr_ice_candidate_pair_restart_stun_nominated_cb(NR_SOCKET s, int how, void *cb_arg); 567 int nr_ice_candidate_pair_destroy(nr_ice_cand_pair **pairp); 568 569 #ifdef __cplusplus 570 } 571 #endif /* __cplusplus */ 572 #endif 573 574diff -U10 -r /Users/ekr/dev/mtransport-import-references/nICEr/src/ice/ice_component.c src/ice/ice_component.c 575--- /Users/ekr/dev/mtransport-import-references/nICEr/src/ice/ice_component.c 2012-09-16 16:26:08.000000000 -0700 576+++ src/ice/ice_component.c 2012-10-06 08:30:22.000000000 -0700 577@@ -451,21 +451,21 @@ 578 if(r=nr_ice_peer_peer_rflx_candidate_create(comp->stream->pctx->ctx,"prflx",comp,&req->src_addr,&pcand)) { 579 *error=(r==R_NO_MEMORY)?500:400; 580 ABORT(r); 581 } 582 if(!nr_stun_message_has_attribute(sreq,NR_STUN_ATTR_PRIORITY,&attr)){ 583 r_log(LOG_ICE,LOG_ERR,"ICE-PEER(%s): Rejecting stun request without priority",comp->stream->pctx->label); 584 *error=487; 585 ABORT(R_BAD_DATA); 586 } 587 pcand->priority=attr->u.priority; 588- pcand->state=NR_ICE_CAND_PEER_CANDIDATE; 589+ pcand->state=NR_ICE_CAND_PEER_CANDIDATE_PAIRED;; 590 TAILQ_INSERT_TAIL(&comp->candidates,pcand,entry_comp); 591 592 if(r=nr_ice_candidate_pair_create(comp->stream->pctx,cand,pcand, 593 &pair)) { 594 *error=(r==R_NO_MEMORY)?500:400; 595 ABORT(r); 596 } 597 nr_ice_candidate_pair_set_state(pair->pctx,pair,NR_ICE_PAIR_STATE_FROZEN); 598 599 if(r=nr_ice_candidate_pair_insert(&comp->stream->check_list,pair)) { 600@@ -563,30 +563,38 @@ 601 break; 602 } 603 604 /* PAIR with each peer*/ 605 if(TAILQ_EMPTY(&pcomp->candidates)) { 606 /* can happen if our peer proposes no (or all bogus) candidates */ 607 goto next_cand; 608 } 609 pcand=TAILQ_FIRST(&pcomp->candidates); 610 while(pcand){ 611- nr_ice_compute_codeword(pcand->label,strlen(pcand->label),codeword); 612- r_log(LOG_ICE,LOG_DEBUG,"Examining peer candidate %s:%s",codeword,pcand->label); 613- 614- if(r=nr_ice_candidate_pair_create(pctx,lcand,pcand,&pair)) 615- ABORT(r); 616- 617- if(r=nr_ice_candidate_pair_insert(&pcomp->stream->check_list, 618- pair)) 619- ABORT(r); 620+ /* Only pair peer candidates which have not yet been paired. 621+ This allows "trickle ICE". (Not yet standardized, but 622+ part of WebRTC). 623+ 624+ TODO(ekr@rtfm.com): Add refernece to the spec when there 625+ is one. 626+ */ 627+ if (pcand->state = NR_ICE_CAND_PEER_CANDIDATE_UNPAIRED) { 628+ nr_ice_compute_codeword(pcand->label,strlen(pcand->label),codeword); 629+ r_log(LOG_ICE,LOG_DEBUG,"Examining peer candidate %s:%s",codeword,pcand->label); 630+ 631+ if(r=nr_ice_candidate_pair_create(pctx,lcand,pcand,&pair)) 632+ ABORT(r); 633 634+ if(r=nr_ice_candidate_pair_insert(&pcomp->stream->check_list, 635+ pair)) 636+ ABORT(r); 637+ } 638 pcand=TAILQ_NEXT(pcand,entry_comp); 639 } 640 641 if(!pair) 642 ABORT(R_INTERNAL); 643 644 /* Add the stun username/password pair from the last pair (any 645 would do) to the stun contexts */ 646 isock=STAILQ_FIRST(&lcomp->sockets); 647 while(isock){ 648@@ -594,20 +602,28 @@ 649 pair->r2l_user,&pair->r2l_pwd,nr_ice_component_stun_server_cb,pcomp)) 650 ABORT(r); 651 652 isock=STAILQ_NEXT(isock,entry); 653 } 654 655 next_cand: 656 lcand=TAILQ_NEXT(lcand,entry_comp); 657 } 658 659+ /* Mark all peer candidates as paired */ 660+ pcand=TAILQ_FIRST(&pcomp->candidates); 661+ while(pcand){ 662+ pcand->state = NR_ICE_CAND_PEER_CANDIDATE_PAIRED; 663+ 664+ pcand=TAILQ_NEXT(pcand,entry_comp); 665+ } 666+ 667 _status=0; 668 abort: 669 return(_status); 670 } 671 672 int nr_ice_component_nominated_pair(nr_ice_component *comp, nr_ice_cand_pair *pair) 673 { 674 int r,_status; 675 int fire_cb=0; 676 nr_ice_cand_pair *p2; 677@@ -616,32 +632,32 @@ 678 fire_cb=1; 679 680 /* Are we changing what the nominated pair is? */ 681 if(comp->nominated){ 682 if(comp->nominated->priority > pair->priority) 683 return(0); 684 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); 685 } 686 687 /* Set the new nominated pair */ 688- 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); 689+ 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); 690 comp->state=NR_ICE_COMPONENT_NOMINATED; 691 comp->nominated=pair; 692 comp->active=pair; 693 694- 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); 695+ 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); 696 697 /* OK, we need to cancel off everything on this component */ 698 p2=TAILQ_FIRST(&comp->stream->check_list); 699 while(p2){ 700 if((p2 != pair) && (p2->remote->component->component_id == comp->component_id)){ 701- 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); 702+ 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); 703 704 if(r=nr_ice_candidate_pair_cancel(pair->pctx,p2)) 705 ABORT(r); 706 } 707 708 p2=TAILQ_NEXT(p2,entry); 709 } 710 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); 711 712 if(r=nr_ice_media_stream_component_nominated(comp->stream,comp)) 713@@ -734,21 +750,21 @@ 714 ABORT(r); 715 } 716 717 _status=0; 718 abort: 719 RFREE(pairs); 720 return(_status); 721 } 722 723 724-static void nr_ice_component_keepalive_cb(int s, int how, void *cb_arg) 725+static void nr_ice_component_keepalive_cb(NR_SOCKET s, int how, void *cb_arg) 726 { 727 nr_ice_component *comp=cb_arg; 728 UINT4 keepalive_timeout; 729 730 assert(comp->keepalive_ctx); 731 732 if(NR_reg_get_uint4(NR_ICE_REG_KEEPALIVE_TIMER,&keepalive_timeout)){ 733 keepalive_timeout=15000; /* Default */ 734 } 735 736diff -U10 -r /Users/ekr/dev/mtransport-import-references/nICEr/src/ice/ice_ctx.c src/ice/ice_ctx.c 737--- /Users/ekr/dev/mtransport-import-references/nICEr/src/ice/ice_ctx.c 2012-09-16 16:26:08.000000000 -0700 738+++ src/ice/ice_ctx.c 2012-10-06 08:30:22.000000000 -0700 739@@ -56,21 +56,21 @@ 740 #include "util.h" 741 742 743 int LOG_ICE = 0; 744 745 static int nr_ice_random_string(char *str, int len); 746 static int nr_ice_fetch_stun_servers(int ct, nr_ice_stun_server **out); 747 #ifdef USE_TURN 748 static int nr_ice_fetch_turn_servers(int ct, nr_ice_turn_server **out); 749 #endif /* USE_TURN */ 750-static void nr_ice_ctx_destroy_cb(int s, int how, void *cb_arg); 751+static void nr_ice_ctx_destroy_cb(NR_SOCKET s, int how, void *cb_arg); 752 753 int nr_ice_fetch_stun_servers(int ct, nr_ice_stun_server **out) 754 { 755 int r,_status; 756 nr_ice_stun_server *servers = 0; 757 int i; 758 NR_registry child; 759 char *addr=0; 760 UINT2 port; 761 in_addr_t addr_int; 762@@ -271,21 +271,21 @@ 763 *ctxp=ctx; 764 765 _status=0; 766 abort: 767 if(_status) 768 nr_ice_ctx_destroy_cb(0,0,ctx); 769 770 return(_status); 771 } 772 773-static void nr_ice_ctx_destroy_cb(int s, int how, void *cb_arg) 774+static void nr_ice_ctx_destroy_cb(NR_SOCKET s, int how, void *cb_arg) 775 { 776 nr_ice_ctx *ctx=cb_arg; 777 nr_ice_foundation *f1,*f2; 778 nr_ice_media_stream *s1,*s2; 779 int i; 780 nr_ice_stun_id *id1,*id2; 781 782 RFREE(ctx->label); 783 784 RFREE(ctx->stun_servers); 785@@ -323,21 +323,21 @@ 786 if(!ctxp || !*ctxp) 787 return(0); 788 789 NR_ASYNC_SCHEDULE(nr_ice_ctx_destroy_cb,*ctxp); 790 791 *ctxp=0; 792 793 return(0); 794 } 795 796-void nr_ice_initialize_finished_cb(int s, int h, void *cb_arg) 797+void nr_ice_initialize_finished_cb(NR_SOCKET s, int h, void *cb_arg) 798 { 799 nr_ice_ctx *ctx=cb_arg; 800 801 /* r_log(LOG_ICE,LOG_DEBUG,"ICE(%s): Candidate %s %s",ctx->label, 802 cand->label, cand->state==NR_ICE_CAND_STATE_INITIALIZED?"INITIALIZED":"FAILED"); 803 */ 804 ctx->uninitialized_candidates--; 805 806 if(ctx->uninitialized_candidates==0){ 807 r_log(LOG_ICE,LOG_DEBUG,"ICE(%s): All candidates initialized",ctx->label); 808@@ -368,21 +368,22 @@ 809 stream=STAILQ_FIRST(&ctx->streams); 810 while(stream){ 811 if(r=nr_ice_media_stream_initialize(ctx,stream)) 812 ABORT(r); 813 814 stream=STAILQ_NEXT(stream,entry); 815 } 816 817 if(ctx->uninitialized_candidates) 818 ABORT(R_WOULDBLOCK); 819- 820+ 821+ 822 _status=0; 823 abort: 824 return(_status); 825 } 826 827 int nr_ice_add_media_stream(nr_ice_ctx *ctx,char *label,int components, nr_ice_media_stream **streamp) 828 { 829 int r,_status; 830 831 if(r=nr_ice_media_stream_create(ctx,label,components,streamp)) 832diff -U10 -r /Users/ekr/dev/mtransport-import-references/nICEr/src/ice/ice_ctx.h src/ice/ice_ctx.h 833--- /Users/ekr/dev/mtransport-import-references/nICEr/src/ice/ice_ctx.h 2012-09-16 16:26:08.000000000 -0700 834+++ src/ice/ice_ctx.h 2012-10-06 08:30:22.000000000 -0700 835@@ -92,23 +92,23 @@ 836 UCHAR id[12]; 837 838 STAILQ_ENTRY(nr_ice_stun_id_) entry; 839 } nr_ice_stun_id; 840 841 typedef STAILQ_HEAD(nr_ice_stun_id_head_,nr_ice_stun_id_) nr_ice_stun_id_head; 842 843 struct nr_ice_ctx_ { 844 UINT4 flags; 845 int state; 846-#define NR_ICE_STATE_CREATED 1 847-#define NR_ICE_STATE_INITIALIZING 2 848-#define NR_ICE_STATE_INITIALIZED 3 849+#define NR_ICE_STATE_CREATED 1 850+#define NR_ICE_STATE_INITIALIZING 2 851+#define NR_ICE_STATE_INITIALIZED 3 852 char *label; 853 854 char *ufrag; 855 char *pwd; 856 857 UINT4 Ta; 858 859 nr_ice_stun_server *stun_servers; /* The list of stun servers */ 860 int stun_server_ct; 861 nr_ice_turn_server *turn_servers; /* The list of turn servers */ 862@@ -133,21 +133,21 @@ 863 864 int nr_ice_ctx_create(char *label, UINT4 flags, nr_ice_ctx **ctxp); 865 #define NR_ICE_CTX_FLAGS_OFFERER 1 866 #define NR_ICE_CTX_FLAGS_ANSWERER (1<<1) 867 #define NR_ICE_CTX_FLAGS_AGGRESSIVE_NOMINATION (1<<2) 868 #define NR_ICE_CTX_FLAGS_LITE (1<<3) 869 870 int nr_ice_ctx_destroy(nr_ice_ctx **ctxp); 871 int nr_ice_initialize(nr_ice_ctx *ctx, NR_async_cb done_cb, void *cb_arg); 872 int nr_ice_add_candidate(nr_ice_ctx *ctx, nr_ice_candidate *cand); 873-void nr_ice_initialize_finished_cb(int s, int h, void *cb_arg); 874+void nr_ice_initialize_finished_cb(NR_SOCKET s, int h, void *cb_arg); 875 int nr_ice_add_media_stream(nr_ice_ctx *ctx,char *label,int components, nr_ice_media_stream **streamp); 876 int nr_ice_get_global_attributes(nr_ice_ctx *ctx,char ***attrsp, int *attrctp); 877 int nr_ice_ctx_deliver_packet(nr_ice_ctx *ctx, nr_ice_component *comp, nr_transport_addr *source_addr, UCHAR *data, int len); 878 int nr_ice_ctx_is_known_id(nr_ice_ctx *ctx, UCHAR id[12]); 879 int nr_ice_ctx_remember_id(nr_ice_ctx *ctx, nr_stun_message *msg); 880 int nr_ice_ctx_finalize(nr_ice_ctx *ctx, nr_ice_peer_ctx *pctx); 881 882 extern int LOG_ICE; 883 884 #ifdef __cplusplus 885diff -U10 -r /Users/ekr/dev/mtransport-import-references/nICEr/src/ice/ice_media_stream.c src/ice/ice_media_stream.c 886--- /Users/ekr/dev/mtransport-import-references/nICEr/src/ice/ice_media_stream.c 2012-09-16 16:26:08.000000000 -0700 887+++ src/ice/ice_media_stream.c 2012-10-06 08:30:22.000000000 -0700 888@@ -35,21 +35,21 @@ 889 static char *RCSSTRING __UNUSED__="$Id: ice_media_stream.c,v 1.2 2008/04/28 17:59:01 ekr Exp $"; 890 891 #include <string.h> 892 #include <assert.h> 893 #include <nr_api.h> 894 #include <r_assoc.h> 895 #include <async_timer.h> 896 #include "ice_ctx.h" 897 898 static char *nr_ice_media_stream_states[]={"INVALID", 899- "FROZEN","ACTIVE","COMPLETED","FAILED" 900+ "UNPAIRED","FROZEN","ACTIVE","COMPLETED","FAILED" 901 }; 902 903 int nr_ice_media_stream_set_state(nr_ice_media_stream *str, int state); 904 905 int nr_ice_media_stream_create(nr_ice_ctx *ctx,char *label,int components, nr_ice_media_stream **streamp) 906 { 907 int r,_status; 908 nr_ice_media_stream *stream=0; 909 nr_ice_component *comp=0; 910 int i; 911@@ -66,29 +66,29 @@ 912 for(i=0;i<components;i++){ 913 /* component-id must be > 0, so increment by 1 */ 914 if(r=nr_ice_component_create(stream, i+1, &comp)) 915 ABORT(r); 916 917 } 918 919 TAILQ_INIT(&stream->check_list); 920 921 stream->component_ct=components; 922- 923+ stream->ice_state = NR_ICE_MEDIA_STREAM_UNPAIRED; 924 *streamp=stream; 925 926 _status=0; 927 abort: 928 if(_status){ 929 nr_ice_media_stream_destroy(&stream); 930 } 931- return(_status); 932+ return(_status); 933 } 934 935 int nr_ice_media_stream_destroy(nr_ice_media_stream **streamp) 936 { 937 nr_ice_media_stream *stream; 938 nr_ice_component *c1,*c2; 939 nr_ice_cand_pair *p1,*p2; 940 if(!streamp || !*streamp) 941 return(0); 942 943@@ -200,85 +200,148 @@ 944 if(attrs){ 945 for(index=0;index<attrct;index++){ 946 RFREE(attrs[index]); 947 } 948 RFREE(attrs); 949 } 950 } 951 return(_status); 952 } 953 954+ 955+/* Get a default candidate per 4.1.4 */ 956+int nr_ice_media_stream_get_default_candidate(nr_ice_media_stream *stream, int component, nr_ice_candidate **candp) 957+ { 958+ int _status; 959+ nr_ice_component *comp; 960+ nr_ice_candidate *cand; 961+ nr_ice_candidate *best_cand = NULL; 962+ 963+ comp=STAILQ_FIRST(&stream->components); 964+ while(comp){ 965+ if (comp->component_id == component) 966+ break; 967+ 968+ comp=STAILQ_NEXT(comp,entry); 969+ } 970+ 971+ if (!comp) 972+ ABORT(R_NOT_FOUND); 973+ 974+ /* We have the component. Now find the "best" candidate, making 975+ use of the fact that more "reliable" candidate types have 976+ higher numbers. So, we sort by type and then priority within 977+ type 978+ */ 979+ cand=TAILQ_FIRST(&comp->candidates); 980+ while(cand){ 981+ if (!best_cand) { 982+ best_cand = cand; 983+ } 984+ else { 985+ if (best_cand->type < cand->type) { 986+ best_cand = cand; 987+ } else if (best_cand->type == cand->type) { 988+ if (best_cand->priority < cand->priority) 989+ best_cand = cand; 990+ } 991+ } 992+ 993+ cand=TAILQ_NEXT(cand,entry_comp); 994+ } 995+ 996+ /* No candidates */ 997+ if (!best_cand) 998+ ABORT(R_NOT_FOUND); 999+ 1000+ *candp = best_cand; 1001+ 1002+ _status=0; 1003+ abort: 1004+ return(_status); 1005+ } 1006+ 1007+ 1008 int nr_ice_media_stream_pair_candidates(nr_ice_peer_ctx *pctx,nr_ice_media_stream *lstream,nr_ice_media_stream *pstream) 1009 { 1010 int r,_status; 1011 nr_ice_component *pcomp,*lcomp; 1012 1013 pcomp=STAILQ_FIRST(&pstream->components); 1014 lcomp=STAILQ_FIRST(&lstream->components); 1015 while(pcomp){ 1016 if(r=nr_ice_component_pair_candidates(pctx,lcomp,pcomp)) 1017 ABORT(r); 1018- 1019+ 1020 lcomp=STAILQ_NEXT(lcomp,entry); 1021 pcomp=STAILQ_NEXT(pcomp,entry); 1022 }; 1023 1024+ if (pstream->ice_state == NR_ICE_MEDIA_STREAM_UNPAIRED) { 1025+ r_log(LOG_ICE,LOG_DEBUG,"ICE-PEER(%s): unfreezing stream %s",pstream->pctx->label,pstream->label); 1026+ pstream->ice_state = NR_ICE_MEDIA_STREAM_CHECKS_FROZEN; 1027+ } 1028+ 1029 _status=0; 1030 abort: 1031 return(_status); 1032 } 1033 1034 /* S 5.8 -- run the highest priority WAITING pair or if not available 1035 FROZEN pair */ 1036-static void nr_ice_media_stream_check_timer_cb(int s, int h, void *cb_arg) 1037+static void nr_ice_media_stream_check_timer_cb(NR_SOCKET s, int h, void *cb_arg) 1038 { 1039 int r,_status; 1040 nr_ice_media_stream *stream=cb_arg; 1041 nr_ice_cand_pair *pair; 1042 int timer_val; 1043 1044 assert(stream->pctx->active_streams!=0); 1045 1046 timer_val=stream->pctx->ctx->Ta*stream->pctx->active_streams; 1047 1048+ if (stream->ice_state == NR_ICE_MEDIA_STREAM_CHECKS_COMPLETED) { 1049+ r_log(LOG_ICE,LOG_DEBUG,"ICE-PEER(%s): bogus state for stream %s",stream->pctx->label,stream->label); 1050+ } 1051 assert(stream->ice_state != NR_ICE_MEDIA_STREAM_CHECKS_COMPLETED); 1052 1053 r_log(LOG_ICE,LOG_DEBUG,"ICE-PEER(%s): check timer expired for media stream %s",stream->pctx->label,stream->label); 1054 stream->timer=0; 1055 1056- 1057 /* Find the highest priority WAITING check and move it to RUNNING */ 1058 pair=TAILQ_FIRST(&stream->check_list); 1059 while(pair){ 1060 if(pair->state==NR_ICE_PAIR_STATE_WAITING) 1061 break; 1062 pair=TAILQ_NEXT(pair,entry); 1063 } 1064 1065 /* Hmmm... No WAITING. Let's look for FROZEN */ 1066 if(!pair){ 1067 pair=TAILQ_FIRST(&stream->check_list); 1068- 1069+ 1070 while(pair){ 1071 if(pair->state==NR_ICE_PAIR_STATE_FROZEN){ 1072 if(r=nr_ice_candidate_pair_unfreeze(stream->pctx,pair)) 1073 ABORT(r); 1074 break; 1075 } 1076 pair=TAILQ_NEXT(pair,entry); 1077 } 1078 } 1079 1080 if(pair){ 1081 nr_ice_candidate_pair_start(pair->pctx,pair); /* Ignore failures */ 1082 NR_ASYNC_TIMER_SET(timer_val,nr_ice_media_stream_check_timer_cb,cb_arg,&stream->timer); 1083 } 1084+ /* TODO(ekr@rtfm.com): Report on the special case where there are no checks to 1085+ run at all */ 1086 _status=0; 1087 abort: 1088 return; 1089 } 1090 1091 1092 /* Start checks for this media stream (aka check list) */ 1093 int nr_ice_media_stream_start_checks(nr_ice_peer_ctx *pctx, nr_ice_media_stream *stream) 1094 { 1095 assert(stream->ice_state==NR_ICE_MEDIA_STREAM_CHECKS_FROZEN); 1096@@ -476,21 +539,23 @@ 1097 /* All done... */ 1098 r_log(LOG_ICE,LOG_INFO,"ICE-PEER(%s)/ICE-STREAM(%s): all components have nominated candidate pairs",stream->pctx->label,stream->label); 1099 nr_ice_media_stream_set_state(stream,NR_ICE_MEDIA_STREAM_CHECKS_COMPLETED); 1100 1101 /* Cancel our timer */ 1102 if(stream->timer){ 1103 NR_async_timer_cancel(stream->timer); 1104 stream->timer=0; 1105 } 1106 1107- stream->pctx->handler->vtbl->stream_ready(stream->pctx->handler->obj,stream->local_stream); 1108+ if (stream->pctx->handler) { 1109+ stream->pctx->handler->vtbl->stream_ready(stream->pctx->handler->obj,stream->local_stream); 1110+ } 1111 1112 /* Now tell the peer_ctx that we're done */ 1113 if(r=nr_ice_peer_ctx_stream_done(stream->pctx,stream)) 1114 ABORT(r); 1115 1116 done: 1117 _status=0; 1118 abort: 1119 return(_status); 1120 } 1121@@ -515,21 +580,23 @@ 1122 1123 p2=TAILQ_NEXT(p2,entry); 1124 } 1125 1126 /* Cancel our timer */ 1127 if(stream->timer){ 1128 NR_async_timer_cancel(stream->timer); 1129 stream->timer=0; 1130 } 1131 1132- stream->pctx->handler->vtbl->stream_failed(stream->pctx->handler->obj,stream->local_stream); 1133+ if (stream->pctx->handler) { 1134+ stream->pctx->handler->vtbl->stream_failed(stream->pctx->handler->obj,stream->local_stream); 1135+ } 1136 1137 /* Now tell the peer_ctx that we're done */ 1138 if(r=nr_ice_peer_ctx_stream_done(stream->pctx,stream)) 1139 ABORT(r); 1140 1141 _status=0; 1142 abort: 1143 return(_status); 1144 } 1145 1146diff -U10 -r /Users/ekr/dev/mtransport-import-references/nICEr/src/ice/ice_media_stream.h src/ice/ice_media_stream.h 1147--- /Users/ekr/dev/mtransport-import-references/nICEr/src/ice/ice_media_stream.h 2012-09-16 16:26:08.000000000 -0700 1148+++ src/ice/ice_media_stream.h 2012-10-06 08:30:22.000000000 -0700 1149@@ -45,40 +45,43 @@ 1150 struct nr_ice_peer_ctx_ *pctx; 1151 1152 struct nr_ice_media_stream_ *local_stream; /* used when this is a peer */ 1153 int component_ct; 1154 nr_ice_component_head components; 1155 1156 char *ufrag; /* ICE username */ 1157 char *pwd; /* ICE password */ 1158 1159 int ice_state; 1160-#define NR_ICE_MEDIA_STREAM_CHECKS_FROZEN 1 1161-#define NR_ICE_MEDIA_STREAM_CHECKS_ACTIVE 2 1162-#define NR_ICE_MEDIA_STREAM_CHECKS_COMPLETED 3 1163-#define NR_ICE_MEDIA_STREAM_CHECKS_FAILED 4 1164+ 1165+#define NR_ICE_MEDIA_STREAM_UNPAIRED 1 1166+#define NR_ICE_MEDIA_STREAM_CHECKS_FROZEN 2 1167+#define NR_ICE_MEDIA_STREAM_CHECKS_ACTIVE 3 1168+#define NR_ICE_MEDIA_STREAM_CHECKS_COMPLETED 4 1169+#define NR_ICE_MEDIA_STREAM_CHECKS_FAILED 5 1170 1171 nr_ice_cand_pair_head check_list; 1172 void *timer; /* Check list periodic timer */ 1173 1174 // nr_ice_cand_pair_head valid_list; 1175- 1176+ 1177 STAILQ_ENTRY(nr_ice_media_stream_) entry; 1178 }; 1179 1180 typedef STAILQ_HEAD(nr_ice_media_stream_head_,nr_ice_media_stream_) nr_ice_media_stream_head; 1181 1182 int nr_ice_media_stream_create(struct nr_ice_ctx_ *ctx,char *label, int components, nr_ice_media_stream **streamp); 1183 int nr_ice_media_stream_destroy(nr_ice_media_stream **streamp); 1184 int nr_ice_media_stream_finalize(nr_ice_media_stream *lstr,nr_ice_media_stream *rstr); 1185 int nr_ice_media_stream_initialize(struct nr_ice_ctx_ *ctx, nr_ice_media_stream *stream); 1186 int nr_ice_media_stream_get_attributes(nr_ice_media_stream *stream, char ***attrsp,int *attrctp); 1187+int nr_ice_media_stream_get_default_candidate(nr_ice_media_stream *stream, int component, nr_ice_candidate **candp); 1188 int nr_ice_media_stream_pair_candidates(nr_ice_peer_ctx *pctx,nr_ice_media_stream *lstream,nr_ice_media_stream *pstream); 1189 int nr_ice_media_stream_start_checks(nr_ice_peer_ctx *pctx, nr_ice_media_stream *stream); 1190 int nr_ice_media_stream_unfreeze_pairs(nr_ice_peer_ctx *pctx, nr_ice_media_stream *stream); 1191 int nr_ice_media_stream_unfreeze_pairs_foundation(nr_ice_media_stream *stream, char *foundation); 1192 int nr_ice_media_stream_dump_state(nr_ice_peer_ctx *pctx, nr_ice_media_stream *stream,FILE *out); 1193 int nr_ice_media_stream_component_nominated(nr_ice_media_stream *stream,nr_ice_component *component); 1194 int nr_ice_media_stream_component_failed(nr_ice_media_stream *stream,nr_ice_component *component); 1195 int nr_ice_media_stream_set_state(nr_ice_media_stream *str, int state); 1196 int nr_ice_media_stream_get_best_candidate(nr_ice_media_stream *str, int component, nr_ice_candidate **candp); 1197 int nr_ice_media_stream_send(nr_ice_peer_ctx *pctx,nr_ice_media_stream *str, int component, UCHAR *data, int len); 1198diff -U10 -r /Users/ekr/dev/mtransport-import-references/nICEr/src/ice/ice_parser.c src/ice/ice_parser.c 1199--- /Users/ekr/dev/mtransport-import-references/nICEr/src/ice/ice_parser.c 2012-09-16 16:26:08.000000000 -0700 1200+++ src/ice/ice_parser.c 2012-10-06 08:30:22.000000000 -0700 1201@@ -35,20 +35,21 @@ 1202 static char *RCSSTRING __UNUSED__="$Id: ice_parser.c,v 1.2 2008/04/28 17:59:01 ekr Exp $"; 1203 1204 #include <csi_platform.h> 1205 #include <sys/types.h> 1206 #ifdef WIN32 1207 #include <winsock2.h> 1208 #else 1209 #include <sys/socket.h> 1210 #include <netinet/in.h> 1211 #include <arpa/inet.h> 1212+#include <strings.h> 1213 #endif 1214 #include <string.h> 1215 #include <assert.h> 1216 #include <ctype.h> 1217 #include "nr_api.h" 1218 #include "ice_ctx.h" 1219 #include "ice_candidate.h" 1220 #include "ice_reg.h" 1221 1222 static void 1223@@ -125,21 +126,21 @@ 1224 char *rel_addr=0; 1225 1226 if(!(cand=RCALLOC(sizeof(nr_ice_candidate)))) 1227 ABORT(R_NO_MEMORY); 1228 1229 if(!(cand->label=r_strdup(orig))) 1230 ABORT(R_NO_MEMORY); 1231 1232 cand->ctx=ctx; 1233 cand->isock=0; 1234- cand->state=NR_ICE_CAND_PEER_CANDIDATE; 1235+ cand->state=NR_ICE_CAND_PEER_CANDIDATE_UNPAIRED; 1236 cand->stream=stream; 1237 skip_whitespace(&str); 1238 1239 /* Candidate attr */ 1240 if (strncasecmp(str, "candidate:", 10)) 1241 ABORT(R_BAD_DATA); 1242 1243 fast_forward(&str, 10); 1244 if (*str == '\0') 1245 ABORT(R_BAD_DATA); 1246@@ -311,26 +312,31 @@ 1247 /* it's expected to be at EOD at this point */ 1248 1249 break; 1250 default: 1251 ABORT(R_INTERNAL); 1252 break; 1253 } 1254 1255 skip_whitespace(&str); 1256 1257- assert(strlen(str) == 0); 1258- 1259+ /* This used to be an assert, but we don't want to exit on invalid 1260+ remote data */ 1261+ if (strlen(str) != 0) { 1262+ ABORT(R_BAD_DATA); 1263+ } 1264+ 1265 *candp=cand; 1266 1267 _status=0; 1268 abort: 1269+ /* TODO(ekr@rtfm.com): Fix memory leak if we have a parse error */ 1270 if (_status) 1271 r_log(LOG_ICE,LOG_WARNING,"ICE(%s): Error parsing attribute: %s",ctx->label,orig); 1272 1273 RFREE(connection_address); 1274 RFREE(rel_addr); 1275 return(_status); 1276 } 1277 1278 1279 int 1280diff -U10 -r /Users/ekr/dev/mtransport-import-references/nICEr/src/ice/ice_peer_ctx.c src/ice/ice_peer_ctx.c 1281--- /Users/ekr/dev/mtransport-import-references/nICEr/src/ice/ice_peer_ctx.c 2012-09-16 16:26:08.000000000 -0700 1282+++ src/ice/ice_peer_ctx.c 2012-10-06 08:30:22.000000000 -0700 1283@@ -35,33 +35,35 @@ 1284 static char *RCSSTRING __UNUSED__="$Id: ice_peer_ctx.c,v 1.2 2008/04/28 17:59:01 ekr Exp $"; 1285 1286 #include <string.h> 1287 #include <assert.h> 1288 #include <nr_api.h> 1289 #include "ice_ctx.h" 1290 #include "ice_peer_ctx.h" 1291 #include "nr_crypto.h" 1292 #include "async_timer.h" 1293 1294-static void nr_ice_peer_ctx_destroy_cb(int s, int how, void *cb_arg); 1295+static void nr_ice_peer_ctx_destroy_cb(NR_SOCKET s, int how, void *cb_arg); 1296+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); 1297+static int nr_ice_ctx_parse_candidate(nr_ice_peer_ctx *pctx, nr_ice_media_stream *pstream, char *candidate); 1298 1299 int nr_ice_peer_ctx_create(nr_ice_ctx *ctx, nr_ice_handler *handler,char *label, nr_ice_peer_ctx **pctxp) 1300 { 1301 int r,_status; 1302 nr_ice_peer_ctx *pctx=0; 1303 1304 if(!(pctx=RCALLOC(sizeof(nr_ice_peer_ctx)))) 1305 ABORT(R_NO_MEMORY); 1306 1307 if(!(pctx->label=r_strdup(label))) 1308 ABORT(R_NO_MEMORY); 1309- 1310+ 1311 pctx->ctx=ctx; 1312 pctx->handler=handler; 1313 1314 /* Decide controlling vs. controlled */ 1315 if(ctx->flags & NR_ICE_CTX_FLAGS_LITE){ 1316 if(pctx->peer_lite){ 1317 r_log(LOG_ICE,LOG_ERR,"Both sides are ICE-Lite"); 1318 ABORT(R_BAD_DATA); 1319 } 1320 1321@@ -88,85 +90,177 @@ 1322 nr_ice_peer_ctx_destroy_cb(0,0,pctx); 1323 } 1324 return(_status); 1325 } 1326 1327 1328 1329 int nr_ice_peer_ctx_parse_stream_attributes(nr_ice_peer_ctx *pctx, nr_ice_media_stream *stream, char **attrs, int attr_ct) 1330 { 1331 nr_ice_media_stream *pstream=0; 1332- nr_ice_candidate *cand=0; 1333 nr_ice_component *comp,*comp2; 1334 int r,_status; 1335- int i,j; 1336 1337- /* Note: use component_ct from our own stream since components other 1338- than this offered by the other side are unusable */ 1339+ /* 1340+ Note: use component_ct from our own stream since components other 1341+ than this offered by the other side are unusable */ 1342 if(r=nr_ice_media_stream_create(pctx->ctx,stream->label,stream->component_ct,&pstream)) 1343 ABORT(r); 1344- 1345- /* Match up the local and remote components */ 1346+ 1347+ /* Match up the local and remote components */ 1348 comp=STAILQ_FIRST(&stream->components); 1349 comp2=STAILQ_FIRST(&pstream->components); 1350 while(comp){ 1351 comp2->local_component=comp; 1352 1353 comp=STAILQ_NEXT(comp,entry); 1354 comp2=STAILQ_NEXT(comp2,entry); 1355 } 1356- 1357 1358- pstream->ice_state=NR_ICE_MEDIA_STREAM_CHECKS_FROZEN; 1359 pstream->local_stream=stream; 1360 pstream->pctx=pctx; 1361 1362+ if (r=nr_ice_peer_ctx_parse_stream_attributes_int(pctx,stream,pstream,attrs,attr_ct)) 1363+ ABORT(r); 1364+ 1365+ 1366+ STAILQ_INSERT_TAIL(&pctx->peer_streams,pstream,entry); 1367+ 1368+ _status=0; 1369+ abort: 1370+ return(_status); 1371+ } 1372+ 1373+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) 1374+ { 1375+ int r; 1376+ int i; 1377+ 1378 for(i=0;i<attr_ct;i++){ 1379 if(!strncmp(attrs[i],"ice-",4)){ 1380- if(r=nr_ice_peer_ctx_parse_media_stream_attribute(pctx,pstream,attrs[i])) 1381+ if(r=nr_ice_peer_ctx_parse_media_stream_attribute(pctx,pstream,attrs[i])) { 1382+ r_log(LOG_ICE,LOG_ERR,"ICE(%s): peer (%s) specified bogus ICE attribute",pctx->ctx->label,pctx->label); 1383 continue; 1384- continue; 1385+ } 1386 } 1387- 1388- if(r=nr_ice_peer_candidate_from_attribute(pctx->ctx,attrs[i],pstream,&cand)) 1389- continue; 1390- if(cand->component_id-1>=pstream->component_ct){ 1391- r_log(LOG_ICE,LOG_ERR,"ICE(%s): peer (%s) specified too many components",pctx->ctx->label,pctx->label); 1392- continue; 1393+ else if (!strncmp(attrs[i],"candidate",9)){ 1394+ if(r=nr_ice_ctx_parse_candidate(pctx,pstream,attrs[i])) { 1395+ r_log(LOG_ICE,LOG_ERR,"ICE(%s): peer (%s) specified bogus candidate",pctx->ctx->label,pctx->label); 1396+ continue; 1397+ } 1398+ } 1399+ else { 1400+ r_log(LOG_ICE,LOG_ERR,"ICE(%s): peer (%s) specified bogus attribute",pctx->ctx->label,pctx->label); 1401 } 1402+ } 1403 1404- /* Not the fastest way to find a component, but it's what we got */ 1405- j=1; 1406- for(comp=STAILQ_FIRST(&pstream->components);comp;comp=STAILQ_NEXT(comp,entry)){ 1407- if(j==cand->component_id) 1408- break; 1409+ /* Doesn't fail because we just skip errors */ 1410+ return(0); 1411+ } 1412 1413- j++; 1414- } 1415- 1416- if(!comp){ 1417- r_log(LOG_ICE,LOG_ERR,"Peer answered with more components than we offered"); 1418- ABORT(R_BAD_DATA); 1419- } 1420- 1421- cand->component=comp; 1422+static int nr_ice_ctx_parse_candidate(nr_ice_peer_ctx *pctx, nr_ice_media_stream *pstream, char *candidate) 1423+ { 1424+ nr_ice_candidate *cand=0; 1425+ nr_ice_component *comp; 1426+ int j; 1427+ int r, _status; 1428 1429- TAILQ_INSERT_TAIL(&comp->candidates,cand,entry_comp); 1430+ if(r=nr_ice_peer_candidate_from_attribute(pctx->ctx,candidate,pstream,&cand)) 1431+ ABORT(r); 1432+ if(cand->component_id-1>=pstream->component_ct){ 1433+ r_log(LOG_ICE,LOG_ERR,"ICE(%s): peer (%s) specified too many components",pctx->ctx->label,pctx->label); 1434+ ABORT(R_BAD_DATA); 1435 } 1436 1437- STAILQ_INSERT_TAIL(&pctx->peer_streams,pstream,entry); 1438+ /* Not the fastest way to find a component, but it's what we got */ 1439+ j=1; 1440+ for(comp=STAILQ_FIRST(&pstream->components);comp;comp=STAILQ_NEXT(comp,entry)){ 1441+ if(j==cand->component_id) 1442+ break; 1443+ 1444+ j++; 1445+ } 1446+ 1447+ if(!comp){ 1448+ r_log(LOG_ICE,LOG_ERR,"Peer answered with more components than we offered"); 1449+ ABORT(R_BAD_DATA); 1450+ } 1451+ 1452+ cand->component=comp; 1453+ 1454+ TAILQ_INSERT_TAIL(&comp->candidates,cand,entry_comp); 1455 1456 _status=0; 1457- abort: 1458+ abort: 1459+ if (_status) { 1460+ nr_ice_candidate_destroy(&cand); 1461+ } 1462 return(_status); 1463 } 1464 1465+ 1466+ 1467+int nr_ice_peer_ctx_parse_trickle_candidate(nr_ice_peer_ctx *pctx, nr_ice_media_stream *stream, char *candidate) 1468+ { 1469+ /* First need to find the stream. Because we don't have forward pointers, 1470+ iterate through all the peer streams to find one that matches us */ 1471+ nr_ice_media_stream *pstream; 1472+ int r,_status; 1473+ int needs_pairing = 0; 1474+ 1475+ pstream=STAILQ_FIRST(&pctx->peer_streams); 1476+ while(pstream) { 1477+ if (pstream->local_stream == stream) 1478+ break; 1479+ 1480+ pstream = STAILQ_NEXT(pstream, entry); 1481+ } 1482+ if (!pstream) { 1483+ r_log(LOG_ICE,LOG_ERR,"ICE(%s): peer (%s) has no stream matching stream %s",pctx->ctx->label,pctx->label,stream->label); 1484+ ABORT(R_NOT_FOUND); 1485+ } 1486+ 1487+ switch(pstream->ice_state) { 1488+ case NR_ICE_MEDIA_STREAM_UNPAIRED: 1489+ break; 1490+ case NR_ICE_MEDIA_STREAM_CHECKS_FROZEN: 1491+ case NR_ICE_MEDIA_STREAM_CHECKS_ACTIVE: 1492+ needs_pairing = 1; 1493+ break; 1494+ default: 1495+ 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); 1496+ ABORT(R_ALREADY); 1497+ break; 1498+ } 1499+ 1500+ if(r=nr_ice_ctx_parse_candidate(pctx,pstream,candidate)){ 1501+ ABORT(r); 1502+ } 1503+ 1504+ /* If ICE is running (i.e., we are in FROZEN or ACTIVE states) 1505+ then we need to pair this new candidate. For now we 1506+ just re-pair the stream which is inefficient but still 1507+ fine because we suppress duplicate pairing */ 1508+ if (needs_pairing) { 1509+ if(r=nr_ice_media_stream_pair_candidates(pctx, stream, pstream)) { 1510+ 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); 1511+ ABORT(r); 1512+ } 1513+ } 1514+ 1515+ _status =0; 1516+ abort: 1517+ return(_status); 1518+ 1519+ } 1520+ 1521+ 1522 int nr_ice_peer_ctx_pair_candidates(nr_ice_peer_ctx *pctx) 1523 { 1524 nr_ice_media_stream *stream; 1525 int r,_status; 1526 1527 if(STAILQ_EMPTY(&pctx->peer_streams)) { 1528 r_log(LOG_ICE,LOG_ERR,"ICE(%s): peer (%s) received no media stream attribributes",pctx->ctx->label,pctx->label); 1529 ABORT(R_FAILED); 1530 } 1531 1532@@ -177,21 +271,21 @@ 1533 ABORT(r); 1534 1535 stream=STAILQ_NEXT(stream,entry); 1536 } 1537 1538 _status=0; 1539 abort: 1540 return(_status); 1541 } 1542 1543-static void nr_ice_peer_ctx_destroy_cb(int s, int how, void *cb_arg) 1544+static void nr_ice_peer_ctx_destroy_cb(NR_SOCKET s, int how, void *cb_arg) 1545 { 1546 nr_ice_peer_ctx *pctx=cb_arg; 1547 nr_ice_media_stream *str1,*str2; 1548 1549 RFREE(pctx->label); 1550 RFREE(pctx->peer_ufrag); 1551 RFREE(pctx->peer_pwd); 1552 1553 STAILQ_FOREACH_SAFE(str1, &pctx->peer_streams, entry, str2){ 1554 STAILQ_REMOVE(&pctx->peer_streams,str1,nr_ice_media_stream_,entry); 1555@@ -199,44 +293,79 @@ 1556 } 1557 1558 RFREE(pctx); 1559 } 1560 1561 int nr_ice_peer_ctx_destroy(nr_ice_peer_ctx **pctxp) 1562 { 1563 1564 if(!pctxp || !*pctxp) 1565 return(0); 1566- 1567+ 1568+ /* Stop calling the handler */ 1569+ (*pctxp)->handler = 0; 1570+ 1571 NR_ASYNC_SCHEDULE(nr_ice_peer_ctx_destroy_cb,*pctxp); 1572 1573 *pctxp=0; 1574 1575 return(0); 1576 } 1577 1578+ 1579 /* Start the checks for the first media stream (S 5.7) 1580 The rest remain FROZEN */ 1581 int nr_ice_peer_ctx_start_checks(nr_ice_peer_ctx *pctx) 1582 { 1583+ return nr_ice_peer_ctx_start_checks2(pctx, 0); 1584+ } 1585+ 1586+/* Start checks for some media stream. 1587+ 1588+ If allow_non_first == 0, then we only look at the first stream, 1589+ which is 5245-complaint. 1590+ 1591+ If allow_non_first == 1 then we find the first non-empty stream 1592+ This is not compliant with RFC 5245 but is necessary to make trickle ICE 1593+ work plausibly 1594+*/ 1595+int nr_ice_peer_ctx_start_checks2(nr_ice_peer_ctx *pctx, int allow_non_first) 1596+ { 1597 int r,_status; 1598 nr_ice_media_stream *stream; 1599 1600 stream=STAILQ_FIRST(&pctx->peer_streams); 1601 if(!stream) 1602 ABORT(R_FAILED); 1603 1604+ while (stream) { 1605+ if(!TAILQ_EMPTY(&stream->check_list)) 1606+ break; 1607+ 1608+ if(!allow_non_first){ 1609+ r_log(LOG_ICE,LOG_ERR,"ICE(%s): peer (%s) first stream has empty check list",pctx->ctx->label,pctx->label); 1610+ ABORT(R_FAILED); 1611+ } 1612+ 1613+ stream=STAILQ_NEXT(stream, entry); 1614+ } 1615+ 1616+ if (!stream) { 1617+ r_log(LOG_ICE,LOG_ERR,"ICE(%s): peer (%s) no streams with non-empty check lists",pctx->ctx->label,pctx->label); 1618+ ABORT(R_NOT_FOUND); 1619+ } 1620+ 1621 if (stream->ice_state == NR_ICE_MEDIA_STREAM_CHECKS_FROZEN) { 1622- if(r=nr_ice_media_stream_unfreeze_pairs(pctx,stream)) 1623- ABORT(r); 1624- if(r=nr_ice_media_stream_start_checks(pctx,stream)) 1625- ABORT(r); 1626+ if(r=nr_ice_media_stream_unfreeze_pairs(pctx,stream)) 1627+ ABORT(r); 1628+ if(r=nr_ice_media_stream_start_checks(pctx,stream)) 1629+ ABORT(r); 1630 } 1631 1632 _status=0; 1633 abort: 1634 return(_status); 1635 } 1636 1637 #ifndef NDEBUG 1638 int nr_ice_peer_ctx_dump_state(nr_ice_peer_ctx *pctx,FILE *out) 1639 { 1640@@ -253,26 +382,28 @@ 1641 stream=STAILQ_NEXT(stream,entry); 1642 } 1643 fprintf(out,"==========================================\n"); 1644 1645 _status=0; 1646 abort: 1647 return(_status); 1648 } 1649 #endif 1650 1651-static void nr_ice_peer_ctx_fire_done(int s, int how, void *cb_arg) 1652+static void nr_ice_peer_ctx_fire_done(NR_SOCKET s, int how, void *cb_arg) 1653 { 1654 nr_ice_peer_ctx *pctx=cb_arg; 1655 1656 /* Fire the handler callback to say we're done */ 1657- pctx->handler->vtbl->ice_completed(pctx->handler->obj, pctx); 1658+ if (pctx->handler) { 1659+ pctx->handler->vtbl->ice_completed(pctx->handler->obj, pctx); 1660+ } 1661 } 1662 1663 1664 /* OK, a stream just went ready. Examine all the streams to see if we're 1665 maybe miraculously done */ 1666 int nr_ice_peer_ctx_stream_done(nr_ice_peer_ctx *pctx, nr_ice_media_stream *stream) 1667 { 1668 int _status; 1669 nr_ice_media_stream *str; 1670 int failed=0; 1671@@ -365,21 +496,24 @@ 1672 NR_TRANSPORT_ADDR_CMP_MODE_ALL)) 1673 break; 1674 1675 cand=TAILQ_NEXT(cand,entry_comp); 1676 } 1677 1678 if(!cand) 1679 ABORT(R_REJECTED); 1680 1681 /* OK, there's a match. Call the handler */ 1682- r_log(LOG_ICE,LOG_DEBUG,"ICE-PEER(%s): Delivering data", pctx->label); 1683 1684- pctx->handler->vtbl->msg_recvd(pctx->handler->obj, 1685- pctx,comp->stream,comp->component_id,data,len); 1686+ if (pctx->handler) { 1687+ r_log(LOG_ICE,LOG_DEBUG,"ICE-PEER(%s): Delivering data", pctx->label); 1688+ 1689+ pctx->handler->vtbl->msg_recvd(pctx->handler->obj, 1690+ pctx,comp->stream,comp->component_id,data,len); 1691+ } 1692 1693 _status=0; 1694 abort: 1695 return(_status); 1696 } 1697 1698 1699diff -U10 -r /Users/ekr/dev/mtransport-import-references/nICEr/src/ice/ice_peer_ctx.h src/ice/ice_peer_ctx.h 1700--- /Users/ekr/dev/mtransport-import-references/nICEr/src/ice/ice_peer_ctx.h 2012-09-16 16:26:08.000000000 -0700 1701+++ src/ice/ice_peer_ctx.h 2012-10-06 08:30:22.000000000 -0700 1702@@ -33,23 +33,21 @@ 1703 1704 1705 #ifndef _ice_peer_ctx_h 1706 #define _ice_peer_ctx_h 1707 #ifdef __cplusplus 1708 using namespace std; 1709 extern "C" { 1710 #endif /* __cplusplus */ 1711 1712 struct nr_ice_peer_ctx_ { 1713- int state; 1714 char *label; 1715- 1716 nr_ice_ctx *ctx; 1717 nr_ice_handler *handler; 1718 1719 UCHAR controlling; /* 1 for controlling, 0 for controlled */ 1720 UINT8 tiebreaker; 1721 1722 char *peer_ufrag; 1723 char *peer_pwd; 1724 int peer_lite; 1725 int peer_ice_mismatch; 1726@@ -59,23 +57,26 @@ 1727 int waiting_pairs; 1728 1729 STAILQ_ENTRY(nr_ice_peer_ctx_) entry; 1730 }; 1731 1732 typedef STAILQ_HEAD(nr_ice_peer_ctx_head_, nr_ice_peer_ctx_) nr_ice_peer_ctx_head; 1733 1734 int nr_ice_peer_ctx_create(nr_ice_ctx *ctx, nr_ice_handler *handler,char *label, nr_ice_peer_ctx **pctxp); 1735 int nr_ice_peer_ctx_destroy(nr_ice_peer_ctx **pctxp); 1736 int nr_ice_peer_ctx_parse_stream_attributes(nr_ice_peer_ctx *pctx, nr_ice_media_stream *stream, char **attrs, int attr_ct); 1737+int nr_ice_peer_ctx_parse_trickle_candidate(nr_ice_peer_ctx *pctx, nr_ice_media_stream *stream, char *cand); 1738+ 1739 int nr_ice_peer_ctx_pair_candidates(nr_ice_peer_ctx *pctx); 1740 int nr_ice_peer_ctx_parse_global_attributes(nr_ice_peer_ctx *pctx, char **attrs, int attr_ct); 1741 int nr_ice_peer_ctx_start_checks(nr_ice_peer_ctx *pctx); 1742+int nr_ice_peer_ctx_start_checks2(nr_ice_peer_ctx *pctx, int allow_non_first); 1743 int nr_ice_peer_ctx_dump_state(nr_ice_peer_ctx *pctx,FILE *out); 1744 int nr_ice_peer_ctx_log_state(nr_ice_peer_ctx *pctx); 1745 int nr_ice_peer_ctx_stream_done(nr_ice_peer_ctx *pctx, nr_ice_media_stream *stream); 1746 int nr_ice_peer_ctx_find_component(nr_ice_peer_ctx *pctx, nr_ice_media_stream *str, int component_id, nr_ice_component **compp); 1747 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); 1748 #ifdef __cplusplus 1749 } 1750 #endif /* __cplusplus */ 1751 #endif 1752 1753diff -U10 -r /Users/ekr/dev/mtransport-import-references/nICEr/src/ice/ice_socket.c src/ice/ice_socket.c 1754--- /Users/ekr/dev/mtransport-import-references/nICEr/src/ice/ice_socket.c 2012-09-16 16:26:08.000000000 -0700 1755+++ src/ice/ice_socket.c 2012-10-06 08:30:22.000000000 -0700 1756@@ -216,28 +216,34 @@ 1757 RFREE(s1); 1758 } 1759 1760 RFREE(isock); 1761 1762 return(0); 1763 } 1764 1765 int nr_ice_socket_close(nr_ice_socket *isock) 1766 { 1767+#ifdef NR_SOCKET_IS_VOID_PTR 1768+ NR_SOCKET fd=NULL; 1769+ NR_SOCKET no_socket = NULL; 1770+#else 1771 NR_SOCKET fd=-1; 1772+ NR_SOCKET no_socket = -1; 1773+#endif 1774 1775 if (!isock||!isock->sock) 1776 return(0); 1777 1778 nr_socket_getfd(isock->sock,&fd); 1779 assert(isock->sock!=0); 1780- if(fd!=-1){ 1781+ if(fd != no_socket){ 1782 NR_ASYNC_CANCEL(fd,NR_ASYNC_WAIT_READ); 1783 NR_ASYNC_CANCEL(fd,NR_ASYNC_WAIT_WRITE); 1784 nr_socket_destroy(&isock->sock); 1785 } 1786 1787 return(0); 1788 } 1789 1790 int nr_ice_socket_register_stun_client(nr_ice_socket *sock, nr_stun_client_ctx *srv,void **handle) 1791 { 1792diff -U10 -r /Users/ekr/dev/mtransport-import-references/nICEr/src/net/nr_socket.h src/net/nr_socket.h 1793--- /Users/ekr/dev/mtransport-import-references/nICEr/src/net/nr_socket.h 2012-09-16 16:26:09.000000000 -0700 1794+++ src/net/nr_socket.h 2012-10-06 08:30:22.000000000 -0700 1795@@ -38,21 +38,23 @@ 1796 #include <sys/types.h> 1797 #ifdef WIN32 1798 #include <winsock2.h> 1799 #include <ws2tcpip.h> 1800 #else 1801 #include <sys/socket.h> 1802 #endif 1803 1804 #include "transport_addr.h" 1805 1806-#ifdef WIN32 1807+#ifdef __cplusplus 1808+#define restrict 1809+#elif defined(WIN32) 1810 #define restrict __restrict 1811 #endif 1812 1813 typedef struct nr_socket_vtbl_ { 1814 int (*destroy)(void **obj); 1815 int (*ssendto)(void *obj,const void *msg, size_t len, int flags, 1816 nr_transport_addr *addr); 1817 int (*srecvfrom)(void *obj,void * restrict buf, size_t maxlen, size_t *len, int flags, 1818 nr_transport_addr *addr); 1819 int (*getfd)(void *obj, NR_SOCKET *fd); 1820diff -U10 -r /Users/ekr/dev/mtransport-import-references/nICEr/src/net/transport_addr_reg.c src/net/transport_addr_reg.c 1821--- /Users/ekr/dev/mtransport-import-references/nICEr/src/net/transport_addr_reg.c 2012-09-16 16:26:09.000000000 -0700 1822+++ src/net/transport_addr_reg.c 2012-10-06 08:30:22.000000000 -0700 1823@@ -29,25 +29,27 @@ 1824 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 1825 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 1826 */ 1827 1828 1829 1830 static char *RCSSTRING __UNUSED__="$Id: transport_addr_reg.c,v 1.2 2008/04/28 17:59:03 ekr Exp $"; 1831 1832 #include <csi_platform.h> 1833 #include <stdio.h> 1834+#include <string.h> 1835 #include <memory.h> 1836 #include <sys/types.h> 1837 #ifdef WIN32 1838 #include <winsock2.h> 1839 #else 1840+#include <strings.h> 1841 #include <unistd.h> 1842 #include <sys/socket.h> 1843 #include <netinet/in.h> 1844 #include <arpa/inet.h> 1845 #endif 1846 #include <assert.h> 1847 #include "nr_api.h" 1848 #include "transport_addr.h" 1849 #include "transport_addr_reg.h" 1850 1851@@ -83,20 +85,22 @@ 1852 1853 if ((r=NR_reg_get2_uint2(prefix, "port", &port))) { 1854 if (r != R_NOT_FOUND) 1855 ABORT(r); 1856 port = 0; 1857 } 1858 1859 if ((r=NR_reg_alloc2_string(prefix, "protocol", &protocol))) { 1860 if (r != R_NOT_FOUND) 1861 ABORT(r); 1862+ p = IPPROTO_UDP; 1863+ 1864 protocol = 0; 1865 } 1866 else { 1867 if (!strcasecmp("tcp", protocol)) 1868 p = IPPROTO_TCP; 1869 else if (!strcasecmp("udp", protocol)) 1870 p = IPPROTO_UDP; 1871 else 1872 ABORT(R_BAD_DATA); 1873 } 1874diff -U10 -r /Users/ekr/dev/mtransport-import-references/nICEr/src/stun/addrs.c src/stun/addrs.c 1875--- /Users/ekr/dev/mtransport-import-references/nICEr/src/stun/addrs.c 2012-09-16 16:26:10.000000000 -0700 1876+++ src/stun/addrs.c 2012-10-06 09:42:43.000000000 -0700 1877@@ -46,20 +46,22 @@ 1878 #include <sys/sysctl.h> 1879 #include <sys/param.h> 1880 #include <sys/socket.h> 1881 #include <sys/syslog.h> 1882 #include <net/if.h> 1883 #ifndef LINUX 1884 #include <net/if_var.h> 1885 #include <net/if_dl.h> 1886 #include <net/if_types.h> 1887 #include <sys/sockio.h> 1888+#else 1889+#include <linux/if.h> 1890 #endif 1891 #include <net/route.h> 1892 1893 /* IP */ 1894 #include <netinet/in.h> 1895 #ifdef LINUX 1896 #include "sys/ioctl.h" 1897 #else 1898 #include <netinet/in_var.h> 1899 #endif 1900@@ -105,20 +107,23 @@ 1901 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 1902 * SUCH DAMAGE. 1903 */ 1904 1905 #include <err.h> 1906 1907 static void stun_rt_xaddrs(caddr_t, caddr_t, struct rt_addrinfo *); 1908 static int stun_grab_addrs(char *name, int addrcount, 1909 struct ifa_msghdr *ifam, 1910 nr_transport_addr addrs[], int maxaddrs, int *count); 1911+static int 1912+nr_stun_is_duplicate_addr(nr_transport_addr addrs[], int count, nr_transport_addr *addr); 1913+ 1914 1915 /* 1916 * Expand the compacted form of addresses as returned via the 1917 * configuration read via sysctl(). 1918 */ 1919 #define ROUNDUP(a) \ 1920 ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long)) 1921 #define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len)) 1922 1923 static void 1924@@ -135,21 +140,21 @@ 1925 continue; 1926 rtinfo->rti_info[i] = sa = (struct sockaddr *)cp; 1927 ADVANCE(cp, sa); 1928 } 1929 } 1930 1931 static int 1932 stun_grab_addrs(char *name, int addrcount, struct ifa_msghdr *ifam, nr_transport_addr addrs[], int maxaddrs, int *count) 1933 { 1934 int r,_status; 1935- NR_SOCKET s = -1; 1936+ int s = -1; 1937 struct ifreq ifr; 1938 struct rt_addrinfo info; 1939 struct sockaddr_in *sin; 1940 1941 ifr.ifr_addr.sa_family = AF_INET; 1942 strncpy(ifr.ifr_name, name, sizeof ifr.ifr_name); 1943 1944 if ((s = socket(ifr.ifr_addr.sa_family, SOCK_DGRAM, 0)) < 0) { 1945 r_log(NR_LOG_STUN, LOG_WARNING, "unable to obtain addresses from socket"); 1946 ABORT(R_FAILED); 1947@@ -180,21 +185,20 @@ 1948 addrcount--; 1949 1950 if (*count >= maxaddrs) { 1951 r_log(NR_LOG_STUN, LOG_WARNING, "Address list truncated at %d out of entries", maxaddrs, maxaddrs+addrcount); 1952 break; 1953 } 1954 1955 ifam = (struct ifa_msghdr *)((char *)ifam + ifam->ifam_msglen); 1956 } 1957 1958- 1959 _status = 0; 1960 abort: 1961 if (s != -1) close(s); 1962 return _status; 1963 } 1964 1965 static int 1966 stun_get_mib_addrs(nr_transport_addr addrs[], int maxaddrs, int *count) 1967 { 1968 int _status; 1969@@ -551,44 +555,48 @@ 1970 #else 1971 1972 static int 1973 stun_get_siocgifconf_addrs(nr_transport_addr addrs[], int maxaddrs, int *count) 1974 { 1975 struct ifconf ifc; 1976 int _status; 1977 int s = socket( AF_INET, SOCK_DGRAM, 0 ); 1978 int len = 100 * sizeof(struct ifreq); 1979 int r; 1980+ int e; 1981+ char *ptr; 1982+ int tl; 1983+ int n; 1984+ struct ifreq ifr2; 1985 1986 char buf[ len ]; 1987 1988 ifc.ifc_len = len; 1989 ifc.ifc_buf = buf; 1990 1991- int e = ioctl(s,SIOCGIFCONF,&ifc); 1992- char *ptr = buf; 1993- int tl = ifc.ifc_len; 1994- int n=0; 1995+ e = ioctl(s,SIOCGIFCONF,&ifc); 1996+ ptr = buf; 1997+ tl = ifc.ifc_len; 1998+ n=0; 1999 2000 while ( (tl > 0) && ( n < maxaddrs) ) 2001 { 2002 struct ifreq* ifr = (struct ifreq *)ptr; 2003 2004 #ifdef LINUX 2005- int si = sizeof(ifr->ifr_name) + sizeof(ifr->ifr_addr); 2006+ int si = sizeof(struct ifreq); 2007 #else 2008 int si = sizeof(ifr->ifr_name) + MAX(ifr->ifr_addr.sa_len, sizeof(ifr->ifr_addr)); 2009 #endif 2010 tl -= si; 2011 ptr += si; 2012 2013- struct ifreq ifr2; 2014 ifr2 = *ifr; 2015 2016 e = ioctl(s,SIOCGIFADDR,&ifr2); 2017 if ( e == -1 ) 2018 { 2019 continue; 2020 } 2021 2022 //r_log(NR_LOG_STUN, LOG_ERR, "ioctl addr e = %d",e); 2023 2024@@ -603,21 +611,21 @@ 2025 2026 close(s); 2027 2028 *count = n; 2029 2030 _status = 0; 2031 return _status; 2032 } 2033 #endif 2034 2035-int 2036+static int 2037 nr_stun_is_duplicate_addr(nr_transport_addr addrs[], int count, nr_transport_addr *addr) 2038 { 2039 int i; 2040 int different; 2041 2042 for (i = 0; i < count; ++i) { 2043 different = nr_transport_addr_cmp(&addrs[i], addr, NR_TRANSPORT_ADDR_CMP_MODE_ALL); 2044 if (!different) 2045 return 1; /* duplicate */ 2046 } 2047diff -U10 -r /Users/ekr/dev/mtransport-import-references/nICEr/src/stun/nr_socket_turn.c src/stun/nr_socket_turn.c 2048--- /Users/ekr/dev/mtransport-import-references/nICEr/src/stun/nr_socket_turn.c 2012-09-16 16:26:10.000000000 -0700 2049+++ src/stun/nr_socket_turn.c 2012-10-06 08:30:22.000000000 -0700 2050@@ -246,17 +246,19 @@ 2051 default: 2052 assert(0); 2053 break; 2054 } 2055 2056 return R_FAILED; 2057 } 2058 2059 static int nr_socket_turn_close(void *obj) 2060 { 2061+#ifndef NDEBUG 2062 nr_socket_turn *sturn=obj; 2063 assert(sturn->magic_cookie == nr_socket_turn_magic_cookie); 2064+#endif 2065 2066 return 0; 2067 } 2068 2069 #endif /* USE_TURN */ 2070diff -U10 -r /Users/ekr/dev/mtransport-import-references/nICEr/src/stun/stun_client_ctx.c src/stun/stun_client_ctx.c 2071--- /Users/ekr/dev/mtransport-import-references/nICEr/src/stun/stun_client_ctx.c 2012-09-16 16:26:10.000000000 -0700 2072+++ src/stun/stun_client_ctx.c 2012-10-06 08:30:22.000000000 -0700 2073@@ -38,21 +38,22 @@ 2074 #include <string.h> 2075 2076 #include <nr_api.h> 2077 #include "stun.h" 2078 #include "async_timer.h" 2079 #include "registry.h" 2080 #include "stun_reg.h" 2081 #include "r_time.h" 2082 2083 static int nr_stun_client_send_request(nr_stun_client_ctx *ctx); 2084-static void nr_stun_client_timer_expired_cb(int a, int b, void *cb_arg); 2085+static void nr_stun_client_timer_expired_cb(NR_SOCKET s, int b, void *cb_arg); 2086+static int nr_stun_client_get_password(void *arg, nr_stun_message *msg, Data **password); 2087 2088 int nr_stun_client_ctx_create(char *label, nr_socket *sock, nr_transport_addr *peer, UINT4 RTO, nr_stun_client_ctx **ctxp) 2089 { 2090 nr_stun_client_ctx *ctx=0; 2091 int r,_status; 2092 2093 if ((r=nr_stun_startup())) 2094 ABORT(r); 2095 2096 if(!(ctx=RCALLOC(sizeof(nr_stun_client_ctx)))) 2097@@ -185,21 +186,21 @@ 2098 ctx->finished_cb = 0; 2099 ctx->cb_arg = 0; 2100 ctx->request_ct = 0; 2101 ctx->timeout_ms = 0; 2102 2103 ctx->state = NR_STUN_CLIENT_STATE_INITTED; 2104 2105 return 0; 2106 } 2107 2108-static void nr_stun_client_timer_expired_cb(int a, int b, void *cb_arg) 2109+static void nr_stun_client_timer_expired_cb(NR_SOCKET s, int b, void *cb_arg) 2110 { 2111 int _status; 2112 nr_stun_client_ctx *ctx=cb_arg; 2113 struct timeval now; 2114 INT8 ms_waited; 2115 2116 /* Prevent this timer from being cancelled later */ 2117 ctx->timer_handle=0; 2118 2119 /* Shouldn't happen */ 2120@@ -387,21 +388,21 @@ 2121 } 2122 2123 _status=0; 2124 abort: 2125 if (_status) { 2126 ctx->state=NR_STUN_CLIENT_STATE_FAILED; 2127 } 2128 return(_status); 2129 } 2130 2131-int nr_stun_client_get_password(void *arg, nr_stun_message *msg, Data **password) 2132+static int nr_stun_client_get_password(void *arg, nr_stun_message *msg, Data **password) 2133 { 2134 *password = (Data*)arg; 2135 if (!arg) 2136 return(R_NOT_FOUND); 2137 return(0); 2138 } 2139 2140 int nr_stun_client_process_response(nr_stun_client_ctx *ctx, UCHAR *msg, int len, nr_transport_addr *peer_addr) 2141 { 2142 int r,_status; 2143diff -U10 -r /Users/ekr/dev/mtransport-import-references/nICEr/src/stun/stun_codec.c src/stun/stun_codec.c 2144--- /Users/ekr/dev/mtransport-import-references/nICEr/src/stun/stun_codec.c 2012-09-16 16:26:10.000000000 -0700 2145+++ src/stun/stun_codec.c 2012-10-06 08:30:22.000000000 -0700 2146@@ -73,20 +73,22 @@ 2147 static int nr_stun_decode_htonll(UCHAR *buf, int buflen, int *offset, UINT8 *data); 2148 static int nr_stun_decode(int length, UCHAR *buf, int buflen, int *offset, UCHAR *data); 2149 2150 static int nr_stun_attr_string_illegal(nr_stun_attr_info *attr_info, int len, void *data, int max_bytes, int max_chars); 2151 2152 static int nr_stun_attr_error_code_illegal(nr_stun_attr_info *attr_info, int attrlen, void *data); 2153 static int nr_stun_attr_nonce_illegal(nr_stun_attr_info *attr_info, int attrlen, void *data); 2154 static int nr_stun_attr_realm_illegal(nr_stun_attr_info *attr_info, int attrlen, void *data); 2155 static int nr_stun_attr_server_illegal(nr_stun_attr_info *attr_info, int attrlen, void *data); 2156 static int nr_stun_attr_username_illegal(nr_stun_attr_info *attr_info, int attrlen, void *data); 2157+static int 2158+nr_stun_attr_codec_fingerprint_decode(nr_stun_attr_info *attr_info, int attrlen, UCHAR *buf, int offset, int buflen, void *data); 2159 2160 2161 int 2162 nr_stun_encode_htons(UINT2 data, int buflen, UCHAR *buf, int *offset) 2163 { 2164 UINT2 d = htons(data); 2165 2166 if (*offset + sizeof(d) >= buflen) { 2167 r_log(NR_LOG_STUN, LOG_WARNING, "Attempted buffer overrun: %d + %d >= %d", *offset, sizeof(d), buflen); 2168 return R_BAD_DATA; 2169@@ -632,21 +634,21 @@ 2170 } 2171 2172 fingerprint->checksum = checksum ^ 0x5354554e; 2173 2174 r_log(NR_LOG_STUN, LOG_DEBUG, "Computed FINGERPRINT %08x", fingerprint->checksum); 2175 2176 fingerprint->valid = 1; 2177 return nr_stun_attr_codec_UINT4.encode(attr_info, &fingerprint->checksum, offset, buflen, buf, attrlen); 2178 } 2179 2180-int 2181+static int 2182 nr_stun_attr_codec_fingerprint_decode(nr_stun_attr_info *attr_info, int attrlen, UCHAR *buf, int offset, int buflen, void *data) 2183 { 2184 int r,_status; 2185 nr_stun_attr_fingerprint *fingerprint = data; 2186 nr_stun_message_header *header = (nr_stun_message_header*)buf; 2187 int length; 2188 UINT4 checksum; 2189 2190 if ((r=nr_stun_attr_codec_UINT4.decode(attr_info, attrlen, buf, offset, buflen, &fingerprint->checksum))) 2191 ABORT(r); 2192diff -U10 -r /Users/ekr/dev/mtransport-import-references/nICEr/src/stun/stun_proc.c src/stun/stun_proc.c 2193--- /Users/ekr/dev/mtransport-import-references/nICEr/src/stun/stun_proc.c 2012-09-16 16:26:10.000000000 -0700 2194+++ src/stun/stun_proc.c 2012-10-06 08:30:22.000000000 -0700 2195@@ -43,20 +43,22 @@ 2196 #include <time.h> 2197 #else /* UNIX */ 2198 #include <string.h> 2199 #endif /* end UNIX */ 2200 #include <assert.h> 2201 2202 #include "stun.h" 2203 #include "stun_reg.h" 2204 #include "registry.h" 2205 2206+static int 2207+nr_stun_add_realm_and_nonce(int new_nonce, nr_stun_server_client *clnt, nr_stun_message *res); 2208 2209 /* draft-ietf-behave-rfc3489bis-10.txt S 7.3 */ 2210 int 2211 nr_stun_receive_message(nr_stun_message *req, nr_stun_message *msg) 2212 { 2213 int _status; 2214 nr_stun_message_attribute *attr; 2215 2216 #ifdef USE_RFC_3489_BACKWARDS_COMPATIBLE 2217 /* if this message was generated by an RFC 3489 impementation, 2218@@ -371,21 +373,21 @@ 2219 /* nothing to check in this case */ 2220 break; 2221 #endif /* USE_STUND_0_96 */ 2222 } 2223 2224 _status=0; 2225 abort: 2226 return _status; 2227 } 2228 2229-int 2230+static int 2231 nr_stun_add_realm_and_nonce(int new_nonce, nr_stun_server_client *clnt, nr_stun_message *res) 2232 { 2233 int r,_status; 2234 char *realm = 0; 2235 char *nonce; 2236 UINT2 size; 2237 2238 if ((r=NR_reg_alloc_string(NR_STUN_REG_PREF_SERVER_REALM, &realm))) 2239 ABORT(r); 2240 2241diff -U10 -r /Users/ekr/dev/mtransport-import-references/nICEr/src/stun/stun_server_ctx.c src/stun/stun_server_ctx.c 2242--- /Users/ekr/dev/mtransport-import-references/nICEr/src/stun/stun_server_ctx.c 2012-09-16 16:26:10.000000000 -0700 2243+++ src/stun/stun_server_ctx.c 2012-10-06 08:30:22.000000000 -0700 2244@@ -114,21 +114,21 @@ 2245 STAILQ_INSERT_TAIL(&ctx->clients,clnt,entry); 2246 2247 _status=0; 2248 abort: 2249 if(_status){ 2250 nr_stun_server_destroy_client(clnt); 2251 } 2252 return(_status); 2253 } 2254 2255-int nr_stun_server_get_password(void *arg, nr_stun_message *msg, Data **password) 2256+static int nr_stun_server_get_password(void *arg, nr_stun_message *msg, Data **password) 2257 { 2258 int _status; 2259 nr_stun_server_ctx *ctx = (nr_stun_server_ctx*)arg; 2260 nr_stun_server_client *clnt = 0; 2261 nr_stun_message_attribute *username_attribute; 2262 2263 if ((nr_stun_get_message_client(ctx, msg, &clnt))) { 2264 if (! nr_stun_message_has_attribute(msg, NR_STUN_ATTR_USERNAME, &username_attribute)) { 2265 r_log(NR_LOG_STUN,LOG_NOTICE,"STUN-SERVER(%s): Missing Username",ctx->label); 2266 ABORT(R_NOT_FOUND); 2267diff -U10 -r /Users/ekr/dev/mtransport-import-references/nICEr/src/stun/stun_util.c src/stun/stun_util.c 2268--- /Users/ekr/dev/mtransport-import-references/nICEr/src/stun/stun_util.c 2012-09-16 16:26:10.000000000 -0700 2269+++ src/stun/stun_util.c 2012-10-06 08:30:22.000000000 -0700 2270@@ -94,21 +94,20 @@ 2271 _status = 0; 2272 abort: 2273 return _status; 2274 } 2275 2276 int 2277 nr_stun_find_local_addresses(nr_transport_addr addrs[], int maxaddrs, int *count) 2278 { 2279 int r,_status; 2280 NR_registry *children = 0; 2281- int i; 2282 2283 if ((r=NR_reg_get_child_count(NR_STUN_REG_PREF_ADDRESS_PRFX, (unsigned int*)count))) 2284 if (r == R_NOT_FOUND) 2285 *count = 0; 2286 else 2287 ABORT(r); 2288 2289 if (*count == 0) { 2290 if ((r=nr_stun_get_addrs(addrs, maxaddrs, 1, count))) 2291 ABORT(r); 2292diff -U10 -r /Users/ekr/dev/mtransport-import-references/nICEr/src/stun/turn_client_ctx.c src/stun/turn_client_ctx.c 2293--- /Users/ekr/dev/mtransport-import-references/nICEr/src/stun/turn_client_ctx.c 2012-09-16 16:26:10.000000000 -0700 2294+++ src/stun/turn_client_ctx.c 2012-10-06 08:30:22.000000000 -0700 2295@@ -55,21 +55,24 @@ 2296 }; 2297 2298 static int TURN_PHASE_MODE[NUMBER_OF_STUN_CTX] = { 2299 NR_TURN_CLIENT_MODE_ALLOCATE_REQUEST1, 2300 NR_TURN_CLIENT_MODE_ALLOCATE_REQUEST2, 2301 NR_TURN_CLIENT_MODE_SET_ACTIVE_DEST_REQUEST 2302 }; 2303 2304 2305 static int nr_turn_client_next_action(nr_turn_client_ctx *ctx, int stun_ctx_state); 2306-static void nr_turn_client_cb(int s, int how, void *cb_arg); 2307+static void nr_turn_client_cb(NR_SOCKET s, int how, void *cb_arg); 2308+static int 2309+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); 2310+ 2311 2312 int 2313 nr_turn_client_next_action(nr_turn_client_ctx *ctx, int stun_ctx_state) 2314 { 2315 int r,_status; 2316 2317 assert(ctx->phase >= -1 && ctx->phase < NUMBER_OF_STUN_CTX); 2318 2319 switch (ctx->state) { 2320 //case NR_TURN_CLIENT_STATE_ALLOCATING: 2321@@ -147,21 +150,21 @@ 2322 * because as a side effect this ctx may be operated on in the 2323 * callback */ 2324 finished_cb(0,0,ctx->cb_arg); 2325 } 2326 } 2327 2328 return(_status); 2329 } 2330 2331 void 2332-nr_turn_client_cb(int s, int how, void *cb_arg) 2333+nr_turn_client_cb(NR_SOCKET s, int how, void *cb_arg) 2334 { 2335 int r,_status; 2336 nr_turn_client_ctx *ctx = (nr_turn_client_ctx*)cb_arg; 2337 nr_stun_client_ctx *stun_ctx = ctx->stun_ctx[ctx->phase]; 2338 2339 assert(ctx->phase >= 0); 2340 2341 if ((r=nr_turn_client_next_action(ctx, stun_ctx->state))) 2342 ABORT(r); 2343 2344@@ -234,21 +237,21 @@ 2345 2346 RFREE(ctx->username); 2347 r_data_destroy(&ctx->password); 2348 2349 RFREE(ctx->label); 2350 RFREE(ctx); 2351 2352 return(0); 2353 } 2354 2355-int 2356+static int 2357 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) 2358 { 2359 int r,_status; 2360 nr_stun_client_allocate_request1_params *allocate_request1 = 0; 2361 nr_stun_client_allocate_request2_params *allocate_request2 = 0; 2362 nr_stun_client_allocate_response1_results *allocate_response1 = 0; 2363 // nr_stun_client_allocate_response2_results *allocate_response2; 2364 2365 if (ctx->state != NR_TURN_CLIENT_STATE_INITTED) 2366 ABORT(R_NOT_PERMITTED); 2367diff -U10 -r /Users/ekr/dev/mtransport-import-references/nICEr/src/util/ice_util.c src/util/ice_util.c 2368--- /Users/ekr/dev/mtransport-import-references/nICEr/src/util/ice_util.c 2012-09-16 16:26:10.000000000 -0700 2369+++ src/util/ice_util.c 2012-10-06 08:30:22.000000000 -0700 2370@@ -31,20 +31,21 @@ 2371 */ 2372 2373 #include <stdarg.h> 2374 2375 2376 static char *RCSSTRING __UNUSED__="$Id: ice_util.c,v 1.2 2008/04/28 17:59:05 ekr Exp $"; 2377 2378 #include <stdarg.h> 2379 #include <string.h> 2380 #include "nr_api.h" 2381+#include "ice_util.h" 2382 2383 int nr_concat_strings(char **outp,...) 2384 { 2385 va_list ap; 2386 char *s,*out=0; 2387 int len=0; 2388 int _status; 2389 2390 va_start(ap,outp); 2391 while(s=va_arg(ap,char *)){ 2392diff -U10 -r /Users/ekr/dev/mtransport-import-references/nICEr/src/util/mbslen.c src/util/mbslen.c 2393--- /Users/ekr/dev/mtransport-import-references/nICEr/src/util/mbslen.c 2012-09-16 16:26:10.000000000 -0700 2394+++ src/util/mbslen.c 2012-10-06 08:31:01.000000000 -0700 2395@@ -56,21 +56,21 @@ 2396 { 2397 #ifdef DARWIN 2398 static locale_t loc = 0; 2399 static int initialized = 0; 2400 #endif /* DARWIN */ 2401 #ifdef WIN32 2402 char *my_locale=0; 2403 unsigned int i; 2404 #endif /* WIN32 */ 2405 int _status; 2406- int nbytes; 2407+ size_t nbytes; 2408 int nchars; 2409 mbstate_t mbs; 2410 2411 #ifdef DARWIN 2412 if (! initialized) { 2413 initialized = 1; 2414 loc = newlocale(LC_CTYPE_MASK, "UTF-8", LC_GLOBAL_LOCALE); 2415 } 2416 2417 if (loc == 0) { 2418@@ -102,25 +102,28 @@ 2419 2420 memset(&mbs, 0, sizeof(mbs)); 2421 nchars = 0; 2422 2423 #ifdef DARWIN 2424 while (*s != '\0' && (nbytes = mbrlen_l(s, strlen(s), &mbs, loc)) != 0) 2425 #else 2426 while (*s != '\0' && (nbytes = mbrlen(s, strlen(s), &mbs)) != 0) 2427 #endif /* DARWIN */ 2428 { 2429- assert(nbytes >= 0); 2430- if (nbytes == (size_t)-1) /* should never happen */ 2431+ if (nbytes == (size_t)-1) /* should never happen */ { 2432+ assert(0); 2433 ABORT(R_INTERNAL); 2434- if (nbytes == (size_t)-2) /* encoding error */ 2435+ } 2436+ if (nbytes == (size_t)-2) /* encoding error */ { 2437+ assert(0); 2438 ABORT(R_BAD_DATA); 2439+ } 2440 2441 s += nbytes; 2442 ++nchars; 2443 } 2444 2445 *ncharsp = nchars; 2446 2447 _status = 0; 2448 abort: 2449 #ifdef WIN32 2450