int nr_turn_client_process_response(nr_turn_client_ctx *ctx, UCHAR *msg, int len, nr_transport_addr *turn_server_addr) { int r, _status; nr_turn_stun_ctx *sc1; switch (ctx->state) { case NR_TURN_CLIENT_STATE_ALLOCATING: case NR_TURN_CLIENT_STATE_ALLOCATED: break; default: ABORT(R_FAILED); } sc1 = STAILQ_FIRST(&ctx->stun_ctxs); while (sc1) { r = nr_stun_client_process_response(sc1->stun, msg, len, turn_server_addr); if (!r) break; if (r==R_RETRY) /* Likely a 401 and we will retry */ break; if (r != R_REJECTED) ABORT(r); sc1 = STAILQ_NEXT(sc1, entry); } if (!sc1) ABORT(R_REJECTED); _status=0; abort: return(_status); }
int nr_turn_client_process_response(nr_turn_client_ctx *ctx, UCHAR *msg, int len, nr_transport_addr *turn_server_addr) { int r,_status; nr_stun_client_ctx *stun_ctx; assert(ctx->phase >= 0 && ctx->phase < NUMBER_OF_STUN_CTX); if (ctx->phase < 0 || ctx->phase > NUMBER_OF_STUN_CTX) ABORT(R_INTERNAL); /* should never happen */ stun_ctx = ctx->stun_ctx[ctx->phase]; if (ctx->state != NR_TURN_CLIENT_STATE_RUNNING && ctx->state != NR_TURN_CLIENT_STATE_ALLOCATED) { #if 0 //TODO: !nn! it really shouldn't be the case that we're processing a response in this state, //TODO: but perhaps we failed and we haven't taken ourself off the //TODO: ASYNC wait list, so an outstanding packet can cause us this grief assert(0); ABORT(R_INTERNAL); /* should never happen */ #else //TODO: !nn! fix so we can never get into this state r_log(NR_LOG_TURN,LOG_ERR,"TURN-CLIENT(%s): dropping packet in phase %s", ctx->label, TURN_PHASE_LABEL[ctx->phase]); return R_INTERNAL; #endif } if (ctx->phase != NR_TURN_CLIENT_PHASE_INITIALIZED) { r_log(NR_LOG_TURN,LOG_DEBUG,"TURN-CLIENT(%s): Received response in phase %s", ctx->label, TURN_PHASE_LABEL[ctx->phase]); } else { ABORT(R_INTERNAL); } if ((r=nr_stun_client_process_response(stun_ctx, msg, len, turn_server_addr))) ABORT(r); _status=0; abort: if (ctx->state != NR_TURN_CLIENT_STATE_RUNNING) { if (ctx->finished_cb) { NR_async_cb finished_cb = ctx->finished_cb; ctx->finished_cb = 0; /* prevent 2nd call */ /* finished_cb call must be absolutely last thing in function * because as a side effect this ctx may be operated on in the * callback */ finished_cb(0,0,ctx->cb_arg); } } return(_status); }