= Функция маршрутизации SIP в плате VE-01 = == Описание функции == Плата VE-01 содержит в себе шлюз, позволяющий работать с различными типами канальных окончаний. Среди них есть канальные окончания (например R2, 1IND, FXS, PRI), которые могут принимать со стороны канала TDM вызовы, адресованные множеству разных абонентов - номер вызываемого абонента передается в соответствии с используемым протоколом сигнализации. Вызов, полученный от канала TDM, превращается шлюзом в сообщение INVITE и направляется хосту, на котором зарегистрировано канальное окончание (предполагается, что это телефонный коммутатор). Рассмотрим пример такой схемы: [[Image(dia1.png)]] В этой схеме канальное окончание PRI платы VE-01 регистрируется на АТС 10.0.0.1 как шлюз и все вызовы, поступающие по линии ISDN PRI, направляются в эту АТС. Но что делать, если требуется, например, вызовы абонентов, номера которых начинаются с цифры 1, направлять в одну АТС, вызовы абонентов, номера которых начинаются с цифры 9 - в другую АТС, а все остальные вызовы - в третью? В этом случае поможет функция маршрутизации SIP. Прокси-сервер платы VE-01 имеет таблицу маршрутов SIP. Каждый маршрут состоит из двух основных частей - регулярного выражения, на совпадение с которым проверяется цель (target URI) запроса SIP, и строки, которой заменяется цель в случае совпадения. В маршрутах SIP используются [https://www.pcre.org/ Perl Compatible Regular Expressions] (начиная с прошивки платы ревизии 41, в прошивках до ревизии 41 использовались регулярные выражения POSIX). Благодаря этому механизму можно организовать желаемую схему подключения: [[Image(dia2.png)]] В этой схеме канальное окончание PRI регистрируется на АТС3 с адресом 10.0.0.3, которая является получателем вызовов по умолчанию. Для вызовов абонентов, номера которых начинаются с цифры 1, создается маршрут, заменяющий в цели адрес 10.0.0.3 на адрес 10.0.0.1. Для номеров, начинающихся с цифры 9, создается аналогичный маршрут, заменяющий адрес на 10.0.0.2. == Конфигурация == Поддержка загрузки таблицы маршрутизации SIP в плату VE-01 появилась начиная с прошивки версии 31. В веб-интерфейсе конфигурации платы VE-01 имеется вкладка "Маршруты SIP": [[Image(ss1.jpg)]] На этой вкладке отображается таблица маршрутов, содержащая регулярное выражение target URI, замену target URI и комментарий. Для случаев, когда требуется определенный порядок проверки маршрутов, у каждого маршрута имеется поле "Порядок", значение которого определяет приоритет маршрута: проверки выполняется в порядке возрастания значения. Также каждый маршрут имеет необязательные поля "Регулярное выражение from URI" и "Комментарий". Для добавления маршрутов в таблицу служит кнопка "Добавить маршрут" над таблицей. Также для каждого маршрута в таблице имеются кнопки "Редактировать маршрут" и "Удалить маршрут", расположенные в столбце "Действия" справа. В данном примере в таблице маршрутизации установлено два маршрута. Первый маршрут имеет регулярное выражение `^sip:(1.*)@10.0.0.3`, которому удовлетворяют SIP URI, имя пользователя которых начинается с цифры 1, а имя хоста - "10.0.0.3". Имя пользователя в этом выражении заключено в круглые скобки для того чтобы подставить его в новый URI в процессе замены. В качестве замены в этом маршруте указана строка `sip:$1@10.0.0.1`. Вместо имени пользователя в этом URI стоит комбинация "$1", предписывающая подставить вместо нее подстроку, соответствующую фрагменту регулярного выражения, заключенного в круглые скобки. Рассмотрим пример. Канальным окончанием PRI принят вызов номера 143. Шлюз формирует сообщение INVITE с URI "sip:143@10.0.0.3". Прокси сервер платы VE-01, получив это сообщение, последовательно проверяет URI "sip:143@10.0.0.3" на совпадение с регулярными выражениями маршрутов из таблицы маршрутизации. При проверке регулярного выражения `^sip:(1.*)@10.0.0.3` будет обнаружено совпадение. Прокси сервер заменит исходный URI в сообщении INVITE на URI из найденного маршрута, подставив на место "$1" исходное имя пользователя. На этом поиск в таблице маршрутизации будет закончен, и сообщение INVITE будет направлено на URI "sip:143@10.0.0.1". //Обратите внимание, что в конце приведенных выше регулярных выражений нет символа "доллар" ($), означающего конец строки. Это вызвано тем, что вызываемый URI не всегда заканчивается доменом, после домена могут следовать другие элементы, например порт и/или параметры.// Аналогичным образом таблицу маршрутов можно использовать для модификации имени пользователя. Например, для удаления префикса "9" можно создать маршрут с регулярным выражением `^sip:9` и заменой URI `sip:`. == Продвинутое использование маршрутизации == Рассмотренные выше примеры использования маршрутов SIP тривиальны и приведены для простоты понимания функционирования механизма маршрутизации. При этом именно подобные простые примеры наиболее часто встречаются в реальной жизни. Однако возможности использования маршрутов SIP не ограничиваются подобными простыми случаями. Далее рассматривается несколько более продвинутых примеров использования маршрутизации. === Маршрутизация самому себе === Вернемся к рассмотренному ранее случаю подключения к трем IP АТС, но предположим, что в блоке MC04-DSL-3U также имеются и собственные абоненты - несколько телефонных аппаратов, подключенных к шлюзу через канальные окончания FXS. Пусть их номера состоят из трех цифр и начинаются с цифры 2: [[Image(dia3.png)]] Для того чтобы номера вида 2XX обслуживались блоком локально, достаточно создать маршрут, направляющий вызов обратно в шлюз. Для этого в поле "Замена URI" маршрута в качестве домена можно указать собственный IP адрес платы VE-01, в данном примере "10.0.0.10". Также можно использовать loopback-адрес 127.0.0.1. Таким образом, для решения данной задачи добавим маршрут с регулярным выражением `^sip:(2..)@10.0.0.3` и заменой URI `sip:$1@127.0.0.1`: [[Image(ss2.jpg)]] === Альтернативные маршруты === До сих пор в рассматриваемых нами примерах предполагалось, что вызываемый URI либо совпадает с регулярным выражением одного из маршрутов, либо не совпадает ни с одним из них. Сейчас же мы рассмотрим случай, когда вызываемый URI совпадает с регулярными выражениями нескольких маршрутов. Рассмотрим новый пример. Предположим, что в бухгалтерии предприятия работают главный бухгалтер, имеющий телефон с номером 102, и его заместитель, имеющий телефон с номером 105. Предположим также, что в конфигурации платы VE-01 созданы следующие маршруты: [[Image(ss3.jpg)]] Как нетрудно заметить, с регулярным выражением обоих маршрутов совпадает один и тот же URI - `sip:111@192.168.1.67`. Изображенная на рисунке конфигурация маршрутов работает следующим образом. При получении вызова URI `sip:111@192.168.1.67` прокси-сервер ищет в таблице маршрутов записи, с регулярными выражениями которых совпадает вызываемый URI. Так как вызываемый URI совпадает с регулярными выражениями обоих маршрутов, прокси-сервер последовательно выполняет вызовы найденных маршрутов, пока вызов не окажется успешным (пока вызываемый абонент не ответит на вызов, и прокси-сервер получит "200 OK") или пока не кончатся найденные маршруты. В данном примере сначала будет сформирован вызов URI `sip:102@127.0.0.1`, который поступит на телефон главного бухгалтера. Если он ответит на вызов, состоится разговор, и обработка вызова на этом завершится. Если же главбух отклонит вызов (например уже занят другим разговором, или включил режим "не беспокоить"), прокси-сервер, получив ответ "486 Busy here", перейдет к следующему маршруту и сформирует вызов URI `sip:105@127.0.0.1`, который поступит на телефон зама. Обратите внимание, что сконфигурированные маршруты имеют разное значение параметра "Порядок", в результате чего вызов поступает сначала на номер 102, а потом - на номер 105. Если в первом маршруте изменить значение параметра "Порядок" с 0 на 2, порядок выполнения вызовов изменится на обратный. === Параллельный вызов === Описанное в предыдущем примере поведение прокси-сервера может быть изменено отметкой чекбокса "Параллельный вызов маршрутов", расположенного на вкладке "Маршруты SIP" диалога конфигурации платы VE-01. При его отметке найденные в таблице маршруты обрабатываются не последовательно, а параллельно (одновременно). Так, при получении вызова URI `sip:111@192.168.1.67` прокси сервер направит INVITE и на URI `sip:102@127.0.0.1`, и на URI `sip:105@127.0.0.1`, в результате чего телефоны главбуха и его зама будут звенеть одновременно. Разговор состоится при снятии трубки любого из телефонов, при этом другой аппарат звенеть перестанет. Данная конфигурация маршрутов работает подобно функции "Группы вызова". === Два режима поиска цели === Существует два режима поиска цели вызова, различающиеся поведением в случае, когда маршруты были найдены (было совпадение хотя бы с одним маршрутом), но вызовы целевых URI завершились неудачей (типичный пример неудачного вызова - вызываемый абонент занят, и прокси-сервер получил ответ "486 Busy here"). Эти режимы конфигурируются чекбоксом "Прекратить поиск после нахождения маршрутов", расположенным на вкладке "Маршруты SIP" диалога конфигурации платы VE-01. По умолчанию чекбокс не отмечен, и в случае неудачного вызова прокси-сервер продолжает обработку исходного вызова, как если бы никаких совпадений в таблице маршрутов не было найдено. Рассмотрим пример маршрутов, приведенных на следующем рисунке: [[Image(ss5.jpg)]] В данном примере при вызове номера 111 прокси-сервер последовательно направляет вызов номерам 901, 902 (если вызов номера 901 был неудачным) и 903 (если вызовы номеров 901 и 902 были неудачными). В случае, если вызовы всех трех номеров была неудачными, прокси-сервер продолжает обработку вызова номера 111, как если бы никаких маршрутов не было - при наличии при наличии пользователя SIP с номером 111 вызов будет передан ему, а при отсутствии такого пользователя вызов номера 111 будет передан шлюзу. При установленной отметке чекбокса "Прекратить поиск после нахождения маршрутов" описанное выше поведение прокси-сервера меняется. При вызове номера 111 прокси-сервер последовательно направляет вызов номерам 901, 902 (если вызов номера 901 был неудачным) и 903 (если вызовы номеров 901 и 902 были неудачными), и на этом обработка вызова прекращается. SIP-пользователи и шлюз не получат вызов даже если вызовы всех трех номеров (901, 902 и 903) завершились неудачно. Если по условию задачи требуется, чтобы вызов все-таки передавался шлюзу, необходимо добавить еще один маршрут, который явно выполняет такое перенаправление. Постарайтесь при этом не допустить создания "закольцованных" маршрутов (когда SIP сообщение снова и снова совпадает с одним и тем же маршрутом). Пример такого решения приведен на следующем рисунке: [[Image(ss6.jpg)]] === Маршрутизация с учетом вызывающего === Как правило, при маршрутизации вызовов имеет значение только номер вызываемого абонента, вызывающий же абонент на выбор маршрута никакого влияния не оказывает. Однако в некоторых случаях может оказаться полезным учитывать при маршрутизации также и вызывающего абонента. Для подобных случаев маршруты SIP имеют необязательное поле "Регулярное выражение from URI". Если задать в этом поле непустую строку, маршрут будет действовать только при одновременном совпадении URI поля From принятого запроса SIP с регулярным выражением "Регулярное выражение from URI" и совпадении вызываемого URI с регулярным выражением "Регулярное выражение target URI". Если же в поле "Регулярное выражение from URI" содержится пустая строка, поверка URI поля From не производится, и маршрут действует для любого URI вызывающего абонента, как это было в примерах, рассмотренных выше. Рассмотрим еще один пример. Предположим, что в организации есть два отдела - отдел X и отдел Y. Номера телефонов сотрудников отдела X начинаются с цифры 5, номера телефонов сотрудников отдела Y начинаются с цифры 7. Также предположим, что имеется две телефонные линии (и два канальных окончания FXO), обслуживающие исходящие телефонные вызовы. Требуется, чтобы сотрудники отдела X совершали исходящие вызовы только через первую линию, а сотрудники отдела Y - только через вторую. Для решения данной задачи создадим два маршрута, которые будут добавлять к номерам, вызываемым сотрудниками отдела X, префикс "X-", а к номерам, вызываемым сотрудниками отдела Y - префикс "Y-". Пример таких маршрутов показан на рисунке: [[Image(ss4.jpg)]] В поле "Регулярное выражение from URI" первого из маршрутов содержится регулярное выражение `^sip:5`, благодаря чему маршрут действует только для исходящих вызовов от сотрудников отдела X, номера которых начинаются с цифры 5. Второй маршрут в том же поле содержит регулярное выражение `^sip:7` и, таким образом, действует только для вызовов от сотрудников отдела Y. Регулярное выражение target URI первого маршрута совпадает с любыми SIP URI, не имеющими префикса "X-" (имя пользователя в которых не начинается с комбинации символов "X-"). Выражения же замены target URI добавляет префикс "X-" сразу после "sip:". Аналогично, второй маршрут добавляет префикс "Y-" всем target URI, не начинающимся с этого префикса. В завершении остается только настроить канальные окончания FXO так, чтобы они принимали только вызовы со "своим" префиксом. Для этого в поле "Рег. выражение вызова" канального окончания, обслуживающего линию отдела X, запишем регулярное выражение `^X-`, а в это же поле канального окончания, обслуживающего линию отдела Y, запишем регулярное выражение `^Y-`. Так как канальные окончания FXO игнорируют нецифровые символы в номере вызываемого абонента, префиксы "X-" и "Y-" не нарушат процесс передачи номера в телефонную линию.