...
По уникальному внешнему идентификатору выполняется поиск имеющейся неархивной записи о сессии в коллекции sessions
базы данных кэша. Если подходящая запись найдена, она обновляется данными из пакета, если нет — пакет аккаунтинга считается первым по сессии и создаётся новая запись о сессии.
Схема поиска сессий
На схеме t1 - момент начала поиска сессии. От момента t1 до (t1 -
...
.
...
.
...
. → accounting → session → lookup → hours) (синий интервал) подбирается
...
активная сессия (сессия, не закртая по таймауту), сессия закртая по таймауту ищется на интервале от t1 до (t1 - ... → accounting
...
→ session
...
→ lookup
...
→ timed_out_days) (не отмечен на схеме). Зеленый интервал - интервал, в котором batch
...
закрыл сессии, обычно этот интервал и синий интервал поиска
...
не закрытых по таймауту сессий - пересекаются (в крайнем случае - идут встык)
...
. Если по каким либо причинам batch не работал определенное время, между этими интервалами возникнет пробел, сессия, попавшая в этот пробел не подберется, и создастся ее дубль. Для разрешения таких ситуаций к интервалу подбора активных сессий добавляется ... → accounting
...
→ session
...
→ lookup
...
→ additional_hours (обозначен красным не схеме).
При обработке первого пакета аккаунтинга по сессии ядро плагина подбирает профили абонентского и операторского оборудования в соответствии с критериями, указанными в ключах customer_profile
и provider_profile
блока plugins
→ base
→ <plugin_instance_name>
→ actions
→ accounting
. Эти профили фиксируются в сессии и используются для определения её типа при загрузке в основную БД Гидры. Подбор профилей настраивается аналогично действию authorize
. Как правило, критерии подбора профилей используются те же, что и в действии authorize
— чтобы их не повторять в конфигурации, рекомендуется применять такие элементы YAML-формата как якори и ссылки.
...
В условиях применения шаблона можно использовать данные подобранной ядром плагина записи о сессии, которые доступны через системную переменную $session
$prev_session
. Это позволяет, например, настраивать выбор шаблона сессии по данным профилей оборудования, которые были подобраны при обработке первого пакета аккаунтинга по сессии.
Code Block | ||||
---|---|---|---|---|
| ||||
plugins: base: l2tp-by-login: actions: authorize: ... authenticate: ... accounting: # Абонентский профиль подбирается так же, как и при авторизации customer_profile: <<: *customer_profile # Операторский профиль не используется provider_profile: {} session: # Набор атрибутов для формирования уникального внешнего идентификатора сессии unique_id_attributes: [User-Name, NAS-IP-Address, Framed-IP-Address, NAS-Port] # Шаблоны сессий templates: # Сессия с доступом в Интернет - condition: ' $customer_profile.attributes.try("Service-State-Code") == "SERV_STATE_Provision" or $session$prev_session.attributes.try("Service-State-Code") == "SERV_STATE_Provision"' attributes: &session_attributes Calling-Station-Id: $request.RAD_REQUEST.try("Calling-Station-Id") Called-Station-Id: $request.RAD_REQUEST.try("Called-Station-Id") Framed-IP-Address: $request.RAD_REQUEST.try("Framed-IP-Address") NAS-Identifier: $request.RAD_REQUEST.NAS-Identifier NAS-IP-Address: $request.RAD_REQUEST.NAS-IP-Address Service-State-Code: $customer_profile.attributes.try("Service-State-Code") Session-Template: '"Full access session"' User-Name: $request.RAD_REQUEST.User-Name # Тарификация потоковых услуг передачи данных # Счётчики в пакетах приходят относительно сервера доступа — необходимо инвертировать направление для абонента services: # Услуга «Интернет-трафик вх.» - service_id: 40213701 value: $request.RAD_REQUEST.try("Acct-Output-Octets", "0").to_i() + 4 * $request.RAD_REQUEST.try("Acct-Output-Gigawords", "0").to_i().gigabytes() unit: bytes # Услуга «Интернет-трафик исх.» - service_id: 40213501 value: $request.RAD_REQUEST.try("Acct-Input-Octets", "0").to_i() + 4 * $request.RAD_REQUEST.try("Acct-Input-Gigawords", "0").to_i().gigabytes() unit: bytes # Гостевые сессии незарегистрированных абонентов — не нужно загружать в Гидру - condition: ' $customer_profile.null?() and $session$prev_session.customer_profile_id.empty?()' attributes: <<: *session_attributes Session-Template: '"Guest session"' load_to_hydra: false # Сессии с ограниченным доступом — не нужно тарифицировать услуги - attributes: <<: *session_attributes Session-Template: '"Restricted session"' services: {} |
...