Модуль сервера OpenSER - LCR
Обзор
Модуль поддержки выбора маршрута с минимальной стоимостью Least cost routing (LCR) реализует два связанных функционала:
Последовательная пересылка запроса на один или несколько шлюзов (функции load_gws и next_gw).
Последовательная отправка запросов на контакты, которые обслуживаются самим сервером, если они не используют одно и тоже значение qvalue (функции load_contacts и next_contacts).
Выбор шлюзов базируется на значении RPID URI вызывающего агента (если доступно, на основании RPID AVP вызывающего агента, после авторизации) или на основании From URI и пользовательской части поля Request-URI (номер телефона). Выбор шлюза, на который можно переправить запрос, основывается на поиске совпадения пользовательской части поля Request-URI и URI из поля "From" с префиксом (prefix) и полем From для каждого из шлюза. Найденные шлюзы могут быть отсортированы для пересылки запроса по следующим признакам: (1) согласно самому длинному совпадению пользовательской части Request-URI, (2) согласно приоритетам шлюзов, и (3) случайным образом.
Каждый шлюз принадлежит группе шлюзов, где он может быть один или в наборе с другими шлюзами. Все шлюзы, принадлежащие группе, имеют одинаковый приоритет.
Информация о шлюзах и маршрутах храниться в двух таблицах: gw и lcr.
Когда произошел выбор подходящего шлюза, из пользовательской части поля Request-URI будет удалено то количество цифр, которое указано в параметре strip шлюза. Далее, поле Request-URI будет перезаписано информацией из таблицы gw: схема для URI, префикс, IP адрес, порт и транспортный протокол. Доступные URI схемы это: NULL = sip, 1 = sip и 2 = sips. Префикс будет добавлен к началу пользовательской части поля Request-URI. На данный момент поддерживаются следующие транспортные протоколы: NULL = none, 1 = udp, 2 = tcp и 3 = tls.
Таблица lcr содержит префиксы для проверки пользовательской части поля Request-URI, From URI, идентификатор группы шлюзов и приоритет. From URI - это регулярное выражение. Пустое поле From URI подразумевает любое значение в From URI. Меньшее значение поля priority указывает на больший приоритет (наивысший приоритет имеет запись с полем приоритета равным 0).
В дополнение к таблицам gw и lcr, есть еще третья таблица - gw_grp, которая служит для хранения соответствий имени и идентификатора группы шлюзов.
Зависимости от других модулей.
Этот модуль имеет зависимости от следующих модулей (другими словами, ниже перечисленные модули должны быть загружены до загрузки этого модуля):
1. SER module tm: Модуль управления транзакциями.
2. database - любой из модулей для интерфейса с конкретной базой данных (на данный момент: mysql, postgres, dbtext)
Зависимости от внешних библиотек и приложений.
Следующие библиотеки или приложения должны быть установлены перед использованием OpenSER с этим модулем:
Нет.
Экспортируемые параметры.
db_url (string)
Значения URL используемой базы данных.Значение, по умолчанию: "mysql://openserro:openserro@localhost/openser".
Пример использования параметра db_url:
...
modparam("lcr","db_url","mysql://muser:pwd@localhost/openser")
...
gw_table (string)
Имя таблицы, которая содержит данные для шлюзов.Значение, по умолчанию: "gw".
Пример использования параметра gw_table:
...
modparam("lcr","gw_table","gw")
...
gw_name_column (string)
Название столбца таблицы, содержащего имя шлюза.Значение, по умолчанию: "gw_name".
Пример использования параметра gw_name_column:
...
modparam("lcr","gw_name_column","gw_name")
...
ip_addr_column (string)
Название столбца таблицы, содержащего IP адрес шлюза.Значение, по умолчанию: "ip_addr".
Пример использования параметра ip_addr_column:
...
modparam("lcr","ip_addr_column","ip_addr")
...
port_column (string)
Название столбца таблицы, содержащего номер порта шлюза.Значение, по умолчанию: "port".
Пример использования параметра port_column:
...
modparam("lcr","port_column","port")
...
uri_scheme_column (string)
Название столбца таблицы, содержащего url схему шлюза.Значение, по умолчанию: "uri_scheme".
Пример использования параметра uri_scheme_column:
...
modparam("lcr","uri_scheme_column","scheme")
...
transport_column (string)
Название столбца таблицы, содержащего тип транспорта используемого для шлюза.Значение, по умолчанию: "transport".
Пример использования параметра transport_column:
...
modparam("lcr","transport_column","transport")
...
grp_id_column (string)
Название столбца таблицы, содержащего идентификатор группы.Значение, по умолчанию: "grp_id".
Пример использования параметра grp_id_column:
...
modparam("lcr","grp_id_column","grp_id")
...
lcr_table (string)
Имя таблицы, содержащей правила маршрутизации (LCR rules).Значение, по умолчанию: "lcr".
Пример использования параметра lcr_table:
...
modparam("lcr","lcr_table","lcr")
...
strip_column (string)
Название столбца таблицы, содержащего кол-во цифр удаляемых от RURI, перед тем, как добавить префикс.Значение, по умолчанию: "strip".
Пример использования параметра strip_column:
...
modparam("lcr","strip_column","strip")
...
prefix_column (string)
Название столбца таблицы, содержащего RURI префикс (назначения).Значение, по умолчанию: "prefix".
Пример использования параметра prefix_column:
...
modparam("lcr","prefix_column","prefix")
...
from_uri_column (string)
Название столбца таблицы, содержащего FROM URI (источника).Значение, по умолчанию: "from_uri".
Пример использования параметра from_uri_column:
...
modparam("lcr","from_uri_column","from_uri")
...
priority_column (string)
Название столбца таблицы, содержащего приоритет правила.Значение, по умолчанию: "priority".
Пример использования параметра priority_column:
...
modparam("lcr","priority_column","priority")
...
gw_uri_avp (string)
Параметр переназначает имя AVP, содержащей URI схему, хост, порт и тип транспорта шлюза. Если имя AVP содержит только цифры, именем AVP будет цифровое представление заданной строки.Значение, по умолчанию: "1400".
Пример использования параметра gw_uri_avp:
...
modparam("lcr","gw_uri_avp","1400")
...
ruri_user_avp (string)
Параметр переназначает имя AVP, содержащей пользовательскую часть Request-URI, после первого вызова функции next_gw(). Если имя AVP содержит только цифры, именем AVP будет цифровое представление заданной строки.Значение, по умолчанию: "1402".
Пример использования параметра ruri_user_avp:
...
modparam("lcr","ruri_user_avp","500")
...
contact_avp (string)
Параметр переназначает имя AVP, содержащей значение поля contact. Если имя AVP содержит только цифры, именем AVP будет цифровое представление заданной строки.Значение, по умолчанию: "1401".
Пример использования параметра contact_avp:
...
modparam("lcr","contact_avp","1401")
...
fr_inv_timer_avp (string)
Параметр переназначает имя AVP, содержащей значение таймаута ожидания финального ответа на сообщение INVITE.Значение, по умолчанию: "fr_inv_timer_avp".
Пример использования параметра fr_inv_timer_avp:
...
modparam("lcr","fr_inv_timer_avp","fr_inv_timer_avp")
...
fr_inv_timer (integer)
Параметр устанавливает значение таймера ожидания финального ответа для первого сообщения INVITE, который используется для последовательной отправки сообщения.Значение, по умолчанию: 90.
Пример использования параметра fr_inv_timer:
...
modparam("lcr","fr_inv_timer",90)
...
fr_inv_timer_next (integer)
Параметр устанавливает значение таймера ожидания финального ответа для последующих сообщений INVITE, который используется для последовательной отправки сообщения:Функция next_contacts() устанавливает значение таймера модуля tm fr_inv_timer в fr_inv_timer_next, если, после выполнения функции next_contacts(), еще существуют доступные контакты с меньшим значением qvalue, и в значение fr_inv_timer, если это была последняя из доступных запись с контактной информацией.
Значение, по умолчанию: 30.
Пример использования параметра fr_inv_timer_next:
...
modparam("lcr","fr_inv_timer_next",30)
...
rpid_avp (string)
Параметр устанавливает имя AVP, содержащей RPID.Значение, по умолчанию: "rpid".
Пример использования параметра rpid_avp:
...
modparam("lcr","rpid_avp","rpid")
...
Экспортируемые функции
load_gws([group-id])
Функция загружает URI схемы, адреса, номера портов и тип транспорта шлюзов, которые подходят под пользовательскую часть поля Request-URI в AVP: gw_uri_avp (смотри секцию Обзор). Если задан необязательный параметр group-id, будут загружены шлюзы, входящие в указанную группу. Функция возвращает 1 или -1, в зависимости от успеха выполнения.Эта функция может использоваться из блоков: REQUEST_ROUTE.
Пример использования функции load_gws:
...
if (!load_gws()) {
sl_send_reply("500", "Server Internal Error - Cannot load gateways");
exit;
};
...
Пример использования функции load_gws с параметром group-id:
...
if (!load_gws("1")) {
sl_send_reply("500", "Server Internal Error - Cannot load gateways from group 1");
exit;
};
...
next_gw()
Если функция вызывается из основного блока маршрутизации, она заменяет: URI схему, хост, номер порта и тип транспорта поля Request-URI на значения, сохраненные в первой AVP - gw_uri_avp и удаляет данную AVP. Сохраняет пользовательскую часть поля Request-URI в AVP - ruri_user_avp, для использования в последующих вызовах функции next_gw().Если функция используется в маршрутизационных блоках обработки ошибок (on_failure), то она добавляет новое ответвление (branch) для запроса, где URI схема, хост, порт и тип транспорта поля Request-URI заменяется на значения, сохраненные в первой AVP - gw_uri_avp и удаляет данную AVP. пользовательское поле Request-URI берется из AVP: ruri_user_avp.
Функция возвращает 1 в случае успеха и -1, если больше не осталось шлюзов или возникла ошибка (см. сообщения в syslog).
Перед использованием этой функции должна быть успешно выполнена функция load_gws().
Эта функция может использоваться из блоков: REQUEST_ROUTE, FAILURE_ROUTE.
Пример использования функции next_gw usage из основного блока маршрутизации REQUEST_ROUTE:
...
if (!next_gw()) {
sl_send_reply("503", "Service not available - No gateways");
exit;
};
Пример использования функции next_gw из блока маршрутизации FAILURE_ROUTE:
...
if (!next_gw()) {
t_reply("503", "Service not available - No more gateways");
exit;
};
...
from_gw([group-id])
Функция проверяет, поступил ли запрос с IP адреса, который принадлежит шлюзу. Если задан необязательный параметр group-id, то будут проверяться только адреса шлюзов входящих в указанную группу.Эта функция может использоваться из блоков: REQUEST_ROUTE, FAILURE_ROUTE, ONREPLY_ROUTE.
Пример использования функции from_gw:
...
if (from_gw()) {
...
exit;
};
...
Пример использования функции from_gw с идентификатором группы:
...
if (from_gw("1")) {
...
exit;
};
...
to_gw([group-id])
Функция проверяет факт того, что запрос в пределах диалога будет отправлен на адрес принадлежащий шлюзу. Если задан необязательный параметр group-id, то будут проверяться только адреса шлюзов входящих в указанную группу.Эта функция может использоваться из блоков: REQUEST_ROUTE, FAILURE_ROUTE.
Пример использования функции to_gw:
...
if (to_gw()) {
...
exit;
};
...
Пример использования функции to_gw с идентификатором группы:
...
if (to_gw("1")) {
...
exit;
};
...
load_contacts()
Функция загружает контактную информацию в массив адресов для отправки сообщения, которая имеют последовательно увеличивающиеся параметр qvalue, как значения для AVP lcr_contact. Если все контакты в наборе для отправки сообщения имеют одинаковое значение qvalue, функция load_contacts() не производит никаких действий, это позволяет минимизировать потери в производительности при разветвлении сообщения по разным адресам назначения, когда в этом нет необходимости. Функция возвращает 1, если загрузка контактов прошла успешна или, если нет контактов для загрузки. Возвращает -1 при возникновении ошибки (смотри сообщения из syslog).Эта функция может использоваться из блоков: REQUEST_ROUTE.
Пример использования функции load_contacts:
...
if (!load_contacts()) {
sl_send_reply("500", "Server Internal Error - Cannot load contacts");
exit;
};
...
next_contacts()
Если функция вызывается из основного блока маршрутизации, она заменяет поле Request-URI на первое значение AVP: lcr_contact, добавляет текущее значение AVP lcr_contact с тем же значением qvalue, как ответвление (branches), и удаляет данную AVP. Функция не производит никаких действий, если нет доступных AVP lcr_contact. Возвращает 1, при отсутствии ошибок или -1, при возникновении ошибки (смотри сообщения из syslog).Если функция используется в маршрутизационных блоках обработки ошибок (on_failure), добавляет первое значение AVP lcr_contact и все последующие значения lcr_contact с одинаковым значением qvalue, как новые ответвления (branches), к запросу и удаляет данные AVP. Возвращает 1, если было успешно добавлено новое ответвление (branch), или -1 при возникновении ошибки (смотри сообщения из syslog) или если больше нет доступных AVP: lcr_contact.
Перед использованием этой функции должна быть успешно выполнена функция load_contacts().
Эта функция может использоваться из блоков: REQUEST_ROUTE, FAILURE_ROUTE.
Пример использования функции next_contacts из блока маршрутизации REQUEST_ROUTE:
...
if (!next_contacts()) {
sl_send_reply("500", "Server Internal Error");
exit;
} else {
t_relay();
};
...
Пример использования функции next_contacts из блока маршрутизации FAILURE_ROUTE:
...
if (next_contacts()) {
t_relay();
};
...