Дабы подогреть интерес, прикрепил пример модуля, который динамически шейпит по такому критерию:
если за определенный интервал времени клиент утилизирует больше x% скорости своего тарифа, то ему устанавливается скорость y% тарифной на время z.
Естественно, можно усложнить модуль и включать эту фичу, если утилизация всей сеткой канала в интернет составляет w%.
Если посмотреть на модуль, то мы видим, что, несмотря на усложненную логику шейпа по сравнению со стандартным, читается и понимается он легко (я надеюсь на это).
Походу несколько комментариев. Вычислить загрузку канала в интервал времени - это не тривиальная задача как может показаться, поскольку необходимо иметь данные по трафику за каждый срез времени. Например, клиент скачал 100 мб в первую минуту, потом 200 во 2ю, 300 в 3ю и 400 в 4ю. Если считать среднюю скорость за 2 минуты, то в первые 2 минуты он скачал 300 мб, с 2й минуты по 3ю: 500 мб, с 3й по 4ю: 700 мб.
Вот это в скрипте:
# Массив значений трафика в определенную единицу времени:
# [ time1 , { uid1 => traf1, uid2 => traf2 } ],
# [ time2 , { uid1 => traf1, uid2 => traf2 } ],
my $Traf = ();
с этим все понятно:
# Подпишемся на событие `получен трафик клиентов`
nod->event_add('load_usr_traf', \&load_usr_traf);
Подпрограмма load_usr_traf заполняет $Traf в каждый срез. Кроме того, вычисляет среднюю скорость за требуемый промежуток времени. Естественно, при старте $Traf пустой и заполняется постепенно, поэтому пока не соберутся данные за требуемый период времени - скорости клиентов не трогаем.
$Limits_end хранит время, когда уже можно перестать понижать скорость:
$Limits_end->{$uid} = $time_now + $limit_period;
Единственная проблема, с которой вы можете столкнуться так это многоуровневые хеши и массивы. Я раньше пытался избегать их, чтобы проще было разобраться, однако результат был обратным - кучи переменных разбросанных по коду. Здесь же мы имеем иерархию в одном объекте:
$M->{users} - данные клиентов
$M->{users}{15} - данные клиента с id = 15
$M->{users}{15}{ip} - ip клиента с id = 15
После тестов, выложу и сам noserver