Маршрутизация

Оглавление

Общее

Маршрутизация — это процесс принятия решения о том, что делать с поступившим вызовом. Каждый вызов приходит в платформу в виде SIP-запроса INVITE, который содержит информацию об источнике (From), назначении (To) и других параметрах. На основе этих данных платформа определяет дальнейшие действия.

Главный вопрос, на который отвечает маршрутизация: куда направить вызов? Ответ может быть разным: внутренний абонент, внешняя сеть через провайдера, сервисная функция, другой домен. При этом направлений может быть несколько — вызов способен разветвляться на форки, обслуживая одновременно несколько устройств, параллельные номера или группы.

В процессе маршрутизации дополнительно решается вопрос представления вызывающего абонента для вызываемого: какой номер и отображаемое имя увидит получатель вызова.

Результатом маршрутизации может быть не только отправка INVITE вызываемому абоненту, но и отказ в обслуживании вызова.

На ход маршрутизации влияют настроенные переадресации. Перехват вызова также использует механизмы маршрутизации, но инициируется отдельным действием.

Маршрутизация применяется ко всем типам вызовов без исключения: внутренним, внешним, кросс-доменным, сервисным, а также к вызовам, инициированным системой — от IVR, конференций и других сервисных компонентов.

Конвейер маршрутизации способен покинуть пределы исходного домена и продолжить поиск решения в других доменах. При переадресациях и действии next маршрутизация запускается повторно с изменёнными параметрами. При форках любого типа (группы, параллельные вызовы, множественные регистрации) маршрутизация разветвляется и продолжается независимо для каждого направления.

В этой платформе маршрутизация представляет собой полноценный конвейер, в котором участвуют несколько микросервисов, множество сущностей и фильтров. Понимание этого конвейера — основа для настройки маршрутизации любой сложности.

Глава 2. Архитектура маршрутизации: кто за что отвечает

Процесс маршрутизации распределён между несколькими микросервисами. Каждый из них выполняет свою часть работы на разных этапах обработки вызова.

Роли микросервисов

Микросервис Описание

esg

Внешний шлюз. Обрабатывает вызовы, поступающие из внешних сетей (провайдеры, PSTN). Выполняет пограничную фильтрацию (borderrule), привязку к учётной записи провайдера, контроль лимитов, а также нормализацию номеров — преобразование внешнего номерного плана во внутренний и обратно.

sg

Внутренний шлюз. Принимает вызовы от внутренних устройства, прошедших авторизацию. Выполняет пограничную фильтрацию, подстановку адресов и доменов для устройств, которые не используют доменные имена в SIP-URI.

sr

Регистрар. Хранит контакты устройств, зарегистрированных под учётными записями внутренних абонентов. Вызов на внутреннего абонента возможен только в том случае, если его устройство зарегистрировано, и информация о контакте присутствует в регистраре.

sts

Хранилище SUBSCRIBE-подписок и BLF-состояний. Подписки также проходят маршрутизацию, но со значительными ограничениями. При совершении звонков подписчикам отправляются уведомления об изменениях состояний и составе диалогов.

b2b

Основной маршрутизатор. Именно здесь принимается решение о направлении вызова. Выполняет поиск векторов и правил маршрутизации, применяет модификации, проверяет групповые политики доступа, обрабатывает переадресации и формирует форки.

ivr

Сервис интерактивного голосового взаимодействия. Обслуживает вызовы, направленные на IVR-сценарии. Может инициировать вызовы по запросу через CTI, API колл-менеджера, из сценариев. IVR способен подставлять в качестве инициатора любые номера и имена, и все такие вызовы проходят маршрутизацию на общих основаниях.

conf

Сервис конференций. Обрабатывает вызовы, направленные на конференц-комнаты, управляет участниками и микшированием аудио.

prompt

Сервис подключений к разговорам. Обеспечивает функции прослушивания, суфлирования и подключения к существующим диалогам.

dc

Хранилище статических коллекций домена. Содержит основные настройки доменов и телефонии, включая векторы маршрутизации, правила, представления, переадресации и другие сущности, определяющие поведение маршрутизации.

Номерные планы

В системе существует внутренний номерной план — номера, по которым маршрутизация выполняется внутри платформы. Это номера пользователей, групп, сервисных функций. Все настройки маршрутизации производятся именно во внутреннем номерном плане.

Однако вызовы могут поступать из внешних сетей или направляться в них. Внешний номерной план — это понятие, которое администратор должен держать в уме при настройке. Например, подключенный провайдер PSTN может адресовать 10-значные номера с кодом региона, а внешняя АТС — использовать 6-значную адресацию.

Задача администратора — настроить переход из внутреннего номерного плана во внешний и обратно таким образом, чтобы на вход в следующий этап обработки попадали ожидаемые значения номеров. Для этого на esg применяются правила нормализации, преобразующие номера между планами.

Поток вызова

Внешний вызов проходит через esg, где выполняется пограничная фильтрация, привязка к провайдеру и нормализация номера во внутренний план. Внутренний вызов от устройства поступает на sg, где происходит авторизация и подготовка вызова. Вызов от системного сервиса (ivr, conf, prompt) поступает на b2b с полным контекстом инициатора. Каждый из этих потоков в итоге направляется в b2b.

На b2b выполняется маршрутизация: поиск подходящего вектора и правила, применение модификаторов, проверка прав. По результату маршрутизации вызов либо направляется на исполнение, либо отклоняется.

При внутреннем направлении вызов возвращается на sg и далее на устройство вызываемого абонента (при условии наличия контакта в регистраре). При внешнем направлении вызов направляется на esg, где выполняется обратная нормализация номера во внешний план, после чего отправляется провайдеру.

При кросс-доменном направлении процесс маршрутизации продолжается в целевом домене. После того как в целевом домене обнаружен абонент назначения, применяется представление инициатора для этого вызываемого абонента.

При направлении на сервис вызов передаётся соответствующему микросервису (ivr, conf, prompt) для обработки.

Сущности маршрутизации

Настройка маршрутизации оперирует следующими классами сущностей:

Сущность Описание

sipuser

Учётные записи внутренних абонентов. Определяют внутренние номера пользователей, номера параллельного вызова, ограничения на номера для переадресаций и другие опции вызова.

route

Векторы маршрутизации. Группируют правила по смыслу, задают общие фильтры и расписания.

vectorrule

Правила маршрутизации. Определяют генеральное направление вызова: внутреннее, внешнее, кросс-доменное, сервисное, повтор с модификацией или отказ.

featurecode

Коды абонентских функций. Определяют сервисные номера и их поведение (IVR, конференции, голосовая почта, перехват, парковка и другие).

featurerule

Правила разрешения функций. Ограничивают доступ к сервисным функциям, определённым в featurecode.

representative

Правила представления. Определяют, какой номер и имя будет видеть вызываемый абонент при кросс-доменных вызовах. Также могут дополнять правила нормализации при внешних вызовах. Не применяются при звонках на внутренних абонентов домена.

provider_callerid

Правила нормализации. Преобразуют номера между внешним и внутренним номерными планами на esg.

redirectrule

Правила переадресации. Настраивают серверную переадресацию для конкретных абонентов по различным условиям. Не следует путать с переадресацией, настроенной на самом устройстве пользователя: такие переадресации обрабатываются сервером после получения SIP-ответа 301 или 302.

sipgroup

Групповые номера. Объединяют несколько учётных записей в один номер с различными режимами вызова.

sipkit

