BiTel

Форум BiTel
bgbilling.ru     docs.bitel.ru     wiki.bitel.ru     dbinfo.bitel.ru     bgcrm.ru     billing.bitel.ru     bitel.ru    
Текущее время: 10 май 2024, 07:34

Часовой пояс: UTC + 5 часов [ Летнее время ]




Начать новую тему Ответить на тему  [ Сообщений: 5 ] 
Автор Сообщение
СообщениеДобавлено: 25 май 2009, 19:51 
Не в сети

Зарегистрирован: 20 окт 2008, 12:14
Сообщения: 121
Карма: 3
Конфигурация
Код:
user_rule.editor.class=bitel.billing.module.services.ipn.editor.ManadContractRuleEditor
gate_manager.class=bitel.billing.server.ipn.ManadGateWorker
use.script=1

Скрипт
Код:
import java.io.*;
import java.net.*;
import java.util.*;
import bitel.billing.common.module.ipn.*;
import bitel.billing.server.ipn.bean.*;
 
void doSync()
{
   host = gate.getHost();
   port = gate.getPort();
   gid = gate.getId();
 
   if ( log.isDebugEnabled() )
   {
       log.debug( gid + " gate: " + host + ":" + port );
   }
 
 
      socket = new Socket( host, port );
      out = new PrintWriter( socket.getOutputStream(), true );
      isr = new InputStreamReader( socket.getInputStream() );
      in = new BufferedReader( isr );
 
      out.println( "test" );
      kods = in.readLine();
 
                if ( log.isDebugEnabled() )
                {
                    log.debug( gid + " Test => " + kods + "\n" );
                }
 
      // список открытых договоров с шлюза
      gateRules = new HashSet( 5, 5 );
      st = new StringTokenizer( kods );
      while ( st.hasMoreTokens() )
      {
         gateRules.add( new Integer( st.nextToken() ) );
      }
 
      for( i = 0; i < statusList.size(); i++ )
      {
         status = statusList.get(i);
         cid = status.contractId;
 
         // флаг того то правило есть на шлюзе
         flag = false;
 
         // правило для этого договора есть на шлюзе
         if ( gateRules.contains( cid ) )
         {
            //   если правило есть и юзер открыт делаем проверку шейпера
            if ( status.status == IPNContractStatus.STATUS_OPEN )
                {
               rule = getRule( status );
               command = "check\t" + cid.intValue() + "\t" + rule;
               out.println( command );
                    if ( log.isDebugEnabled() )
                    {
                        log.debug( gid + " " + command );
                    }
                }                  
            //   если правило есть а юзер заблокирован - удаляем правило
            if ( status.status > 0 )
                {
               rule = getRule( status );
               command = "remove\t" + cid.intValue() + "\t" + rule;
               out.println( command );
                    if ( log.isDebugEnabled() )
                    {
                        log.debug( gid + " " + command );
                    }
                }                  
 
            flag = true;
            gateRules.remove( cid );
         }
 
         // правила нет, а юзер открыт
         if ( !flag &&
            status.status == IPNContractStatus.STATUS_OPEN )
         {
            rule = getRule( status );
 
            command = "add\t" + cid.intValue() + "\t" + rule;
            out.println( command );
 
             if ( log.isDebugEnabled() )
                {
                    log.debug( gid + " " + command );
                }
         }
      }
 
      in.close();
      out.close();
      socket.close();   
}
 
getRule( status )
{
   rule = null;
 
   // пользовательское правило, без типа
   if( status.ruleType == null )
   {
      rule = status.rule.getRuleText();
   }
   // типизированное правило
   else
   {   
      rule = generateRule( status.rule.getRuleText(), status.gateType, status.ruleType );         
   }
 
   rule = rule.replaceAll( "\r", "" );
   rule = rule.replaceAll( "\n", "|" );
 
   return rule;
}   
 
generateRule( addresses, gateType, ruleType )
{
    ruleText = ManadUtils.getRule( gateType, ruleType );
    return ManadUtils.generateRule( ruleText, addresses, null, ruleType );       
}

Сам манад чуть попозже, есть одна неоднозначость которую решить надо.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: 26 май 2009, 17:09 
Не в сети

Зарегистрирован: 20 окт 2008, 12:14
Сообщения: 121
Карма: 3
Код:
#!/usr/bin/perl

use POSIX;
use IO::Socket;
use IO::Select;
use Socket;
use Fcntl;
use Tie::RefHash;

$debug = 1;
$port = 4567;
$iptables = "/sbin/iptables";
$rule_insert_index = 1;

$| = 1;
print "starting manad..\n";

# База данных правил клиентов
%CLRULE = ();
%NRULE = ();
%RUL_NUMBERS = ();
%DEL_RULES = ();
%CHECK_RULES = ();
%CONTRACT_INDEX = ();


# Начать с пустыми буферами
%inbuffer   = ();
%outbuffer   = ();
%ready      = ();

tie %ready, 'Tie::RefHash';

# Прослушивать порт
$server = IO::Socket::INET->new( LocalPort => $port, Listen => 10 )
   or die "Can`t make server socket: $@\n";

nonblock( $server );

$SIG{INT} = sub { $server->close(); exit( 0 ); };

$select = IO::Select->new( $server );

$pid = getpid();

open(FILE, ">/var/run/manad.pid");
print FILE $pid;
close(FILE);

# Устанавливаем новый root каталог для процесса
# chroot( $homedir ) or die "Couldn`t chroot to $homedir: $!\n";

# Главный цикл: проверка чтения/принятия, проверка записи,
# проверка готовности к работе

while( 1 )
{
   my $client;
   my $rv;
   my $data;

   # Проверить наличие новой информации на имеющихся подключениях

   # Есть ли что-нибудь для чтения или подтверждения?   
   foreach $client ( $select->can_read( 1 ) )
   {
      if ( $client == $server )
      {
         # Принять новое подключение
         $client = $server->accept();
         $select->add( $client );
         nonblock( $client );
      }      
      else
      {
         # Прочитать данные
         $data = '';
         $rv = $client->recv( $data, POSIX::BUFSIZ, 0 );

         unless( defined( $rv ) && length $data )
         {
            # Это должен быть конец файла, поэтому закрываем клиента
            delete $inbuffer{$client};
            delete $outbuffer{$client};
            delete $ready{$client};

            $select->remove( $client );
            close $client;
            next;
         }

         $inbuffer{$client} .= $data;

         # Проверить, говорят ли данные в буфере или только что прочитанные
         # данные о наличии полного запроса, ожидающего выполнения. Если да -
         # заполнить $ready{$client} запросами, ожидающими обработки.
         while( $inbuffer{$client} =~ s/(.*\n)// ) { push( @{$ready{$client}}, $1 ) }
      }
   }
   
   # Есть ли полные запросы для обработки?
   foreach $client ( keys %ready ) { handle( $client ); }

   # Сбрасываем буферы?
   foreach $client ( $select->can_write( 1 ) )
   {
      # Пропустить этого клиента, если нам нечего сказать
      next unless $outbuffer{$client};

      $rv = $client->send( $outbuffer{$client}, 0 );
      unless( defined $rv )
      {
         # Пожаловаться, но следовать дальше
         warn "I was told I could write? but I can`t.\n";
         next;
      }
      if ( $rv == length $outbuffer{$client} || $! == POSIX::EWOULDBLOCK )
      {
         substr( $outbuffer{$client}, 0, $rv ) = '';
         delete $outbuffer{$client} unless length $outbuffer{$client};
      }
      else
      {
         # Не удалось записать все данные и не из-за блокировки.
         # Очистить буферы и следовать дальше.
         delete $inbuffer{$client};
         delete $outbuffer{$client};
         delete $ready{$client};

         $select->remove($client);
         close($client);
         next;
      }
   }
}

# handle( $socket ) обрабатывает все необработанные запросы
# для клиента $client
sub handle
{
   # Запрос находится в $ready{$client}
   # Отправить вывод в $outbuffer{$client}
   my $client = shift;
   my $request;

   foreach $request ( @{$ready{$client}} )
   {

      print "\nrequest =".$request."\n" if ( $debug == 1 );
      
      if ( $request =~ /^test/ )
      {
         my $open_client = "";
         foreach my $kod ( keys %CLRULE )
            { $open_client .= $open_client eq "" ? $kod : " ".$kod; }
         $outbuffer{$client} .= $open_client."\n";
      }
      elsif ( $request =~ /^add\t([0-9]+)\t(.*)/ )
      {
         my ($kod, $rule) = ($1, $2);
         &delete_rule( $kod, $rule ) if ( exists $CLRULE{$kod} );
         &add_rule( $kod, $rule ) if ( !exists $CLRULE{$kod} );
      }
      elsif ( $request =~ /^remove\t([0-9]+)(\t(.*))?/ )
      {
         my $kod = $1;         
         &delete_rule( $kod ) if ( exists $CLRULE{$1} );
      }
      elsif ( $request =~ /^check\t([0-9]+)\t(.*)/ )
      {
         my ($kod, $rule) = ($1, $2);
         &check_rule( $kod, $rule ) if ( exists $CLRULE{$1} );
      }
   }

   delete $ready{$client};
}

# nonblock( $socket ) переводит сокет в неблокирующий режим
sub nonblock
{
   my $socket = shift;
   my $flags;

   $flags = fcntl( $socket, F_GETFL, 0 )
      or die "Can`t get flags for socket: $!\n";
   fcntl( $socket, F_SETFL, $flags | O_NONBLOCK )
      or die "Can`t make socket nonblocking: $!\n";
}

sub add_rule
{
   my $kod = $_[0];
   my $rule = $_[1];
   
   #заменяем все контсрукции типа {N0}
   while ( $rule =~ /\[N([0-9]+)\]/ )
   {
      my $n = $1;
      my $i = 20;   

      #находим первый свободный номер
      while( 1 )
      {
         $i++;
         last if ( !exists $RUL_NUMBERS{$i} );
      }
      $RUL_NUMBERS{$i} = "1";
      $rule =~ s/\[N$n\]/$i/g;

      $CONTRACT_INDEX{$kod}{$i}=$i;
      $NRULE{$kod}{$n} = $i;
   }

   $CLRULE{$kod} = $rule;
   
   #добавляем правило
   my $add_rule = $rule;
   $add_rule =~ s/\[OPEN\]((.|\n)+)\[\/OPEN\]((.|\n)*)/${1}/;
   
   print "commands:\n" if ( $debug == 1 );   
   my @rules = split( /\|/, $add_rule );
        foreach $line ( @rules )
        {
           print "$line\n" if ( $debug == 1 );
           $err = `$line`;
        }
   #запоминаем правило на удаление в кэш
   my $del_rule = $rule;
   $del_rule =~ s/(?:(.|\n?:)*)\[CLOSE\]((.|\n)+)\[\/CLOSE\]((.|\n)*)/${2}/;
   print "\ndelete =".$del_rule."\n" if ( $debug == 1 );
   $DEL_RULES{$kod}=$del_rule;

   my $check_rule = $rule;
   $check_rule =~ s/(?:(.|\n?:)*)\[CHECK\]((.|\n)+)\[\/CHECK\]((.|\n)*)/${2}/;
   print "\ncheck =".$check_rule."\n" if ( $debug == 1 );
   $CHECK_RULES{$kod}=$check_rule;
}

sub check_rule
{
   my $kod = $_[0];
   my $rule = $_[1];

   my $check_rule = $rule;
   $check_rule =~ s/(?:(.|\n?:)*)\[CHECK\]((.|\n)+)\[\/CHECK\]((.|\n)*)/${2}/;

   while ( $check_rule =~ /\[N([0-9]+)\]/ )
   {
      my $n = $1;
      $check_rule =~ s/\[N$n\]/$NRULE{$kod}{$n}/g;
   }

   $CHECK_RULES{$kod}=$check_rule;

   print "rules\n";
   print "$CHECK_RULES{$kod}";

   my $rule = $CHECK_RULES{$kod};
          my @rules = split( /\|/, $rule );

   print "commands:\n" if ( $debug == 1 );          
   foreach $line ( @rules )
        {
           print "$line\n" if ( $debug == 1 );
           $err = `$line`;
        }
}

sub delete_rule
{
   my $kod = $_[0];

   my $rule = $DEL_RULES{$kod};
          my @rules = split( /\|/, $rule );

   print "commands:\n" if ( $debug == 1 );          
   foreach $line ( @rules )
        {
           print "$line\n" if ( $debug == 1 );
           $err = `$line`;
        }

   delete $DEL_RULES{$kod};   
   delete $CHECK_RULES{$kod};   
   delete $NRULE{$kod};   
   delete $CLRULE{$kod};

   foreach my $idx ( keys %{$CONTRACT_INDEX{$kod}} )
   {
       print "\n deleting rules with idx=".$CONTRACT_INDEX{$kod}{$idx}."\n";      
       delete $RUL_NUMBERS{$CONTRACT_INDEX{$kod}{$idx}};              
   }   
   
   delete $CONTRACT_INDEX{$kod};
}

Теперь в теги [CHECK]пишем все что угодно[/CHECK]


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: 26 май 2009, 17:23 
Не в сети

Зарегистрирован: 29 окт 2008, 15:17
Сообщения: 140
Карма: 0
Мужик, ну это реально круто.
Скажи под какую версию эта вся телега у тебя работает ?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: 26 май 2009, 17:47 
Не в сети

Зарегистрирован: 20 окт 2008, 12:14
Сообщения: 121
Карма: 3
bgbilling 4.5, но насколько я понимаю особо разницы в версии нет, тут же все на скриптах


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: 26 май 2009, 17:52 
Не в сети

Зарегистрирован: 20 окт 2008, 12:14
Сообщения: 121
Карма: 3
Ну и напоследок для совсем ленивых
Команды:
Код:
[DEFAULT]

[OPEN]
[/OPEN]

[CLOSE]
[/CLOSE]

[CHECK]
/usr/local/manad/changetc.sh 1:[N1] ${speed}
[/CHECK]

[/DEFAULT]

Сам скрипт
Код:
#!/bin/sh
if [ `tc class show dev eth0|awk '''$3=="'$1'"{print $11}'` != "$2" ];
    then (
            tc class change dev eth0 parent 1:1 classid $1 htb rate $2 burst 8k prio 1
        )
fi

Ну вот вроде все поправляйте где ошибся


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 5 ] 

Часовой пояс: UTC + 5 часов [ Летнее время ]


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
POWERED_BY
Русская поддержка phpBB
[ Time : 0.049s | 28 Queries | GZIP : On ]