связка mpd5+dummynet за несколько часов работы трапает сервер.
Я задался целью отказаться от думинета и использовать ng_car.
Через радиус атрибуты в тарифном плане - не красиво. Пришлось немного поработать над биллингом.
Прошу оценить мои наработки.
в mpd.conf закомментируйте строки
set iface up-script "/usr/abills/libexec/linkupdown mpd up"
set iface down-script "/usr/abills/libexec/linkupdown mpd down"
Версия Abills у меня
=====0.42=====
27.05.2009\\
Изменения в файле abills/Abills/mysql/Auth.pm
Код: Выделить всё
488,489d487
<
<
565a564,666
> #MaK 29.05.2009 ng_car Shaper
> #=comment
> elsif ($NAS->{NAS_TYPE} eq 'mpd5') {
> #$traf_tarif
> my $EX_PARAMS = $self->ex_traffic_params( {
> traf_limit => $traf_limit,
> deposit => $self->{DEPOSIT},
> MAX_SESSION_TRAFFIC => $MAX_SESSION_TRAFFIC });
>
> #=comment
> my $net_id = 0;
> my @net_list = ();
> my $flt_num = 1;
> my $lim_num_in = 1;
> my $lim_num_out = 1;
>
> my $flt_in = "";
> my $flt_out = "";
> my $limit_in = "";
> my $limit_out = "";
> my $speed_in = 0;
> my $speed_out = 0;
>
> my $is_first = 1;
> my $is_filter = 0;
> my $burst = 0;
>
> #Last ID of traff_tariff
> $net_id = $EX_PARAMS->{id};
> for(my $i=$net_id; $i>=0; $i--) {
> if (defined($EX_PARAMS->{net_list}->{$i})) {
> @net_list = split(/\n|\r|;/, $EX_PARAMS->{net_list}->{$i});
> $is_first = 1;
>
> #Generate match rules for mpd
> foreach my $line (@net_list) {
> if (length($line) >= 8) {
> if ($is_first == 1)
> {
> $flt_in = $flt_num . "#1=match ";
> $limit_in = "in#" . $lim_num_in++ . "#Traf" . $i . "=flt" . $flt_num++;
>
> $flt_out = $flt_num . "#1=match ";
> $limit_out = "out#" . $lim_num_out++ . "#Traf" . $i . "=flt" . $flt_num++;
>
> $is_first = 0;
> }
> else
> {
> $flt_in .= " or ";
> $flt_out .= " or ";
> }
> $flt_out .= "src net " . $line;
> $flt_in .= "dst net " . $line;
> }
> }
> if ($is_first == 1) { # Якщо мережі не прописані, значить лімітувати весь трафік
> $limit_in = "in#" . $lim_num_in++ . "#Traf" . $i . "=all ";
> $limit_out = "out#" . $lim_num_out++ . "#Traf" . $i . "=all ";
> }
> else { #закидуємо в параметри фільтри
> push @{ $RAD_PAIRS->{'mpd-filter'} }, $flt_in;
> push @{ $RAD_PAIRS->{'mpd-filter'} }, $flt_out;
> }
>
> if ($i == 0 && $self->{USER_SPEED} > 0)
> {
> $speed_in = int($self->{USER_SPEED}) * $CONF->{KBYTE_SIZE};
> $speed_out = $speed_in;
> }
> else {
> $speed_in = int($EX_PARAMS->{speed}->{$i}->{IN}) * $CONF->{KBYTE_SIZE};
> $speed_out = int($EX_PARAMS->{speed}->{$i}->{OUT}) * $CONF->{KBYTE_SIZE};
> }
>
> if ($speed_in > 0) {
> $burst = $speed_in * 3 / 16;
> if ($speed_in <= 2097152) {
> $limit_in .= " shape " . $speed_in . " $burst";
> }
> else {
> $limit_in .= " rate-limit " . $speed_in . " $burst " . $burst*2;
> }
> }
> if ($speed_out > 0) {
> $burst = $speed_out * 3 / 16;
> if ($speed_out <= 2097152) {
> $limit_out .= " shape " . $speed_out . " $burst";
> }
> else {
> $limit_out .= " rate-limit " . $speed_out . " $burst " . $burst*2;
> }
> }
> $limit_in .= " pass";
> $limit_out .= " pass";
> push @{ $RAD_PAIRS->{'mpd-limit'} }, $limit_in;
> push @{ $RAD_PAIRS->{'mpd-limit'} }, $limit_out;
> }
> }
> #трафік, який буде передаватись стандартними атрибутами радіуса
> $RAD_PAIRS->{'mpd-input-acct'} = "Traf0";
> $RAD_PAIRS->{'mpd-output-acct'}= "Traf0";
> }
1064,1065c1165,1166
<
< $self->query($db, "SELECT id, in_price, out_price, prepaid, in_speed, out_speed, LENGTH(nets), expression
---
> #MaK 29.05.2009 Added field nets and ORDER BY. This changes related to mpd-limit
> $self->query($db, "SELECT id, in_price, out_price, prepaid, in_speed, out_speed, LENGTH(nets), expression, nets
1067c1168,1169
< WHERE interval_id='$self->{TT_INTERVAL}';");
---
> WHERE interval_id='$self->{TT_INTERVAL}'
> ORDER BY id DESC;");
1075c1177
<
---
> my $max_id = 0;
1077a1180,1186
> #MaK 29.05.2009 This changes related to mpd-limit
> if ($max_id == 0) {
> $max_id=int($line->[0]);
> $EX_PARAMS{id}=$max_id;
> }
> $EX_PARAMS{net_list}{$line->[0]}=$line->[8];
>
Если скорость меньше 2 Мбит/с используется shape
Больше - rate-limit
Если 0 - ограничение снимается
Меня интерисует, правильно ли я выбрал условия использования шейпа и рейтлимита. И правильно ли я расчитываю бурст.
В этом коде уже реализовано Typed Accounting Update http://mpd.sourceforge.net/doc5/mpd36.html#36. Тоесть мпд уже отдаёт на радиус объёмы трафика по зонах такими атрибутами как mpd-input-packets = Local:213213 . При этом глобальный трафик отдаётся, кроме того, стандартными атрибутами. Пока что абилс не учитывает дополнительные атрибуты. Я планирую оценить возможность доработки по учету трафика по зонам.
Ну и вообще, если есть замечания по коду - пишите.