Функциональные группы. Добавляют модифицирующую логику к вызовам на существующие учётные записи.

hunt

Хант-группы. Организуют очереди уровня АТС с распределением по ресурсам. В отличие от очередей колл-центра, по ним не отслеживается статистика.

CosProfile, CorProfile, CorPolicy, TollList, TollLink

Групповые политики. Управляют доступом к направлениям и функциям на уровне групп.

Все эти сущности работают в связке, и их совокупность определяет поведение маршрутизации в домене.

Глава 3. Что происходит с вызовом на каждом этапе

Процесс маршрутизации можно представить как последовательность этапов, через которые проходит вызов. Понимание этой последовательности — основа для осознанной настройки. Каждый этап решает свою задачу, и пропуск или неверная настройка любого из них приводит к тому, что вызов не достигает цели или достигает её в неверном виде.

Этапы описаны в порядке их прохождения. Некоторые из них могут повторяться (например, маршрутизация при действии next или при переадресациях), но общая логика остаётся неизменной.

3.1. Входящий контроль

На этом этапе платформа определяет, кто инициировал вызов, откуда он пришёл, и разрешено ли его обслуживание. Способ контроля зависит от того, с какой стороны поступил вызов.

Внешний вызов (через esg) — вызов, поступивший от провайдера или из PSTN. Последовательность обработки:

  1. borderrule — пограничный фильтр, проверяющий IP-адрес и порт отправителя. Может разрешить вызов, отклонить или игнорировать (drop).

  2. sipmodrule — полнотекстовый модификатор SIP-сообщения, позволяющий модифицировать произвольные поля INVITE до того, как начнётся его разбор.

  3. sip-alg — подстановка адресов: локальные адреса в пакете заменяются на внешние в соответствии с настройками. Выполняется до парсинга запроса и анализа заголовков.

  4. Привязка к учётной записи провайдера — сопоставление параметров входящего INVITE с полями учётных записей с использованием нескольких этапов поиска.

  5. Проверка лимитов — количество активных транков, состояние регистрации (если предусмотрено), результаты пинга.

  6. Нормализация номера — преобразование внешнего номера во внутренний номерной план с помощью правил provider_callerid.

После всех этих преобразований вызов направляется в b2b для маршрутизации.

Внутренний вызов (через sg) — вызов от устройства, зарегистрированного в системе. Такой вызов уже прошёл авторизацию, и платформа знает, какой учётной записи принадлежит устройство. Последовательность обработки:

  1. borderrule — пограничный фильтр (опционально).

  2. sipmodrule — полнотекстовый модификатор SIP-сообщения (опционально).

  3. sip-alg — подстановка адресов, если включена.

  4. Подстановка доменов — для устройств, которые не поддерживают доменные имена в SIP-URI.

После этого вызов направляется в b2b для маршрутизации.

Вызов от системного сервиса (ivr, conf, prompt) — вызов, инициированный самой платформой. Такой вызов поступает в b2b напрямую, минуя внешние шлюзы. Он содержит полный контекст инициатора — номер и имя могут быть заданы произвольно сервисом. Это позволяет, например, организовать обратный звонок от имени абонента или системное уведомление.

3.2. Выбор маршрута

Это центральный этап маршрутизации. На нём b2b принимает решение о том, что делать с вызовом. Процесс состоит из двух шагов: поиск вектора и поиск правила.

Поиск вектора осуществляется по коллекции route. Векторы проверяются в порядке приоритета: чем меньше значение priority, тем раньше проверяется вектор. Для каждого вектора применяются фильтры: номер источника (fromnumber), номер назначения (tonumber), домен источника (fromdomain), код учётной записи провайдера (fromextaccount) и среда инициатора (dir). Если все фильтры проходят, и расписание вектора (schedule) допускает его применение в текущий момент времени, вектор считается подходящим.

Если несколько векторов имеют одинаковый приоритет, порядок их проверки случаен. Это важно учитывать при проектировании: на случайный порядок нельзя полагаться для обеспечения детерминированного поведения.

После того как вектор выбран, начинается поиск правила внутри этого вектора. Правила (vectorrule) проверяются в порядке приоритета внутри вектора. Для каждого правила применяются те же фильтры, что и для вектора, но с дополнительными полями: todomain (домен назначения) и routecode (служебный код). Если правило проходит все фильтры, и расписание правила допускает его применение, и проверка групповых политик (CoS/CoR) не запрещает вызов, правило считается подходящим.

Если правило имеет опцию fallback_next = true, то в случае неудачи при исполнении (например, недоступность esg для внешнего вызова) поиск продолжается со следующего по приоритету правила.

При одинаковых приоритетах правила проверяются в случайном порядке. Это свойство может быть использовано для распределения нагрузки между несколькими маршрутами.

3.3. Модификация вызова

На этом этапе платформа изменяет параметры вызова в соответствии с настройками найденного правила. Модификации применяются к номерам, которые будут использоваться на следующих шагах.

Может быть изменён номер источника (modfromnumber), номер назначения (modtonumber) или служебный код (modroutecode). Для модификации используются однотипные механизмы: посимвольный режим, регулярные выражения, диапазоны и таблицы.

Если действие правила — next, то после применения модификаций маршрутизация запускается повторно с новыми параметрами. Это позволяет организовать многоэтапную обработку, когда один вызов последовательно проходит через несколько правил. Ключевая цель next — обеспечение компактности путём своевременной канонизации параметров (номеров инициатора и вызываемого).

3.4. Проверка прав

Прежде чем исполнить выбранное действие, платформа проверяет, имеет ли инициатор право на данный вызов. Проверка осуществляется на двух уровнях: групповые политики и правила разрешения функций.

Групповые политики (CoS/CoR/TollLists) проверяют доступ к направлениям вызова. CoS (Class of Service) определяет, что разрешено инициатору. CoR (Class of Restriction) определяет, кто может достичь объекта назначения. CosProfile задаёт набор разрешённых направлений и функций для группы. CorPolicy — это матрица, которая определяет, может ли CoS звонить на CoR. TollList и TollLink позволяют гибко связывать направления с группами.

Этот механизм предназначен для крупных инсталляций, где однотипные настройки прав для большого количества абонентов становятся очевидно затратными. Для малых и средних систем он может быть избыточен. По умолчанию всё разрешено, и групповые политики применяются только тогда, когда администратор явно их настраивает.

Проверка выполняется по следующему алгоритму. Определяется CoS инициатора в контексте вызова (для пользователя — из sipuser, для провайдера — из provider, для IVR — пустой CoS, что означает «всё разрешено»). Если в правиле установлен restriction_level, проверяется, что CosProfile имеет не меньший уровень доступа. Если в правиле установлен call_type, проверяется пересечение с разрешёнными направлениями из CosProfile (через call_types или toll_lists). Если вызываемый абонент является пользователем системы и у него задан cor, проверяется матрица CorPolicy на пару src_cos — dst_cor с функцией call.

Правила разрешения функций (featurerule) проверяют доступ к сервисным функциям. Они работают на уровне конкретных пользователей и номеров, проверяя пару from—to и тип функции.

3.5. Исполнение

Найденное правило определяет действие, которое будет выполнено с вызовом. Доступные действия и их особенности:

Действие Описание

internal

Направить вызов на внутреннего абонента. Платформа ищет учётную запись sipuser или групповой номер sipgroup по номеру назначения. Если абонент найден, проверяются его переадресации, формируются форки на зарегистрированные устройства и параллельные номера. Вызов направляется на sg и далее на устройство.

