예제 #1
0
static int nr_turn_stun_set_auth_params(nr_turn_stun_ctx *ctx,
                                        char *realm, char *nonce)
{
  int _status;

  RFREE(ctx->realm);
  RFREE(ctx->nonce);

  assert(realm);
  if (!realm)
    ABORT(R_BAD_ARGS);
  ctx->realm=r_strdup(realm);
  if (!ctx->realm)
    ABORT(R_NO_MEMORY);

  assert(nonce);
  if (!nonce)
    ABORT(R_BAD_ARGS);
  ctx->nonce=r_strdup(nonce);
  if (!ctx->nonce)
    ABORT(R_NO_MEMORY);

  RFREE(ctx->stun->realm);
  ctx->stun->realm = r_strdup(ctx->realm);
  if (!ctx->stun->realm)
    ABORT(R_NO_MEMORY);

  ctx->stun->auth_params.realm = ctx->realm;
  ctx->stun->auth_params.nonce = ctx->nonce;
  ctx->stun->auth_params.authenticate = 1;  /* May already be 1 */

  _status=0;
abort:
  return(_status);
}
예제 #2
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);
}
예제 #3
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;
}
예제 #4
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());
}
예제 #5
0
파일: addrs.c 프로젝트: Jar-win/Waterfox
static int nr_win32_get_adapter_friendly_name(char *adapter_GUID, char **friendly_name)
{
    int r,_status;
    HKEY adapter_reg;
    TCHAR adapter_key[_NR_MAX_KEY_LENGTH];
    TCHAR keyval_buf[_NR_MAX_KEY_LENGTH];
    TCHAR adapter_GUID_tchar[_NR_MAX_NAME_LENGTH];
    DWORD keyval_len, key_type;
    size_t converted_chars, newlen;
    char *my_fn = 0;

#ifdef _UNICODE
    mbstowcs_s(&converted_chars, adapter_GUID_tchar, strlen(adapter_GUID)+1,
               adapter_GUID, _TRUNCATE);
#else
    strlcpy(adapter_GUID_tchar, adapter_GUID, _NR_MAX_NAME_LENGTH);
#endif

    _tcscpy_s(adapter_key, _NR_MAX_KEY_LENGTH, TEXT(_ADAPTERS_BASE_REG));
    _tcscat_s(adapter_key, _NR_MAX_KEY_LENGTH, TEXT("\\"));
    _tcscat_s(adapter_key, _NR_MAX_KEY_LENGTH, adapter_GUID_tchar);
    _tcscat_s(adapter_key, _NR_MAX_KEY_LENGTH, TEXT("\\Connection"));

    r = RegOpenKeyEx(HKEY_LOCAL_MACHINE, adapter_key, 0, KEY_READ, &adapter_reg);

    if (r != ERROR_SUCCESS) {
      r_log(NR_LOG_STUN, LOG_ERR, "Got error %d opening adapter reg key\n", r);
      ABORT(R_INTERNAL);
    }

    keyval_len = sizeof(keyval_buf);
    r = RegQueryValueEx(adapter_reg, TEXT("Name"), NULL, &key_type,
                        (BYTE *)keyval_buf, &keyval_len);

    RegCloseKey(adapter_reg);

#ifdef UNICODE
    newlen = wcslen(keyval_buf)+1;
    my_fn = (char *) RCALLOC(newlen);
    if (!my_fn) {
      ABORT(R_NO_MEMORY);
    }
    wcstombs_s(&converted_chars, my_fn, newlen, keyval_buf, _TRUNCATE);
#else
    my_fn = r_strdup(keyval_buf);
#endif

    *friendly_name = my_fn;
    _status=0;

abort:
    if (_status) {
      if (my_fn) free(my_fn);
    }
    return(_status);
}
예제 #6
0
파일: rthreads.c 프로젝트: ieei/rlib
void
r_thread_init (void)
{
  RThread * thread = r_thread_current ();

  r_log_category_register (&rthreadcat);

#ifdef HAVE_PTHREAD_GETNAME_NP
  static const int maxname = 24;
  rchar name[maxname + 1];
  if (pthread_getname_np (thread->thread, name, maxname) == 0 && name[0] != 0) {
    thread->name = r_strdup (name);
  } else
#endif
  {
    thread->name = r_strdup ("main/root");
  }

  thread->is_root = TRUE;
}
예제 #7
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);
}
예제 #8
0
int nr_stun_client_ctx_create(char *label, nr_socket *sock, nr_transport_addr *peer, UINT4 RTO, nr_stun_client_ctx **ctxp)
{
    nr_stun_client_ctx *ctx=0;
    int r,_status;

    if ((r=nr_stun_startup()))
        ABORT(r);

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

    ctx->state=NR_STUN_CLIENT_STATE_INITTED;

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

    ctx->sock=sock;

    nr_socket_getaddr(sock,&ctx->my_addr);
    nr_transport_addr_copy(&ctx->peer_addr,peer);

    if (NR_reg_get_uint4(NR_STUN_REG_PREF_CLNT_RETRANSMIT_TIMEOUT, &ctx->rto_ms)) {
        if (RTO != 0)
            ctx->rto_ms = RTO;
        else
            ctx->rto_ms = 100;
    }

    if (NR_reg_get_double(NR_STUN_REG_PREF_CLNT_RETRANSMIT_BACKOFF, &ctx->retransmission_backoff_factor))
        ctx->retransmission_backoff_factor = 2.0;

    if (NR_reg_get_uint4(NR_STUN_REG_PREF_CLNT_MAXIMUM_TRANSMITS, &ctx->maximum_transmits))
        ctx->maximum_transmits = 7;

    if (NR_reg_get_uint4(NR_STUN_REG_PREF_CLNT_FINAL_RETRANSMIT_BACKOFF, &ctx->final_retransmit_backoff_ms))
        ctx->final_retransmit_backoff_ms = 16 * ctx->rto_ms;

    *ctxp=ctx;

    _status=0;
abort:
    if(_status) {
        nr_stun_client_ctx_destroy(&ctx);
    }
    return(_status);
}
예제 #9
0
int
nr_turn_client_ctx_create(char *label, nr_socket *sock, nr_socket *wsock, nr_transport_addr *turn_server, UINT4 RTO, nr_turn_client_ctx **ctxp)
{
    nr_turn_client_ctx *ctx=0;
    int r,_status;
    int i;
    char string[256];

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

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

    ctx->state=NR_TURN_CLIENT_STATE_INITTED;

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

    ctx->sock=sock;
    ctx->wrapping_sock=wsock;

    ctx->phase=NR_TURN_CLIENT_PHASE_INITIALIZED;

    nr_transport_addr_copy(&ctx->turn_server_addr,turn_server);

    for (i = 0; i < NUMBER_OF_STUN_CTX; ++i) {
        snprintf(string, sizeof(string), "%s:%s", label, TURN_PHASE_LABEL[i]);

        if ((r=nr_stun_client_ctx_create(string, sock, turn_server, RTO, &ctx->stun_ctx[i]))) {
            r_log_nr(NR_LOG_TURN,LOG_ERR,r,"TURN(%s): Failed to start",string);
            ABORT(r);
        }
    }

    *ctxp=ctx;

    _status=0;
  abort:
    if(_status){
      nr_turn_client_ctx_destroy(&ctx);
    }
    return(_status);
}
예제 #10
0
int
nr_ice_peer_candidate_from_attribute(nr_ice_ctx *ctx,char *orig,nr_ice_media_stream *stream,nr_ice_candidate **candp)
{
    int r,_status;
    char* str = orig;
    nr_ice_candidate *cand;
    char *connection_address=0;
    unsigned int port;
    in_addr_t addr;
    int i;
    unsigned int component_id;
    char *rel_addr=0;

    if(!(cand=RCALLOC(sizeof(nr_ice_candidate))))
        ABORT(R_NO_MEMORY);

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

    cand->ctx=ctx;
    cand->isock=0;
    cand->state=NR_ICE_CAND_PEER_CANDIDATE;
    cand->stream=stream;
    skip_whitespace(&str);

    /* Candidate attr */
    if (strncasecmp(str, "candidate:", 10))
        ABORT(R_BAD_DATA);

    fast_forward(&str, 10);
    if (*str == '\0')
        ABORT(R_BAD_DATA);

    skip_whitespace(&str);
    if (*str == '\0')
        ABORT(R_BAD_DATA);

    /* Foundation */
    if ((r=grab_token(&str, &cand->foundation)))
        ABORT(r);

    if (*str == '\0')
        ABORT(R_BAD_DATA);

    skip_whitespace(&str);
    if (*str == '\0')
        ABORT(R_BAD_DATA);

    /* component */
    if (sscanf(str, "%u", &component_id) != 1)
        ABORT(R_BAD_DATA);

    if (component_id < 1 || component_id > 256)
        ABORT(R_BAD_DATA);

    cand->component_id = (UCHAR)component_id;

    skip_to_past_space(&str);
    if (*str == '\0')
        ABORT(R_BAD_DATA);

    /* Protocol */
    if (strncasecmp(str, "UDP", 3))
        ABORT(R_BAD_DATA);

    fast_forward(&str, 3);
    if (*str == '\0')
        ABORT(R_BAD_DATA);

    skip_whitespace(&str);
    if (*str == '\0')
        ABORT(R_BAD_DATA);

    /* priority */
    if (sscanf(str, "%u", &cand->priority) != 1)
        ABORT(R_BAD_DATA);

    if (cand->priority < 1)
        ABORT(R_BAD_DATA);

    skip_to_past_space(&str);
    if (*str == '\0')
        ABORT(R_BAD_DATA);

    /* Peer address/port */
    if ((r=grab_token(&str, &connection_address)))
        ABORT(r);

    if (*str == '\0')
        ABORT(R_BAD_DATA);

    addr = inet_addr(connection_address);
    if (addr == INADDR_NONE)
        ABORT(R_BAD_DATA);

    skip_whitespace(&str);
    if (*str == '\0')
        ABORT(R_BAD_DATA);

    if (sscanf(str, "%u", &port) != 1)
        ABORT(R_BAD_DATA);

    if (port < 1 || port > 0x0FFFF)
        ABORT(R_BAD_DATA);

    /* Assume v4 for now */
    if(r=nr_ip4_port_to_transport_addr(ntohl(addr),port,IPPROTO_UDP,&cand->addr))
      ABORT(r);

    skip_to_past_space(&str);
    if (*str == '\0')
        ABORT(R_BAD_DATA);

    /* Type */
    if (strncasecmp("typ", str, 3))
        ABORT(R_BAD_DATA);

    fast_forward(&str, 3);
    if (*str == '\0')
        ABORT(R_BAD_DATA);

    skip_whitespace(&str);
    if (*str == '\0')
        ABORT(R_BAD_DATA);

    assert(nr_ice_candidate_type_names[0] == 0);
    for (i = 1; nr_ice_candidate_type_names[i]; ++i) {
        if(!strncasecmp(nr_ice_candidate_type_names[i], str, strlen(nr_ice_candidate_type_names[i]))) {
            cand->type=i;
            break;
        }
    }
    if (nr_ice_candidate_type_names[i] == 0)
        ABORT(R_BAD_DATA);

    fast_forward(&str, strlen(nr_ice_candidate_type_names[i]));

    /* Look for the other side's raddr, rport */
    /* raddr, rport */
    switch (cand->type) {
    case HOST:
        break;
    case SERVER_REFLEXIVE:
    case PEER_REFLEXIVE:
    case RELAYED:

        skip_whitespace(&str);
        if (*str == '\0')
            ABORT(R_BAD_DATA);

        if (strncasecmp("raddr", str, 5))
            ABORT(R_BAD_DATA);

        fast_forward(&str, 5);
        if (*str == '\0')
            ABORT(R_BAD_DATA);

        skip_whitespace(&str);
        if (*str == '\0')
            ABORT(R_BAD_DATA);

        if ((r=grab_token(&str, &rel_addr)))
            ABORT(r);

        if (*str == '\0')
            ABORT(R_BAD_DATA);

        addr = inet_addr(rel_addr);
        if (addr == INADDR_NONE)
            ABORT(R_BAD_DATA);

        skip_whitespace(&str);
        if (*str == '\0')
            ABORT(R_BAD_DATA);

        if (strncasecmp("rport", str, 5))
              ABORT(R_BAD_DATA);

        fast_forward(&str, 5);
        if (*str == '\0')
            ABORT(R_BAD_DATA);

        skip_whitespace(&str);
        if (*str == '\0')
            ABORT(R_BAD_DATA);

        if (sscanf(str, "%u", &port) != 1)
            ABORT(R_BAD_DATA);

        if (port < 1 || port > 0x0FFFF)
            ABORT(R_BAD_DATA);

        /* Assume v4 for now */
        if(r=nr_ip4_port_to_transport_addr(ntohl(addr),port,IPPROTO_UDP,&cand->base))
          ABORT(r);

        skip_to_past_space(&str);
        /* it's expected to be at EOD at this point */

        break;
    default:
        ABORT(R_INTERNAL);
        break;
    }

    skip_whitespace(&str);

    assert(strlen(str) == 0);

    *candp=cand;

    _status=0;
  abort:
    if (_status)
        r_log(LOG_ICE,LOG_WARNING,"ICE(%s): Error parsing attribute: %s",ctx->label,orig);

    RFREE(connection_address);
    RFREE(rel_addr);
    return(_status);
}
예제 #11
0
int nr_stun_client_ctx_create(char *label, nr_socket *sock, nr_transport_addr *peer, UINT4 RTO, nr_stun_client_ctx **ctxp)
  {
    nr_stun_client_ctx *ctx=0;
    char allow_loopback;
    int r,_status;

    if ((r=nr_stun_startup()))
      ABORT(r);

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

    ctx->state=NR_STUN_CLIENT_STATE_INITTED;

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

    ctx->sock=sock;

    nr_socket_getaddr(sock,&ctx->my_addr);
    nr_transport_addr_copy(&ctx->peer_addr,peer);

    if (RTO != 0) {
      ctx->rto_ms = RTO;
    } else if (NR_reg_get_uint4(NR_STUN_REG_PREF_CLNT_RETRANSMIT_TIMEOUT, &ctx->rto_ms)) {
      ctx->rto_ms = 100;
    }

    if (NR_reg_get_double(NR_STUN_REG_PREF_CLNT_RETRANSMIT_BACKOFF, &ctx->retransmission_backoff_factor))
      ctx->retransmission_backoff_factor = 2.0;

    if (NR_reg_get_uint4(NR_STUN_REG_PREF_CLNT_MAXIMUM_TRANSMITS, &ctx->maximum_transmits))
      ctx->maximum_transmits = 7;

    if (NR_reg_get_uint4(NR_STUN_REG_PREF_CLNT_FINAL_RETRANSMIT_BACKOFF, &ctx->maximum_transmits_timeout_ms))
      ctx->maximum_transmits_timeout_ms = 16 * ctx->rto_ms;

    ctx->mapped_addr_check_mask = NR_STUN_TRANSPORT_ADDR_CHECK_WILDCARD;
    if (NR_reg_get_char(NR_STUN_REG_PREF_ALLOW_LOOPBACK_ADDRS, &allow_loopback) ||
        !allow_loopback) {
      ctx->mapped_addr_check_mask |= NR_STUN_TRANSPORT_ADDR_CHECK_LOOPBACK;
    }

    if (ctx->my_addr.protocol == IPPROTO_TCP) {
      /* Because TCP is reliable there is only one final timeout value.
       * We store the timeout value for TCP in here, because timeout_ms gets
       * reset to 0 in client_reset() which gets called from client_start() */
      ctx->maximum_transmits_timeout_ms = ctx->rto_ms *
                        pow(ctx->retransmission_backoff_factor,
                            ctx->maximum_transmits);
      ctx->maximum_transmits = 1;
    }

    *ctxp=ctx;

    _status=0;
  abort:
    if(_status){
      nr_stun_client_ctx_destroy(&ctx);
    }
    return(_status);
  }
