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); }
/* 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); }
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; }
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()); }
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); }
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; }
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); }
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); }
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); }
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); }
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); }
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); } }
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); }
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); }
/* 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; }
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); }
/* 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; }