Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
1 diff -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 @@
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"
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 */
27 char *nr_ice_candidate_type_names[]={0,"host","srflx","prflx","relay",0};
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);
50 RFREE(cand->foundation);
51 RFREE(cand->label);
52 RFREE(cand);
54 return(0);
55 }
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 }
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 }
75 if(type_preference > 126)
76 r_log(LOG_ICE,LOG_ERR,"Illegal type preference %d",type_preference);
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 + }
101 cand->priority=
102 (type_preference << 24) |
103 (interface_preference << 16) |
104 (stun_priority << 8) |
105 (256 - cand->component_id);
107 /* S 4.1.2 */
108 assert(cand->priority>=1&&cand->priority<=2147483647);
110 @@ -306,21 +324,22 @@
112 cand->done_cb=ready_cb;
113 cand->cb_arg=cb_arg;
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 }
138 _status=0;
139 abort:
140 if(_status && _status!=R_WOULDBLOCK)
141 cand->state=NR_ICE_CAND_STATE_FAILED;
142 return(_status);
143 }
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;
151 cand->delay_timer=0;
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 @@
159 _status=0;
160 abort:
161 if(_status){
162 cand->state=NR_ICE_CAND_STATE_FAILED;
163 }
164 return(_status);
165 }
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;
175 cand->delay_timer=0;
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);
180 @@ -443,21 +462,21 @@
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 */
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;
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 }
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 }
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;
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 }
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 */
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);
238 r_log(LOG_ICE,LOG_DEBUG,"ICE(%s): Switching from TURN (%s) to RELAY (%s)",cand->u.relayed.turn->label,cand->label,label);
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);
244 r_log(LOG_ICE,LOG_DEBUG,"ICE-CANDIDATE(%s): base=%s, candidate=%s", cand->label, cand->base.as_string, cand->addr.as_string);
246 diff -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 @@
251 typedef enum {HOST=1, SERVER_REFLEXIVE, PEER_REFLEXIVE, RELAYED} nr_ice_candidate_type;
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 };
277 extern char *nr_ice_candidate_type_names[];
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);
291 #ifdef __cplusplus
292 }
293 #endif /* __cplusplus */
294 #endif
296 diff -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"
308 static char *nr_ice_cand_pair_states[]={"UNKNOWN","FROZEN","WAITING","IN_PROGRESS","FAILED","SUCCEEDED","CANCELLED"};
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);
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;
325 if(!(pair=RCALLOC(sizeof(nr_ice_cand_pair))))
326 ABORT(R_NO_MEMORY);
328 pair->pctx=pctx;
330 nr_ice_candidate_pair_compute_codeword(pair,lcand,rcand);
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);
337 nr_ice_candidate_pair_set_state(pctx,pair,NR_ICE_PAIR_STATE_FROZEN);
338 pair->local=lcand;
339 pair->remote=rcand;
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);
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);
354 /* Foundation */
355 if(r=nr_concat_strings(&pair->foundation,lcand->foundation,"|",
356 - rcand->foundation,0))
357 + rcand->foundation,NULL))
358 ABORT(r);
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;
368 @@ -110,39 +110,39 @@
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;
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;
394 pair->stun_client->params.ice_binding_request.tiebreaker=pctx->tiebreaker;
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));
405 *pairp=pair;
407 _status=0;
408 abort:
409 RFREE(l2ruser);
410 @@ -178,21 +178,21 @@
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);
416 nr_ice_candidate_pair_set_state(pctx,pair,NR_ICE_PAIR_STATE_WAITING);
418 return(0);
419 }
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 }
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;
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;
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--;
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 }
478 _status=0;
479 abort:
480 return(_status);
481 }
483 @@ -505,42 +520,42 @@
484 break;
485 }
487 c1=TAILQ_NEXT(c1,entry);
488 }
489 if(!c1) TAILQ_INSERT_TAIL(head,pair,entry);
491 return(0);
492 }
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;
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);
502 nr_stun_client_reset(pair->stun_client);
503 pair->stun_client->params.ice_binding_request.control=NR_ICE_CONTROLLING;
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);
508 if(r=nr_ice_ctx_remember_id(pair->pctx->ctx, pair->stun_client->request))
509 ABORT(r);
511 _status=0;
512 abort:
513 return;
514 }
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;
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);
524 nr_stun_client_reset(pair->stun_client);
525 pair->stun_client->params.ice_binding_request.control=NR_ICE_CONTROLLED;
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 @@
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;
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);
543 nr_ice_compute_codeword(as_string,strlen(as_string),pair->codeword);
545 _status=0;
546 abort:
547 RFREE(as_string);
548 return;
549 }
551 diff -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 @@
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);
569 #ifdef __cplusplus
570 }
571 #endif /* __cplusplus */
572 #endif
574 diff -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);
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);
599 if(r=nr_ice_candidate_pair_insert(&comp->stream->check_list,pair)) {
600 @@ -563,30 +563,38 @@
601 break;
602 }
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);
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 }
641 if(!pair)
642 ABORT(R_INTERNAL);
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);
652 isock=STAILQ_NEXT(isock,entry);
653 }
655 next_cand:
656 lcand=TAILQ_NEXT(lcand,entry_comp);
657 }
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 }
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;
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 }
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;
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);
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);
704 if(r=nr_ice_candidate_pair_cancel(pair->pctx,p2))
705 ABORT(r);
706 }
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);
712 if(r=nr_ice_media_stream_component_nominated(comp->stream,comp))
713 @@ -734,21 +750,21 @@
714 ABORT(r);
715 }
717 _status=0;
718 abort:
719 RFREE(pairs);
720 return(_status);
721 }
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;
730 assert(comp->keepalive_ctx);
732 if(NR_reg_get_uint4(NR_ICE_REG_KEEPALIVE_TIMER,&keepalive_timeout)){
733 keepalive_timeout=15000; /* Default */
734 }
736 diff -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"
743 int LOG_ICE = 0;
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);
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;
765 _status=0;
766 abort:
767 if(_status)
768 nr_ice_ctx_destroy_cb(0,0,ctx);
770 return(_status);
771 }
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;
782 RFREE(ctx->label);
784 RFREE(ctx->stun_servers);
785 @@ -323,21 +323,21 @@
786 if(!ctxp || !*ctxp)
787 return(0);
789 NR_ASYNC_SCHEDULE(nr_ice_ctx_destroy_cb,*ctxp);
791 *ctxp=0;
793 return(0);
794 }
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;
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--;
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);
814 stream=STAILQ_NEXT(stream,entry);
815 }
817 if(ctx->uninitialized_candidates)
818 ABORT(R_WOULDBLOCK);
819 -
820 +
821 +
822 _status=0;
823 abort:
824 return(_status);
825 }
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;
831 if(r=nr_ice_media_stream_create(ctx,label,components,streamp))
832 diff -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];
838 STAILQ_ENTRY(nr_ice_stun_id_) entry;
839 } nr_ice_stun_id;
841 typedef STAILQ_HEAD(nr_ice_stun_id_head_,nr_ice_stun_id_) nr_ice_stun_id_head;
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;
854 char *ufrag;
855 char *pwd;
857 UINT4 Ta;
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 @@
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)
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);
882 extern int LOG_ICE;
884 #ifdef __cplusplus
885 diff -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 $";
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"
898 static char *nr_ice_media_stream_states[]={"INVALID",
899 - "FROZEN","ACTIVE","COMPLETED","FAILED"
900 + "UNPAIRED","FROZEN","ACTIVE","COMPLETED","FAILED"
901 };
903 int nr_ice_media_stream_set_state(nr_ice_media_stream *str, int state);
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);
917 }
919 TAILQ_INIT(&stream->check_list);
921 stream->component_ct=components;
922 -
923 + stream->ice_state = NR_ICE_MEDIA_STREAM_UNPAIRED;
924 *streamp=stream;
926 _status=0;
927 abort:
928 if(_status){
929 nr_ice_media_stream_destroy(&stream);
930 }
931 - return(_status);
932 + return(_status);
933 }
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);
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 }
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;
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 };
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 }
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;
1044 assert(stream->pctx->active_streams!=0);
1046 timer_val=stream->pctx->ctx->Ta*stream->pctx->active_streams;
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);
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;
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 }
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 }
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 }
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);
1101 /* Cancel our timer */
1102 if(stream->timer){
1103 NR_async_timer_cancel(stream->timer);
1104 stream->timer=0;
1105 }
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 + }
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);
1116 done:
1117 _status=0;
1118 abort:
1119 return(_status);
1120 }
1121 @@ -515,21 +580,23 @@
1123 p2=TAILQ_NEXT(p2,entry);
1124 }
1126 /* Cancel our timer */
1127 if(stream->timer){
1128 NR_async_timer_cancel(stream->timer);
1129 stream->timer=0;
1130 }
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 + }
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);
1141 _status=0;
1142 abort:
1143 return(_status);
1144 }
1146 diff -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;
1152 struct nr_ice_media_stream_ *local_stream; /* used when this is a peer */
1153 int component_ct;
1154 nr_ice_component_head components;
1156 char *ufrag; /* ICE username */
1157 char *pwd; /* ICE password */
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
1171 nr_ice_cand_pair_head check_list;
1172 void *timer; /* Check list periodic timer */
1174 // nr_ice_cand_pair_head valid_list;
1175 -
1176 +
1177 STAILQ_ENTRY(nr_ice_media_stream_) entry;
1178 };
1180 typedef STAILQ_HEAD(nr_ice_media_stream_head_,nr_ice_media_stream_) nr_ice_media_stream_head;
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);
1198 diff -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 $";
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"
1222 static void
1223 @@ -125,21 +126,21 @@
1224 char *rel_addr=0;
1226 if(!(cand=RCALLOC(sizeof(nr_ice_candidate))))
1227 ABORT(R_NO_MEMORY);
1229 if(!(cand->label=r_strdup(orig)))
1230 ABORT(R_NO_MEMORY);
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);
1239 /* Candidate attr */
1240 if (strncasecmp(str, "candidate:", 10))
1241 ABORT(R_BAD_DATA);
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 */
1249 break;
1250 default:
1251 ABORT(R_INTERNAL);
1252 break;
1253 }
1255 skip_whitespace(&str);
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;
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);
1273 RFREE(connection_address);
1274 RFREE(rel_addr);
1275 return(_status);
1276 }
1279 int
1280 diff -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 $";
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"
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);
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;
1304 if(!(pctx=RCALLOC(sizeof(nr_ice_peer_ctx))))
1305 ABORT(R_NO_MEMORY);
1307 if(!(pctx->label=r_strdup(label)))
1308 ABORT(R_NO_MEMORY);
1309 -
1310 +
1311 pctx->ctx=ctx;
1312 pctx->handler=handler;
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 }
1321 @@ -88,85 +90,177 @@
1322 nr_ice_peer_ctx_destroy_cb(0,0,pctx);
1323 }
1324 return(_status);
1325 }
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;
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;
1353 comp=STAILQ_NEXT(comp,entry);
1354 comp2=STAILQ_NEXT(comp2,entry);
1355 }
1356 -
1358 - pstream->ice_state=NR_ICE_MEDIA_STREAM_CHECKS_FROZEN;
1359 pstream->local_stream=stream;
1360 pstream->pctx=pctx;
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 + }
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 + }
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;
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 }
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);
1456 _status=0;
1457 - abort:
1458 + abort:
1459 + if (_status) {
1460 + nr_ice_candidate_destroy(&cand);
1461 + }
1462 return(_status);
1463 }
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;
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 }
1532 @@ -177,21 +271,21 @@
1533 ABORT(r);
1535 stream=STAILQ_NEXT(stream,entry);
1536 }
1538 _status=0;
1539 abort:
1540 return(_status);
1541 }
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;
1549 RFREE(pctx->label);
1550 RFREE(pctx->peer_ufrag);
1551 RFREE(pctx->peer_pwd);
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 }
1558 RFREE(pctx);
1559 }
1561 int nr_ice_peer_ctx_destroy(nr_ice_peer_ctx **pctxp)
1562 {
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);
1573 *pctxp=0;
1575 return(0);
1576 }
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;
1600 stream=STAILQ_FIRST(&pctx->peer_streams);
1601 if(!stream)
1602 ABORT(R_FAILED);
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 }
1632 _status=0;
1633 abort:
1634 return(_status);
1635 }
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");
1645 _status=0;
1646 abort:
1647 return(_status);
1648 }
1649 #endif
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;
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 }
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;
1675 cand=TAILQ_NEXT(cand,entry_comp);
1676 }
1678 if(!cand)
1679 ABORT(R_REJECTED);
1681 /* OK, there's a match. Call the handler */
1682 - r_log(LOG_ICE,LOG_DEBUG,"ICE-PEER(%s): Delivering data", pctx->label);
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 + }
1693 _status=0;
1694 abort:
1695 return(_status);
1696 }
1699 diff -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 @@
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 */
1712 struct nr_ice_peer_ctx_ {
1713 - int state;
1714 char *label;
1715 -
1716 nr_ice_ctx *ctx;
1717 nr_ice_handler *handler;
1719 UCHAR controlling; /* 1 for controlling, 0 for controlled */
1720 UINT8 tiebreaker;
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;
1729 STAILQ_ENTRY(nr_ice_peer_ctx_) entry;
1730 };
1732 typedef STAILQ_HEAD(nr_ice_peer_ctx_head_, nr_ice_peer_ctx_) nr_ice_peer_ctx_head;
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
1753 diff -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 }
1760 RFREE(isock);
1762 return(0);
1763 }
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
1775 if (!isock||!isock->sock)
1776 return(0);
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 }
1787 return(0);
1788 }
1790 int nr_ice_socket_register_stun_client(nr_ice_socket *sock, nr_stun_client_ctx *srv,void **handle)
1791 {
1792 diff -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
1804 #include "transport_addr.h"
1806 -#ifdef WIN32
1807 +#ifdef __cplusplus
1808 +#define restrict
1809 +#elif defined(WIN32)
1810 #define restrict __restrict
1811 #endif
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);
1820 diff -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 */
1830 static char *RCSSTRING __UNUSED__="$Id: transport_addr_reg.c,v 1.2 2008/04/28 17:59:03 ekr Exp $";
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"
1851 @@ -83,20 +85,22 @@
1853 if ((r=NR_reg_get2_uint2(prefix, "port", &port))) {
1854 if (r != R_NOT_FOUND)
1855 ABORT(r);
1856 port = 0;
1857 }
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 }
1874 diff -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>
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 */
1905 #include <err.h>
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 +
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))
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 }
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;
1941 ifr.ifr_addr.sa_family = AF_INET;
1942 strncpy(ifr.ifr_name, name, sizeof ifr.ifr_name);
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--;
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 }
1955 ifam = (struct ifa_msghdr *)((char *)ifam + ifam->ifam_msglen);
1956 }
1958 -
1959 _status = 0;
1960 abort:
1961 if (s != -1) close(s);
1962 return _status;
1963 }
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
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;
1986 char buf[ len ];
1988 ifc.ifc_len = len;
1989 ifc.ifc_buf = buf;
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;
2000 while ( (tl > 0) && ( n < maxaddrs) )
2001 {
2002 struct ifreq* ifr = (struct ifreq *)ptr;
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;
2013 - struct ifreq ifr2;
2014 ifr2 = *ifr;
2016 e = ioctl(s,SIOCGIFADDR,&ifr2);
2017 if ( e == -1 )
2018 {
2019 continue;
2020 }
2022 //r_log(NR_LOG_STUN, LOG_ERR, "ioctl addr e = %d",e);
2024 @@ -603,21 +611,21 @@
2026 close(s);
2028 *count = n;
2030 _status = 0;
2031 return _status;
2032 }
2033 #endif
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;
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 }
2047 diff -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 }
2056 return R_FAILED;
2057 }
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
2066 return 0;
2067 }
2069 #endif /* USE_TURN */
2070 diff -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>
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"
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);
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;
2093 if ((r=nr_stun_startup()))
2094 ABORT(r);
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;
2103 ctx->state = NR_STUN_CLIENT_STATE_INITTED;
2105 return 0;
2106 }
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;
2116 /* Prevent this timer from being cancelled later */
2117 ctx->timer_handle=0;
2119 /* Shouldn't happen */
2120 @@ -387,21 +388,21 @@
2121 }
2123 _status=0;
2124 abort:
2125 if (_status) {
2126 ctx->state=NR_STUN_CLIENT_STATE_FAILED;
2127 }
2128 return(_status);
2129 }
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 }
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;
2143 diff -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);
2150 static int nr_stun_attr_string_illegal(nr_stun_attr_info *attr_info, int len, void *data, int max_bytes, int max_chars);
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);
2161 int
2162 nr_stun_encode_htons(UINT2 data, int buflen, UCHAR *buf, int *offset)
2163 {
2164 UINT2 d = htons(data);
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 }
2172 fingerprint->checksum = checksum ^ 0x5354554e;
2174 r_log(NR_LOG_STUN, LOG_DEBUG, "Computed FINGERPRINT %08x", fingerprint->checksum);
2176 fingerprint->valid = 1;
2177 return nr_stun_attr_codec_UINT4.encode(attr_info, &fingerprint->checksum, offset, buflen, buf, attrlen);
2178 }
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;
2190 if ((r=nr_stun_attr_codec_UINT4.decode(attr_info, attrlen, buf, offset, buflen, &fingerprint->checksum)))
2191 ABORT(r);
2192 diff -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>
2202 #include "stun.h"
2203 #include "stun_reg.h"
2204 #include "registry.h"
2206 +static int
2207 +nr_stun_add_realm_and_nonce(int new_nonce, nr_stun_server_client *clnt, nr_stun_message *res);
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;
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 }
2224 _status=0;
2225 abort:
2226 return _status;
2227 }
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;
2238 if ((r=NR_reg_alloc_string(NR_STUN_REG_PREF_SERVER_REALM, &realm)))
2239 ABORT(r);
2241 diff -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);
2247 _status=0;
2248 abort:
2249 if(_status){
2250 nr_stun_server_destroy_client(clnt);
2251 }
2252 return(_status);
2253 }
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;
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);
2267 diff -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 }
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;
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);
2289 if (*count == 0) {
2290 if ((r=nr_stun_get_addrs(addrs, maxaddrs, 1, count)))
2291 ABORT(r);
2292 diff -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 };
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 };
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 +
2312 int
2313 nr_turn_client_next_action(nr_turn_client_ctx *ctx, int stun_ctx_state)
2314 {
2315 int r,_status;
2317 assert(ctx->phase >= -1 && ctx->phase < NUMBER_OF_STUN_CTX);
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 }
2328 return(_status);
2329 }
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];
2339 assert(ctx->phase >= 0);
2341 if ((r=nr_turn_client_next_action(ctx, stun_ctx->state)))
2342 ABORT(r);
2344 @@ -234,21 +237,21 @@
2346 RFREE(ctx->username);
2347 r_data_destroy(&ctx->password);
2349 RFREE(ctx->label);
2350 RFREE(ctx);
2352 return(0);
2353 }
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;
2365 if (ctx->state != NR_TURN_CLIENT_STATE_INITTED)
2366 ABORT(R_NOT_PERMITTED);
2367 diff -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 */
2373 #include <stdarg.h>
2376 static char *RCSSTRING __UNUSED__="$Id: ice_util.c,v 1.2 2008/04/28 17:59:05 ekr Exp $";
2378 #include <stdarg.h>
2379 #include <string.h>
2380 #include "nr_api.h"
2381 +#include "ice_util.h"
2383 int nr_concat_strings(char **outp,...)
2384 {
2385 va_list ap;
2386 char *s,*out=0;
2387 int len=0;
2388 int _status;
2390 va_start(ap,outp);
2391 while(s=va_arg(ap,char *)){
2392 diff -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;
2411 #ifdef DARWIN
2412 if (! initialized) {
2413 initialized = 1;
2414 loc = newlocale(LC_CTYPE_MASK, "UTF-8", LC_GLOBAL_LOCALE);
2415 }
2417 if (loc == 0) {
2418 @@ -102,25 +102,28 @@
2420 memset(&mbs, 0, sizeof(mbs));
2421 nchars = 0;
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 + }
2441 s += nbytes;
2442 ++nchars;
2443 }
2445 *ncharsp = nchars;
2447 _status = 0;
2448 abort:
2449 #ifdef WIN32