예제 #12
0
static void nr_turn_stun_ctx_cb(NR_SOCKET s, int how, void *arg)
{
  int r, _status;
  nr_turn_stun_ctx *ctx = (nr_turn_stun_ctx *)arg;

  ctx->last_error_code = ctx->stun->error_code;

  switch (ctx->stun->state) {
    case NR_STUN_CLIENT_STATE_DONE:
      /* Save the realm and nonce */
      if (ctx->stun->realm && (!ctx->tctx->realm || strcmp(ctx->stun->realm,
                                                           ctx->tctx->realm))) {
        RFREE(ctx->tctx->realm);
        ctx->tctx->realm = r_strdup(ctx->stun->realm);
        if (!ctx->tctx->realm)
          ABORT(R_NO_MEMORY);
      }
      if (ctx->stun->nonce && (!ctx->tctx->nonce || strcmp(ctx->stun->nonce,
                                                           ctx->tctx->nonce))) {
        RFREE(ctx->tctx->nonce);
        ctx->tctx->nonce = r_strdup(ctx->stun->nonce);
        if (!ctx->tctx->nonce)
          ABORT(R_NO_MEMORY);
      }

      ctx->retry_ct=0;
      ctx->success_cb(0, 0, ctx);
      break;

    case NR_STUN_CLIENT_STATE_FAILED:
      /* Special case: if this is an authentication error,
         we retry once. This allows the 401/438 nonce retry
         paradigm. After that, we fail */
      /* TODO([email protected]): 401 needs a #define */
      /* TODO([email protected]): Add alternate-server (Mozilla bug 857688) */
      if (ctx->stun->error_code == 401 || ctx->stun->error_code == 438) {
        if (ctx->retry_ct > 0) {
          r_log(NR_LOG_TURN, LOG_WARNING, "TURN(%s): Exceeded the number of retries", ctx->tctx->label);
          ABORT(R_FAILED);
        }

        if (!ctx->stun->nonce) {
          r_log(NR_LOG_TURN, LOG_WARNING, "TURN(%s): 401 but no nonce", ctx->tctx->label);
          ABORT(R_FAILED);
        }
        if (!ctx->stun->realm) {
          r_log(NR_LOG_TURN, LOG_WARNING, "TURN(%s): 401 but no realm", ctx->tctx->label);
          ABORT(R_FAILED);
        }

        /* Try to retry */
        if ((r=nr_turn_stun_set_auth_params(ctx, ctx->stun->realm,
                                            ctx->stun->nonce)))
          ABORT(r);

        ctx->stun->error_code = 0;  /* Reset to avoid inf-looping */

        if ((r=nr_turn_stun_ctx_start(ctx))) {
          r_log(NR_LOG_TURN, LOG_ERR, "TURN(%s): Couldn't start STUN", ctx->tctx->label);
          ABORT(r);
        }

        ctx->retry_ct++;
      }
      else {
        ABORT(R_FAILED);
      }
      break;

    case NR_STUN_CLIENT_STATE_TIMED_OUT:
      ABORT(R_FAILED);
      break;

    case NR_STUN_CLIENT_STATE_CANCELLED:
      assert(0);  /* Shouldn't happen */
      return;
      break;

    default:
      assert(0);  /* Shouldn't happen */
      return;
  }

  _status=0;
abort:
  if (_status) {
    ctx->error_cb(0, 0, ctx);
  }
}
예제 #13
0
int nr_ice_candidate_pair_create(nr_ice_peer_ctx *pctx, nr_ice_candidate *lcand,nr_ice_candidate *rcand,nr_ice_cand_pair **pairp)
  {
    nr_ice_cand_pair *pair=0;
    UINT8 o_priority, a_priority;
    char *lufrag,*rufrag;
    char *lpwd,*rpwd;
    char *l2ruser=0,*r2lpass=0;
    int r,_status;
    UINT4 RTO;
    nr_ice_candidate tmpcand;
    UINT8 t_priority;

    if(!(pair=RCALLOC(sizeof(nr_ice_cand_pair))))
      ABORT(R_NO_MEMORY);
    
    pair->pctx=pctx;
    
    nr_ice_candidate_pair_compute_codeword(pair,lcand,rcand);
    
    if(r=nr_concat_strings(&pair->as_string,pair->codeword,"|",lcand->addr.as_string,"|",
         rcand->addr.as_string,"(",lcand->label,"|",rcand->label,")",0))
      ABORT(r);

    nr_ice_candidate_pair_set_state(pctx,pair,NR_ICE_PAIR_STATE_FROZEN);
    pair->local=lcand;
    pair->remote=rcand;

    /* Priority computation S 5.7.2 */
    if(pctx->ctx->flags & NR_ICE_CTX_FLAGS_OFFERER)
    {
      assert(!(pctx->ctx->flags & NR_ICE_CTX_FLAGS_ANSWERER));
      
      o_priority=lcand->priority;
      a_priority=rcand->priority;
    }
    else{
      o_priority=rcand->priority;
      a_priority=lcand->priority;
    }
    pair->priority=(MIN(o_priority, a_priority))<<32 | 
      (MAX(o_priority, a_priority))<<1 | (o_priority > a_priority?0:1);
    
    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);

    /* Foundation */
    if(r=nr_concat_strings(&pair->foundation,lcand->foundation,"|",
      rcand->foundation,0))
      ABORT(r);


    /* OK, now the STUN data */
    lufrag=lcand->stream->ufrag?lcand->stream->ufrag:pctx->ctx->ufrag;
    lpwd=lcand->stream->pwd?lcand->stream->pwd:pctx->ctx->pwd;
    rufrag=rcand->stream->ufrag?rcand->stream->ufrag:pctx->peer_ufrag;
    rpwd=rcand->stream->pwd?rcand->stream->pwd:pctx->peer_pwd;


    /* Compute the RTO per S 16 */
    RTO = MAX(100, (pctx->ctx->Ta * pctx->waiting_pairs));

    /* Make a bogus candidate to compute a theoretical peer reflexive
     * priority per S 7.1.1.1 */
    memcpy(&tmpcand, lcand, sizeof(tmpcand));
    tmpcand.type = PEER_REFLEXIVE;
    if (r=nr_ice_candidate_compute_priority(&tmpcand))
      ABORT(r);
    t_priority = tmpcand.priority;

    /* Our sending context */
    if(r=nr_concat_strings(&l2ruser,lufrag,":",rufrag,0))
      ABORT(r);
    if(r=nr_stun_client_ctx_create(pair->as_string,
      lcand->osock,
      &rcand->addr,RTO,&pair->stun_client))
      ABORT(r);
    if(!(pair->stun_client->params.ice_binding_request.username=r_strdup(l2ruser)))
      ABORT(R_NO_MEMORY);
    if(r=r_data_make(&pair->stun_client->params.ice_binding_request.password,(UCHAR *)lpwd,strlen(lpwd)))
      ABORT(r);
    pair->stun_client->params.ice_binding_request.priority=t_priority;
    pair->stun_client->params.ice_binding_request.control = pctx->controlling?
      NR_ICE_CONTROLLING:NR_ICE_CONTROLLED;

    pair->stun_client->params.ice_binding_request.tiebreaker=pctx->tiebreaker;

    /* Our receiving username/passwords. Stash these for later 
       injection into the stun server ctx*/
    if(r=nr_concat_strings(&pair->r2l_user,rufrag,":",lufrag,0))
      ABORT(r);
    if(!(r2lpass=r_strdup(rpwd)))
      ABORT(R_NO_MEMORY);
    INIT_DATA(pair->r2l_pwd,(UCHAR *)r2lpass,strlen(r2lpass));
    
    *pairp=pair;

    _status=0;
  abort:
    RFREE(l2ruser);
    if(_status){
      RFREE(r2lpass);
    }
    return(_status);
  }
