public function getUserTrafByThisDay(&$totalDay, &$totalIP) {
$thisdate = date('Y-m-d');
$handle1 = fopen($this->world.$thisdate, "r");
$handle2 = fopen($this->city.$thisdate, "r");
$sum['win'] = '0';
$sum['wout'] = '0';
$sum['cin'] = '0';
$sum['cout'] = '0';
while ($userinfo = fscanf($handle1, "%s\t%s\t%s\n")) {
$userByIp[$userinfo[0]]['win'] = $userinfo[1];
$userByIp[$userinfo[0]]['wout'] = $userinfo[2];
$sum['win'] = bcadd($sum['win'], $userinfo[1]);
$sum['wout'] = bcadd($sum['wout'], $userinfo[2]);
if (isset($totalIP[$userinfo[0]])) {
$totalIP[$userinfo[0]]['win'] = bcadd($totalIP[$userinfo[0]]['win'], $userinfo[1]);
$totalIP[$userinfo[0]]['wout'] = bcadd($totalIP[$userinfo[0]]['wout'], $userinfo[2]);
}
else {
$totalIP[$userinfo[0]]['win'] = $userinfo[1];
$totalIP[$userinfo[0]]['wout'] = $userinfo[2];
$totalIP[$userinfo[0]]['cin'] = '0';
$totalIP[$userinfo[0]]['cout'] = '0';
}
}
while ($userinfo = fscanf($handle2, "%s\t%s\t%s\n")) {
$userByIp[$userinfo[0]]['cin'] = $userinfo[1];
$userByIp[$userinfo[0]]['cout'] = $userinfo[2];
$sum['cin'] = bcadd($sum['cin'], $userinfo[1]);
$sum['cout'] = bcadd($sum['cout'], $userinfo[2]);
if (isset($totalIP[$userinfo[0]])) {
$totalIP[$userinfo[0]]['cin'] = bcadd($totalIP[$userinfo[0]]['cin'], $userinfo[1]);
$totalIP[$userinfo[0]]['cout'] = bcadd($totalIP[$userinfo[0]]['cout'], $userinfo[2]);
}
else {
$totalIP[$userinfo[0]]['cin'] = $userinfo[1];
$totalIP[$userinfo[0]]['cout'] = $userinfo[2];
}
}
fclose($handle1);
fclose($handle2);
$trafByDay[$thisdate] = $userByIp;
$totalDay[$thisdate] = $sum;
unset ($userByIp);
unset ($sum);
return $trafByDay;
}
<?php
class Limit {
private $limitFile = "billing/limit";
private $users = "/usr/local/etc/ethers";
private $userMAC;
private $userLimit;
private function getLimit() {
$handle = fopen($this->limitFile, "r");
while ($userinfo = fscanf($handle, "%s\t%s\t%s\t%s\n")) {
$this->userLimit[$userinfo[0]]['in'] = $userinfo[1];
$this->userLimit[$userinfo[0]]['out'] = $userinfo[2];
$this->userLimit[$userinfo[0]]['total'] = $userinfo[3];
}
fclose($handle);
}
private function getUserMAC() {
$handle = fopen($this->users, "r");
while ($userinfo = fscanf($handle, "%s\t%s\n")) {
$this->userMAC[$userinfo[1]] = $userinfo[0];
}
fclose($handle);
}
public function disableUsers() {
$this->getLimit();
$this->getUserMAC();
include_once("FileExtractor.php");
$fe = new FileExtractor();
$trafByDay = $fe->getUserTrafByDay($totalDay, $totalIP);
foreach ($this->userLimit as $ip => $limit) {
if (isset ($this->userMAC[$ip]) && isset ($totalIP[$ip]) &&
( bccomp(bcdiv($totalIP[$ip]['win'], '1048576'), $limit['in']) == 1
|| bccomp(bcdiv($totalIP[$ip]['wout'], '1048576'), $limit['out']) == 1
|| bccomp(bcdiv(bcadd($totalIP[$ip]['win'], $totalIP[$ip]['wout']), '1048576'), $limit['total']) == 1
)
){
shell_exec('iptables -D MAC_IP -s '.$ip.' -m mac --mac-source '.$this->userMAC[$ip].' -j RETURN');
}
}
}
}
$limit = new Limit();
$limit->disableUsers();
?>
Все лимиты задаются целыми числами.
пользователю дано 1750МБ входящего, 275МБ исходящего трафик и 2010МБ суммарного трафика (входящий+исходящий). При достижении пользователем хотя бы одного из ограничений он будет отключен.
В этот файл можно не вписывать всех пользователей, если мы не хотим задавать для них лимит.
+ Необходимо настроить кроны:
В кронтаб добавить:
*/5 * * * * root cd /opt/share/www/statistic/ && /opt/bin/php ./limit.php > /dev/null 2>&1 1 0 1 * * root /user/local/sbin/makefilter
1 0 1 * * root /user/local/sbin/makefilter
0 0 * * * root /user/local/sbin/makefilter
billing.php
измените строки$yesterday = date("Y-m", time()-300);
if (date("Y-m") != $yesterday) {
$yesterday = date("Y-m-d", time()-300);
if (date("Y-m-d") != $yesterday) {
if
выполняется удаление файлов с данными о использованном трафике. При их отсутствии должна сниматься блокировка. В данный блок можно попасть если только 5 минут назад было не тот же месяц и год, что сейчас (наступил следующий месяц). Поэтому для снятия блокировки ежедневно, необходимо проверять еще день. То есть "Y-m"
надо заменить на "Y-m-d"
, что позволит выполнять удаление файлов каждый день. Ну и мой предыдущий ответ про cron тоже надо учесть.