📄 tuple.cxx
字号:
#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::DNS
Tuple::Tuple() :
transport(0),
connectionId(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) :
transport(0),
connectionId(0),
onlyUseExistingConnection(false),
mTransportType(type),
mTargetDomain(targetDomain)
{
if (genericAddress.isVersion4())
{
m_anonv4 = genericAddress.v4Address;
}
else
#ifdef USE_IPV6
{
m_anonv6 = genericAddress.v6Address;
}
#else
{
assert(0);
}
#endif
}
Tuple::Tuple(const Data& printableAddr,
int port,
IpVersion ipVer,
TransportType type,
const Data& targetDomain) :
transport(0),
connectionId(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) :
transport(0),
connectionId(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)
: transport(0),
connectionId(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_IPV6
Tuple::Tuple(const in6_addr& ipv6,
int port,
TransportType ptype,
const Data& targetDomaina)
: transport(0),
connectionId(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;
}
#endif
Tuple::Tuple(const struct sockaddr& addr,
TransportType ptype,
const Data& targetDomain) :
transport(0),
connectionId(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);
}
}
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
}
void
Tuple::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;
}
bool
Tuple::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
}
bool
Tuple::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_t
Tuple::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
}
}
else
{
return false;
}
// !dlb! don't include connection
}
bool
Tuple::operator<(const Tuple& rhs) const
{
if (mTransportType < rhs.mTransportType)
{
return true;
}
else if (mTransportType > rhs.mTransportType)
{
return false;
}
else if (mSockaddr.sa_family == AF_INET && rhs.mSockaddr.sa_family == AF_INET)
{
int c=memcmp(&m_anonv4.sin_addr,
&rhs.m_anonv4.sin_addr,
sizeof(in_addr));
if (c < 0)
{
return true;
}
else if (c > 0)
{
return false;
}
else if (m_anonv4.sin_port < rhs.m_anonv4.sin_port)
{
return true;
}
else
{
return false;
}
}
#ifdef USE_IPV6
else if (mSockaddr.sa_family == AF_INET6 &&
rhs.mSockaddr.sa_family == AF_INET6)
{
int c = memcmp(&m_anonv6.sin6_addr,
&rhs.m_anonv6.sin6_addr,
sizeof(in6_addr));
if (c < 0)
{
return true;
}
else if (c > 0)
{
return false;
}
else if (m_anonv6.sin6_port < rhs.m_anonv6.sin6_port)
{
return true;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -