无法在PJSIP / PJNATH库中找到NAT映射的内部端口

时间:2014-06-17 03:10:37

标签: p2p nat pjsip sip-server

我使用PJSIP / PJNATH端口打孔库(用于STUN / TURN / ICE),并希望通过打孔端口创建自己的基于UDP的传输。

无法查找包含NAT映射的内部端口的数据结构。我需要内部端口(两侧)的原因是将UDP套接字绑定到内部端口(而不是操作系统选择随机端口)。请参见图表。

我意识到icedemo示例应用程序能够在互联网上来回发送数据(在打完端口之后);所以它必须绑定到内部UDP端口。我只需要知道哪个数据结构保存内部端口。 Internal port of the NAT mapping

pj_ice_sess_send_data文件中的ice_session.c函数看起来像是一个很有希望转储变量的地方。但是没有一个包含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:端口随时可用。

背景
PJNATH库实现了基于标准的STUN / TURN / ICE协议,并在交换了主机/服务器反身/中继IP:端口之后,使用ICE-UDP检查来打击UDP端口。

2 个答案:

答案 0 :(得分:1)

它看起来像是bound_addr结构中的pj_stun_sock_cfg pj_sockaddr。

根据the docs,"如果端口设置为零,则套接字将绑定在任何端口(由OS选择)。"

答案 1 :(得分:0)

我发现,在ICE"完成",数据结构的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;
    }
}