static int nr_turn_client_refresh_setup(nr_turn_client_ctx *ctx, nr_turn_stun_ctx **sctx) { nr_turn_stun_ctx *stun = 0; int r,_status; assert(ctx->state == NR_TURN_CLIENT_STATE_ALLOCATED); if (ctx->state != NR_TURN_CLIENT_STATE_ALLOCATED) ABORT(R_NOT_PERMITTED); if ((r=nr_turn_stun_ctx_create(ctx, NR_TURN_CLIENT_MODE_REFRESH_REQUEST, nr_turn_client_refresh_cb, nr_turn_client_error_cb, &stun))) ABORT(r); if ((r=nr_turn_stun_set_auth_params(stun, ctx->realm, ctx->nonce))) ABORT(r); stun->stun->params.refresh_request.lifetime_secs = TURN_LIFETIME_REQUEST_SECONDS; *sctx=stun; _status=0; abort: return(_status); }
int nr_turn_client_allocate(nr_turn_client_ctx *ctx, NR_async_cb finished_cb, void *cb_arg) { nr_turn_stun_ctx *stun = 0; int r,_status; if(ctx->state == NR_TURN_CLIENT_STATE_FAILED || ctx->state == NR_TURN_CLIENT_STATE_CANCELLED){ /* TURN TCP contexts can fail before we ever try to form an allocation, * since the TCP connection can fail. It is also conceivable that a TURN * TCP context could be cancelled before we are done forming all * allocations (although we do not do this at the time this code was * written) */ assert(ctx->turn_server_addr.protocol == IPPROTO_TCP); ABORT(R_NOT_FOUND); } assert(ctx->state == NR_TURN_CLIENT_STATE_INITTED); ctx->finished_cb=finished_cb; ctx->cb_arg=cb_arg; if ((r=nr_turn_stun_ctx_create(ctx, NR_TURN_CLIENT_MODE_ALLOCATE_REQUEST, nr_turn_client_allocate_cb, nr_turn_client_error_cb, &stun))) ABORT(r); stun->stun->params.allocate_request.lifetime_secs = TURN_LIFETIME_REQUEST_SECONDS; if (ctx->state == NR_TURN_CLIENT_STATE_INITTED) { if ((r=nr_turn_stun_ctx_start(stun))) ABORT(r); ctx->state = NR_TURN_CLIENT_STATE_ALLOCATING; } else { ABORT(R_ALREADY); } _status=0; abort: if (_status) { nr_turn_client_failed(ctx); } return(_status); }
static int nr_turn_permission_create(nr_turn_client_ctx *ctx, nr_transport_addr *addr, nr_turn_permission **permp) { int r, _status; nr_turn_permission *perm = 0; assert(ctx->state == NR_TURN_CLIENT_STATE_ALLOCATED); r_log(NR_LOG_TURN, LOG_INFO, "TURN(%s): Creating permission for %s", ctx->label, addr->as_string); if (!(perm = RCALLOC(sizeof(nr_turn_permission)))) ABORT(R_NO_MEMORY); if ((r=nr_transport_addr_copy(&perm->addr, addr))) ABORT(r); perm->last_used = 0; if ((r=nr_turn_stun_ctx_create(ctx, NR_TURN_CLIENT_MODE_PERMISSION_REQUEST, nr_turn_client_permissions_cb, nr_turn_client_permission_error_cb, &perm->stun))) ABORT(r); /* We want to authenticate on the first packet */ if ((r=nr_turn_stun_set_auth_params(perm->stun, ctx->realm, ctx->nonce))) ABORT(r); if ((r=nr_transport_addr_copy( &perm->stun->stun->params.permission_request.remote_addr, addr))) ABORT(r); STAILQ_INSERT_TAIL(&ctx->permissions, perm, entry); *permp = perm; _status=0; abort: if (_status) { nr_turn_permission_destroy(&perm); } return(_status); }
int nr_turn_client_allocate(nr_turn_client_ctx *ctx, NR_async_cb finished_cb, void *cb_arg) { nr_turn_stun_ctx *stun = 0; int r,_status; assert(ctx->state == NR_TURN_CLIENT_STATE_INITTED || ctx->state == NR_TURN_CLIENT_STATE_CONNECTED); ctx->finished_cb=finished_cb; ctx->cb_arg=cb_arg; if ((r=nr_turn_stun_ctx_create(ctx, NR_TURN_CLIENT_MODE_ALLOCATE_REQUEST, nr_turn_client_allocate_cb, nr_turn_client_error_cb, &stun))) ABORT(r); stun->stun->params.allocate_request.lifetime_secs = TURN_LIFETIME_REQUEST_SECONDS; switch(ctx->state) { case NR_TURN_CLIENT_STATE_INITTED: /* We are waiting for connect before we can allocate */ ctx->state = NR_TURN_CLIENT_STATE_ALLOCATION_WAIT; break; case NR_TURN_CLIENT_STATE_CONNECTED: if ((r=nr_turn_stun_ctx_start(stun))) ABORT(r); ctx->state = NR_TURN_CLIENT_STATE_ALLOCATING; break; default: ABORT(R_ALREADY); } _status=0; abort: if (_status) { nr_turn_client_failed(ctx); } return(_status); }