Модуль сервера 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();
};
...



Ссылки по теме