internalpbx

То же, что и internal, но с учётом extension — дополнительного номера, который передаётся вызываемому абоненту. Используется для организации АТС за абонентом.

external

Направить вызов на внешнего провайдера. Платформа проверяет доступность указанной учётной записи провайдера: активен ли esg, не превышены ли лимиты транков, зарегистрирована ли учётная запись (если требуется), отвечает ли на пинги. Если учётная запись недоступна, и в правиле установлен fallback_next, поиск продолжается со следующего правила. Если доступна, вызов направляется на esg с указанием учётной записи.

cross

Направить вызов в другой домен. На вход параметры номера инициатора и вызываемого номера представляют собой результат модификации из предыдущего правила. Процесс маршрутизации продолжается в целевом домене. Представление инициатора для вызываемого абонента будет применено позже, когда целевой абонент будет определён.

featurecode

Выполнить сервисную функцию. Вызов передаётся соответствующему сервису (ivr, conf, prompt) в зависимости от типа featurecode, либо выполняется сервисное действие (например, перехват).

next

Повторить маршрутизацию с модифицированными параметрами. Позволяет организовать цепочки правил. Ключевая цель — обеспечение компактности путём своевременной канонизации параметров.

denied

Отклонить вызов.

3.6. Выходной контроль

После того как вызов подготовлен к отправке, платформа выполняет заключительные преобразования, чтобы исходящий INVITE выглядел корректно для получателя.

При внешнем вызове (через esg) выполняется обратная нормализация: внутренний номерной план преобразуется во внешний с помощью правил provider_callerid.

При кросс-доменном вызове применяются правила представления (representative), которые определяют, какой номер и имя увидит вызываемый абонент в другом домене. Представление применяется для каждого форка независимо, что позволяет одному вызову быть представленным по-разному для разных получателей.

На этом этапе также может быть применена подстановка адресов (sip-alg) и полнотекстовый модификатор SIP-сообщения (sipmodrule).

После всех преобразований исходящий INVITE отправляется следующему звену — устройству, провайдеру или сервису.

Глава 4. Сквозные примеры

Теория маршрутизации становится понятной только тогда, когда она проявляется в реальных вызовах. В этой главе мы последовательно разберём несколько сквозных примеров — от входящего INVITE до исходящего. Каждый пример показывает, как параметры вызова изменяются на каждом этапе, какие сущности и фильтры участвуют, и как маршрутизация превращает исходный запрос в конечный.

Примеры построены от простого к сложному. Рекомендуется изучать их в порядке изложения.

Все примеры используют единое условное обозначение: INVITE показывается в сокращённом виде, с выделением ключевых полей — From, To, Request-URI, а также дополнительных параметров, если они важны для понимания.

Пример 1. Внутренний звонок

Пользователь А с внутренним номером 101 звонит пользователю Б с внутренним номером 102. Оба находятся в одном домене.

Входящий INVITE (от устройства А на sg):

INVITE sip:102@domain.local SIP/2.0
From: <sip:101@domain.local>
To: <sip:102@domain.local>

Этап 1. Входящий контроль (sg).

Вызов поступает на sg от зарегистрированного устройства. Платформа знает, что устройство принадлежит учётной записи 101. После обработки вызов направляется в b2b.

Параметры на входе в b2b: * fromnumber: 101 * tonumber: 102 * fromdomain: domain.local * dir: inner (инициатор — внутренний абонент)

Этап 2. Выбор маршрута (b2b).

Поиск векторов: находится вектор с фильтром dir=inner и tonumber=10*, который подходит под номер 102.

Поиск правил внутри вектора: находится правило с action=internal и фильтрами fromnumber=* и tonumber=* (подходит под любые номера).

Этап 3. Проверка прав.

CoS инициатора — пустой (всё разрешено). Правило не имеет restriction_level и call_type. Групповые политики не применяются.

Этап 4. Исполнение (internal).

Поиск абонента по номеру 102: находится учётная запись sipuser с phonenumber=102. Проверяются переадресации: абсолютных нет, устройство зарегистрировано. Формируется форк на зарегистрированное устройство. Параллельные номера не настроены.

Этап 5. Выходной контроль.

Вызов не является внешним и не кросс-доменным. Представление не применяется (внутренний звонок внутри домена). Нормализация не требуется.

Исходящий INVITE (от b2b на sg, далее на устройство Б):

INVITE sip:102@device-b-ip:5060 SIP/2.0
From: <sip:101@domain.local>
To: <sip:102@domain.local>

Итог: вызов доставлен пользователю Б. Номер инициатора остался 101, номер назначения — 102.


Пример 2. Внешний исходящий звонок

Пользователь А с внутренним номером 101 звонит по внешнему номеру 84951234567. В домене настроен провайдер provider1, который требует, чтобы исходящие вызовы имели федеральный номер в поле From. Внутренний номер 101 должен быть преобразован во внешний номер компании 7654321 с федеральным префиксом 7495.

Входящий INVITE (от устройства А на sg):

INVITE sip:84951234567@domain.local SIP/2.0
From: <sip:101@domain.local>
To: <sip:84951234567@domain.local>

Этап 1. Входящий контроль (sg).

Вызов поступает на sg от зарегистрированного устройства. Платформа знает, что устройство принадлежит учётной записи 101. Вызов направляется в b2b.

Параметры на входе в b2b: * fromnumber: 101 * tonumber: 84951234567 * fromdomain: domain.local * dir: inner

Этап 2. Выбор маршрута (b2b).

Поиск векторов: находится вектор с фильтром tonumber=8495* (внешние номера).

Поиск правил внутри вектора: находится правило с action=external и toextaccount=provider1. Фильтры: fromnumber=, tonumber=8495 (подходит). Правило имеет fallback_next=true.

Этап 3. Проверка прав.

CoS инициатора — пустой. В правиле не заданы restriction_level и call_type. Групповые политики не применяются.

Этап 4. Исполнение (external).

Платформа проверяет доступность учётной записи provider1: esg активен, лимиты транков не превышены, регистрация активна. Вызов направляется на esg с указанием учётной записи provider1.

Параметры на входе в esg: * fromnumber: 101 * tonumber: 84951234567 * provider: provider1

На esg выполняется обратная нормализация с помощью provider_callerid. Правило нормализации преобразует fromnumber 101 → 74957654321 (федеральный номер компании). Параметр to остаётся без изменений.

Этап 5. Выходной контроль (esg).

Применяется sip-alg и sipmodrule (если настроены). В поле domain подставляется домен из учётной записи провайдера.

Исходящий INVITE (от esg к провайдеру):

INVITE sip:84951234567@pstn-provider.net SIP/2.0
From: <sip:74957654321@pstn-provider.net>
To: <sip:84951234567@pstn-provider.net>

Итог: вызов направлен провайдеру. В поле From подставлен федеральный номер компании 74957654321.


Пример 3. Внешний входящий звонок

На платформу поступает звонок от провайдера на федеральный номер компании 74957654321. Внутренняя маршрутизация должна направить его на IVR-сценарий с внутренним номером 555.

Входящий INVITE (от провайдера на esg):

INVITE sip:74957654321@pstn-provider.net SIP/2.0
From: <sip:74950000000@pstn-provider.net>
To: <sip:74957654321@pstn-provider.net>

Этап 1. Входящий контроль (esg).

Вызов поступает на esg. Применяется borderrule (IP разрешён). Выполняется привязка к учётной записи провайдера provider1 (по From/To/Contact).

