コード例 #1
0
static void nr_turn_client_connected_cb(NR_SOCKET s, int how, void *cb_arg)
{
  int r, _status;
  nr_turn_client_ctx *ctx = (nr_turn_client_ctx *)cb_arg;

  /* Cancel the connection failure timer */
  NR_async_timer_cancel(ctx->connected_timer_handle);
  ctx->connected_timer_handle=0;

  /* Assume we connected successfully */
  if (ctx->state == NR_TURN_CLIENT_STATE_ALLOCATION_WAIT) {
    if ((r=nr_turn_stun_ctx_start(STAILQ_FIRST(&ctx->stun_ctxs))))
      ABORT(r);
    ctx->state = NR_TURN_CLIENT_STATE_ALLOCATING;
  }
  else {
    ctx->state = NR_TURN_CLIENT_STATE_CONNECTED;
  }

  _status = 0;
abort:
  if (_status) {
    nr_turn_client_failed(ctx);
  }
}
コード例 #2
0
ファイル: turn_client_ctx.c プロジェクト: Jar-win/Waterfox
static int nr_turn_client_start_refresh_timer(nr_turn_client_ctx *tctx,
                                              nr_turn_stun_ctx *sctx,
                                              UINT4 lifetime)
{
  int _status;

  assert(!tctx->refresh_timer_handle);

  if (lifetime <= TURN_REFRESH_SLACK_SECONDS) {
    r_log(NR_LOG_TURN, LOG_ERR, "Too short lifetime specified for turn %u", lifetime);
    ABORT(R_BAD_DATA);
  }

  if (lifetime > 3600)
    lifetime = 3600;

  lifetime -= TURN_REFRESH_SLACK_SECONDS;

  r_log(NR_LOG_TURN, LOG_DEBUG, "TURN(%s): Setting refresh timer for %u seconds",
        tctx->label, lifetime);
  NR_ASYNC_TIMER_SET(lifetime * 1000, nr_turn_client_refresh_timer_cb, sctx,
                     &tctx->refresh_timer_handle);

  _status=0;
abort:
  if (_status) {
    nr_turn_client_failed(tctx);
  }
  return _status;
}
コード例 #3
0
ファイル: turn_client_ctx.c プロジェクト: Jar-win/Waterfox
static void nr_turn_client_error_cb(NR_SOCKET s, int how, void *arg)
{
  nr_turn_stun_ctx *ctx = (nr_turn_stun_ctx *)arg;

  r_log(NR_LOG_TURN, LOG_WARNING, "TURN(%s): mode %d, %s",
        ctx->tctx->label, ctx->mode, __FUNCTION__);

  nr_turn_client_failed(ctx->tctx);
}
コード例 #4
0
static void nr_turn_client_connect_timeout_cb(NR_SOCKET s, int how, void *cb_arg)
{
  nr_turn_client_ctx *ctx = (nr_turn_client_ctx *)cb_arg;

  r_log(NR_LOG_TURN, LOG_INFO, "TURN(%s): connect timeout", ctx->label);

  ctx->connected_timer_handle = 0;

  /* This also cancels waiting on the file descriptor */
  nr_turn_client_failed(ctx);
}
コード例 #5
0
ファイル: turn_client_ctx.c プロジェクト: Jar-win/Waterfox
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);
}
コード例 #6
0
ファイル: turn_client_ctx.c プロジェクト: Jar-win/Waterfox
static void nr_turn_client_allocate_cb(NR_SOCKET s, int how, void *arg)
{
  nr_turn_stun_ctx *ctx = (nr_turn_stun_ctx *)arg;
  nr_turn_stun_ctx *refresh_ctx;
  NR_async_cb tmp_finished_cb;
  int r,_status;

  ctx->tctx->state = NR_TURN_CLIENT_STATE_ALLOCATED;

  if ((r=nr_transport_addr_copy(
          &ctx->tctx->relay_addr,
          &ctx->stun->results.allocate_response.relay_addr)))
    ABORT(r);

  if ((r=nr_transport_addr_copy(
          &ctx->tctx->mapped_addr,
          &ctx->stun->results.allocate_response.mapped_addr)))
    ABORT(r);

  if ((r=nr_turn_client_refresh_setup(ctx->tctx, &refresh_ctx)))
    ABORT(r);

  if ((r=nr_turn_client_start_refresh_timer(
          ctx->tctx, refresh_ctx,
          ctx->stun->results.allocate_response.lifetime_secs)))
    ABORT(r);

  r_log(NR_LOG_TURN, LOG_INFO,
        "TURN(%s): Succesfully allocated addr %s lifetime=%u",
        ctx->tctx->label,
        ctx->tctx->relay_addr.as_string,
        ctx->stun->results.allocate_response.lifetime_secs);

  _status=0;
abort:
  if (_status) {
    nr_turn_client_failed(ctx->tctx);
  }
  tmp_finished_cb = ctx->tctx->finished_cb;
  ctx->tctx->finished_cb = 0;  /* So we don't call it again */
  tmp_finished_cb(0, 0, ctx->tctx->cb_arg);
}
コード例 #7
0
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);
}
コード例 #8
0
ファイル: turn_client_ctx.c プロジェクト: Jar-win/Waterfox
static void nr_turn_client_refresh_timer_cb(NR_SOCKET s, int how, void *arg)
{
  nr_turn_stun_ctx *ctx = (nr_turn_stun_ctx *)arg;
  int r,_status;

  r_log(NR_LOG_TURN, LOG_DEBUG, "TURN(%s): Refresh timer fired",
        ctx->tctx->label);

  ctx->tctx->refresh_timer_handle=0;
  if ((r=nr_turn_stun_ctx_start(ctx))) {
    ABORT(r);
  }

  _status=0;
abort:
  if (_status) {
    nr_turn_client_failed(ctx->tctx);
  }
  return;
}
コード例 #9
0
ファイル: turn_client_ctx.c プロジェクト: Jar-win/Waterfox
static void nr_turn_client_refresh_cb(NR_SOCKET s, int how, void *arg)
{
  int r, _status;
  nr_turn_stun_ctx *ctx = (nr_turn_stun_ctx *)arg;
  /* Save lifetime from the reset */
  UINT4 lifetime = ctx->stun->results.refresh_response.lifetime_secs;

  r_log(NR_LOG_TURN, LOG_DEBUG, "TURN(%s): Refresh succeeded. lifetime=%u",
        ctx->tctx->label, lifetime);

  if ((r=nr_turn_client_start_refresh_timer(
          ctx->tctx, ctx, lifetime)))
    ABORT(r);

  _status=0;

abort:
  if (_status) {
    nr_turn_client_failed(ctx->tctx);
  }
}