BiTel

Форум BiTel
bgbilling.ru     docs.bitel.ru     wiki.bitel.ru     dbinfo.bitel.ru     bgcrm.ru     billing.bitel.ru     bitel.ru    
Текущее время: 18 июн 2025, 04:47

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




Начать новую тему Ответить на тему  [ Сообщений: 4 ] 
Автор Сообщение
СообщениеДобавлено: 30 мар 2016, 16:59 
Не в сети

Зарегистрирован: 16 ноя 2007, 16:11
Сообщения: 829
Карма: 49
Есть оборудование, отсылающее только RADIUS Access-Request и Netflow.
IP адрес также выделяется оборудованием и присылается в Access-Request.
Поиск сервиса осуществляется по User-Name.

Можно ли в обработчике радиус-протокола, или каким-либо другим способом создать сессию или подключение для того, что бы Netflow трафик привязался к сервису?

Проверены варианты:

1. connection.start.fromAccept=1
Результат: запись в таблице inet_connection создается с пустым ipAddress , netflow трафик не привязывается, не создает сессии.

2. Отправлять Accounting с помощью RadiusClienta из обработчика протокола для штатной процедуры создания сессии.
Результат: утечка ресурсов в BGInetAccess (https://forum.bitel.ru/viewtopic.php?f=44&t=11480)

Известны варианты:
1. Забить на радиус. - Не хотелось бы, так как другие варианты управления хуже.
2. Создать имитатор полноценного радиус-клиента. - Можно, но "бритва Оккама" душит.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 30 мар 2016, 19:08 
Не в сети
Разработчик
Аватара пользователя

Зарегистрирован: 19 дек 2006, 21:04
Сообщения: 5970
Карма: 256
Можно попробовать попросить стартовать сессию InetAccounting, т.к. как это примерно делается при работе DHCP-сервера:
Код:

import java.util.Date;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import javax.annotation.Resource;
import javax.naming.NameNotFoundException;

import org.apache.log4j.Logger;

import ru.bitel.bgbilling.kernel.container.managed.ServerContext;
import ru.bitel.bgbilling.kernel.container.resource.ResourceManager;
import ru.bitel.bgbilling.kernel.network.dhcp.DhcpProtocolHandler;
import ru.bitel.bgbilling.kernel.network.radius.RadiusAttributeSet;
import ru.bitel.bgbilling.kernel.network.radius.RadiusDictionary;
import ru.bitel.bgbilling.kernel.network.radius.RadiusListenerWorker;
import ru.bitel.bgbilling.kernel.network.radius.RadiusPacket;
import ru.bitel.bgbilling.kernel.network.radius.RadiusProtocolHandler;
import ru.bitel.bgbilling.kernel.network.radius.RadiusSession;
import ru.bitel.bgbilling.modules.inet.access.Access;
import ru.bitel.bgbilling.modules.inet.access.sa.ProtocolHandlerAdapter;
import ru.bitel.bgbilling.modules.inet.api.common.AccessCodes;
import ru.bitel.bgbilling.modules.inet.api.common.bean.InetConnection;
import ru.bitel.bgbilling.modules.inet.api.common.bean.InetDevice;
import ru.bitel.bgbilling.modules.inet.api.common.bean.InetDeviceType;
import ru.bitel.bgbilling.modules.inet.api.common.bean.InetServ;
import ru.bitel.bgbilling.modules.inet.api.common.bean.InetServType;
import ru.bitel.bgbilling.modules.inet.radius.InetNas;
import ru.bitel.bgbilling.modules.inet.radius.InetRadiusSessionParams;
import ru.bitel.bgbilling.modules.inet.radius.RadiusAccessRequestHandler;
import ru.bitel.bgbilling.server.util.Setup;
import ru.bitel.common.ParameterMap;
import ru.bitel.common.function.ThrowingRunnable;

public class MyProtocolHandler
   extends ProtocolHandlerAdapter
   implements
   RadiusProtocolHandler, DhcpProtocolHandler, RadiusAccessRequestHandler
{
   private static final Logger logger = Logger.getLogger( MyProtocolHandler.class );

   private static final ExecutorService executor = Executors.newFixedThreadPool( 10 );

   @Resource(name = "access")
   private Access access;

   private int deviceId;

   @Override
   public void init( Setup setup, int moduleId, InetDevice inetDevice, InetDeviceType inetDeviceType, ParameterMap deviceConfig )
      throws Exception
   {
      super.init( setup, moduleId, inetDevice, inetDeviceType, deviceConfig );

      this.deviceId = inetDevice.getId();

      ServerContext ctx = new ServerContext( setup, moduleId, 0 );
      ctx.init();
      try
      {
         ResourceManager rm = new ResourceManager();
         rm.inject( ctx, this, moduleId );

         ctx.commit();
      }
      catch( NameNotFoundException ex )
      {}
      catch( Exception ex )
      {
         logger.error( ex.getMessage(), ex );
      }
      finally
      {
         ctx.destroy();
      }
   }

   @Override
   public void beforeAuthentication( ServerContext context, RadiusListenerWorker<InetNas> req, RadiusSession<InetNas, InetRadiusSessionParams> radiusSession, RadiusPacket request, RadiusPacket response )
      throws Exception
   {}

   @Override
   public boolean addResponseAttributes( ServerContext context, InetServType inetServType, InetServ inetServ, RadiusPacket response, String realm, Map<String, RadiusAttributeSet> realmAttributeMap, RadiusAttributeSet inetServAttributes, Set<Integer> inetOptionSet )
      throws Exception
   {
      return false;
   }

   @Override
   public void afterAuthorization( ServerContext conext, RadiusListenerWorker<InetNas> req, RadiusSession<InetNas, InetRadiusSessionParams> radiusSession, RadiusPacket request, RadiusPacket response )
      throws Exception
   {
      if( response.getCode() != RadiusPacket.ACCESS_ACCEPT )
      {
         return;
      }

      int accessCode = radiusSession.errorCode;

      InetServ serv = (InetServ)req.getRadiusSession().login;

      InetConnection connection = new InetConnection();
      connection.setDeviceId( deviceId );
      connection.setDevicePort( serv.getInterfaceId() );
      connection.setCircuitId( req.getCircuitId() );

      connection.setContractId( req.getContractId() );
      connection.setServId( serv.getId() );
      connection.setAcctSessionId( request.getStringAttribute( -1, RadiusDictionary.Acct_Session_Id, "UNDEF" ) );
      connection.setCallingStationId( request.getStringAttribute( -1, RadiusDictionary.Calling_Station_Id, "" ) );
      connection.setIpResourceId( req.getIpResourceId() );
      connection.setInetAddressBytes( req.getIpAddress() );
      connection.setAccessCode( accessCode );
      connection.setDeviceState( (accessCode != AccessCodes.AUTHORIZATION_SUCCEEDED) ? InetServ.STATE_DISABLE : InetServ.STATE_ENABLE );
      connection.setConnectionStart( new Date() );

      executor.execute( (ThrowingRunnable)() -> {
         
         access.connectionManager.accountingStart( serv, connection, 4000 );
      } );
   }
}


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 30 мар 2016, 19:13 
Не в сети
Разработчик
Аватара пользователя

Зарегистрирован: 19 дек 2006, 21:04
Сообщения: 5970
Карма: 256
В данном случае обработчику процессора протокола я добавил implements RadiusAccessRequestHandler
и теперь можно использовать дополнительные три метода. Использую afterAuthorization во-первых, потому что там доступно больше данных,
во-вторых, потому что preprocess/postprocessRequest в случае EAP может вызываться несколько раз до того как произойдет Access-Accept.
executor.execute использую, чтобы сам старт выполнялся асинхронно уже в другом потоке (чтобы не дожидаясь создания сессии отправить Access-Accept).

Это пример, не факт что сразу заработает, но в принципе так должно работать тоже.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 30 мар 2016, 19:53 
Не в сети

Зарегистрирован: 16 ноя 2007, 16:11
Сообщения: 829
Карма: 49
Понял, спасибо. Не получится стабильного решения с автоАккоунтингом - попробую этот вариант.


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

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


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

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


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

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