예제 #14
0
int r_log_register(char *facility_name,int *log_facility)
  {
    int i,j;
    int level;
    int r,_status;
    char *buf=0;
    NR_registry dest_prefix, dest_facility_prefix;
 
    for(i=0;i<log_type_ct;i++){
      if(!strcmp(facility_name,log_types[i].facility_name)){
        *log_facility=i;
        return(0);
      }
    }

    if(log_type_ct==MAX_LOG_TYPES){
      ABORT(R_INTERNAL);
    }

    i=log_type_ct;

    /* Initial registration completed, increment log_type_ct */
    log_types[i].facility_name=r_strdup(facility_name);
    *log_facility=log_type_ct;
    log_type_ct++;
    
    for(j=0; j<LOG_NUM_DESTINATIONS; j++){
      log_types[i].level[j]=LOG_LEVEL_UNDEFINED;

      if(NR_reg_initted()){

        if(snprintf(dest_prefix,sizeof(NR_registry),
          "logging.%s.facility",log_destinations[j].dest_name)>=sizeof(NR_registry))
          ABORT(R_INTERNAL);

        if (r=NR_reg_make_registry(dest_prefix,facility_name,dest_facility_prefix))
          ABORT(r);

        if(snprintf(log_types[i].dest_facility_key[j],sizeof(NR_registry),
          "%s.level",dest_facility_prefix)>=sizeof(NR_registry))
          ABORT(R_INTERNAL);

        if(!r_log_get_reg_level(log_types[i].dest_facility_key[j],&level)){
          log_types[i].level[j]=level;
        }

        /* Set a callback for the facility's level */
        if(r=NR_reg_register_callback(log_types[i].dest_facility_key[j],
          NR_REG_CB_ACTION_ADD|NR_REG_CB_ACTION_CHANGE,
          r_log_facility_change_cb,(void *)&(log_types[i].level[j])))
          ABORT(r);
        if(r=NR_reg_register_callback(log_types[i].dest_facility_key[j],
          NR_REG_CB_ACTION_DELETE,
          r_log_facility_delete_cb,(void *)&(log_types[i].level[j])))
          ABORT(r);

      }
    }

    _status=0;
  abort:
    if(_status)
      RFREE(buf);
    return(_status);
  }
