⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 authagent.cxx

📁 SIP(Session Initiation Protocol)是由IETF定义
💻 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 AuthAgent_cxx_Version =    "$Id: AuthAgent.cxx,v 1.23.2.1 2003/02/05 02:56:53 sprajpat Exp $";#include "ByeMsg.hxx"#include "InfoMsg.hxx"#include "SipTextData.hxx"#include "SipProxyAuthorization.hxx"#include "SystemInfo.hxx"#include "SipRoute.hxx"#include "ControlStateFactory.hxx"#include "CallDB.hxx"#include "B2bFacade.hxx"#include "MultiLegCallControl.hxx"#include "UaServer.hxx"#include "UaClient.hxx"#include "AuthAgent.hxx"#include "B2bConfig.hxx"#include "CallTimerEvent.hxx"#include "AAAEvent.hxx"#include "AuthData.hxx"#include "BillingData.hxx"#include "SipVia.hxx"using namespace Vocal;using namespace Vocal::UA;AuthAgent::AuthAgent(unsigned long authId, const Sptr<SipMsg>& sipMsg)    : BasicAgent(authId) {     myState = ControlStateFactory::instance().getState(C_STATE_INIT);    ///Create new UserAgent    myInvokee = new UaServer(sipMsg, B2bFacade::instance().getSipTransceiver(), this);    myInvokee->receivedMsg(sipMsg);    //Extract the PUID if out there, or else use FROM header    Sptr<SipCommand> sipCmd;    sipCmd.dynamicCast(sipMsg);    const SipProxyAuthorization& pAuth = sipCmd->getProxyAuthorization();    string puid;    string encryptedPassword;    LocalScopeAllocator lo;    if(pAuth.encode().length())    {        if(pAuth.getAuthScheme() == AUTH_BASIC)        {            puid = sipMsg->getFrom().getUser().getData(lo);            encryptedPassword = pAuth.getBasicCookie().getData(lo);        }        else        {            puid = pAuth.getTokenValue(USERNAME).getData(lo);            encryptedPassword = pAuth.getTokenValue("response").getData(lo);        }        cpLog(LOG_DEBUG, "Setting UID (%s), password (%s) from Proxy-Authorization header", puid.c_str(), encryptedPassword.c_str());    }    else    {        //No Authentication scheme, set the dummy password        puid = sipMsg->getFrom().getUser().getData(lo);        encryptedPassword = ".";        cpLog(LOG_DEBUG, "No Authentication info available, setting UID (%s) from FROM header", puid.c_str());    }    //Extracted PUID    //Add the callleg in CallDb    CallDB::instance().addCallLeg(myInvokee);    //Set the authData    myAAAData = new AuthData(puid, encryptedPassword,                     theSystem.gethostAddress(), sipMsg->getFrom().getUser().getData(lo),                     sipMsg->getTo().getUser().getData(lo));};void AuthAgent::doAuth() {    myState->auth(*this);    Sptr<AAAEvent> authEvent = new AAAEvent(this);    if(B2bConfig::instance().getStr(B2bConfig::PP_OPTIONS) == B2bConfig::PP_FREE)    {        //Since call is free, no need to authenticate and no        //Need to timeout either        Sptr<AuthData> authData;        authData.dynamicCast(myAAAData);        assert(myAAAData != 0);        //This should be done by the stack, to check the mandator FROM and TO field        //If radius server is used, this situation would result in a REJECTION any ways        if(myInvokee->getRequest()->getFrom().getUser().length() &&           myInvokee->getRequest()->getTo().getUser().length())        {            authData->setStatus(A_ACCEPT);        }        else        {            authData->setStatus(A_REJECT);        }        //Set the callout time to infinite        authData->setSessionTimeOut(-1);        authDone(authEvent);    }    else    {        ///Queue the request for authorization        const SipCallLeg& cLeg =  myInvokee->getCallLeg();        cpLog(LOG_DEBUG, "Sending AAA request for id: %ld, callleg(%s)",                                   getId(), cLeg.encode().logData());        B2bFacade::instance().getAAATransceiver()->sendAuthRequest(authEvent);    }}void AuthAgent::authDone(const Sptr<AAAEvent>& aEvent) {    Sptr<AuthData> authData;    authData.dynamicCast(myAAAData);    assert(myAAAData != 0);    if(authData->getStatus() == A_ACCEPT)    {        const SipCallLeg& cLeg =  myInvokee->getCallLeg();        cpLog(LOG_DEBUG, "Authorization accepted for id(%ld), callleg(%s)",                          getId(), cLeg.encode().logData());        Sptr<AccountingData> aData = new AccountingData(myAuthId);        CallDB::instance().setAccountingData(cLeg, myAuthId, aData);        Sptr<AuthData> authData;        authData.dynamicCast(myAAAData);        int duration = authData->getSessionTimeOut();        cpLog(LOG_DEBUG, "Call duration is (%d)", duration);         aData->setUnusedSeconds(duration);        myState->authDone(*this);    }    else    {        const SipCallLeg& cLeg =  myInvokee->getCallLeg();        cpLog(LOG_DEBUG, "Authorization failed for id(%ld), callleg(%s)",                          getId(), cLeg.encode().logData());        //Auth failed        //Send 404 to the caller        Sptr<SipMsg> sipMsg = myInvokee->getRequest();        //Send 404 first        Sptr<SipCommand> sCmd;        sCmd.dynamicCast(sipMsg);        Sptr<StatusMsg> statusMsg = new StatusMsg(*sCmd, 404);        myInvokee->sendMsg(statusMsg);        myState->fail(*this);    }}void AuthAgent::placeCall(){    cpLog(LOG_DEBUG, "AuthAgent::placeCall()");    //Create a client side user agent    //Create Invite from the source invite     Sptr<SipMsg> sipMsg = myInvokee->getRequest();    Sptr<InviteMsg> iMsg;    iMsg.dynamicCast(sipMsg);    Sptr<InviteMsg> inviteMsg = UaBase::createInvite(iMsg);    if(B2bConfig::instance().getStr(B2bConfig::PP_OPTIONS)                       != B2bConfig::PP_FREE)    {        ///Send the start account data event        //Get the saved user name        string uName = myAAAData->getUserName();        LocalScopeAllocator lo;        myAAAData = new BillingData(myInvokee->getRequest()->getCallId().getData().getData(lo),                        uName,                         theSystem.gethostAddress(),                         sipMsg->getFrom().getUser().getData(lo),                        sipMsg->getTo().getUser().getData(lo));        Sptr<AAAEvent> aEvent = new AAAEvent(this);        cpLog(LOG_DEBUG, "Sending Start account data");        B2bFacade::instance().getAAATransceiver()->sendAcctStart(aEvent);    }    Sptr<MultiLegCallData> mData =                  CallDB::instance().getMultiLegCallData(myInvokee->getCallLeg());    assert(mData != 0);    Sptr<AccountingData> accData = mData->getAccountingData();    time_t t;    t = time(&t);    accData->setStartTime(t);    Sptr<UaBase> userAgent = new UaClient(inviteMsg, B2bFacade::instance().getSipTransceiver(), this);    CallDB::instance().addPeer(myInvokee, userAgent);    userAgent->sendMsg(inviteMsg);    cpLog(LOG_DEBUG, "%s, sending %s", userAgent->className().c_str(),                          inviteMsg->encode().logData());}void AuthAgent::doBye(){    cpLog(LOG_DEBUG, "AuthAgent::doBye()");    myInvokee->sendBye();    //Send bye to the caller and its peers    //Find the agent's peer and send bye to all peers    Sptr<UserAgentPeerList> pList = CallDB::instance().findAllPeers(*myInvokee);    for(UserAgentPeerList::iterator itr = pList->begin();                                    itr != pList->end(); itr++)    {         (*itr)->sendBye();    }    Sptr<BillingData> bData;    bData.dynamicCast(myAAAData);    assert(bData != 0);    bData->setTermCause(BT_SESSION_TIMEOUT);    endCall();}void AuthAgent::endCall(){    //Cancel timer    B2bFacade::instance().getEventFifo()->cancel(myTimerId);    cpLog(LOG_DEBUG, "AuthAgent::endCall()");    Sptr<MultiLegCallData> mData =                  CallDB::instance().getMultiLegCallData(myInvokee->getCallLeg());    assert(mData != 0);    Sptr<AccountingData> accData = mData->getAccountingData();    time_t t;    t = time(&t);    accData->setEndTime(t);    if(B2bConfig::instance().getStr(B2bConfig::PP_OPTIONS)                    != B2bConfig::PP_FREE)    {        ///Send Stop records to billing        int duration = t - accData->getStartTime();        Sptr<BillingData> bData;        bData.dynamicCast(myAAAData);        assert(bData != 0);        bData->setDuration(duration);        Sptr<AAAEvent> aEvent = new AAAEvent(this);        cpLog(LOG_DEBUG, "AuthAgent::Sending Acct Stop");        B2bFacade::instance().getAAATransceiver()->sendAcctStop(aEvent);    }    ///Transit the controller state    myState->bye(*this);}void AuthAgent::doCancel(){    cpLog(LOG_DEBUG, "AuthAgent::doCancel()");    myState->cancel(*this);}voidAuthAgent::timerExpired(){    cpLog(LOG_DEBUG, "AuthAgent::timerExpired()");    myState->timerExpired(*this);}voidAuthAgent::inCall(){    cpLog(LOG_DEBUG, "AuthAgent::inCall()");    assert(myInvokee->isAServer());    cpLog(LOG_DEBUG, "AuthAgent::inCall" );    //Transit the controller state machine to be inCall    myState->inCall(*this);    if(B2bConfig::instance().getStr(B2bConfig::PP_OPTIONS)                    != B2bConfig::PP_FREE)    {        ///Send the interim Account Record        Sptr<MultiLegCallData> mData =              CallDB::instance().getMultiLegCallData(myInvokee->getCallLeg());        assert(mData != 0);        Sptr<AccountingData> accData = mData->getAccountingData();        ///Calculate the setup delay, which is the time difference between         // the first        ///invite sent to the callee and a final response wwas received        time_t t;        t = time(&t);        int delay = t - accData->getStartTime();        cpLog(LOG_DEBUG, "Sending interim account data with delay (%ld)", delay);        Sptr<AAAEvent> aEvent = new AAAEvent(this);        Sptr<BillingData> bData;        bData.dynamicCast(myAAAData);        assert(bData != 0);        bData->setSetupDelay(delay);        B2bFacade::instance().getAAATransceiver()->sendAcctInterim(aEvent);        //Disable it for now        //sendInfoMsg(accData->getUnusedSeconds());        //Start the timer        cpLog(LOG_DEBUG, "In Call, setting timer to (%d) seconds", accData->getUnusedSeconds());        Sptr<CallTimerEvent> tEvent = new CallTimerEvent(this);        myTimerId = B2bFacade::instance().getEventFifo()->addDelayMs(tEvent,accData->getUnusedSeconds()*1000);    }}voidAuthAgent::callFailed(){    cpLog(LOG_DEBUG, "AuthAgent::callFailed()");    myState->fail(*this);}voidAuthAgent::setDeleted(){   myDelFlag = true;   cpLog(LOG_DEBUG, "Deleting AuthAgent::setDeleted:%d", getId()) ;   CallDB::instance().removePeer(*myInvokee);   CallDB::instance().removeAccountingData(getId());   MultiLegCallControl::instance().removeAgent(getId(), 30000);}voidAuthAgent::sendInfoMsg(int secs){    //Create Info message    Sptr<InfoMsg> infoMsg = new InfoMsg();    infoMsg->setNumRecordRoute(0);    infoMsg->setNumRoute(0);    infoMsg->flushViaList();    SipVia via2;    via2.setHost(theSystem.gethostAddress());    via2.setPort(B2bConfig::instance().getLocalSipPort());    infoMsg->setVia(via2);    infoMsg->setRouteList(myInvokee->getRouteList());    SipRoute siproute = infoMsg->getRoute(0);    infoMsg->removeRoute(0);    SipRequestLine rLine(SIP_INFO, siproute.getUrl());    infoMsg->setRequestLine(rLine);    infoMsg->setCallId(myInvokee->getRequest()->getCallId());    //Get local CSeq number, increment it and set it in the Info Message    SipCSeq lSeq = myInvokee->getLocalCSeq();    lSeq.incrCSeq();    myInvokee->setLocalCSeq(lSeq);    SipCSeq cSeq(SIP_INFO, lSeq.getCSeqData());    infoMsg->setCSeq(cSeq);    char buf[256];    sprintf(buf, "You have (%d) seconds for the call\n", secs);    Data ltData(buf);    ltData += CRLF;     SipTextData tData(ltData);    infoMsg->setContentData(&tData);    cpLog(LOG_DEBUG, "%s" , infoMsg->encode().logData());    B2bFacade::instance().getSipTransceiver()->sendAsync(infoMsg);}///void AuthAgent::receivedRequest(UaBase& agent, const Sptr<SipMsg>& msg){    MultiLegCallControl::instance().receivedRequest(agent,msg);}///void AuthAgent::receivedStatus(UaBase& agent, const Sptr<SipMsg>& msg){    MultiLegCallControl::instance().receivedStatus(agent,msg);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -