Сессии

Статус сессии

В ходе жизненного цикла сессия, привязанная к устройству, проходит несколько статусов: ожидание (waiting), активна (working), приостановлена (suspended), закрыта (closed) и завершена (finished). Сессии могут создаваться/закрываться по сигналу (RADIUS, DHCP), либо по наличию трафика (netflow/sflow) и его отсутствию в течение какого-то времени (автосессии).

При типе инициации "по сигналу" соединение может быть приостановлено, а затем закрыто при отсутствии в течение определённого времени пакетов, подтверждающих её активность (RADIUS-Update, DHCP-Request). Таймауты после последнего подобного пакета задаются в секундах переменными конфигурации устройства connection.suspend.timeout (таймаут после последнего подтверждающего пакета, после которого соединение будет считаться приостановленным) и connection.close.timeout (таймаут после последнего подтверждающего пакета, когда соеденение будет закрыто, если оно уже приостановлено). Приход подтверждающего пакета переводит соединение из приостановленного статуса в активный. Значения параметры connection.suspend.timeout и connection.close.timeout рекомендуется указывать чуть больше, чем 2 * (время между RADIUS/DHCP пакетами). При завершении соединения по сигналу Stop-пакетом (RADIUS-Stop) оно фактически завершается через количество секунд, определяемое переменной connection.finish.timeout. Это позволяет, в частности, реализовать сбор "запоздалой" информации о трафике, которая может прийти после Stop-пакета.

После перезапуска InetAccounting временем последней активности сессии считает время запуска InetAccounting (а не время из столбца "Активность" сессии). Это сделано для того, чтобы при возможном долгом простое InetAccounting, после его запуска он не начал завершать все сессии по таймауту.

Для автоматических сессий (сессий по трафику) параметр connection.close.timeout определяет время в секундах после последнего поступления информации о трафике данной сессии, по прошествии которого, сессия будет завершена. Для таких сессий не рекомедуется устанавливать слишком маленькое значение connection.close.timeout. Параметр connection.auto.minDuration указывает минимальную длительность для сессии по трафику. Рекомендуемые значения для сессий по трафику:

connection.close.timeout=3600
connection.auto.minDuration=1800

Приостановленная сессия не учитывается в ограничении на количество сессий, однако её IP-адрес не выдаётся до тех пор, пока она не завершена.

Для сессий в состоянии "отключена" можно назначить другие значения таймаутов после последнего RADIUS-пакета: connection.disable.suspend.timeout (по умолчанию равен значению connection.suspend.timeout) и connection.disable.close.timeout (по умолчанию равен значению connection.close.timeout), т.к. на отдельных маршрутизаторах для сессий в таком состоянии можно увеличить интервал посылки update-пакетов.

Состояние сессии

Также как у сервиса, у сессии может быть состояние: подключена или отключена. Состояние "подключена" означает, что доступ открыт, клиент может нормально работать, "отключена" - означает, что доступ закрыт - используется для схем без физического отключения сессий, например, когда вместо PoD-пакета при нехватке денег на балансе отправляется CoA с запретом всех направлений, кроме сервера статистики; или при инициации сессии по трафику, когда доступом управляет коммутатор: в состоянии "отключена" тарификация сессии не производится.

По умолчанию состояние сессии всегда "подключена". Переключить состояние сессии можно в обработчике процессора протокола при приходе update-пакета RADIUS (или же start/stop пакета сервисной сессии), в зависимости от содержимого этого пакета: request.setOption( InetRadiusProcessor.DEVICE_STATE, InetServ.STATE_ENABLE ) или request.setOption( InetRadiusProcessor.DEVICE_STATE, InetServ.STATE_DISABLE ). А также в обработчике активации сервисов, если по RADIUS-пакетам не ясно в каком состоянии сессия: для этого в connectionModify( e ) при обработке переключения доступа нужно установить e.setConnectionStateModified( true ). В стандартных обработчиках этот функционал уже реализован и требует только настройки для соответствующего обработчика - например, sa.radius.connection.stateModify=1 для CoAServiceActivator меняет состояние после получения ACK на CoA-запрос блокировки или шаблон radius.disable.pattern.attributes для CoAProtocolHandler меняет состояние по наличию или отсутствию указанного набора атрибутов, а radius.serviceName.disable для ISGProtocolHandler/SmartEdgeProtocolHandler меняет состояние в зависимости от наличия или отсутствия сервисной сессии с указанным именем.

При работе с RADIUS, если по Start-пакету нельзя определить в каком состоянии началась сессия или ни в Start-пакете, ни в Update от NASа не приходит IP-адрес, в конфигурации устройства - NAS'а, или в конфигурации его типа устройства, или в одном из предков следует указать параметр connection.start.fromAccept=1. В этом режиме при отправке Access-сервером Access-Accept в ответ на Access-Request в базу будет добавлена запись по сессии в статусе ожидание (waiting), которую считает Accounting-сервер при получении Start-пакета. По умолчанию этот режим отключен.

Рекомендуемые параметры для определения состояния сессии

