Логика маршрутизации
Логика маршрутизации представляет из себя сумму маршрутов (routes), которые содержат правила обработки сообщений SIP.
Маршруты делятся на два вида:
- основные маршруты (top routes) - это маршруты, которые напрямую запускаются (вызываются) OpenSIPS при возникновении некоторых событий (таких как поступление запроса или ответа, ошибка транзакции и т.п.);
- подмарштуры (sub-routes)- маршруты, которые вызываются из других маршрутов скрипта. Подмаршруты имеют имена и должны вызываться по ним из других маршрутов или подмаршрутов. Подмаршруты могут принимать параметры или возвращать числовой код (избегайте возврата нулевого значения (0), так как это завершит работу всего скрипта). Подмаршруты похожи на процедуры или функции в любом языке программирования!
Для перехода в подмаршрут используется функция route.
route(name [, param1 [, param2 [, ...] ] ] )
Она может принимать до семи параметров, которые в дальнейшем могут быть получены обращением к псевдо переменной '$param(idx)'.
Например, route(HANDLE_SEQUENTIALS, 1, "param", $var(param));
Типы маршрутов
В логике маршрутизации OpenSIPS используются несколько типов маршрутов. Каждый тип маршрута вызывается определенным событием и позволяет обрабатывать определенный тип сообщения (запрос или ответ).
Различают следующие типы.
1. route
Блок маршрутизации запросов (requests), он содержит набор действий, которые должны быть применены к запросам SIP.
Вызывается: получением SIP запроса из внешней сети
Обрабатывает: вызвавший его запрос
Состояние: изначально stateless, но может стать stateful при использовании модуля TM
Действие по-умолчанию: если запрос никак не обрабатывается, то в результате просто отбрасывается.
Основной блок маршрута, определяемый функцией 'route{...}' или 'route[0]{...}', выполняется для каждого SIP запроса. Неявное действие после выполнения основного блока маршрута — отбросить запрос SIP. Чтобы отправить ответ или переслать запрос, необходимо вызвать явные действия внутри блока маршрута (t_reply, например).
2. branch_route
SIP branch - это "ветка" вызова. Код в branch_route исполняется перед отправкой запроса этой ветки. Ветка - это фактически новый входящий запрос (включая INVITE, REINVITE, BYE, INFO и т.д., кроме ACK) с новым значением поля branch заголовка Via, т.е. новая транзакция. При этом, по-умолчанию в рамках диалога branch_id у этих веток будет одинаков и равен "0".
Смысл branch_route в возможности дополнительной манипуляции запросом перед отправкой, просто как аналог функции в скриптовом языке, при этом не все функции модулей работают в branch_route, надо заранее уточнять. Код в branch_route выполняется только с помощью модуля TM, после того, как он был вызван функцией t_on_branch("branch_id"). Мы можем ветвить вызов, вручную разделяя его на разные ветки и обрабатывая каждую из них отдельно. Например, для двух параллельных вызовов разных устройств одного абонента (parallel forking) нужно создать две ветки с помощью ядровой функции append_branch или псевдо переменной $branch, тем самым создадутся две ветки с разными branch_id и сформируются два исходящий запроса. При этом для каждого запроса можно только один раз вызвать код из branch_route. Если выполнить функцию t_on_branch() несколько раз, то отработает только последняя.
Вызывается: подготовкой новой ветки запроса; ветка сформирована, но пока не отправлена
Обрабатывает: SIP запрос
Состояние: stateful, требует модуля TM
Действие по-умолчанию: если ветка принудительно не отбрасывается командой "drop", то она будет переслана дальше
3. failure_route
Блок, который выполнятся для транзакций, закончившихся получением ошибки, т.е. у которых код ответа только >=300 для всех веток.
Вызывается: получением или внутренней генерацией негативного ответа, который завершает транзакцию (все ветки завершаются негативными ответами)
Обрабатывает: оригинальный SIP запрос, который был отправлен получателю
Состояние: stateful
Действие по-умолчанию: если не генерируется ни новой ветки, ни нового ответа, то исходный ответ отправится к UAC
Код в failure_route выполняется только с помощью модуля TM, после того, как он был вызван функцией t_on_failure("failure_route_index").
Важно помнить, что внутри failure_route обрабатывается исходный запрос, инициировавший транзакцию, а не ответ, вызвавший failure_route.
4. onreply_route
Блок кода для SIP ответов.
Вызывается: получением SIP ответа
Обрабатывает: полученный ответ
Состояние: stateful (если связан с транзакцией) или stateless (только для глобальных маршрутов, см. ниже)
Действие по-умолчанию: если ответ не отбрасывается (только ответы на начальный запрос могут быть отброшены), то обрабатывается
Есть три типа маршрутов onreply:
- глобальный (global) - это маршрут ловит все ответы, полученные OpenSIPS, и не требует вызова отдельной функции, достаточно создать блок 'onreply_route {...}' или 'onreply_route[0] {...}'. Т.к. этот маршрут не транзакционный (ответ не привязан к какой-либо транзакции), то в нём нет доступа к транзакционным данным.
- по запросу/транзакции (per request/transaction) - этот маршрут ловит все ответы, принадлежащии конкретной транзакции и должен быть вызван функцией t_on_reply() во время генерации запроса.
- по ветке (per branch) - этот маршурт ловит только ответы, принадлежащие конкретной ветке. Он тоже должен быть вызван функцией t_on_reply(), но из branch_route.
5. error_route
Маршрут ошибки вызывается автоматически, если во время обработки SIP-запроса возникает синтаксическая ошибка или если функция assert() возвращает False. Это позволяет администратору принимать решение, что делать в конкретных случаях.
ВАЖНО: этот блок вызывается только для SIP запросов. OpenSIPS должен уметь правильно анализировать первую строку SIP-сообщения, так что любая синтаксическая ошибка в первой строке не приведет к вызову error_route (т.к. иначе OpenSIPS не сможет определить ответ это или запрос).
Вызывается: ошибкой парсинга
Обрабатывает: сбойный запрос
Состояние: stateless (рекомендуемое)
Действие по-умолчанию: отбросить запрос
В error_route доступны некоторые псевдо переменные, предоставляющие данные об ошибке:
- $(err.class) - класс ошибки ('1' для ошибок парсинга);
- $(err.level) - уровень серьёзности ошибки;
- $(err.info) - текстовое описание ошибки;
- $(err.rcode) - рекомендуемый код ответа;
- $(err.rreason) - рекомендуемый текст причины ошибки.
6. local_route
Локальный маршрут вызывается автоматически, когда модулем TM генерируется новый SIP запрос (внутренне, без участия UAC). Это маршрут, предназначенный для проверки сообщений, аккаунтинга и применения последних изменений в заголовках. Функции маршрутизации и сигнализации не допускаются.
Вызывается: модулем TM при генерации нового запроса
Обрабатывает: новый запрос
Состояние: stateful
Действие по-умолчанию: отправляет запрос получателю
7. startup_route
Маршрут startup_route вызывается только один раз при загрузке OpenSIPS и до того, как начнётся обработка сообщений SIP. Он может быть полезен для предварительного заполнения кэша данными. Ещё раз, этот маршрут не связан с получением запроса и обработкой сообщений в целом, так что никакие функции в нём не могут обрабатывать сообщения.
Вызывается: при запуске, до инициации обработчика сообщений
Обрабатывает: инициализирующие функции
8. timer_route
Маршрут таймера вызывается периодически, период времени устанавливается в секундах в имени маршрута. Аналогично startup_route этот маршрут не обрабатывает сообщения. В скрипте допускается вызов нескольких маршрутов таймера с разными периодами.
Вызывается: процессом таймера
Обрабатывает: периодические функции
ВАЖНО! После запуска OpenSIPS, маршруты таймера впервые срабатывают после заданного периода в секундах.
9. event_route
Маршрут событий используется интерфейсом событий (OpenSIPS Event Interface) для запуска кода при возникновении события. Имя маршрута является тем самым событием, которое должно быть обработано в коде маршрута. Сам маршрут вызывается асинхронно относительно момента срабатывания.
Вызывается: модулем error_route при возникновении события, вызванного интерфейсом событий OpenSIPS
Обрабатывает: возникнувшее событие
Состояние: stateless (рекомендуемое)
Действие по-умолчанию: никакой код не выполняется при возникновении события
Комментариев нет:
Отправить комментарий