📄 aaatransceiver.cxx
字号:
/* ==================================================================== * The Vovida Software License, Version 1.0 * * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The names "VOCAL", "Vovida Open Communication Application Library", * and "Vovida Open Communication Application Library (VOCAL)" must * not be used to endorse or promote products derived from this * software without prior written permission. For written * permission, please contact vocal@vovida.org. * * 4. Products derived from this software may not be called "VOCAL", nor * may "VOCAL" appear in their name, without prior written * permission of Vovida Networks, Inc. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * DAMAGE. * * ==================================================================== * * This software consists of voluntary contributions made by Vovida * Networks, Inc. and many individuals on behalf of Vovida Networks, * Inc. For more information on Vovida Networks, Inc., please see * <http://www.vovida.org/>. * */static const char* const AAATransceiver_cxx_Version = "$Id: AAATransceiver.cxx,v 1.18.18.1 2003/02/04 22:02:26 bko Exp $";#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include "UdpStack.hxx"#include "B2bConfig.hxx"#include "AAATransceiver.hxx"#include "AuthData.hxx"#include "BillingData.hxx"AAATransceiver::AAATransceiver(int recvPort, Sptr<Fifo<Sptr<SipProxyEvent> > > outputFifo) : myOutputFifo(outputFifo), myShutdownFlg(false), myRadiusIdCounter(0){ myUdpStack = new UdpStack(0, recvPort); mySendThread.spawn(sendThreadWrapper, this); myRecvThread.spawn(rcvThreadWrapper, this);}void AAATransceiver::setResponse(Sptr<AAAEvent> event){ myOutputFifo->add(event);}AAATransceiver::~AAATransceiver(){ myShutdownFlg = true; mySendFifo.add(0); mySendThread.join(); myRecvThread.exit();}void* AAATransceiver::sendThreadWrapper(void *p){ AAATransceiver* self = static_cast<AAATransceiver*>(p); return(self->sendMain());}void* AAATransceiver::rcvThreadWrapper(void *p){ AAATransceiver* self = static_cast<AAATransceiver*>(p); return(self->receiveMain());}void* AAATransceiver::receiveMain(){ NetworkAddress sender; while (1) { int len = 0; static const string::size_type MTU = 3600; char buf[MTU+1]; buf[0] = '\0'; len = 0; len = myUdpStack->receiveFrom( buf,MTU , &sender ); buf[len] = '\0'; if (( len == 0) || ( len < 0 )) { return 0; } if(myShutdownFlg) { return 0; } RadiusData msgReceived(buf, len); const char* secret = B2bConfig::instance().getStr(B2bConfig::RAD_BILLING_PASSWD).c_str(); Sptr<RadiusMessage> responseMsg = 0; try { responseMsg = new RadiusMessage( msgReceived , secret); u_int8_t rId = responseMsg->getIdentifier(); if((responseMsg->type() == RP_ACCESS_ACCEPT) || (responseMsg->type() == RP_ACCESS_REJECT)) { Sptr<RadiusPayload> rPayload; myMutex.lock(); if(myRetransMap[rId] == 0) { cpLog(LOG_ERR,"Got response for id=%d, but no request found, ignoring", rId); myMutex.unlock(); continue; } rPayload = myRetransMap[rId]; cleanUp(rId); myMutex.unlock(); Sptr<AAAEvent> aEvent = rPayload->aEvent; AuthAgent* authAgent = aEvent->getAuthAgent(); if(authAgent == 0) continue; Sptr<BasicAAAData> basicData = authAgent->getAAAData(); Sptr<AuthData> authData; authData.dynamicCast(basicData); if(authData == 0) { //Got a delayed response, which does not have any //pending transaction, ignore cpLog(LOG_INFO, "Got a delayed response from radius server, which does not have any pending transaction, ignoring"); continue; } if(responseMsg->type() == RP_ACCESS_ACCEPT) { RadiusData durationData = (responseMsg->get( RA_SESSION_TIMEOUT)).value(); u_int32_t duration=0; memcpy(&duration, durationData.data(), durationData.length()); duration = ntohl(duration); cpLog(LOG_DEBUG, "Got session timeout %ld", duration); authData->setSessionTimeOut(duration); authData->setStatus(A_ACCEPT); } else { authData->setStatus(A_REJECT); } myOutputFifo->add(aEvent); } else { //Accounting response, do nothing myMutex.lock(); cleanUp(rId); myMutex.unlock(); } } catch(VException& e) { cpLog(LOG_WARNING, "Problem with Radius message ,reason:%s" ,e.getDescription().c_str()); } }}void* AAATransceiver::sendMain(){ while(1) { Sptr<AAAEvent> aaaEvent = mySendFifo.getNext(); if(myShutdownFlg) { return 0; } udpSend(aaaEvent); //Retransmission handleRetransmission(aaaEvent);#if 0 ///Simulate the response received vusleep(100000); Sptr<AuthData> authData; authData.dynamicCast(aaaEvent->getAuthAgent()->getAAAData()); if(authData != 0) { authData->setStatus(A_ACCEPT); myOutputFifo->add(aaaEvent); } u_int8_t rId = aaaEvent->getReqId(); Sptr<RadiusPayload> rPayload = myRetransMap[rId]; rPayload->retransCount = 0; //Cancel the retransmission event also mySendFifo.cancel(rPayload->myRetransId); cleanUp(rId); ///#endif } return 0;}voidAAATransceiver::handleRetransmission(Sptr<AAAEvent> aaaEvent){ u_int8_t rId = aaaEvent->getReqId(); myMutex.lock(); if(myRetransMap[rId] == 0) { //rId not found, ignore retransmission myMutex.unlock(); return; } Sptr<RadiusPayload> rPayload = myRetransMap[rId]; myMutex.unlock(); if(rPayload->retransCount) { rPayload->retransCount--; cpLog(LOG_DEBUG, "Scheduled for retransmission, count left:%d", rPayload->retransCount); //Schedule for retransmission after 3 seconds rPayload->myRetransId = mySendFifo.addDelayMs(aaaEvent, 3000); } else { cpLog(LOG_DEBUG, "Retransmission exhausted"); RadiusPacketType rType = rPayload->rMsg->type(); if(rType == RP_ACCESS_REQUEST) { //Auth failed myMutex.lock(); myRetransMap[rId] = 0; myMutex.unlock(); myOutputFifo->add(aaaEvent); } else {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -