diff options
-rw-r--r-- | node/InetAddress.cpp | 100 | ||||
-rw-r--r-- | node/InetAddress.hpp | 55 |
2 files changed, 83 insertions, 72 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() { diff --git a/node/InetAddress.hpp b/node/InetAddress.hpp index 5e4dbfd8..0cc4542b 100644 --- a/node/InetAddress.hpp +++ b/node/InetAddress.hpp @@ -62,16 +62,6 @@ struct InetAddress : public sockaddr_storage static const InetAddress LO6; /** - * 0.0.0.0/0 - */ - static const InetAddress DEFAULT4; - - /** - * ::/0 - */ - static const InetAddress DEFAULT6; - - /** * IP address scope * * Do not change these numeric index values without taking a look @@ -91,6 +81,7 @@ struct InetAddress : public sockaddr_storage InetAddress() throw() { memset(this,0,sizeof(InetAddress)); } InetAddress(const InetAddress &a) throw() { memcpy(this,&a,sizeof(InetAddress)); } + InetAddress(const InetAddress *a) throw() { memcpy(this,a,sizeof(InetAddress)); } InetAddress(const struct sockaddr_storage &ss) throw() { *this = ss; } InetAddress(const struct sockaddr_storage *ss) throw() { *this = ss; } InetAddress(const struct sockaddr &sa) throw() { *this = sa; } @@ -112,6 +103,13 @@ struct InetAddress : public sockaddr_storage return *this; } + inline InetAddress &operator=(const InetAddress *a) + throw() + { + memcpy(this,a,sizeof(InetAddress)); + return *this; + } + inline InetAddress &operator=(const struct sockaddr_storage &ss) throw() { @@ -295,39 +293,6 @@ struct InetAddress : public sockaddr_storage inline bool isV6() const throw() { return (ss_family == AF_INET6); } /** - * Force type to IPv4 - */ - inline void setV4() throw() { ss_family = AF_INET; } - - /** - * Force type to IPv6 - */ - inline void setV6() throw() { ss_family = AF_INET6; } - - /** - * @return Length of sockaddr_in if IPv4, sockaddr_in6 if IPv6 - */ - inline unsigned int saddrLen() const - throw() - { - switch(ss_family) { - case AF_INET: return sizeof(struct sockaddr_in); - case AF_INET6: return sizeof(struct sockaddr_in6); - default: return 0; - } - } - - /** - * @return Raw sockaddr_in structure (valid if IPv4) - */ - inline const struct sockaddr_in *saddr4() const throw() { return reinterpret_cast<const struct sockaddr_in *>(this); } - - /** - * @return Raw sockaddr_in6 structure (valid if IPv6) - */ - inline const struct sockaddr_in6 *saddr6() const throw() { return reinterpret_cast<const struct sockaddr_in6 *>(this); } - - /** * @return pointer to raw IP address bytes */ inline const void *rawIpData() const @@ -376,9 +341,9 @@ struct InetAddress : public sockaddr_storage */ inline operator bool() const throw() { return (ss_family != 0); } - inline bool operator==(const InetAddress &a) const throw() { return (memcmp(this,&a,sizeof(InetAddress)) == 0); } + bool operator==(const InetAddress &a) const throw(); + bool operator<(const InetAddress &a) const throw(); inline bool operator!=(const InetAddress &a) const throw() { return !(*this == a); } - inline bool operator<(const InetAddress &a) const throw() { return (memcmp(this,&a,sizeof(InetAddress)) < 0); } inline bool operator>(const InetAddress &a) const throw() { return (a < *this); } inline bool operator<=(const InetAddress &a) const throw() { return !(a < *this); } inline bool operator>=(const InetAddress &a) const throw() { return !(*this < a); } |