media/mtransport/third_party/nICEr/upstream.diff

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

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

mercurial