diff options
Diffstat (limited to 'node/InetAddress.cpp')
-rw-r--r-- | node/InetAddress.cpp | 100 |
1 files changed, 73 insertions, 27 deletions
diff --git a/node/InetAddress.cpp b/node/InetAddress.cpp index b9d07ea5..3727d471 100644 --- a/node/InetAddress.cpp +++ b/node/InetAddress.cpp @@ -37,10 +37,8 @@ namespace ZeroTier { -const InetAddress InetAddress::LO4("127.0.0.1",0); -const InetAddress InetAddress::LO6("::1",0); -const InetAddress InetAddress::DEFAULT4((uint32_t)0,0); -const InetAddress InetAddress::DEFAULT6((const void *)0,16,0); +const InetAddress InetAddress::LO4((const void *)("\x7f\x00\x00\x01"),4,0); +const InetAddress InetAddress::LO6((const void *)("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01"),16,0); InetAddress::IpScope InetAddress::ipScope() const throw() @@ -113,22 +111,19 @@ InetAddress::IpScope InetAddress::ipScope() const void InetAddress::set(const std::string &ip,unsigned int port) throw() { + memset(this,0,sizeof(InetAddress)); if (ip.find(':') != std::string::npos) { - struct sockaddr_in6 sin6; - memset(&sin6,0,sizeof(sin6)); - sin6.sin6_family = AF_INET6; - sin6.sin6_port = Utils::hton((uint16_t)port); - if (inet_pton(AF_INET6,ip.c_str(),(void *)&(sin6.sin6_addr.s6_addr)) <= 0) + struct sockaddr_in6 *sin6 = reinterpret_cast<struct sockaddr_in6 *>(this); + ss_family = AF_INET6; + sin6->sin6_port = Utils::hton((uint16_t)port); + if (inet_pton(AF_INET6,ip.c_str(),(void *)&(sin6->sin6_addr.s6_addr)) <= 0) memset(this,0,sizeof(InetAddress)); - else *this = sin6; } else { - struct sockaddr_in sin; - memset(&sin,0,sizeof(sin)); - sin.sin_family = AF_INET; - sin.sin_port = Utils::hton((uint16_t)port); - if (inet_pton(AF_INET,ip.c_str(),(void *)&(sin.sin_addr.s_addr)) <= 0) + struct sockaddr_in *sin = reinterpret_cast<struct sockaddr_in *>(this); + ss_family = AF_INET; + sin->sin_port = Utils::hton((uint16_t)port); + if (inet_pton(AF_INET,ip.c_str(),(void *)&(sin->sin_addr.s_addr)) <= 0) memset(this,0,sizeof(InetAddress)); - else *this = sin; } } @@ -137,15 +132,14 @@ void InetAddress::set(const void *ipBytes,unsigned int ipLen,unsigned int port) { memset(this,0,sizeof(InetAddress)); if (ipLen == 4) { - setV4(); - if (ipBytes) - memcpy(rawIpData(),ipBytes,4); - setPort(port); + ss_family = AF_INET; + reinterpret_cast<struct sockaddr_in *>(this)->sin_addr.s_addr = *(reinterpret_cast<const uint32_t *>(ipBytes)); + reinterpret_cast<struct sockaddr_in *>(this)->sin_port = Utils::hton((uint16_t)port); } else if (ipLen == 16) { - setV6(); - if (ipBytes) - memcpy(rawIpData(),ipBytes,16); - setPort(port); + ss_family = AF_INET6; + (reinterpret_cast<uint64_t *>(reinterpret_cast<struct sockaddr_in6 *>(this)->sin6_addr.s6_addr))[0] = ((const uint64_t *)ipBytes)[0]; + (reinterpret_cast<uint64_t *>(reinterpret_cast<struct sockaddr_in6 *>(this)->sin6_addr.s6_addr))[1] = ((const uint64_t *)ipBytes)[1]; + reinterpret_cast<struct sockaddr_in6 *>(this)->sin6_port = Utils::hton((uint16_t)port); } } @@ -225,10 +219,10 @@ std::string InetAddress::toIpString() const void InetAddress::fromString(const std::string &ipSlashPort) { - std::size_t slashAt = ipSlashPort.find('/'); - if ((slashAt == std::string::npos)||(slashAt >= ipSlashPort.length())) + const std::size_t slashAt = ipSlashPort.find('/'); + if (slashAt == std::string::npos) { set(ipSlashPort,0); - else { + } else { long p = strtol(ipSlashPort.substr(slashAt+1).c_str(),(char **)0,10); if ((p > 0)&&(p <= 0xffff)) set(ipSlashPort.substr(0,slashAt),(unsigned int)p); @@ -280,6 +274,58 @@ InetAddress InetAddress::broadcast() const return r; } +bool InetAddress::operator==(const InetAddress &a) const + throw() +{ + if (ss_family == a.ss_family) { + switch(ss_family) { + case AF_INET: + return ( + (reinterpret_cast<const struct sockaddr_in *>(this)->sin_port == reinterpret_cast<const struct sockaddr_in *>(&a)->sin_port)&& + (reinterpret_cast<const struct sockaddr_in *>(this)->sin_addr.s_addr == reinterpret_cast<const struct sockaddr_in *>(&a)->sin_addr.s_addr)); + break; + case AF_INET6: + return ( + (reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_port == reinterpret_cast<const struct sockaddr_in6 *>(&a)->sin6_port)&& + (reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_flowinfo == reinterpret_cast<const struct sockaddr_in6 *>(&a)->sin6_flowinfo)&& + (memcmp(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr,reinterpret_cast<const struct sockaddr_in6 *>(&a)->sin6_addr.s6_addr,16) == 0)&& + (reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_scope_id == reinterpret_cast<const struct sockaddr_in6 *>(&a)->sin6_scope_id)); + break; + default: + return (memcmp(this,&a,sizeof(InetAddress)) == 0); + } + } + return false; +} + +bool InetAddress::operator<(const InetAddress &a) const + throw() +{ + if (ss_family < a.ss_family) { + switch(ss_family) { + case AF_INET: + if (reinterpret_cast<const struct sockaddr_in *>(this)->sin_port < reinterpret_cast<const struct sockaddr_in *>(&a)->sin_port) + return true; + if (reinterpret_cast<const struct sockaddr_in *>(this)->sin_addr.s_addr < reinterpret_cast<const struct sockaddr_in *>(&a)->sin_addr.s_addr) + return true; + break; + case AF_INET6: + if (reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_port < reinterpret_cast<const struct sockaddr_in6 *>(&a)->sin6_port) + return true; + if (reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_flowinfo < reinterpret_cast<const struct sockaddr_in6 *>(&a)->sin6_flowinfo) + return true; + if (memcmp(reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_addr.s6_addr,reinterpret_cast<const struct sockaddr_in6 *>(&a)->sin6_addr.s6_addr,16) < 0) + return true; + if (reinterpret_cast<const struct sockaddr_in6 *>(this)->sin6_scope_id < reinterpret_cast<const struct sockaddr_in6 *>(&a)->sin6_scope_id) + return true; + break; + default: + return (memcmp(this,&a,sizeof(InetAddress)) < 0); + } + } + return false; +} + InetAddress InetAddress::makeIpv6LinkLocal(const MAC &mac) throw() { |