Example #1
0
nsresult NrIceTurnServer::ToNicerTurnStruct(nr_ice_turn_server *server) const {
  memset(server, 0, sizeof(nr_ice_turn_server));

  nsresult rv = ToNicerStunStruct(&server->turn_server);
  if (NS_FAILED(rv))
    return rv;

  if (username_.empty())
    return NS_ERROR_INVALID_ARG;
  if (password_.empty())
    return NS_ERROR_INVALID_ARG;

  if (!(server->username=r_strdup(username_.c_str())))
    return NS_ERROR_OUT_OF_MEMORY;

  // TODO([email protected]): handle non-ASCII passwords somehow?
  // STUN requires they be SASLpreped, but we don't know if
  // they are at this point.

  // C++03 23.2.4, Paragraph 1 stipulates that the elements
  // in std::vector must be contiguous, and can therefore be
  // used as input to functions expecting C arrays.
  int r = r_data_create(&server->password,
                        const_cast<UCHAR *>(&password_[0]),
                        password_.size());
  if (r) {
    RFREE(server->username);
    return NS_ERROR_OUT_OF_MEMORY;
  }

  return NS_OK;
}
Example #2
0
void NicerConnection::setupTurnServer() {
  if (ice_config_.turn_server.empty()) {
    return;
  }
  auto servers = std::unique_ptr<nr_ice_turn_server[]>(new nr_ice_turn_server[1]);
  nr_ice_turn_server *server = &servers[0];
  nr_ice_stun_server *stun_server = &server->turn_server;
  memset(server, 0, sizeof(nr_ice_turn_server));
  stun_server->transport = IPPROTO_UDP;
  stun_server->type = NR_ICE_STUN_SERVER_TYPE_ADDR;
  nr_transport_addr addr;
  nr_str_port_to_transport_addr(ice_config_.turn_server.c_str(), ice_config_.turn_port, IPPROTO_UDP, &addr);
  stun_server->u.addr = addr;

  server->username = r_strdup(const_cast<char*>(ice_config_.turn_username.c_str()));
  int r = r_data_create(&server->password,
                        reinterpret_cast<UCHAR*>(const_cast<char *>(&ice_config_.turn_pass[0])),
                        ice_config_.turn_pass.size());
  if (r) {
    RFREE(server->username);
    return;
  }

  r = nicer_->IceContextSetTurnServers(ctx_, servers.get(), 1);
  if (r) {
    ELOG_WARN("%s message: Could not setup Turn", toLog());
  }

  ELOG_DEBUG("%s message: TURN server configured", toLog());
}
Example #3
0
static int
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)
{
    int r,_status;
    nr_stun_client_allocate_request1_params          *allocate_request1 = 0;
    nr_stun_client_allocate_request2_params          *allocate_request2 = 0;
    nr_stun_client_allocate_response1_results        *allocate_response1 = 0;
//    nr_stun_client_allocate_response2_results        *allocate_response2;

    if (ctx->state != NR_TURN_CLIENT_STATE_INITTED)
        ABORT(R_NOT_PERMITTED);

    assert(ctx->phase == NR_TURN_CLIENT_PHASE_INITIALIZED);

    allocate_request1        = &ctx->stun_ctx[NR_TURN_CLIENT_PHASE_ALLOCATE_REQUEST1]->params.allocate_request1;
    allocate_response1       = &ctx->stun_ctx[NR_TURN_CLIENT_PHASE_ALLOCATE_REQUEST1]->results.allocate_response1;
    allocate_request2        = &ctx->stun_ctx[NR_TURN_CLIENT_PHASE_ALLOCATE_REQUEST2]->params.allocate_request2;

    ctx->state=NR_TURN_CLIENT_STATE_RUNNING;
    ctx->finished_cb=finished_cb;
    ctx->cb_arg=cb_arg;

    ctx->username = r_strdup(username);
    if (!ctx->username)
        ABORT(R_NO_MEMORY);

    if ((r=r_data_create(&ctx->password,
                         password->data, password->len)))
        ABORT(r);

    allocate_request1->username = ctx->username;

    allocate_request2->username = ctx->username;
    allocate_request2->password = ctx->password;
    allocate_request2->realm = allocate_response1->realm;
    allocate_request2->nonce = allocate_response1->nonce;
    allocate_request2->bandwidth_kbps = bandwidth_kbps;
    allocate_request2->lifetime_secs = lifetime_secs;

    _status=0;
  abort:
    if (_status)
        ctx->state = NR_TURN_CLIENT_STATE_FAILED;
    if (ctx->state != NR_TURN_CLIENT_STATE_RUNNING) {
        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,cb_arg);
    }

    return(_status);
}
Example #4
0
/* nr_turn_client_ctx functions */
int nr_turn_client_ctx_create(const char *label, nr_socket *sock,
                              const char *username, Data *password,
                              nr_transport_addr *addr,
                              nr_turn_client_ctx **ctxp)
{
  nr_turn_client_ctx *ctx=0;
  int r,_status;

  if ((r=r_log_register("turn", &NR_LOG_TURN)))
    ABORT(r);

  if(!(ctx=RCALLOC(sizeof(nr_turn_client_ctx))))
    ABORT(R_NO_MEMORY);

  STAILQ_INIT(&ctx->stun_ctxs);
  STAILQ_INIT(&ctx->permissions);

  if(!(ctx->label=r_strdup(label)))
    ABORT(R_NO_MEMORY);

  ctx->sock=sock;
  ctx->username = r_strdup(username);
  if (!ctx->username)
    ABORT(R_NO_MEMORY);

  if ((r=r_data_create(&ctx->password, password->data, password->len)))
    ABORT(r);
  if ((r=nr_transport_addr_copy(&ctx->turn_server_addr, addr)))
    ABORT(r);

  if (addr->protocol == IPPROTO_UDP) {
    ctx->state = NR_TURN_CLIENT_STATE_CONNECTED;
  }
  else {
    assert(addr->protocol == IPPROTO_TCP);
    ctx->state = NR_TURN_CLIENT_STATE_INITTED;

    if (r=nr_turn_client_connect(ctx)) {
      if (r != R_WOULDBLOCK)
        ABORT(r);
    }
  }

  *ctxp=ctx;

  _status=0;
abort:
  if(_status){
    nr_turn_client_ctx_destroy(&ctx);
  }
  return(_status);
}