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

📄 transportselector.cxx

📁 这是国外的resip协议栈
💻 CXX
📖 第 1 页 / 共 3 页
字号:
                  // See draft-ietf-sip-identity         if (mSecurity && msg->exists(h_Identity) && msg->header(h_Identity).value().empty())         {            DateCategory now;            msg->header(h_Date) = now;#if defined(USE_SSL)            try            {               const Data& domain = msg->header(h_From).uri().host();               msg->header(h_Identity).value() = mSecurity->computeIdentity( domain,                                                                             msg->getCanonicalIdentityString());            }            catch (Security::Exception& e)            {               InfoLog (<< "Couldn't add identity header: " << e);               msg->remove(h_Identity);               if (msg->exists(h_IdentityInfo))                {                  msg->remove(h_IdentityInfo);               }                              }#endif         }         // Call back anyone who wants to perform outbound decoration         msg->callOutboundDecorators(source, target);         Data& encoded = msg->getEncoded();         encoded.clear();         DataStream encodeStream(encoded);         msg->encode(encodeStream);         encodeStream.flush();         msg->getCompartmentId() = remoteSigcompId;                  assert(!msg->getEncoded().empty());         DebugLog (<< "Transmitting to " << target                   << " tlsDomain=" << msg->getTlsDomain()                   << " via " << source				   << std::endl << std::endl << encoded.escaped());         target.transport->send(target, encoded, msg->getTransactionId(),                                remoteSigcompId);      }      else      {         InfoLog (<< "tid=" << msg->getTransactionId() << " failed to find a transport to " << target);         mStateMacFifo.add(new TransportFailure(msg->getTransactionId(), TransportFailure::NoTransport));      }   }   catch (Transport::Exception& )   {      InfoLog (<< "tid=" << msg->getTransactionId() << " no route to target: " << target);      mStateMacFifo.add(new TransportFailure(msg->getTransactionId(), TransportFailure::NoRoute));      return;   }}voidTransportSelector::retransmit(SipMessage* msg, Tuple& target){   assert(target.transport);   // !jf! The previous call to transmit may have blocked or failed (It seems to   // block in windows when the network is disconnected - don't know why just   // yet.   // !kh!   // My speculation for blocking is; when network is disconnected, WinSock sets   // a timer (to give up) and tries to defer reporting the error, in hope of   // the network would be recovered. Before the timer fires, applications could   // still select() (or the likes) their socket descriptors and find they are   // writable if there is still room in buffer (per socket). If the send()s or   // sendto()s made during this time period overflows the buffer, it blocks.   // But I somewhat doubt this would be noticed, because block would be brief,   // once the timer fires, the blocked call would return error.   // Note that the block applies to both UDP and TCP sockets.   // Quote from Linux man page:   // When the message does not fit into the send buffer of the socket,  send   // normally  blocks, unless the socket has been placed in non-blocking I/O   // mode. In non-blocking mode it would return EAGAIN in this case.   // Quote from MSDN library:   // If no buffer space is available within the transport system to hold the   // data to be transmitted, sendto will block unless the socket has been   // placed in a nonblocking mode.   if(!msg->getEncoded().empty())   {      //DebugLog(<<"!ah! retransmit to " << target);      target.transport->send(target, msg->getEncoded(), msg->getTransactionId(), msg->getCompartmentId());   }}unsigned intTransportSelector::sumTransportFifoSizes() const{   unsigned int sum = 0;   for (AnyPortTupleMap::const_iterator i = mAnyPortTransports.begin();        i != mAnyPortTransports.end(); ++i)   {      sum += i->second->getFifoSize();   }   for (AnyPortAnyInterfaceTupleMap::const_iterator i = mAnyPortAnyInterfaceTransports.begin();        i != mAnyPortAnyInterfaceTransports.end(); ++i)   {      sum += i->second->getFifoSize();   }   for (TlsTransportMap::const_iterator i = mTlsTransports.begin();        i != mTlsTransports.end(); ++i)   {      sum += i->second->getFifoSize();   }   return sum;}boolTransportSelector::connectionAlive(const Tuple& target) const{   return (findConnection(target)!=0);}const Connection*TransportSelector::findConnection(const Tuple& target) const{   // !bwc! If we can find a match in the ConnectionManager, we can   // determine what Transport this needs to be sent on. This may also let   // us know immediately what our source needs to be.   if(target.getType()==TCP || target.getType()==TLS)   {      TcpBaseTransport* tcpb=0;      Connection* conn=0;      TypeToTransportMap::const_iterator i;      TypeToTransportMap::const_iterator l=mTypeToTransportMap.lower_bound(target);      TypeToTransportMap::const_iterator u=mTypeToTransportMap.upper_bound(target);      for(i=l;i!=u;++i)      {         tcpb=static_cast<TcpBaseTransport*>(i->second);         conn = tcpb->getConnectionManager().findConnection(target);         if(conn)         {            return conn;         }      }   }      return 0;}Transport*TransportSelector::findTransportByDest(SipMessage* msg, Tuple& target){   if(!target.transport)   {      if(target.getType()==UDP || target.getType()==DTLS)      {         if(target.mFlowKey)         {            std::map<FlowKey,Transport*>::iterator i=mConnectionlessMap.find(target.mFlowKey);            if(i!=mConnectionlessMap.end())            {               return i->second;            }         }      }      else if(target.getType()==TCP || target.getType()==TLS)      {         // .bwc. We might find a match by the cid, or maybe using the         // tuple itself.         const Connection* conn = findConnection(target);                  if(conn) // .bwc. Woohoo! Home free!         {            return conn->transport();         }         else if(target.onlyUseExistingConnection)         {            // .bwc. Connection no longer exists, so we fail.            return 0;         }      }            // !bwc! No luck finding with a FlowKey.      if(target.getType()==TLS || target.getType()==DTLS)      {         return findTlsTransport(msg->getTlsDomain(),target.getType(),target.ipVersion());      }               }   else // .bwc. Easy as pie.   {      return target.transport;   }   // .bwc. No luck here. Maybe findTransportBySource will end up working.   return 0; }Transport*TransportSelector::findTransportBySource(Tuple& search){   DebugLog(<< "findTransportBySource(" << search << ")");   if (search.getPort() != 0)   {      //0. When we are sending to a loopback address, the kernel makes an      //(effectively) arbitrary choice of which loopback address to send      //from. (Since any loopback address can be used to send to any other      //loopback address) This choice may not agree with our idea of what      //address we should be sending from, so we need to just choose the      //loopback address we like, and ignore what the kernel told us to do.      if( search.isLoopback() )      {         ExactTupleMap::const_iterator i;         for (i=mExactTransports.begin();i != mExactTransports.end();i++)         {            DebugLog(<<"search: " << search << " elem: " << i->first);            if(i->first.ipVersion()==V4)            {               //Compare only the first byte (the 127)               if(i->first.isEqualWithMask(search,8,false))               {                  search=i->first;                  DebugLog(<<"Match!");                  return i->second;               }            }#ifdef USE_IPV6            else if(i->first.ipVersion()==V6)            {               //What to do?            }#endif            else            {               assert(0);            }         }      }      // 1. search for matching port on a specific interface      {         ExactTupleMap::const_iterator i = mExactTransports.find(search);         if (i != mExactTransports.end())         {            DebugLog(<< "findTransport (exact) => " << *(i->second));            return i->second;         }      }      // 2. search for specific port on ANY interface      {         AnyInterfaceTupleMap::const_iterator i = mAnyInterfaceTransports.find(search);         if (i != mAnyInterfaceTransports.end())         {            DebugLog(<< "findTransport (any interface) => " << *(i->second));            return i->second;         }      }   }   else   {      //0. When we are sending to a loopback address, the kernel makes an      //(effectively) arbitrary choice of which loopback address to send      //from. (Since any loopback address can be used to send to any other      //loopback address) This choice may not agree with our idea of what      //address we should be sending from, so we need to just choose the      //loopback address we like, and ignore what the kernel told us to do.      if( search.isLoopback() )      {         ExactTupleMap::const_iterator i;         for (i=mExactTransports.begin();i != mExactTransports.end();i++)         {            DebugLog(<<"search: " << search << " elem: " << i->first);            if(i->first.ipVersion()==V4)            {               //Compare only the first byte (the 127)               if(i->first.isEqualWithMask(search,8,true))               {                  search=i->first;                  DebugLog(<<"Match!");                  return i->second;               }            }#ifdef USE_IPV6            else if(i->first.ipVersion()==V6)            {               //What to do?            }#endif            else            {               assert(0);            }         }      }      // 1. search for ANY port on specific interface      {         AnyPortTupleMap::const_iterator i = mAnyPortTransports.find(search);         if (i != mAnyPortTransports.end())         {            DebugLog(<< "findTransport (any port, specific interface) => " << *(i->second));            return i->second;         }      }      // 2. search for ANY port on ANY interface      {         //CerrLog(<< "Trying AnyPortAnyInterfaceTupleMap " << mAnyPortAnyInterfaceTransports.size());         AnyPortAnyInterfaceTupleMap::const_iterator i = mAnyPortAnyInterfaceTransports.find(search);         if (i != mAnyPortAnyInterfaceTransports.end())         {            DebugLog(<< "findTransport (any port, any interface) => " << *(i->second));            return i->second;         }      }   }   DebugLog (<< "Exact interface / Specific port: " << Inserter(mExactTransports));   DebugLog (<< "Any interface / Specific port: " << Inserter(mAnyInterfaceTransports));   DebugLog (<< "Exact interface / Any port: " << Inserter(mAnyPortTransports));   DebugLog (<< "Any interface / Any port: " << Inserter(mAnyPortAnyInterfaceTransports));   WarningLog(<< "Can't find matching transport " << search);   return 0;}Transport*TransportSelector::findTlsTransport(const Data& domainname,resip::TransportType type,resip::IpVersion version){   assert(type==TLS || type==DTLS);   DebugLog (<< "Searching for" << ((type==TLS) ? "TLS" : "DTLS") << "transport for domain='"                   << domainname << "'" << " have " << mTlsTransports.size());   if (domainname == Data::Empty)   {      for(TlsTransportMap::iterator i=mTlsTransports.begin();            i!=mTlsTransports.end();++i)      {         if(i->first.mType==type && i->first.mVersion==version)         {            DebugLog(<<"Found a default transport.");            return i->second;         }      }   }   else   {      TlsTransportKey key(domainname,type,version);         TlsTransportMap::iterator i=mTlsTransports.find(key);            if(i!=mTlsTransports.end())      {         DebugLog(<< "Found a transport.");         return i->second;      }   }      DebugLog(<<"No transport found.");   return 0;}unsigned int TransportSelector::getTimeTillNextProcessMS(){   if (mDns.requiresProcess())   {      return 50;   }   else   {      return INT_MAX;   }}voidTransportSelector::registerMarkListener(MarkListener* listener){   mDns.getMarkManager().registerMarkListener(listener);}void TransportSelector::unregisterMarkListener(MarkListener* listener){   mDns.getMarkManager().unregisterMarkListener(listener);}/* ==================================================================== * 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 + -