예제 #15
0
파일: mbslen.c 프로젝트: Jar-win/Waterfox
/* get number of characters in a mult-byte character string */
int
mbslen(const char *s, size_t *ncharsp)
{
#ifdef HAVE_XLOCALE
    static locale_t loc = 0;
    static int initialized = 0;
#endif /* HAVE_XLOCALE */
#ifdef WIN32
    char *my_locale=0;
    unsigned int i;
#endif  /* WIN32 */
    int _status;
    size_t nbytes;
    int nchars;
    mbstate_t mbs;

#ifdef HAVE_XLOCALE
    if (! initialized) {
        initialized = 1;
        loc = newlocale(LC_CTYPE_MASK, "UTF-8", LC_GLOBAL_LOCALE);
    }

    if (loc == 0) {
        /* unable to create the UTF-8 locale */
        assert(loc != 0);  /* should never happen */
#endif /* HAVE_XLOCALE */

#ifdef WIN32
    if (!setlocale(LC_CTYPE, 0))
        ABORT(R_INTERNAL);

    if (!(my_locale = r_strdup(setlocale(LC_CTYPE, 0))))
        ABORT(R_NO_MEMORY);

    for (i=0; i<strlen(my_locale); i++)
        my_locale[i] = toupper(my_locale[i]);

    if (!strstr(my_locale, "UTF-8") && !strstr(my_locale, "UTF8"))
        ABORT(R_NOT_FOUND);
#else
    /* can't count UTF-8 characters with mbrlen if the locale isn't UTF-8 */
    /* null-checking setlocale is required because Android */
    char *locale = setlocale(LC_CTYPE, 0);
    /* some systems use "utf8" instead of "UTF-8" like Fedora 17 */
    if (!locale || (!strcasestr(locale, "UTF-8") && !strcasestr(locale, "UTF8")))
        ABORT(R_NOT_FOUND);
#endif

#ifdef HAVE_XLOCALE
    }
#endif /* HAVE_XLOCALE */

    memset(&mbs, 0, sizeof(mbs));
    nchars = 0;

#ifdef HAVE_XLOCALE
    while (*s != '\0' && (nbytes = mbrlen_l(s, strlen(s), &mbs, loc)) != 0)
#else
    while (*s != '\0' && (nbytes = mbrlen(s, strlen(s), &mbs)) != 0)
#endif /* HAVE_XLOCALE */
    {
        if (nbytes == (size_t)-1)   /* should never happen */ {
            ABORT(R_INTERNAL);
        }
        if (nbytes == (size_t)-2)   /* encoding error */ {
            ABORT(R_BAD_DATA);
        }

        s += nbytes;
        ++nchars;
    }

    *ncharsp = nchars;

    _status = 0;
  abort:
#ifdef WIN32
    RFREE(my_locale);
#endif
    return _status;
}
예제 #16
0
int nr_ice_candidate_pair_create(nr_ice_peer_ctx *pctx, nr_ice_candidate *lcand,nr_ice_candidate *rcand,nr_ice_cand_pair **pairp)
  {
    nr_ice_cand_pair *pair=0;
    UINT8 o_priority, a_priority;
    int r,_status;
    UINT4 RTO;
    nr_ice_candidate tmpcand;
    UINT8 t_priority;

    if(!(pair=RCALLOC(sizeof(nr_ice_cand_pair))))
      ABORT(R_NO_MEMORY);

    pair->pctx=pctx;

    nr_ice_candidate_pair_compute_codeword(pair,lcand,rcand);

    if(r=nr_concat_strings(&pair->as_string,pair->codeword,"|",lcand->addr.as_string,"|",
        rcand->addr.as_string,"(",lcand->label,"|",rcand->label,")", NULL))
      ABORT(r);

    nr_ice_candidate_pair_set_state(pctx,pair,NR_ICE_PAIR_STATE_FROZEN);
    pair->local=lcand;
    pair->remote=rcand;

    /* Priority computation S 5.7.2 */
    if(pctx->ctx->flags & NR_ICE_CTX_FLAGS_OFFERER)
    {
      assert(!(pctx->ctx->flags & NR_ICE_CTX_FLAGS_ANSWERER));

      o_priority=lcand->priority;
      a_priority=rcand->priority;
    }
    else{
      o_priority=rcand->priority;
      a_priority=lcand->priority;
    }
    pair->priority=(MIN(o_priority, a_priority))<<32 |
      (MAX(o_priority, a_priority))<<1 | (o_priority > a_priority?0:1);

    /*
       TODO([email protected]): Would be nice to log why this candidate was
       created (initial pair generation, triggered check, and new trickle
       candidate seem to be the possibilities here).
    */
    r_log(LOG_ICE,LOG_INFO,"ICE(%s)/CAND-PAIR(%s): Pairing candidate %s (%x):%s (%x) priority=%llu (%llx)",pctx->ctx->label,pair->codeword,lcand->addr.as_string,lcand->priority,rcand->addr.as_string,rcand->priority,pair->priority,pair->priority);

    /* Foundation */
    if(r=nr_concat_strings(&pair->foundation,lcand->foundation,"|",
      rcand->foundation,NULL))
      ABORT(r);

    /* Compute the RTO per S 16 */
    RTO = MAX(100, (pctx->ctx->Ta * pctx->waiting_pairs));

    /* Make a bogus candidate to compute a theoretical peer reflexive
     * priority per S 7.1.1.1 */
    memcpy(&tmpcand, lcand, sizeof(tmpcand));
    tmpcand.type = PEER_REFLEXIVE;
    if (r=nr_ice_candidate_compute_priority(&tmpcand))
      ABORT(r);
    t_priority = tmpcand.priority;

    /* Our sending context */
    if(r=nr_stun_client_ctx_create(pair->as_string,
      lcand->osock,
      &rcand->addr,RTO,&pair->stun_client))
      ABORT(r);
    if(!(pair->stun_client->params.ice_binding_request.username=r_strdup(rcand->stream->l2r_user)))
      ABORT(R_NO_MEMORY);
    if(r=r_data_copy(&pair->stun_client->params.ice_binding_request.password,
      &rcand->stream->l2r_pass))
      ABORT(r);
    pair->stun_client->params.ice_binding_request.priority=t_priority;
    /* TODO([email protected]): Do we need to frob this when we change role. Bug 890667 */
    pair->stun_client->params.ice_binding_request.control = pctx->controlling?
      NR_ICE_CONTROLLING:NR_ICE_CONTROLLED;
    pair->stun_client->params.ice_use_candidate.priority=t_priority;

    pair->stun_client->params.ice_binding_request.tiebreaker=pctx->tiebreaker;

    *pairp=pair;

    _status=0;
  abort:
    if(_status){
      nr_ice_candidate_pair_destroy(&pair);
    }
    return(_status);
  }
