2014-06-17 9 views
1

PUNS/PJNATH 포트 펀칭 라이브러리 (STUN/TURN/ICE 용)를 사용하고 펀치 위에 자체 UDP 기반 전송을 생성하려고합니다 - 포트.PJSIP/PJNATH 라이브러리에서 NAT 매핑의 내부 포트를 찾을 수 없습니다.

NAT 매핑 포트를 보유하고있는 데이터 구조를 찾으려면 입니다.입니다. 내부 포트가 필요한 이유는 UDP 포트를 내부 포트 (OS가 랜덤 포트를 선택하는 대신)에 바인딩하기 위해서입니다. 다이어그램을 참조하십시오.

icedemo 샘플 앱이 인터넷에서 데이터를 앞뒤로 보낼 수 있다는 것을 알고 있습니다 (포트를 펀치 한 후). 따라서 내부 UDP 포트에 바인드해야합니다. 난 그냥 어떤 데이터 구조가 내부 포트를 보유하고 있는지 알아야합니다. Internal port of the NAT mapping

ice_session.c 파일에서의 pj_ice_sess_send_data 기능은 변수를 덤프 유망 장소처럼 보였다. 그러나 NAT 매핑의 내부 포트는 없습니다.

//my attempt did *not* work 
pj_ice_sess_cand *cand; 
cand = comp->valid_check->lcand; 
char addrinfo[80]; 
pj_sockaddr_print(&cand->base_addr, addrinfo, sizeof(addrinfo), 3); 
printf("***Local address %s\n", addrinfo); 

참고 : 공개 IP : 포트는 쉽게 사용할 수 있습니다.

배경는 호스트/서버 재귀 릴레이/IP 교환 후에도 PJNATH 라이브러리는 표준 기반 STUN/TURN/ICE 프로토콜 펀치 UDP 포트 ICE-UDP 검사를 이용하여 구현
: 양측에서 포트 .

답변

1

구조체 pj_stun_sock_cfgbound_addr pj_sockaddr와 비슷합니다.

the docs에 따르면 "포트가 0으로 설정되면 소켓은 OS에서 선택한 모든 포트에서 바인딩됩니다."

+0

당신이 뭔가에 인쇄 할 수 있습니다

은 ... 응답 주셔서 감사합니다. ICE 절차가 NAT에서 매핑을 생성하기 때문에 소스 포트에 0 값을 사용할 수 없습니다. 우리는 그 매핑을 사용해야합니다. 따라서 로컬 바인딩 된 포트 (0이 아님)를 사용해야합니다. D-Link와 같은 회사의 소비자 NAT에서 NAT 매핑의 내부 및 외부 포트는 동일하지만 모든 NAT에 해당하지는 않습니다. 몇 가지 NAT를 실험 한 후에 해답을 찾았습니다. 아래에 답변을 말씀 드리겠습니다. – auro

0

ICE "complete"에서 데이터 구조의 lcand 부분이 로컬 바운드 IP 및 포트를 보유한다는 것을 알게되었습니다. 대부분의 소비자 NAT에서 이것은 수수께끼 같은 포트 번호였습니다. 몇 개의 enterprice NAT를 실험 한 결과, 포트 번호가 매핑의 양쪽에서 다른 것으로 나타났습니다.

static void cb_on_ice_complete(pj_ice_strans *ice_st, 
           pj_ice_strans_op op, 
           pj_status_t status) 
{ 
    const char *opname = 
     (op==PJ_ICE_STRANS_OP_INIT? "initialization" : 
     (op==PJ_ICE_STRANS_OP_NEGOTIATION ? "negotiation" : "unknown_op")); 

    if (status == PJ_SUCCESS) 
    { 
     PJ_LOG(3,(THIS_FILE, "ICE %s successful", opname)); 

     if (op == PJ_ICE_STRANS_OP_NEGOTIATION) 
     { 
      const pj_ice_sess_check *check; 
      check = pj_ice_strans_get_valid_pair(icedemo.icest, 1); 
      if ((check != NULL) && (check->nominated == PJ_TRUE)) { //local (l) and remote(r) candidate 
       pj_sockaddr_print(&check->lcand->addr, icedemo.local_ip_port, 
         sizeof(icedemo.local_ip_port), 3); 
       pj_sockaddr_print(&check->rcand->addr, icedemo.remote_ip_port, 
         sizeof(icedemo.remote_ip_port), 3); 

     pj_sockaddr_print(&check->lcand->base_addr, icedemo.local_bound_ip_port, sizeof(icedemo.local_bound_ip_port), 3); 

      } 
      else 
      { 
       PJ_LOG(3,(THIS_FILE, "err: unable to get valid pair for ice1 " 
          "component %d", icedemo.icest, 1)); 
      } 


     } 
    } 
    else 
    { 
     char errmsg[PJ_ERR_MSG_SIZE]; 

     pj_strerror(status, errmsg, sizeof(errmsg)); 
     PJ_LOG(1,(THIS_FILE, "ICE %s failed: %s", opname, errmsg)); 
     pj_ice_strans_destroy(ice_st); 
     icedemo.icest = NULL; 
    } 
}