Ejemplo n.º 1
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);
  }
Ejemplo n.º 2
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);
  }