На esg выполняется нормализация с помощью provider_callerid. Правило преобразует: * to: 74957654321 → 555 (внутренний номер IVR-сценария) * from: 74950000000 → (преобразование не требуется, номер остаётся для внутреннего использования)

Вызов направляется в b2b.

Параметры на входе в b2b: * fromnumber: 74950000000 * tonumber: 555 * fromdomain: domain.local * fromextaccount: provider1 * dir: outer (инициатор — внешний провайдер)

Этап 2. Выбор маршрута (b2b).

Поиск векторов: находится вектор с фильтром dir=outer и tonumber=5*.

Поиск правил внутри вектора: находится правило с action=featurecode, фильтрами fromnumber=* и tonumber=555.

Этап 3. Проверка прав.

CoS инициатора (провайдера) — пустой. Правило проходит.

Этап 4. Исполнение (featurecode).

Поиск featurecode с номером 555. Находится код с type=ivr, extension=main_ivr (код IVR-сценария). Вызов направляется на сервис ivr.

Исходящий INVITE (от b2b на ivr):

INVITE sip:ivr-555@ivr-service SIP/2.0
From: <sip:74950000000@domain.local>
To: <sip:ivr-555@domain.local>
X-Era-...: ...

Сервис ivr получает контекст звонка и запускает сценарий main_ivr для обработки входящего вызова.

Итог: вызов направлен на IVR-сценарий main_ivr. Специальные заголовки передают контекст для сценария.


Пример 4. Кросс-доменный звонок с представлением

Пользователь А из домена domain1 с номером 101 звонит пользователю Б из домена domain2 с номером 102 (в domain1 номер 102 не существует, а в domain2 — существует). Номерной план устроен так: для вызова абонента 102 в domain2 из domain1 необходимо набрать 2102 (префикс 2 означает «вызов в domain2»). При этом номер инициатора должен быть представлен для domain2 как 1101 (префикс 1 означает «вызов из domain1»).

Входящий INVITE (от устройства А на sg domain1):

INVITE sip:2102@domain1.local SIP/2.0
From: <sip:101@domain1.local>
To: <sip:2102@domain1.local>

Этап 1. Входящий контроль (sg domain1).

Вызов от зарегистрированного устройства. Параметры на входе в b2b: * fromnumber: 101 * tonumber: 2102 * fromdomain: domain1.local * dir: inner

Этап 2. Выбор маршрута (b2b domain1).

Вектор с фильтром tonumber=2XXX (вызовы в domain2). Правило с action=cross, todomain=domain2.local, modtonumber=/X/XXX (удаляет первую цифру 2, оставляя 102).

Этап 3. Проверка прав.

CoS инициатора — пустой.

Этап 4. Исполнение (cross).

Вызов передаётся в domain2. Параметры на входе в b2b domain2: * fromnumber: 101 (номер инициатора из domain1) * tonumber: 102 (номер назначения в domain2, после удаления префикса) * fromdomain: domain1.local * dir: cross

Этап 5. Выбор маршрута в domain2.

В domain2 выполняется маршрутизация по номеру 102. Находится внутренний пользователь 102. При формировании вызова применяется representative, который преобразует fromnumber 101 → 1101 (внешний вид номера для domain2).

Этап 6. Выходной контроль (domain2).

Представление применено. Вызов направляется на устройство пользователя 102.

Исходящий INVITE (от b2b domain2 на sg, далее на устройство):

INVITE sip:102@device-b-ip:5060 SIP/2.0
From: <sip:1101@domain2.local>
To: <sip:102@domain2.local>

Итог: пользователь Б видит входящий вызов от номера 1101, а не от 101. Redial будет работать с номером 1101, который может быть направлен обратно в domain1.


Пример 5. Двухшаговый перевод с подменой плеча

Пользователь А (101) звонит пользователю Б (102). Б принимает вызов. Затем Б совершает консультационный вызов пользователю В (103). После того как В ответил, Б отправляет REFER с Replaces на А, указывая контакт В и идентификаторы его плеча. В результате А и В соединяются напрямую, Б выходит из диалога.

Исходный диалог (уже установлен):

А (101) ↔ Б (102) — диалог активен, идентификатор диалога D1.

Шаг 1. Консультационный вызов (Б → В)

Б инициирует новый вызов на В. Этот вызов проходит маршрутизацию как обычный внутренний звонок (см. Пример 1).

Исходящий INVITE от Б на В:

INVITE sip:103@domain.local SIP/2.0
From: <sip:102@domain.local>
To: <sip:103@domain.local>

В отвечает. Устанавливается диалог D2 между Б и В.

Шаг 2. REFER с Replaces (Б → А)

Б отправляет REFER на А с параметром replaces в Refer-To, указывающим диалог D2 (между Б и В).

REFER от Б к А:

REFER sip:101@domain.local SIP/2.0
From: <sip:102@domain.local>
To: <sip:101@domain.local>
Refer-To: <sip:103@domain.local?Replaces=dialog-id-D2>

Шаг 3. Обработка REFER (устройство А)

Устройство А обрабатывает REFER. В соответствии с Refer-To и параметром replaces, устройство А инициирует новый INVITE к В с заголовком Replaces, указывающим диалог D2.

INVITE от А к В (с Replaces):

INVITE sip:103@domain.local SIP/2.0
From: <sip:101@domain.local>
To: <sip:103@domain.local>
Replaces: <dialog-id-D2>

Этот INVITE проходит маршрутизацию как обычный внутренний звонок (см. Пример 1).

Шаг 4. Завершение старых диалогов

После успешного установления нового диалога D3 между А и В, диалог D1 (А-Б) завершается, диалог D2 (Б-В) завершается. Б больше не участвует в диалоге.

Итог: А и В соединены напрямую. В видит звонок от А (101), А видит В (103).


Пример 6. Сервисный вызов (featurecode) — конференция

Пользователь А (101) набирает код *10512 для подключения к конференции с номером комнаты 12.

Входящий INVITE (от устройства А на sg):

INVITE sip:*10512@domain.local SIP/2.0
From: <sip:101@domain.local>
To: <sip:*10512@domain.local>

Этап 1. Входящий контроль (sg).

Вызов от зарегистрированного устройства. Параметры на входе в b2b: * fromnumber: 101 * tonumber: *10512 * dir: inner

Этап 2. Выбор маршрута (b2b).

Вектор с фильтром tonumber=105 (сервисные номера). Правило с action=featurecode, фильтром tonumber=105.

Этап 3. Проверка прав.

CoS инициатора — пустой. Проверка featurerule: если настроены запреты на конференции для пользователя 101, вызов будет отклонён. В данном случае правил нет.

Этап 4. Исполнение (featurecode).

Поиск featurecode с префиксом *105. Находится код с type=conference и extension=12 (номер комнаты). Вызов направляется на сервис conf.

Исходящий INVITE (от b2b на conf):

INVITE sip:12@conf-service SIP/2.0
From: <sip:101@domain.local>
To: <sip:*10512@domain.local>
X-Era-...: ...

Сервис conf обрабатывает запрос: подключает пользователя А к конференции с номером комнаты 12.

Итог: пользователь А подключён к конференции с номером 12. INVITE на сервис conf сформирован с указанием комнаты в Request-URI. Специальные заголовки передают контекст для сервиса.

Какую проблему какой сущностью решать

Маршрутизация оперирует большим количеством сущностей. Новичку легко запутаться, что за что отвечает. Ниже — не справочник, а навигатор: какая сущность для какой задачи предназначена, и когда её стоит использовать.

