Sip peer что такое
Настройка SIP-trunk от Asterisk до VoIP Service Provider «Сибирьтелеком»
Начнём с того, что Сибирьтелеком — крупнейший оператор фиксированной связи в СФО в Кемерово предоставляет VoIP с сигнализацией SIP только для абонентов подключенных по ETTH (оптика). Та ещё песня получить такое соединение. Однако здесь опишу опыт настройки SIP-транка между Asterisk из коробки TrixBox и их чудесным железом, которое называется IskraTel SI3000.
Входящие вызовы
host=10.0.25.2
type=peer nat=no
disallow=all
allow=alaw
context=from-trunk
А чтобы звонки приходили естественно необходимо зарегистрировать свой номер на своём IP-адресе у провайдера. Для этого надо достать бумажный конверт с паролем доступа к SIP! (Да, да чтобы получить доступ к защищённой по всем статьям услуге надо съездить в офис и получить бумажные конверты на каждый городской номер 🙂 и указать строку регистрации:
После этого Asterisk без вопросов принимает входящие вызовы.
Исходящие вызовы
Опыт 1.
SIP/2.0 480 Temporarily Unavailable
Опыт 2.
SIP/2.0 480 Temporarily Unavailable
INVITE sip:316544@10.0.25.2 SIP/2.0
[skipped]
Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY
Supported: replaces, timer
Content-Type: application/sdp
Content-Length: 266
После этого второй „не медийный“ поток с кодом кодека „101 telephone-event/8000“ не направляется к этому пиру. Это я узнал из RFC-3261 и как оказалось позже роли не играет.
Опыт 3.
SIP/2.0 480 Temporarily Unavailable
o=root 529554116 529554116 IN IP4 10.
(см. INVITE выше). У других наших клиентов в этом поле приходит [гор_номер].
Должно быть как у всех“.
читаем маны, доки, форумы и т.д. ищем как это сделать в Asterisk. И находим что это рулится только в секции [general] файла sip.conf обычного Asterisk, то есть для всех SIP-пиров и юзеров параметром:
в файле sip_general_custom.conf в TrixBox (точнее в FreePBX). Указываем именно „-“, т.к. в стандарте (RFC tools.ietf.org/html/rfc4566#section-5.2) должен быть указан владелец (owner), либо „-“ если система не поддерживает идентификаторы. Указать [гор_номер] как „советует“ провайдер не возможно, в силу указанной выше причины (секция [general]).
Опыт 4.
SIP/2.0 480 Temporarily Unavailable
(This allows you to set the domain in the From: field of the SIP header. It may be
required by some providers for authentication:
fromdomain=my.hostname.tld — врезка из Книги «Asterisk The Future of Telephony»)
host=10.0.25.2
type=peer
nat=no
disallow=all
allow=alaw
context=from-trunk
insecure=invite
fromdomain=10.0.25.2
и обязательно нужно выставлять Caller ID именно городской номер (см. Опыт 1), иначе Asterisk выдаёт туда местный номер, что не есть правильно :-).
Прямые звонки или звонки Peer-to-Peer (P2P) на DPH-150S.
В данной заметке я расскажу о вариантах организации прямых звонков, минуя SIP-сервер, на популярном SIP-телефоне DPH-150S производства компании D-Link.
Современные устройства IP-телефонии, как правило, поддерживают возможность прямых звонков. Рассмотрим два варианта настройки IP-телефона DPH-150S/F5 для совершения прямых звонков.
1. С использованием функции «P2P IP Prefix».
Назначение данной функции – добавить префикс перед набранным прямым номером. Для совершения прямого звонка необходимо при поднятой трубке перед номером нажимать «#», т.е. при звонке на номер «100» набирать надо «#100#». Нажатие «#» в конце номера в IP-телефонии означает активацию вызова без ожидания установленного тайм-аута.
Если все IP-телефоны находятся в одноранговой сети и каждому IP-телефону присвоить статический IP-адрес, например, из диапазона 192.168.10.0/24, а в префиксе «P2P IP Prefix» указать «192.168.10.», то последний октет IP-адреса IP-телефона можно использовать как номер этого телефона. Например, IP-адрес IP-телефона «192.168.10.102», то его номер «102», и позвонить на него можно «#102#».
В IP-телефоне DPH-150S/F5 с Firmware версией 2.4.0.5674 поле функции доступно на странице WEB-интерфейса «Features» («Функции») во вкладке «Phone settings» («Настройки телефона») в разделе «Common Settings» («Общие настройки»).
В некоторых решениях использование рассмотренного варианта настройки не применимо, например, если используется многопортовый VoIP-шлюз, и необходимо совершить прямой звонок на определённый порт этого шлюза. Кроме того, некоторым пользователям непривычно нажимать «#» перед набором номера.
Для таких случаев удобнее использовать второй вариант настройки.
2. С использованием функции «Dial Peer».
Назначение данной функции – создание одного или нескольких правил набора номеров. Функция позволяет использовать короткие номера, использовать диапазоны цифр, делать добавление или замену цифр в номере, отправлять звонки на домены и IP-адреса и т.д. Подробнее о данной функции можно почитать в руководстве пользователя IP-телефона.
В IP-телефоне DPH-150S/F5 с Firmware версией 2.4.0.5674 настройка данной функции доступна на странице WEB-интерфейса «Dial Plan» («Правила набора») во вкладке «Line» («Аккаунт») в разделах «Add Dial Peer» («План набора»), «Dial Peer Option» («Опции плана набора») и «Dial Peer Table» («Таблица плана набора»).
Если у удалённого IP-телефона номер «101» и IP-адрес «192.168.10.101», то для прямого звонка на этот телефон необходимо добавить у всех других абонентов следующее правило: в разделе «Add Dial Peer» («План набора») в поле «Number» («Номер») указать «101», в поле «Destination (Optional)» («Направление (опционально)») указать «192.168.10.101», в поле «Port (Optional)» («Порт (опционально)») указать «5060», и нажать кнопку «Apply» («Применить»).
В результате в таблицу «Dial Peer Table» («Таблица плана набора») добавится новая строчка с созданным правилом.
Если же необходимо звонить по отдельности на номера многопортового VoIP-шлюза, то можно добавить несколько правил с указанием каждого номера. Например, 4-х портовый FXS шлюз имеет IP-адрес «192.168.10.100». На его 4-х портах настроены номера «110», «111», «112» и «113». Тогда правила будут иметь следующий вид:
Чтобы сэкономить на количестве правил, в подобных случаях лучше использовать одно правило с указанием диапазона номеров:
Таким образом, подбирая правила набора, можно организовать на IP-телефоне требуемую логику работы при наборе различных номеров.
В некоторых случаях для возможности совершать прямые звонки без регистрации IP-телефона на SIP-сервере, необходимо активировать функцию «Dial Without Registered» («Вызовы без регистрации»), поставив соответствующую «галочку». В IP-телефоне DPH-150S/F5 с Firmware версией 2.4.0.5674 данная функция доступна на странице WEB-интерфейса «SIP» («SIP») во вкладке «Line» («Аккаунт») в разделе «Advanced Settings» («Расширенные настройки»).
Asterisk SIP trunk
Соединение обозначенное как user, это определение любой системы или оконечной точки (endpoint), которой мы разрешаем входящие вызовы на наш сервер Asterisk. Соединение type=user не обозначает никакого пользователя, а только создает канал и указывает контекст, для входа в диалплан аутентифицированных входящих вызовов.
Через соединение обозначенное как peer совершаются исходящие вызовы.
Asterisk Register String
register ⇒ sipuser[:secret[:authuser]]@host[:port][/extension]
Вышеприведенный пример, упрощенный вариант строки регистрации. Полный вариант содержит больше информации:
register => [peer?][transport://]user[@domain][:secret[:authuser]]@host[:port][/extension][
Обратите внимание на параметр transport, например tls:
register => tls://user:password@host
Строка регистрации имеет напрямую связанные с ней параметры [general]:
Пример вывода команды sip show registry в консоли Asterisk:
Возможные состояния (state):
Asterisk SIP peer
Для совершения исходящих вызовов должен быть создан объект type=peer.
Нажмите, чтобы отобразить
Нажмите, чтобы скрыть
Asterisk не делает различий между внутренними и внешними линиями, любой вызов совершается через какой-либо канал. Когда SIP сервер провайдера, вызывает Asterisk, то он совершает вызов через peer, проходя аутентификацию у user.
Конфигурация пиров осуществляется при помощи текстовых блоков, отделенных друг от друга квадратными скобками. Имя в квадратных скобках может совпадать с параметром ‘defaultuser’, но не обязательно.
Приведенный пример, являет собой типовой, самый распространенный вариант конфигурации sip транка с регистрацией через публичную сеть:
Входящая и исходящая маршрутизация sip транка в диалплане Asterisk
В диалплане (extensions.conf ) можно использовать разнообразный синтаксис для вызова (dial ) SIP устройств.
В файле extensions.conf, для совершения исходящих вызовов, у Вас должно присутствовать правило набора, примерно такого вида:
Пример контекста для входящих вызовов в файле ‘extensions.conf’:
Где from-siptrunk контекст заданный user или friend объекту.
Настройка SIP пира для регистрации внутренних абонентов
Как уже отмечалось Asterisk не делает особых различий между транками и абонентами, поэтому конфиг телефона будет похож на SIP транк, но все же немного другой.
Рассмотрим некоторые опции:
‘call-limit’ опция признана устаревшей и заменена на ‘callcounter’. Установить ограничение одновременных вызовов теперь можно переменной канала function ‘GROUP_COUNT’
пример использования данного метода можно помотреть здесь: Ограничение количества одновременных вызовов по набранному номеру.
Настройка нескольких SIP пиров по шаблону
А затем определить уникальные свойства пиров, добавив рядом с именем каждого пира, имя общего шаблона в круглых скобках:
Asterisk sip.conf General SIP Options
Полный список параметров general sip.conf
Следующие параметры используются в общей [general] секции sip.conf:
allowexternalinvites
Если установлено ‘no’, запрещает INVITE и REFER от внешних (не из localnet) доменов. См domain
allowguest
Если ‘no’, запрещает гостевые(без аутентификации) подключения. По умолчанию sipguest подключения разрешены.
allowoverlap
Вкл. или Выкл набор по одной цифре (т.е. каждая набранная цифра будет сразу отправляться в канал)
allowsubscribe
allowtransfers
Когда установлено ‘no’, запрещает любые трансферы, если не переопределено в настройках пира.
alwaysauthreject
autodomain
Установите эту опцию ‘yes’, чтобы добавить локальное HOSTNAME и локальный IP адрес в список доменов:
bindaddr and bindport
Эти параметры определяют IP адрес и порт на которых Asterisk будет слушать SIP запросы. Для драйвера канала SIP Asterisk ‘chan_sip’ можно назначить только один адрес и порт для всех подключений для UDP и один порт для TCP транспорта, в отличии от нового драйвера PJSIP. По умолчанию адрес не задан и лучше так и оставить. Некоторые рекомендуют изменять порт по умолчанию 5060, на другой, в целях безопасности. Но помните, что это только одна из мер безопасности, не самая важная, и не гарантирует вам полной защиты от злоумышленников.
Вы можете задать независимые для UDP, TCP и TLS транспорта значения udpbindadd, tcpbindaddr и tlsbindaddr
buggymwi
Вкл. эту опцию, чтобы избежать ошибок при сообщении с некоторыми ip телефонами при отправке MWI сообщений.
callevents
Установите ‘yes’, если хотите генерировать информацию о SIP событиях для AMI (asterisk manager interface)
checkmwi
Время в секундах, между проверками голосовой почты :
compactheaders
Использовать или нет компактные SIP заголовки.
defaultexpiry
Срок действия регистрации в секундах для входящих и исходящих регистраций. При входящей регистрации, этот параметр задается клиентской стороной, и заданное здесь значение используется, только если клиент не сообщил свое занчение. Для исходящих регистраций этот параметр сообщается удаленной стороне UAS (user agent server)
directrtpsetup
domain
Задает имя домена сервера Asterisk по умолчанию. Командой CLI ‘sip show domains’ выводится список локальных доменов.
dumphistory
externhost
externip
externrefresh
g726nonstandard
Значения: yes/no, по умолчанию: no. Если клиент собирается для сеанса связи «договориться» использовать звуковой кодек G726-32, с использованием компрессии AAL2, вместо RFC3551 (что требуется для аппаратов фирмы Sipura и шлюзов от Grandstream, и может другим). То это противоречит спецификации RFC3551, клиент должен вместо этого «договориться» использовать AAL2-G726-32
ignoreregexpire (global)
Если ignoreregexpire установлен ‘yes’, Asterisk сделает одно из двух, в зависимости от настроек пиров: 1)Non-realtime peer Когда регистрация истекает, информация не удаляется из памяти или БД Asterisk и вызовы будут разрешены несмотря на то, что время регистрации истекло.
2)Realtime peers Когда peer сконфигурирован в режиме реального времени, информация о регистрации используется независимо от defaultexpiry
jbenable
jbforce
Принудительное использование jitter buffer принимающей стороной SIP канала.
jbimpl
Использовать фиксированный или подстраиваемый (адаптивный) jitter buffer. fixed jitter buffer всегда использует значение из jbmaxsize adaptive может принимать значение больше jbmaxsize По умолчанию ‘fixed’:
Из личного опыта, вкл. ‘adaptive’ может приводить к весьма плачевным результатам.
jblog
Вкл./выкл jitter buffer frame лог. По умолчанию ‘no’:
jbmaxsize
Установите максимальную длину буфера в миллисекундах:
jbresyncthreshold
Джиттер буфер порог синхронизации. По умолчанию 1000:
icesupport
limitonpeers
Применять call-limit только для type=peer Это улучшит использование call-limit для устройств настроенных, как type=friend, отделив ограничение call-limit от входящих вызовов.
localnet
укажет серверу Asterisk какие подсети являются локальными, прозрачными для использования IP адресов сервера, SIP запросы к которым не требуют модификации поля Contact: c использованием externip или externhost
matchexterniplocally
Сверять ‘externip’ с ‘localnet’ и производить подстановку, только если ‘externip’ из локальной подсети. Не совсем ясно, зачем это может понадобиться? Возможно при очень нестандартной топологии сети.
maxexpiry
Максимальная продолжительность регистрации в секундах.
minexpiry
Минимальная продолжительность регистрации в секундах.
notifymimetype
Указывает MIME тип используемый для message-waiting indication (MWI) в SIP NOTIFY сообщении.
notifyringing
Сообщать подписчикам о состоянии вызов (RINGING):
notifyhold
Сообщать подписчикам (subscribers) о состоянии удержание (HOLD):
pedantic
realm
recordhistory
Вкл. или Выкл историю sip для всех каналов.
registerattempts
Сколько попыток внешних регистраций произведет Asterisk, прежде чем откажется от продолжения. По умолчанию стоит ‘0’, что значит бесконечно.
registertimeout
Таймаут между попытками регистрации на другом устройстве.
relaxdtmf
rtautoclear
(global) Конфигурация Realtime Peers Указывает должен ли Asterisk обнулять созданные на лету friends по истечении времени регистрации. Если установлено ‘yes’, по истечении срока регистрации, удалять friends до нового запроса. Если задано число, то оно используется вместо обычного времени регистрации.
rtcachefriends
Если rtcachefriends включен, Asterisk будет кэшировать friends(реалтайм пиры), которые приходят из realtime engine, так же, как если бы они сконфигурированы в «sip.conf».
rtsavesysname
(global) Определяет, должен ли Asterisk сохранить SystemName в базе данных в режиме реального времени во время регистрации:
rtupdate
(global) Если установлено ‘yes’ Asterisk будет обновлять IP-адрес, порт и период регистрации пиров при регистрации. По умолчанию ‘yes’:
sipdebug
sendrpid
ОТправлять или нет Remote-Party-ID header:
srvlookup
transport
Задает транспорт по умолчанию. По умолчанию ‘udp’, но может быть ‘tcp’, ‘tls’, ‘ws’ или ‘wss’. Если задано TCP а tcpenable=no будет использован UDP транспорт.
tcpenable
Включить поддержку TCP транспорта chan_sip Asterisk.
tcpbindaddr
Адрес на котором Asterisk «слушает» TCP подключения.
tcpauthtimeout
tcpauthtimeout указывает максимальное время в секундах данное клиенту на аутентификацию. Если за заданное время клиент не прошел проверку он отключается. (По умолчаннию 30 секунд)
tcpauthlimit
Максимальное кол-во неаутентифицированных сессий в момент любой времени.
t1min
Минимальная задержка туда-обратно (minimum round-trip) для сообщения контролируемого хоста. По умолчанию 100 миллисеунд:
subscribecontext
Ограничить запросы SUBSCRIBE только указанным контекстом, если не переопределено в настройках пира.
t38pt_udptl
tos_sip, tos_audio, andtos_video
trustrpid
Доверять или нет Remote-Party-ID header: Asterisk SIP trustrpid
useragent
Если вы не желаете сообщать, что используете Asterisk, напишите Cisco или Avaya, или abyrvalg v2.0.
usereqphone
usereqphone опция говорит Asterisk добавить «user=phone» в SIP URIs которые содержат действующий номер телефона:
Взаимодействие клиентов SIP. Часть 2
В предыдущей статье мы рассмотрели простое взаимодействие клиентов SIP без использования Proxy-сервера. Такое взаимодействие на практике встречается чрезвычайно редко, но отлично подходит для того, чтобы понять основы SIP.
Выбор транспортного протокола и поиск Proxy
Поскольку протокол SIP поддерживает несколько транспортных протоколов (UDP, TCP, SCTP, TLS), необходимо каким-то образом определять, какой протокол использовать. Для этого существет несколько способов.
Первый способ предполагает явное указание транспорта в SIP URI (кроме TLS). Выглядит это вот так:
Итак, мы выяснили, параметры Proxy-сервера Ивана. Теперь предлагаю рассмотреть использование Proxy в рамках SIP-диалога.
Ремарка для тех, кто не знает, что такое NAPTR. Я узнал, что есть такой тип DNS-записи только, когда писал эту статью, так что не отчаивайтесь. Чуть подробнее про NAPTR здесь.
Взаимодействие с использованием Proxy
Для чего же нам необходим SIP Proxy? Как я уже сказал, в примере из 1-ой части статьи клиенты знали IP-адреса друг друга и могли общаться напрямую. В реальной жизни клиенты чаще всего получают адреса динамически, поэтому нет смысла «запоминать» тот или иной IP. Первое, что приходит на ум в данной ситуации – использовать A-записи DNS и определить реальный действующий адрес. Однако тут кроется следующая проблема: IP-адрес идентифицирует конкретное устройство, а не пользователя на нем. Особенностью взаимодействия SIP является то, что обмен сообщения происходит не на уровне устройство-устройство, а на пользователь-пользователь. При этом один пользователь может одновременно использовать несколько SIP-клиентов: на мобильном телефоне, на рабочем компьютере, на домашнем компьютере и на SIP-телефоне. Как же быть?
Протокол SIP предлагает следующее решение: создается SIP Proxy и каждый пользователь регистрирует свои устройства на этом Proxy (точнее пользователи регистрируются на сервере регистрации, а Proxy имеет доступ к базе регистрации, но для простоты будем считать, что это один и тот же сервер). Как это делается, я покажу ниже. Пока просто запомните, что Proxy знает, как именно найти тот или иной клиент пользователя.
Для тех, кто изучил первую часть статьи, все выглядит довольно знакомо; добавился только промежуточный Proxy-сервер. Соответственно и обмен сообщениями изменился незначительно.
Прежде, чем преступим к детальному рассмотрению, маленькая ремарка. В рамках SIP разделяют два типа URI. Первый из них – ползовательский URI, также известный как address of recorf (AOR). Запрос, отправленный на этот адрес предполагает поиск в базе данных Proxy и отправку запроса одному или несольким устройствам. Второй – URI устройства (а точнее – пользователя на устроястве). URI устройства обычно называется контакт и содержится, соответственно, в поле Contact SIP-сообщения. AOR содердится в полях From и To.
Начало разговора
Итак, Петр посылает INVITE для Ивана на Proxy-сервер:
Proxy-сервер перенаправляет запрос всем SIP-клиентам Ивана. Для простоты предположим, что Иван использует только одно устройство. Чтобы SIP-клиент понимал, что запрос был перенаправлен через Proxy, сервер добавляет свое заголовочное поле via:
SIP-клиент Ивана шлет ответ 180 Ringing (Иван слышит звонок). При этом он добавляет tag в поле To и указывает свой контакт в поле Contact. Кроме того, в первом поле via добавился параметр received этот параметр показывает, с какого адреса клиент Ивана получил запрос (т.е. адрес Proxy-сервера, как его видит Иван). Это бывает полезно знать для решения возникающих проблем:
Proxy, соответственно, перенаправляет запрос клиенту Петра. При этом он убирает свой via:
После отправки 180 Ringing, как только Иван снимет трубку, клиент Ивана отправляет на Prxoy ответ 200 OK:
Proxy передает этот ответ Петру, убирая при этом via:
Теперь самое интересное. Клиент Петра отправляет сообщение АСК непосредственно клиенту Ивана в обход Proxy. Причем, если бы Иван одновременно использовал несколько клиентов SIP, ответ пришел именно на тот, который нужно. Благодаря чему это возможно?
200 ОК отправляется с клиента на котором Иван снял трубку. Более того, в поле Contact ответа 200 ОК содержится URI, соответствующий пользователю Иван на конкретном устройстве. Таким образом клиент Петра отправляет АСК именно на это устройство, после чего участие Proxy больше не требуется:
Все остальные сообщения, включая медиа-траффик идут в обход Proxy.
Конец разговора
В конце разговора клиент Ивана отправляет BYE напрямую клиенту Петра:
Петр в ответ шлет подтверждение:
Здесь все, как в первой части статьи.
Итак, мы рассмотрели взаимодействие SIP-клиентов с участием Proxу-сервера. Остался один единственный вопрос: откуда Proxy узнал адреса клиентов Ивана? С помощью процедуры регистрации. Как это происходит, я расскажу ниже.
SIP-регистрация
Регистрация выглядит следующим образом:
Давайте подробнее рассмотрим каждое из сообщений. Иван отправляет на сервер запрос Register (для простоты считаем, что роль сервера регистрации установлена на proxy.domain.ru). Самое важное в этом запросе – поле Contact. Это адрес Ивана на конкретном устройстве:
В ответ сервер присылает 401 Unauthorized, то есть требование авторизации. Самое важное поле в ответе — WWW-Authenticate. Не сложно догадаться, что realm — это домен, а algorithm указывает, какой хеш-алгоритм мы будем использовать. Интерес вызывает поле nonce:
Nonce — это сокращение от «number used once». Nonce — это одноразовая случайная последовательность, которую клиент Ивана cкомбинирует со строкой пароля, после чего сгенерирует MD5-хеш от полученной строки и поместит результат в новый запрос в поле WWW-Authenticate (на самом деле все несколько сложнее, но для простоты будем считать, что все именно так). Для этого служит параметр response.
Зачем нужен nonce? Если бы клиент генерировал MD5 от пароля и не использовал nonce, то хеш каждый раз получался бы один и тот же. Злоумешленник мог бы перехватить такой хеш и использовать для авторизации. Это было бы столь же небезопасно, как передавать пароль в открытом виде.
Если использовать nonce, MD5 каждый раз берется от новой строки и получается разным. Поэтому даже перехватив хеш, злоумышленник скорее всего не сможет его использовать для авторизации.
Кстати, обратите внимание, что новый запрос на регистрацию имеет CSeq на единицу больше:
Сервер также комбинирует nonce с паролем Ивана и получает MD5-хеш. После этого он сравнивает свой хеш с хешем, полученным от Ивана. Если они совпадают, то сервер присылает 200 ОК. Обратите внимание на то, что в поле Contact добавился параметр expires. В данном случае регистрация будет храниться в базе сервера в течение 3600 секунд или одного часа:
Если Иван хочет продлить регистрацию, то он должен отправить еще один REGISTER в течение этого часа.
Что делать, если Иван использует сразу несколько устройств с поддержкой SIP? Все очень просто – необходимо отправить запрос на регистрацию с каждого из них.
После того, как в базе данного сервера регистрации появится соответствующая запись, Proxy-сервер сможет перенаправлять запросы на SIP-клиенты Ивана.
Bonus для тех, кому интересно
Вы могли заметить, что, в ответ на запрос регистрации, сервер присылает ответ, содержащий To-tag:
Понятно, что при установке диалога данный tag помогает избежать повторного получения одного и того же сообщения. Для этого существует правило: если сообщение не содержит To-tag и UAS уже получал сообщение с таким же CSeq, From-tag и Call-ID, то сообщение отбрасывается. Для чего же нужен To-tag, если мы не устанавливаем диалог с сервером регистрации. Лучший ответ, который я смог найти — в RFC 3261 написано, что ответ 200 ОК, приходящий на запрос без To-tag должен содержать To-tag. То есть, это ни для чего не нужно, но так принято.
Надеюсь, что работа протокола SIP, после прочтения статьи, стала для вас более понятной. Буду рад вашим комментариям.