Этот способ является стандартным и определен в rfc3261, также работает "в лаборатории", т.е. тестовой сетевой конфигурации или просто в локальной сети. Но в реальной жизни, когда большинство конечных точек находятся за NAT, они обычно идентифицируют себя со своими частными адресами, которые нельзя использовать в вышеописанных стандартах.
Например, мой телефон представляет себя в создаваемом им заголовке Via, который содержит его личные идентификаторы в моей локальной сети:
Via: SIP/2.0/UDP 192.168.X.X:5060;branch=z9hG4bK992054588
Запрашивая вызов общедоступного сервера за пределами моей сети, этот URI абсолютно недоступен для сервера. Следовательно, ответы никогда не возвращаются обратно вызывающему объекту должным образом.
Параметр "received"
«received» — это стандартный параметр в заголовке Via, который содержит фактический адрес отправителя, с которого был получен пакет.
Параметр «received» генерируется, если IP-адрес в заголовке Via отличается от адреса источника пакета.
Параметр "rport"
«rport», также известный как response-port, на самом деле аналогичен параметру «received», за исключением того, что «rport» содержит порт, а не IP-адрес, определенный в rfc3581.
Когда UAC формирует запрос, он может содержать пустой параметр «rport» в заголовке Via.
Когда UAS получает запрос, он проверяет самый верхний заголовок Via на наличие параметра «rport» без значения, если он есть, он ДОЛЖЕН установить значение параметра в исходный порт запроса.
Наличие параметра «rport» также переопределяет правило формирования параметра «received»: UAS должен вставить параметр «received», содержащий исходный IP-адрес, с которого пришел запрос, даже если он идентичен значению, указанному в заголовке Via
Пример
Теперь мой ip-телефон стал умнее и поддерживает rfc3581, добавляя пустой параметр «rport» в его заголовок Via перед отправкой.
INVITE sip:callee@100.0.0.2 SIP/2.0
Via: SIP/2.0/UDP 192.168.X.X:5060;branch=z9hG4bK992054588;rport;
Предположим, что мой общедоступный исходный IP-адрес равен 100.0.0.1. Сервер, который также поддерживает rfc3581, добавляет к ответу параметры «rport» и «received», 12345 — это исходный порт, который мое устройство NAT использует для создания соединения с сервером.
SIP/2.0 200 OK
Via: SIP/2.0/UDP 192.168.X.X:5060;branch=z9hG4bK992054588;rport=12345;received=100.0.0.1
Сервер в этом случае отправляет ответы не на URI в заголовке Via (192.168.X.X:5060), а на то, что присутствует в параметре «rport» и «received», т.е. мой внешний адрес и внешний порт (100.0.0.1:12345) . Моё устройство NAT, которое обрабатывает привязку NAT, будет правильно передавать ответы обратно на мой линфон. Оно «отправлено туда, откуда пришло!».