Куда направить вызов? → route + vectorrule

Это сердце маршрутизации. Используется всегда.

route (вектор) — группировка правил. Позволяет объединить правила по смыслу (например, «внутренние звонки», «звонки на мобильные», «международные») и задать для них общие фильтры и расписание. Основная цель векторов — сокращение количества перебираемых правил за счёт группировки и предварительной фильтрации.

vectorrule (правило) — конкретное действие. Именно оно решает, что делать с вызовом: направить внутрь, наружу, в другой домен, на сервис, или отклонить.

Когда использовать: - Всегда. Без route и vectorrule вызов не будет обработан.

Как адаптировать номера между внутренним и внешним планами? → provider_callerid и representative

Это адаптер между двумя мирами: внутренним номерным планом платформы и внешним номерным планом провайдера/PSTN.

Внутри платформы номера могут быть короткими (101, 102), а провайдер требует полный федеральный номер (74957654321). Или наоборот — провайдер присылает номер в одном формате, а платформа ожидает другой.

Когда использовать provider_callerid: - Когда внутренний номерной план не совпадает с внешним - Когда провайдер требует подстановку константного номера (например, всегда подставлять головной номер компании) - Когда нужно организовать «карусель» — случайный выбор номера из пула для исходящих вызовов - Когда нужно удалить или добавить префикс (код города, код страны) - Когда внутренний номерной план оперирует разными внешними учётными записями провайдеров, у каждого из которых свой номер компании, и требуется адаптация к конкретному провайдеру

Когда использовать representative: - При кросс-доменных вызовах, когда номер в одном домене должен выглядеть иначе в другом - При внешних вызовах, когда нужно показать определённый номер для внешнего мира - Для назначения разных внешних номеров компании разным абонентам или доменам

Когда не использовать преобразования (ни provider_callerid, ни representative): - Если внутренний номерной план уже полностью соответствует тому, что ожидается на следующем этапе (провайдер ожидает именно тот номер, который уже есть в системе). В этом случае преобразование просто не требуется.

Различие: - provider_callerid — адаптер между внутренним и внешним номерными планами, привязан к конкретному провайдеру и выполняется на esg - representative — представление номера в другом домене или для внешнего вызова, привязано к номеру и выполняется на b2b

provider_callerid работает на esg — на входе и на выходе. representative работает на b2b и применяется для каждого форка независимо.

Какой номер показывать в другом домене? → representative

Это про представление. Когда звонок идёт из одного домена в другой (кросс-доменный вызов), у вызывающего абонента в одном домене может быть один номер, а в другом домене его должны видеть по-другому.

Пример: - В домене A пользователь имеет номер 101 - В домене B его должны видеть как 1101

Когда использовать: - При кросс-доменных вызовах - При внешних вызовах, когда нужно показать определённый номер для внешнего мира - Для Redial, когда прямой номер абонента в другом домене недостижим из текущего домена

Когда не использовать: - Для внутренних звонков внутри одного домена

representative применяется на b2b, для каждого форка независимо. Это означает, что один звонок может быть представлен по-разному для разных получателей.

Как создать сервисную функцию? → featurecode

Это про сервисные номера. Featurecode определяет, какой номер соответствует какой сервисной функции: IVR, конференция, голосовая почта, перехват, парковка и другие.

Когда использовать: - Когда нужно организовать сервисный номер (например, *105 — конференции) - Когда нужно, чтобы пользователи могли обращаться к системным сервисам по коротким номерам

Когда не использовать: - Для обычных вызовов между пользователями — для этого есть internal - Для внешних вызовов — для этого есть external

Как запретить пользователю использовать функцию? → featurerule

Это про доступ к сервисным функциям. Featurerule проверяет, может ли пользователь с определённым номером (from) использовать конкретную функцию (тип featurecode) для конкретного номера (to).

Что можно запретить: - Подключение к разговору (monitor, prompt, mesh) - Вторжение (barge) - Интерком (intercom) - Перехват (pickup) - Подмену плеча (replace) - И другие типы featurecode

Когда использовать: - Когда нужно запретить конкретному пользователю использовать конкретную функцию - Когда нужно разрешить функцию только для определённых номеров назначения - Когда без настройки запретов происходит кратное размножение правил маршрутизации. Если одно и то же правило повторяется много раз с незначительными изменениями, это явный маркер того, что пора вводить featurerule. - Когда требуется сохранить компактность настройки через использование масок на номера, а не через введение новых абстрактных сущностей

Когда не использовать: - Для группового управления запретами через введение новых абстрактных сущностей (классов запретов и разрешений) — для этого есть CoS/CoR. Это более высокий уровень абстракции, который требует введения дополнительных сущностей, но обеспечивает структурную компактность при больших масштабах

featurerule работает на b2b, на этапе применения featurecode.

Как управлять доступом к направлениям для групп? → CoS/CoR/TollLists

Это про массовое управление доступом. Не для каждого пользователя, а для групп.

CoS (Class of Service) — что разрешено инициатору. CoR (Class of Restriction) — кто может достичь объекта назначения. CosProfile — профиль с набором разрешённых направлений и функций. CorPolicy — матрица, которая говорит: «Cos A может звонить на Cor B?»

Для обеспечения ещё большей компактности и структурированности система предоставляет дополнительный уровень абстракции: - TollList — список одновременно разрешённых направлений вызова. Позволяет собрать несколько направлений в одну именованную группу и многократно использовать её в разных CosProfile. - TollLink — матрица связей между TollList и конкретными направлениями (CallType). Позволяет гибко добавлять или исключать направления из TollList без изменения самих профилей.

Таким образом, настройка доступа к направлениям может быть организована на трёх уровнях: прямое перечисление в CosProfile, использование TollList, или использование TollList с дополнительной фильтрацией через TollLink. Это позволяет адаптировать сложность конфигурации под реальные потребности.

Когда использовать: - В крупных корпорациях с большим количеством пользователей и групп - Когда нужно централизованно управлять доступом к направлениям (международные, междугородные, местные, внутренние) - Когда нужно разграничить доступ между отделами/группами пользователей - Когда количество однотипных настроек становится очевидно затратным

Когда не использовать: - В малых инсталляциях (до 50-100 пользователей) — избыточно - Если доступ к направлениям удобнее контролировать через vectorrule - Если настройка кажется слишком абстрактной — значит, она действительно сложная

CoS/CoR — опциональный механизм. По умолчанию всё разрешено. Не используйте его, если не уверены, что он нужен. Это инструмент для крупных систем, а не для всех.

Отличие от featurerule: - CoS/CoR управляет доступом к направлениям и сервисам на уровне групп - featurerule управляет доступом к функциям на уровне конкретных пользователей/номеров - Это взаимодополняющие механизмы, а не альтернативы

Как вызвать несколько устройств одновременно? → sipgroup

Это простой групповой номер. У sipgroup есть номер, и когда кто-то звонит на этот номер, вызов направляется на несколько устройств/учётных записей.

Режимы: - cascade — последовательно - parallel — одновременно - random — последовательно, но в случайном порядке

Когда использовать: - Когда нужен простой групповой номер без сложной логики - Когда нужно, чтобы звонок доходил до нескольких абонентов

Когда не использовать: - Когда нужна сложная логика (шеф-секретарь, установка опций вызова) — для этого есть sipkit - Когда нужна очередь ожидания — для этого есть hunt

Как добавить модифицирующую логику к вызову? → sipkit