Суммируя вышесказанное, за определение текущего состояния сессии отвечают параметры:

# при значении 1 перед выдачей Access-Accept InetAccess заносит запись в БД об этом соединении (рекомендуется)
connection.start.fromAccept=1
# состояние соединения можно определить по наличию определенных атрибутов в Accounting-пакетах (не рекомендуется)
radius.disable.pattern.attributes=
# при значении 1 InetAccess при вызове для изменения состояния метода connectionModify из CoAServiceActivator/ISGServiceActivator/SmartEdgeServiceActivator сразу поменяет состояние в БД (вызовет e.setConnectionStateModified( true ), рекомендуется для CoAServiceActivator)
sa.radius.connection.stateModify=1
# для схем ISG, SmartEdge с посервисным аккаунтингом состояние сессии можно определять по активности сервиса ISG/SmartEdge (рекомендуется для схем с посервисным аккаунтингом)
radius.serviceName.disable=

При этом в разных схемах необходимо указывать только некоторые из них (см. далее).

Обычный CoA/PoD

# перед выдачей Access-Accept InetAccess заносит запись в БД об этом соединении
connection.start.fromAccept=1
# InetAccess при отправке CoA сразу поменяет состояние в БД
sa.radius.connection.stateModify=1

Cisco ISG/SmartEdge

# перед выдачей Access-Accept InetAccess заносит запись в БД об этом соединении
connection.start.fromAccept=1
# InetAccess при отправке CoA не меняет состояние в БД
sa.radius.connection.stateModify=0
# текущее состояние сессии определяется по наличию сервисного RADIUS-аккаунтинга
radius.serviceName.disable=<сервис(ы) с ограниченным доступом, через запятую>

Старт сессии по UPDATE-пакету

Бывают ситуации, когда start-пакет не дошел до Accounting-сервера. В этом случае, при connection.start.fromUpdate=1 (значение по умолчанию) сессия создастся от текущего момента. При connection.start.fromUpdate=2 Accounting проверит, что время сессии из update/stop пакета не больше, чем значение connection.close.timeout и создаст сессию от ее начала, иначе, если время сессии больше чем connection.close.timeout, сессия создастся от текущего момента. При connection.start.fromUpdate=0 сессия без старт-пакета создана не будет.

Логическое разбиение сессий

При наступлении нового дня происходит логическое разбиение сессии, т.е. сессия заканчивается в 23:59:59 предыдущего дня и начинается новая в 00:00:00 нового дня. При этом физического разрыва подключения абонента не происходит. Также для правильного переобсчета сессия логически разбивается при активации или деактивации тарифной опции. При посервисном аккаунтинге (SmartEdge или ISG) необходимость в разбиении отпадает - для того, чтобы отключить этот режим, в конфигурации нужно указать session.split.onTariffOption=0.

При использовании схем без физического отключения сессий (исключая посервисный аккаунтинг) или при инициации сессии по трафику (Netflow/sFlow/SNMP) для правильного переобсчета необходимо также логически разбивать сессию при переключении ее состояния (подключена/отключена). Для этого в конфигурации нужно указать session.split.onDeviceState=1.

В этом случае сессия, например, при переключении доступа при нехватке средств на балансе с обычного на ограниченный (доступ только к личному кабинету) будет логически разделена в БД на две - завершенную с состоянием "подключена" и новую активную с состоянием "отключена".

Пример конфигурации устройства

# При выдаче Access-Accept добавлять запись в базу;
# необходимо, если используется Reject-to-Accept и по Start-пакету нельзя определить в каком состоянии соединение
#connection.start.fromAccept=0
# При создании сессии по Update-пакету, 0 - не создавать сессии без Start-пакета, 1 - создать сессию от текущего момента,
# 2 - создавать сессию от реального времени начала, если время сессии не больше connection.close.timeout
#connection.start.fromUpdate=1
 
# Таймаут перевода соединения в статус suspended при остутствии RADIUS-пакетов
connection.suspend.timeout=900
# Таймаут перевода соединения в статус suspended при остутствии RADIUS-пакетов для сессии в состоянии отключен
# (по умолчанию используется значение connection.suspend.timeout)
#connection.disable.suspend.timeout=900
# Таймаут закрытия соединения при остутствии RADIUS-пакетов или, для сессий, создаваемых по наличию трафика, при отсутствии flow-пакетов
# (не складывается с connection.suspend.timeout)
connection.close.timeout=900
# Таймаут закрытия соединения при остутствии RADIUS-пакетов или, для сессий, создаваемых по наличию трафика, при отсутствии flow-пакетов
# в состоянии отключен (не складывается с connection.disable.suspend.timeout, по умолчанию используется значение connection.close.timeout)
#connection.disable.close.timeout=1800
# Таймаут завершения закрытой сессии
connection.finish.timeout=5
 
# Нужно ли логически разрывать сессию при переключении состояния
session.split.onDeviceState=0
# Нужно ли логически разрывать сессию при активации или деактивации тарифной опции
session.split.onTariffOption=1