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

📄 serverregistration.cxx

📁 这是国外的resip协议栈
💻 CXX
字号:
#include "resip/stack/ExtensionParameter.hxx"#include "resip/stack/InteropHelper.hxx"#include "resip/stack/SipMessage.hxx"#include "resip/dum/DialogUsageManager.hxx"#include "resip/dum/MasterProfile.hxx"#include "resip/dum/ServerRegistration.hxx"#include "resip/dum/Dialog.hxx"#include "resip/dum/RegistrationHandler.hxx"#include "resip/dum/RegistrationPersistenceManager.hxx"#include "rutil/Logger.hxx"#include "rutil/Timer.hxx"#include "rutil/WinLeakCheck.hxx"#define RESIPROCATE_SUBSYSTEM Subsystem::DUMusing namespace resip;ServerRegistrationHandle ServerRegistration::getHandle(){   return ServerRegistrationHandle(mDum, getBaseHandle().getId());}ServerRegistration::ServerRegistration(DialogUsageManager& dum,  DialogSet& dialogSet, const SipMessage& request)   : NonDialogUsage(dum, dialogSet),     mRequest(request),     mDidOutbound(false){}ServerRegistration::~ServerRegistration(){   mDialogSet.mServerRegistration = 0;}void ServerRegistration::end(){}voidServerRegistration::accept(SipMessage& ok){  ok.remove(h_Contacts);  InfoLog( << "accepted a registration " << mAor );    // Add all registered contacts to the message.  RegistrationPersistenceManager *database = mDum.mRegistrationPersistenceManager;  ContactList contacts;  ContactList::iterator i;  contacts = database->getContacts(mAor);  database->unlockRecord(mAor);  UInt64 now=Timer::getTimeSecs();  NameAddr contact;  for (i = contacts.begin(); i != contacts.end(); i++)  {    if (i->mRegExpires <= now)    {      database->removeContact(mAor,*i);      continue;    }    contact = i->mContact;    contact.param(p_expires) = UInt32(i->mRegExpires - now);    ok.header(h_Contacts).push_back(contact);  }    if(mDidOutbound)  {     static Token outbound("outbound");     ok.header(h_Supporteds).push_back(outbound);  }  SharedPtr<SipMessage> msg(static_cast<SipMessage*>(ok.clone()));  mDum.send(msg);  delete(this);}voidServerRegistration::accept(int statusCode){   SipMessage success;   mDum.makeResponse(success, mRequest, statusCode);   accept(success);}voidServerRegistration::reject(int statusCode){   InfoLog( << "rejected a registration " << mAor << " with statusCode=" << statusCode );  // First, we roll back the contact database to  // the state it was before the registration request.  RegistrationPersistenceManager *database = mDum.mRegistrationPersistenceManager;  database->removeAor(mAor);  database->addAor(mAor, mOriginalContacts);  database->unlockRecord(mAor);  SharedPtr<SipMessage> failure(new SipMessage);  mDum.makeResponse(*failure, mRequest, statusCode);  failure->remove(h_Contacts);  mDum.send(failure);  delete(this);}void ServerRegistration::dispatch(const SipMessage& msg){   DebugLog( << "got a registration" );      assert(msg.isRequest());   ServerRegistrationHandler* handler = mDum.mServerRegistrationHandler;   RegistrationPersistenceManager *database = mDum.mRegistrationPersistenceManager;    enum {ADD, REMOVE, REFRESH} operation = REFRESH;    if (!handler || !database)    {      // ?bwc? This is a server error; why are we sending a 4xx?       DebugLog( << "No handler or DB - sending 405" );              SharedPtr<SipMessage> failure(new SipMessage);       mDum.makeResponse(*failure, msg, 405);       mDum.send(failure);       delete(this);       return;    }    mAor = msg.header(h_To).uri().getAorAsUri();   // Checks to see whether this scheme is valid, and supported.   if( !( (mAor.scheme()=="sip" || mAor.scheme()=="sips")             && mDum.getMasterProfile()->isSchemeSupported(mAor.scheme()) ) )   {       DebugLog( << "Bad scheme in Aor" );              SharedPtr<SipMessage> failure(new SipMessage);       mDum.makeResponse(*failure, msg, 400);       failure->header(h_StatusLine).reason() = "Bad/unsupported scheme in To: " + mAor.scheme();       mDum.send(failure);       delete(this);       return;   }       database->lockRecord(mAor);    UInt32 globalExpires = 0;    UInt32 expires=0;        if (!msg.empty(h_Expires) && msg.header(h_Expires).isWellFormed())    {      globalExpires = msg.header(h_Expires).value();    }    else    {       globalExpires = 3600;    }    mOriginalContacts = database->getContacts(mAor);    // If no conacts are present in the request, this is simply a query.    if (!msg.exists(h_Contacts))    {      handler->onQuery(getHandle(), msg);      return;    }    ParserContainer<NameAddr> contactList(msg.header(h_Contacts));    ParserContainer<NameAddr>::iterator i;    UInt64 now=Timer::getTimeSecs();    for(i = contactList.begin(); i != contactList.end(); i++)    {      if(!i->isWellFormed())      {         SharedPtr<SipMessage> failure(new SipMessage);         mDum.makeResponse(*failure, msg, 400, "Malformed Contact");         mDum.send(failure);         database->unlockRecord(mAor);         delete(this);         return;      }      if (i->exists(p_expires))      {         expires = i->param(p_expires);      }      else      {         expires = globalExpires;      }      // Check for "Contact: *" style deregistration      if (i->isAllContacts())      {        if (contactList.size() > 1 || expires != 0)        {           SharedPtr<SipMessage> failure(new SipMessage);           mDum.makeResponse(*failure, msg, 400, "Invalid use of 'Contact: *'");           mDum.send(failure);           database->unlockRecord(mAor);           delete(this);           return;        }        database->removeAor(mAor);        handler->onRemoveAll(getHandle(), msg);        return;      }      ContactInstanceRecord rec;      rec.mContact=*i;      rec.mRegExpires=(UInt64)expires+now;      if(i->exists(p_Instance))      {         rec.mInstance=i->param(p_Instance);      }      if(!msg.empty(h_Paths))      {         rec.mSipPath=msg.header(h_Paths);      }      rec.mLastUpdated=now;      // .bwc. If, in the end, this is true, it means all necessary conditions      // for outbound support have been met.      bool supportsOutbound=InteropHelper::getOutboundSupported();      // .bwc. We only store flow information if we have a direct flow to the      // endpoint. We do not create a flow if there is an edge-proxy, because if      // our connection to the edge proxy fails, the flow from the edge-proxy to      // the endpoint is still good, so we should not discard the registration.      bool haveDirectFlow=true;      if(supportsOutbound)      {         try         {            if(!i->exists(p_Instance) || !i->exists(p_regid))            {               DebugLog(<<"instance or reg-id missing");               supportsOutbound=false;            }            if(!msg.empty(h_Paths))            {               haveDirectFlow=false;               if(!msg.header(h_Paths).back().exists(p_ob))               {                  DebugLog(<<"last Path doesn't have ob");                  supportsOutbound=false;               }            }            else if(msg.header(h_Vias).size() > 1)            {               DebugLog(<<"more than one Via, and no Path");               supportsOutbound=false;            }         }         catch(resip::ParseBuffer::Exception&)         {            supportsOutbound=false;         }      }      else      {         DebugLog(<<"outbound support disabled");      }      // .bwc. The outbound processing      if(supportsOutbound)      {         rec.mRegId=i->param(p_regid);         if(haveDirectFlow)         {            // .bwc. We NEVER record the source if outbound is not being used.            // There is nothing we can do with this info in the non-outbound            // case that doesn't flagrantly violate spec (yet).            // (Example: If we remember this info with the intent of sending            // incoming stuff to this source directly, we end up being forced            // to record-route with a flow token to give in-dialog stuff a            // chance of working. Once we have record-routed, we have set this            // decision in stone for the rest of the dialog, preventing target            // refresh requests from working. If record-route was mutable,             // maybe it would be okay to do this, but until this is officially            // allowed, we shouldn't touch it.)            rec.mReceivedFrom=msg.getSource();            // .bwc. In the outbound case, we should fail if the connection is            // gone. No recovery should be attempted by the server.            rec.mReceivedFrom.onlyUseExistingConnection=true;            DebugLog(<<"Set rec.mReceivedFrom: " << rec.mReceivedFrom);         }      }      else if(InteropHelper::getRRTokenHackEnabled())      {         // .bwc. If we are going to do the broken thing, and record-route with         // flow-tokens every time, we enable it here. Keep in mind, this will         // either break target-refreshes (if we have a direct connection to the         // endpoint), or we have a good chance of inadvertently including a          // proxy that didn't record-route in the dialog.         // !bwc! TODO remove this once mid-dialog connection reuse is handled         // by most endpoints.         rec.mReceivedFrom=msg.getSource();         rec.mReceivedFrom.onlyUseExistingConnection=false;         DebugLog(<<"Set rec.mReceivedFrom: " << rec.mReceivedFrom);      }            // Check to see if this is a removal.      if (expires == 0)      {        if (operation == REFRESH)        {          operation = REMOVE;        }        database->removeContact(mAor, rec);      }      // Otherwise, it's an addition or refresh.      else      {        RegistrationPersistenceManager::update_status_t status;        InfoLog (<< "Adding " << mAor << " -> " << *i  );        DebugLog(<< "Contact has tuple " << rec.mReceivedFrom);         status = database->updateContact(mAor, rec);        if (status == RegistrationPersistenceManager::CONTACT_CREATED)        {          operation = ADD;        }      }         // !bwc! If we perform outbound processing for any Contact, we need to      // set this to true.      mDidOutbound |= supportsOutbound;    }    // The way this works is:    //    //  - If no additions or removals are performed, this is a refresh    //    //  - If at least one contact is removed and none are added, this    //    is a removal.    //    //  - If at least one contact is added, this is an addition, *even*    //    *if* a contact was also removed.    switch (operation)    {      case REFRESH:        handler->onRefresh(getHandle(), msg);        break;      case REMOVE:        handler->onRemove(getHandle(), msg);        break;      case ADD:        handler->onAdd(getHandle(), msg);        break;    }}voidServerRegistration::dispatch(const DumTimeout& msg){}std::ostream& ServerRegistration::dump(std::ostream& strm) const{   strm << "ServerRegistration " << mAor;   return strm;}/* ==================================================================== * 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/>. * */

⌨️ 快捷键说明

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