Это про модифицирующую логику. У sipkit нет номера — он не является адресатом. Он изменяет поведение вызовов на существующие учётные записи.

Типы: - redirect — переадресация - reject — отказ - options — установка опций вызова (таймауты, длительность) - parallel — параллельный вызов (альтернатива настройке в sipuser) - chief — шеф-секретарь

Когда использовать: - Когда нужно применить модифицирующую логику к вызовам на определённые номера - Шеф-секретарь — один из самых частых кейсов - Когда нужно установить опции вызова (fork_timeoutsec, dialog_timeoutsec) для группы вызовов

Когда не использовать: - Для простого группового номера — достаточно sipgroup - Для точечного изменения поведения одного пользователя — можно настроить в sipuser

sipkit работает невидимо для инициатора вызова. Он применяется к уже существующим учётным записям, а не создаёт новый адресат.

Как организовать очередь ожидания? → hunt

Это альтернатива sipgroup с локальной очередью ожидания. Hunt — это более сложная альтернатива sipgroup, использующая локальную очередь ожидания, которая не отслеживается в общей статистике звонков.

Когда использовать: - Когда нужна очередь с ожиданием для группы ресурсов - Когда статистика звонков не критична и не требует централизованного учёта

Когда не использовать: - Когда нужна простая группа без очереди — используйте sipgroup - Когда нужна полная статистика и отчётность — используйте колл-центр

Как настроить переадресацию для пользователя? → redirectrule

Это про серверную переадресацию. Redirectrule настраивает переадресацию для конкретных абонентов по различным условиям.

Типы: - absolute — всегда - unregistered — по отсутствию регистрации - busy — занято - timeout — таймаут - decline — отказ - dnd — не беспокоить - error — ошибка - other — другие случаи

Когда использовать: - Когда нужно настроить переадресацию для конкретного пользователя - Когда нужно различать разные условия переадресации (занято, таймаут, отказ)

Не следует путать с переадресацией, настроенной на самом устройстве пользователя. Такие переадресации обрабатываются сервером после получения SIP-ответа 301 или 302 на отправленный INVITE.

Сводная таблица

Что нужно сделать Сущность

Направить вызов

route + vectorrule

Создать сервисную функцию

featurecode

Запретить пользователю использовать функцию

featurerule

Управлять доступом к направлениям для групп

CoS/CoR/TollLists

Адаптировать номера между внутренним и внешним планом

provider_callerid и/или representative

Показать номер по-другому в другом домене

representative

Создать групповой номер

sipgroup

Добавить модифицирующую логику к вызову

sipkit

Организовать очередь с ресурсами (с локальной очередью ожидания)

hunt

Настроить переадресацию для пользователя

redirectrule

Как проектировать маршрутизацию, чтобы она не превращалась в ад

Маршрутизация — это живая система. Она развивается вместе с бизнесом: появляются новые абоненты, новые направления, новые требования, новые провайдеры. Без дисциплины такая эволюция приводит к неизбежной деградации: количество правил растёт, их логика запутывается, исключения плодятся, и в какой-то момент система становится неуправляемой. Новый сотрудник не может ничего изменить без риска всё сломать — и просто добавляет новые правила поверх старых.

Этого можно избежать. Нужен системный подход к проектированию и сопровождению маршрутизации. В этой главе — не строгие правила, а принципы и практики, выработанные на реальных инсталляциях. Они помогут сохранить маршрутизацию понятной, модифицируемой и безопасной на протяжении всего жизненного цикла системы.

Прежде чем настраивать — спроектируйте

Маршрутизация начинается не с создания правил, а с ответов на вопросы о том, как должны обрабатываться вызовы. Без этого ответа любая настройка будет случайной.

Определите типы вызовов: - Внутренние (пользователь → пользователь) - Внешние входящие (PSTN → платформа) - Внешние исходящие (платформа → PSTN) - Кросс-доменные (домен A → домен B) - Сервисные (коды абонентских функций)

Определите группы абонентов: - Обычные пользователи - Руководители - Секретари - Внешние пользователи (через провайдера) - Группы по отделам или функциям

Определите направления вызовов: - Внутренние - Местные - Междугородные - Международные - На конкретных провайдеров

Определите, как будете управлять исключениями: - Какие пользователи имеют особые права? - Какие номера требуют особой обработки? - Какие функции должны быть доступны не всем?

Ответы на эти вопросы — основа для архитектуры маршрутизации. Без них настройка превращается в угадывание.

Проектируйте от общего к частному

Всегда начинайте с общего решения, затем добавляйте исключения. Это фундаментальный принцип, который позволяет сохранять систему понятной.

Даже исключения можно и нужно обобщать до уровня принципов маршрутизации. Вместо того чтобы запрещать каждому конкретному пользователю подключаться к прослушиванию разговора руководителя, можно сформулировать общий принцип: запрет определённых сервисных функций по отношению к определённой группе абонентов. Одно правило, настроенное через featurerule или CoS/CoR, накрывает сразу разные функции и разных абонентов.

Плохо (множество частных правил):

Правило 1: запретить пользователю 105 прослушивание руководителя 101
Правило 2: запретить пользователю 106 прослушивание руководителя 101
Правило 3: запретить пользователю 107 прослушивание руководителя 101
Правило 4: запретить пользователю 105 вторжение к руководителю 101
Правило 5: запретить пользователю 106 вторжение к руководителю 101
...

Хорошо (обобщённый принцип):

featurerule: filter_from=10*, filter_to=101, types=monitor,prompt,mesh,barge, action=deny

Ещё лучше (групповая политика):

CosProfile: {code: "no_supervisor_access", feature_access: []}
CorProfile: {code: "supervisor"}
CorPolicy: {src_cos: "no_supervisor_access", dst_cor: "supervisor",
            feature: "monitor,prompt,mesh,barge", action: deny}

Сигнал к действию: Если вы видите одинаковое правило, повторённое 3+ раз с незначительными изменениями — это сигнал, что нужно вводить группировку или обобщать принцип.

Создавайте группы, а не правила

Группировка — основной инструмент борьбы с разрастанием правил. Вместо множества похожих правил создайте одно общее и примените его к группе.

Если видите…​ Делайте…​

Одинаковые права доступа для многих пользователей

CoS/CoR

Большое количество правил, требующих CPU-интенсивного перебора

route (сокращает перебор)

Много маршрутов с похожей логикой, но разными номерами

общие маски в vectorrule, таблицы (opts.tab), двойной проход через next

Много правил с запретами

featurerule или CoS/CoR вместо запрещающих vectorrule

Много правил представления для разных доменов

перенести representative в корневой домен или домен назначения

Одинаковые преобразования номеров

provider_callerid с масками или служебные сценарии для сложной логики

Одинаковые ограничения на функции

featurerule с масками

Пример группировки через next:

Проблема: на внешний номер надо отправлять 7-, 9- и 10-значные номера из разных доменов, причём в одном из доменов находится централизованный провайдер.

Решение: сначала преобразовать разные варианты в канонический вид с помощью модификаторов в нескольких правилах с действием next, затем одним правилом отправить все канонизированные номера на провайдера.

Правило 1 (приоритет 100): tonumber=7* → modtonumber=7495XXXXXXX, next
Правило 2 (приоритет 100): tonumber=9* → modtonumber=7495XXXXXXX, next
Правило 3 (приоритет 200): tonumber=7495* → action=external, toextaccount=central_provider

Добавляйте исключения осознанно

Исключения — главный источник хаоса в маршрутизации. Каждое исключение должно иметь причину и быть задокументированным.

При добавлении исключения: 1. Запишите причину в комментарий (opts.comment или comment) 2. Проверьте, нельзя ли описать исключение через маску, а не перечисление 3. Проверьте, нельзя ли добавить исключение через группировку, а не новое правило 4. Если исключение временное — укажите дату, когда его можно удалить

Пример хорошего комментария:

"comment": "Временное исключение для отдела продаж до перехода на новый номерной план. Удалить после 01.06.2026"

Пример плохого комментария:

"comment": "для Иванова"

Регулярно ревизуйте правила

Ревизия — это не разовое действие, а регулярный процесс. Маршрутизация имеет свойство «загрязняться»: правила, которые когда-то были нужны, перестают использоваться, но остаются в системе.

Что проверять при ревизии: 1. Правила, которые никогда не срабатывают (можно определить по логам или трассировке) 2. Правила с одинаковым приоритетом и одинаковыми действиями 3. Правила, созданные более года назад 4. Правила с комментарием «временное» 5. Правила, которые дублируют функциональность друг друга

Критерии для удаления: - Правило не срабатывало в течение 3 месяцев → удалить (если нет веской причины сохранять) - Правило дублирует более приоритетное → удалить - Правило создано «на всякий случай» → удалить - Правило с истекшим сроком действия → удалить

В текущей версии системы нет счётчиков использования правил, поэтому ревизия опирается на логи, трассировку и документацию. При необходимости можно вести внешний учёт — например, журнал изменений с указанием даты создания и назначения каждого правила.

Используйте трассировку для понимания

Трассировка — это инструмент, показывающий, какой маршрут был бы выбран для вызова с указанными параметрами. Она доступна через интерфейс администратора и позволяет увидеть процесс принятия решений без отправки реального вызова.

Что показывает трассировка: - Какие векторы и правила проверялись - Какие фильтры сработали или не сработали - Какие модификации были бы применены - Какое действие было бы выбрано

Когда использовать трассировку: - При настройке нового маршрута — проверить, что он срабатывает как ожидается - При диагностике проблемы — понять, почему вызов идёт не по тому пути - При ревизии — проверить, что старые правила всё ещё работают

Трассировка показывает ход принятия решений — какие сущности участвовали, какие фильтры сработали, что было отклонено. Это главный инструмент для понимания того, как на самом деле работает маршрутизация.

Сводные принципы

Принцип Суть

Проектирование

Прежде чем настраивать, ответьте на вопросы: какие вызовы, какие группы, какие направления

От общего к частному

Начинайте с общего решения, добавляйте исключения осознанно. Исключения обобщайте до принципов

Группировка

Вместо перечисления — маски, таблицы, next, CoS/CoR, featurerule

Комментарии

Каждое нетривиальное правило должно иметь комментарий с причиной

Ревизия

Раз в квартал проверяйте, какие правила используются, а какие нет

Трассировка

Используйте для диагностики и понимания

Документация

Ведите учёт изменений — что, когда и зачем было добавлено

Подводные камни и частые ошибки

Даже при правильном понимании теории маршрутизации на практике возникают ситуации, которые ставят в тупик. В этой главе собраны типичные ошибки, неочевидные моменты и заблуждения, с которыми сталкиваются администраторы при настройке маршрутизации. Понимание этих подводных камней поможет избежать проблем до того, как они проявятся в работающей системе.

Откуда берётся номер инициатора в исходящем INVITE

Это один из самых частых источников путаницы. Номер инициатора в исходящем INVITE может быть получен из разных источников, и важно понимать, какой из них работает в каждом конкретном случае.

Источники номера инициатора:

  1. От инициатора (оригинальный номер) — номер, с которым вызов пришёл в систему. Для внутреннего вызова — это номер учётной записи вызывающего абонента. Для внешнего вызова — номер, указанный провайдером в заголовке From.

  2. Представление (representative) — применяется на b2b при кросс-доменных или внешних вызовах. Заменяет номер инициатора на тот, который должен увидеть вызываемый абонент.

  3. Нормализация (provider_callerid) — применяется на esg при внешних вызовах. Преобразует внутренний номер во внешний номерной план (и обратно).

Что не является источником номера инициатора: - modfromnumber в vectorrule — этот модификатор изменяет номер источника для последующих шагов маршрутизации (поиска правил, проверки фильтров), но не подставляет его в исходящий INVITE. Это критическое различие, которое часто упускают.

Пример:

Правило: modfromnumber = 7495101

Этот модификатор повлияет на то, какие следующие правила будут найдены (например, по новому fromnumber), но сам номер 7495101 не попадёт в исходящий INVITE, если не будет применён representative или provider_callerid.

Правильная последовательность для изменения номера в исходящем INVITE: 1. Маршрутизация с modfromnumber (определяет направление) 2. Если вызов внешний — provider_callerid на esg (подставляет номер во внешний план) 3. Если вызов кросс-доменный — representative на b2b (подставляет номер для другого домена)

Если правила имеют одинаковый приоритет — порядок случайный

При равенстве приоритетов нескольких векторов или правил порядок их проверки случаен в пределах одной сессии маршрутизации. Это не ошибка и не баг — это осознанное проектное решение.

Что это даёт: - Возможность распределять нагрузку между несколькими маршрутами без дополнительных механизмов - Естественный fallback: если один маршрут недоступен, следующий будет выбран случайно

Что нельзя делать: - Полагаться на порядок проверки для обеспечения детерминированного поведения - Использовать одинаковые приоритеты, когда важен строгий порядок применения

Рекомендация: Если порядок важен — назначайте разные приоритеты. Если порядок не важен, а нужно распределение — используйте одинаковые приоритеты осознанно.

Приоритет в external: если esg недоступен — будет fallback

Для правил с действием external действует особый механизм: даже если правило подошло по всем фильтрам, но учётная запись провайдера недоступна (esg неактивен, лимиты транков превышены, регистрация потеряна, пинг не отвечает), маршрутизация не останавливается, а продолжает поиск со следующего по приоритету правила.

Это работает только при fallback_next = true (значение по умолчанию).

Типичная ошибка: Администратор создаёт одно правило для внешнего вызова и предполагает, что если провайдер недоступен, вызов будет отклонён. На самом деле, если есть другое подходящее правило с более низким приоритетом, вызов пойдёт по нему.

Пример:

Правило 1 (приоритет 100): external, provider1 — провайдер временно недоступен
Правило 2 (приоритет 200): external, provider2 — работает

Результат: вызов пойдёт через provider2, а не будет отклонён.

Рекомендация: Если требуется строгий отказ при недоступности конкретного провайдера, либо создавайте правило с denied на случай недоступности, либо используйте fallback_next = false.

CoS работает только если задан явно

Групповые политики CoS/CoR — это опциональный механизм. По умолчанию всё разрешено.

Важное следствие: - Пустой CoS = всё разрешено - Отсутствие CosProfile при заданном cos = запрещены все направления, для которых установлен call_type или ненулевой restriction_level

Типичная ошибка: Администратор задаёт пользователю cos = "managers", но не создаёт CosProfile с таким кодом. В результате пользователь не может звонить по направлениям, где в правилах установлен call_type или restriction_level, и администратор долго ищет причину.

Рекомендация: При использовании CoS/CoR всегда создавайте соответствующие профили. Если профиль не нужен — не задавайте cos вообще.

representative применяется не всегда

