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

📄 tuple.cxx

📁 这是国外的resip协议栈
💻 CXX
📖 第 1 页 / 共 2 页
字号:
#if defined(HAVE_CONFIG_H)#include "resip/stack/config.hxx"#endif#include "resip/stack/Tuple.hxx"#include "rutil/compat.hxx"#include <iostream>#include <string.h>#include <sys/types.h>#include <cassert>#if !defined (WIN32)#include <arpa/inet.h>#include <netinet/in.h>#if defined(__APPLE__) && !defined(s6_addr16)#define s6_addr16 __u6_addr.__u6_addr16#endif#endif#include "rutil/Data.hxx"#include "rutil/DnsUtil.hxx"#include "rutil/GenericIPAddress.hxx"#include "rutil/HashMap.hxx"#include "rutil/Logger.hxx"#include "resip/stack/Transport.hxx"using namespace resip;#define RESIPROCATE_SUBSYSTEM Subsystem::DNSTuple::Tuple() :    mFlowKey(0),   transport(0),   onlyUseExistingConnection(false),   mTransportType(UNKNOWN_TRANSPORT){   sockaddr_in* addr4 = (sockaddr_in*)&mSockaddr;   memset(addr4, 0, sizeof(sockaddr_in));   mSockaddr.sa_family = AF_INET;}Tuple::Tuple(const GenericIPAddress& genericAddress, TransportType type,              const Data& targetDomain) :    mFlowKey(0),   transport(0),   onlyUseExistingConnection(false),   mTransportType(type),   mTargetDomain(targetDomain){  setSockaddr(genericAddress);}Tuple::Tuple(const Data& printableAddr,              int port,             IpVersion ipVer,             TransportType type,             const Data& targetDomain) :   mFlowKey(0),   transport(0),   onlyUseExistingConnection(false),   mTransportType(type),   mTargetDomain(targetDomain){   if (ipVer == V4)   {      memset(&m_anonv4, 0, sizeof(m_anonv4));      m_anonv4.sin_family = AF_INET;      m_anonv4.sin_port = htons(port);      if (printableAddr.empty())      {         m_anonv4.sin_addr.s_addr = htonl(INADDR_ANY);       }      else      {         DnsUtil::inet_pton( printableAddr, m_anonv4.sin_addr);      }   }   else   {#ifdef USE_IPV6      memset(&m_anonv6, 0, sizeof(m_anonv6));      m_anonv6.sin6_family = AF_INET6;      m_anonv6.sin6_port = htons(port);      if (printableAddr.empty())      {         m_anonv6.sin6_addr = in6addr_any;      }      else      {         DnsUtil::inet_pton( printableAddr, m_anonv6.sin6_addr);      }#else	  assert(0);#endif   }}Tuple::Tuple(const Data& printableAddr,              int port,             TransportType ptype,             const Data& targetDomain) :    mFlowKey(0),   transport(0),   onlyUseExistingConnection(false),   mTransportType(ptype),   mTargetDomain(targetDomain){   if (DnsUtil::isIpV4Address(printableAddr))   {      memset(&m_anonv4, 0, sizeof(m_anonv4));            DnsUtil::inet_pton( printableAddr, m_anonv4.sin_addr);      m_anonv4.sin_family = AF_INET;      m_anonv4.sin_port = htons(port);   }   else   {#ifdef USE_IPV6      memset(&m_anonv6, 0, sizeof(m_anonv6));      DnsUtil::inet_pton( printableAddr, m_anonv6.sin6_addr);      m_anonv6.sin6_family = AF_INET6;      m_anonv6.sin6_port = htons(port);#else	  assert(0);#endif   }}Tuple::Tuple(const in_addr& ipv4,             int port,             TransportType ptype,             const Data& targetDomain)     :mFlowKey(0),   transport(0),     onlyUseExistingConnection(false),     mTransportType(ptype),     mTargetDomain(targetDomain){   memset(&m_anonv4, 0, sizeof(sockaddr_in));   m_anonv4.sin_addr = ipv4;   m_anonv4.sin_port = htons(port);   m_anonv4.sin_family = AF_INET;}#ifdef USE_IPV6Tuple::Tuple(const in6_addr& ipv6,             int port,             TransportType ptype,             const Data& targetDomaina)     :mFlowKey(0),   transport(0),     onlyUseExistingConnection(false),     mTransportType(ptype),     mTargetDomain(targetDomaina){   memset(&m_anonv6, 0, sizeof(sockaddr_in6));   m_anonv6.sin6_addr = ipv6;   m_anonv6.sin6_port = htons(port);   m_anonv6.sin6_family = AF_INET6;}#endifTuple::Tuple(const struct sockaddr& addr,              TransportType ptype,             const Data& targetDomain) :    mFlowKey(0),   transport(0),   onlyUseExistingConnection(false),   mSockaddr(addr),   mTransportType(ptype),   mTargetDomain(targetDomain){   if (addr.sa_family == AF_INET)      {      m_anonv4 = (sockaddr_in&)(addr);   }#ifdef USE_IPV6   else if (addr.sa_family == AF_INET6)   {      m_anonv6 = (sockaddr_in6&)(addr);   }#endif   else   {      assert(0);   }}voidTuple::setSockaddr(const GenericIPAddress& addr){  if (addr.isVersion4())  {     m_anonv4 = addr.v4Address;  }  else#ifdef USE_IPV6  {     m_anonv6 = addr.v6Address;  }#else  {     assert(0);  }#endif}voidTuple::writeBinaryToken(const resip::Tuple& tuple,resip::Data& container){   // .bwc. Maybe should just write the raw sockaddr into a buffer, and tack   // on the flowid and onlyUseExistingConnection flag. Would require 10 extra   // bytes for V6, and 14 extra bytes for V4.    // V6: sin6_len(1), sin6_flowinfo(4), flowId(4), onlyUseExistingConnection(1)   // V4: sin_family(2 instead of 1), sin_zero(8), flowId(4), onlyUseExistingConnection(1)   UInt32 rawToken[6];   memset(&rawToken, 0, 24);   rawToken[0] = tuple.mFlowKey;   rawToken[1] += (tuple.getType() << 8);   rawToken[1] += (tuple.getPort() << 16);   if(tuple.ipVersion()==V6)   {      rawToken[1] += 0x00000001;      in6_addr address = reinterpret_cast<const sockaddr_in6&>(tuple.getSockaddr()).sin6_addr;      assert(sizeof(address)==16);      memcpy(&rawToken[2],&address,16);   }   else   {      in_addr address = reinterpret_cast<const sockaddr_in&>(tuple.getSockaddr()).sin_addr;      assert(sizeof(address)==4);      memcpy(&rawToken[2],&address,4);   }      if(tuple.onlyUseExistingConnection)   {      rawToken[1] += 0x00000010;   }      container.clear();   container.append((char*)&rawToken[0],(tuple.ipVersion()==V6) ? 24 : 12);}TupleTuple::makeTuple(const resip::Data& binaryFlowToken){   if(binaryFlowToken.size()<12)   {      // !bwc! Should not assert here, since this sort of thing      // can come off the wire easily.      // TODO Throw an exception here?      DebugLog(<<"binary flow token was too small: " << binaryFlowToken.size());      return Tuple();   }   const UInt32* rawToken=reinterpret_cast<const UInt32*>(binaryFlowToken.data());   Socket mFlowKey=rawToken[0];   IpVersion version = (rawToken[1] & 0x00000001 ? V6 : V4);      if(!((version==V4 && binaryFlowToken.size()==12) ||         (version==V6 && binaryFlowToken.size()==24)))   {      DebugLog(<<"Binary flow token is the wrong size for its IP version.");      return Tuple();   }   bool isRealFlow = (rawToken[1] & 0x00000010 ? true : false);      UInt8 temp = (TransportType)((rawToken[1] & 0x00000F00) >> 8);   if(temp >= MAX_TRANSPORT)   {      DebugLog(<<"Garbage transport type in flow token: " << temp );      return Tuple();   }      TransportType type = (TransportType)temp;      UInt16 port= (rawToken[1] >> 16);      if(version==V6)   {#ifdef USE_IPV6      in6_addr address;      assert(sizeof(address)==16);      memcpy(&address,&rawToken[2],16);      Tuple result(address,port,type);#else      Tuple result(resip::Data::Empty, port, type);#endif      result.mFlowKey=mFlowKey;      result.onlyUseExistingConnection=isRealFlow;      return result;   }   else   {      in_addr address;      assert(sizeof(address)==4);      memcpy(&address,&rawToken[2],4);      Tuple result(address,port,type);      result.mFlowKey=mFlowKey;      result.onlyUseExistingConnection=isRealFlow;      return result;   }      // !bwc! We should never end up down here, regardless of what is in token   // This is just here to keep the compiler from whining.   assert(0);   return Tuple();   }Data Tuple::presentationFormat() const{#ifdef USE_IPV6   if (isV4())   {      return Tuple::inet_ntop(*this);   }   else if (IN6_IS_ADDR_V4MAPPED(&m_anonv6.sin6_addr))   {      return DnsUtil::inet_ntop(*(reinterpret_cast<const in_addr*>(                                   (reinterpret_cast<const unsigned char*>(&m_anonv6.sin6_addr) + 12))));   }   else   {      return Tuple::inet_ntop(*this);   }#else      return Tuple::inet_ntop(*this);#endif}voidTuple::setPort(int port){   if (mSockaddr.sa_family == AF_INET) // v4      {      m_anonv4.sin_port = htons(port);   }   else   {#ifdef USE_IPV6      m_anonv6.sin6_port = htons(port);#else	  assert(0);#endif   }}int Tuple::getPort() const{   if (mSockaddr.sa_family == AF_INET) // v4      {      return ntohs(m_anonv4.sin_port);   }   else   {#ifdef USE_IPV6      return ntohs(m_anonv6.sin6_port);#else	  assert(0);#endif   }      return -1;}boolTuple::isAnyInterface() const{   if (isV4())   {      return m_anonv4.sin_addr.s_addr == htonl(INADDR_ANY);    }#if defined (USE_IPV6)   else   {      return memcmp(&m_anonv6.sin6_addr, &in6addr_any, sizeof(in6_addr)) == 0;   }#else   return false;#endif}boolTuple::isLoopback() const{      if(ipVersion()==V4)   {      static Tuple loopbackv4("127.0.0.1",0,UNKNOWN_TRANSPORT);      return isEqualWithMask(loopbackv4,8,true,true);   }   else if (ipVersion()==V6)   {#ifdef USE_IPV6#if defined(__linux__) || defined(__APPLE__) || defined(WIN32)      return IN6_IS_ADDR_LOOPBACK(&(m_anonv6.sin6_addr)) != 0;#else      return ((*(const __uint32_t *)(const void *)(&(m_anonv6.sin6_addr.s6_addr[0])) == 0) &&              (*(const __uint32_t *)(const void *)(&(m_anonv6.sin6_addr.s6_addr[4])) == 0) &&              (*(const __uint32_t *)(const void *)(&(m_anonv6.sin6_addr.s6_addr[8])) == 0) &&              (*(const __uint32_t *)(const void *)(&(m_anonv6.sin6_addr.s6_addr[12])) == ntohl(1)));#endif#endif   }   else   {      assert(0);   }      return false;}bool Tuple::isV4() const{   return mSockaddr.sa_family == AF_INET;}IpVersion Tuple::ipVersion() const{   return mSockaddr.sa_family == AF_INET ? V4 : V6;}socklen_tTuple::length() const{   if (mSockaddr.sa_family == AF_INET) // v4   {      return sizeof(sockaddr_in);   }#ifdef USE_IPV6   else  if (mSockaddr.sa_family == AF_INET6) // v6   {      return sizeof(sockaddr_in6);   }#endif   assert(0);   return 0;}bool Tuple::operator==(const Tuple& rhs) const{   if (mSockaddr.sa_family == rhs.mSockaddr.sa_family)   {      if (mSockaddr.sa_family == AF_INET) // v4      {         return (m_anonv4.sin_port == rhs.m_anonv4.sin_port &&                 mTransportType == rhs.mTransportType &&                 memcmp(&m_anonv4.sin_addr, &rhs.m_anonv4.sin_addr, sizeof(in_addr)) == 0);      }      else // v6      {#ifdef USE_IPV6         return (m_anonv6.sin6_port == rhs.m_anonv6.sin6_port &&                 mTransportType == rhs.mTransportType &&                 memcmp(&m_anonv6.sin6_addr, &rhs.m_anonv6.sin6_addr, sizeof(in6_addr)) == 0);#else         assert(0);		return false;#endif      }

⌨️ 快捷键说明

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