예제 #17
0
/* get number of characters in a mult-byte character string */
int
mbslen(const char *s, size_t *ncharsp)
{
#ifdef DARWIN
    static locale_t loc = 0;
    static int initialized = 0;
#endif /* DARWIN */
#ifdef WIN32
    char *my_locale=0;
    unsigned int i;
#endif  /* WIN32 */
    int _status;
    size_t nbytes;
    int nchars;
    mbstate_t mbs;

#ifdef DARWIN
    if (! initialized) {
        initialized = 1;
        loc = newlocale(LC_CTYPE_MASK, "UTF-8", LC_GLOBAL_LOCALE);
    }

    if (loc == 0) {
        /* unable to create the UTF-8 locale */
        assert(loc != 0);  /* should never happen */
#endif /* DARWIN */

#ifdef WIN32
        if (!setlocale(LC_CTYPE, 0))
            ABORT(R_INTERNAL);

        if (!(my_locale = r_strdup(setlocale(LC_CTYPE, 0))))
            ABORT(R_NO_MEMORY);

        for (i=0; i<strlen(my_locale); i++)
            my_locale[i] = toupper(my_locale[i]);

        if (!strstr(my_locale, "UTF-8"))
            ABORT(R_NOT_FOUND);
#else
        /* can't count UTF-8 characters with mbrlen if the locale isn't UTF-8 */
        if (! strcasestr(setlocale(LC_CTYPE, 0), "UTF-8"))
            ABORT(R_NOT_FOUND);
#endif

#ifdef DARWIN
    }
#endif /* DARWIN */

    memset(&mbs, 0, sizeof(mbs));
    nchars = 0;

#ifdef DARWIN
    while (*s != '\0' && (nbytes = mbrlen_l(s, strlen(s), &mbs, loc)) != 0)
#else
    while (*s != '\0' && (nbytes = mbrlen(s, strlen(s), &mbs)) != 0)
#endif /* DARWIN */
    {
        if (nbytes == (size_t)-1) { /* should never happen */
            assert(0);
            ABORT(R_INTERNAL);
        }
        if (nbytes == (size_t)-2) { /* encoding error */
            assert(0);
            ABORT(R_BAD_DATA);
        }

        s += nbytes;
        ++nchars;
    }

    *ncharsp = nchars;

    _status = 0;
abort:
#ifdef WIN32
    RFREE(my_locale);
#endif
    return _status;
}