Не удалось найти внутренний порт сопоставления NAT в библиотеке PJSIP/PJNATH.

Я использую библиотеку пробивки портов PJSIP/PJNATH (для STUN/TURN/ICE) и хочу создать свой собственный транспорт на основе UDP через перфорированные порты.

Я не могу найти структуру данных, содержащую внутренний порт сопоставления NAT. Причина, по которой мне нужен внутренний порт (с обеих сторон), заключается в том, чтобы привязать сокет UDP к внутреннему порту (вместо того, чтобы ОС выбирала случайный порт). Пожалуйста, смотрите схему.

Я понимаю, что пример приложения icedemo может отправлять данные туда и обратно в Интернете (после пробивки портов); поэтому он должен привязываться к внутреннему порту UDP. Мне просто нужно знать, какая структура данных содержит внутренний порт. Внутренний порт сопоставления NAT

Функция 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 и перфорирует порты UDP с помощью проверок ICE-UDP после обмена IP-адресом хоста/сервера-рефлексивного/ретранслятора с обе стороны.


person auro    schedule 17.06.2014    source источник


Ответы (2)


Похоже, это bound_addr pj_sockaddr в структуре pj_stun_sock_cfg.

Согласно документам, "Если порт установлен на ноль, сокет будет привязан к любому порту (выбранному ОС)».

person user3839349    schedule 15.07.2014
comment
Спасибо за ответ. Мы не можем использовать нулевое значение для исходного порта, поскольку процедура ICE создала сопоставление в NAT; и мы должны использовать это отображение. Итак, мы должны использовать локальный привязанный порт (не 0). В потребительских NAT (от таких компаний, как D-Link) внутренние и внешние порты в сопоставлении NAT одинаковы, но это не относится ко всем NAT. Я нашел ответ после экспериментов с несколькими NAT. Я изложу ответ ниже. - person auro; 25.07.2014

Я обнаружил, что на ICE «complete» часть lcand структуры данных действительно содержит локальный связанный IP-адрес и порт. В большинстве потребительских NAT это был тот же номер порта (что и есть на самом деле), что вызывало недоумение. Поэкспериментировав с несколькими корпоративными 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;
    }
}
person auro    schedule 25.07.2014