Правила представления (representative) применяются только в определённых сценариях:

  • При кросс-доменных вызовах (cross)

  • При внешних вызовах (external) — могут дополнять правила нормализации

Где не применяются: - При внутренних звонках внутри одного домена — номер инициатора остаётся неизменным

Типичная ошибка: Администратор настраивает representative, ожидая, что он изменит номер инициатора при внутреннем звонке. Это не работает.

Рекомендация: Для изменения номера инициатора во внутренних звонках используйте другие механизмы (например, настройку отображения на самом устройстве). Для кросс-доменных и внешних вызовов — representative.

Переадресация: серверная vs клиентская

В системе существуют два типа переадресации, и их важно различать.

Серверная переадресация (redirectrule): - Настраивается в платформе - Применяется сервером до отправки INVITE на устройство - Поддерживает разные условия: абсолютная, по отсутствию регистрации, по результату вызова

Клиентская переадресация (на устройстве): - Настраивается на самом устройстве пользователя (например, через интерфейс телефона) - Применяется после получения SIP-ответа 301 или 302 на отправленный INVITE - Сервер не участвует в принятии решения, только транслирует ответ

Важное различие: В клиентской переадресации сервер не проверяет корректность номера назначения, а просто отправляет INVITE по указанному в ответе адресу.

Типичная ошибка: Администратор пытается ограничить номера для переадресации через redirectrule, но пользователь настроил переадресацию на устройстве, и ограничение не работает.

Рекомендация: Для ограничения номеров, на которые можно переадресовывать вызовы, используйте настройку opts.redirect_allowed_masks в учётной записи sipuser. Она работает для обоих типов переадресации.

При переводах и переадресациях инициатором маршрутизации становится переводящий абонент

Это важный и неочевидный момент, который часто приводит к непониманию логики маршрутизации.

При переводе (REFER): Когда пользователь А переводит вызов на пользователя В, маршрутизация для нового вызова (А → В) выполняется от имени пользователя А, а не от имени инициатора исходного вызова.

При переадресации: Аналогично, при переадресации вызова с номера А на номер В, маршрутизация выполняется от имени владельца переадресации (абонента А).

Почему это важно: - Права доступа проверяются для абонента, который инициирует перевод/переадресацию - CoS/CoR применяются от имени переводящего абонента - Ограничения на исходящие вызовы применяются к переводящему, а не к исходному инициатору

Пример:

Пользователь А (101) звонит пользователю Б (102).
Б переводит вызов на пользователя В (103).
Новый вызов (от Б к В) проходит маршрутизацию от имени Б:
- Проверяются права Б на вызов В
- Применяются ограничения CoS/CoR для Б
- Используются настройки исходящих вызовов для Б

Типичная ошибка: Администратор ожидает, что при переводе проверяются права исходного инициатора (А), и удивляется, почему перевод работает не так, как ожидалось.

Рекомендация: При проектировании маршрутизации учитывайте, что переводы и переадресации всегда выполняются от имени абонента, который осуществляет перевод или переадресацию. Это влияет на проверку прав, CoS/CoR и ограничения.

Нормализация — не всегда обязательна

Правила нормализации (provider_callerid) не являются обязательным элементом. Они нужны только тогда, когда внутренний номерной план не совпадает с внешним.

Когда нормализация обязательна: - Внутренний номер (101) нужно преобразовать во внешний (74957654321) - Провайдер требует подстановку определённого номера - Нужно организовать «карусель» номеров

Когда нормализация не нужна: - Внутренний номерной план уже соответствует внешнему - Преобразование выполняется на стороне провайдера

Типичная ошибка: Администратор создаёт правила нормализации «на всякий случай», даже если они не нужны, что усложняет систему и увеличивает время обработки.

Рекомендация: Используйте provider_callerid только там, где это действительно необходимо. Если звонки проходят без нормализации — не добавляйте её.

Ответ 3xx от устройства обрабатывается сервером

Когда вызываемое устройство возвращает SIP-ответ 3xx (перенаправление), сервер не игнорирует его и не передаёт инициатору «как есть». Он обрабатывает этот ответ:

  1. Извлекает номер назначения из заголовка Contact

  2. Проверяет, разрешён ли этот номер для переадресации

  3. Формирует новый INVITE на указанный номер

Ограничения на номера для переадресации:

Настройка разрешённых номеров для переадресации может быть задана на двух уровнях:

  • Уровень домена — параметр redirect_allowed_masks в настройках домена. Задаёт общий список масок для всех абонентов домена.

  • Уровень абонента — параметр opts.redirect_allowed_masks в учётной записи sipuser. Позволяет задать индивидуальные ограничения для конкретного пользователя.

Правило применения: - Если в учётной записи абонента задан список масок (не пустой и не "/default"), то используются только они. - Если в учётной записи абонента указано значение "/default", то применяются маски, заданные на уровне домена. - Если в учётной записи абонента не задано ничего (поле отсутствует или пустое), то ограничений для данного абонента нет (разрешены все номера).

Пример:

Настройки домена: redirect_allowed_masks = ["1XX", "2XX"]
У абонента А: opts.redirect_allowed_masks = ["10X"] → разрешены только номера 10X
У абонента Б: opts.redirect_allowed_masks = "/default" → разрешены 1XX и 2XX (из домена)
У абонента В: opts.redirect_allowed_masks = [] → разрешены все номера

Это позволяет контролировать, куда могут быть перенаправлены вызовы, даже если переадресация настроена на устройстве.

Типичная ошибка: Администратор не настраивает redirect_allowed_masks и удивляется, что переадресация с устройства не работает.

Рекомендация: Настраивайте redirect_allowed_masks на уровне домена для базовых ограничений и используйте /default в учётных записях, чтобы наследовать эти ограничения. Индивидуальные настройки применяйте только для исключений.

IVR может инициировать вызовы с любым номером

IVR-сценарии могут инициировать вызовы от имени любого абонента. Это мощный механизм, но он требует осторожности.

Как это работает: - В сценарии IVR можно указать произвольный номер и имя для поля From - Такой вызов проходит маршрутизацию на общих основаниях

Риски: - Если сценарий неправильно настроен, он может звонить от имени несуществующего абонента - Это может привести к путанице в статистике и логах

Рекомендация: Контролируйте, какие номера могут быть использованы IVR для инициации вызовов. Документируйте такие сценарии.

Сводка типичных ошибок

Ошибка Последствие Решение

Ожидание, что modfromnumber изменит номер в INVITE

Номер в INVITE не меняется

Использовать representative (для кросс-доменных) или provider_callerid (для внешных)

Одинаковые приоритеты при важном порядке

Непредсказуемое поведение

Назначать разные приоритеты

Ожидание отказа при недоступном провайдере

Вызов идёт по другому маршруту

Использовать fallback_next=false или denied

Задание cos без создания CosProfile

Неожиданные запреты

Всегда создавать профили или не задавать cos

Ожидание representative для внутренних звонков

Не работает

Использовать другие механизмы

Ожидание работы redirectrule для клиентской переадресации

Не работает

Использовать redirect_allowed_masks

Игнорирование того, что при переводе проверяются права переводящего

Неожиданные отказы при переводе

Учитывать при проектировании

Создание provider_callerid «на всякий случай»

Усложнение системы

Использовать только при необходимости

Отсутствие redirect_allowed_masks

Переадресация с устройств не работает

Настраивать для всех учётных записей или на уровне домена

IVR с произвольным номером без контроля

Путаница в статистике

Документировать и контролировать