diff options
author | Adam <Adam@anope.org> | 2013-05-08 09:50:43 -0400 |
---|---|---|
committer | Adam <Adam@anope.org> | 2013-05-08 09:50:43 -0400 |
commit | 9b07e163c0e1ceed30e72aead2338b47ef2da1b2 (patch) | |
tree | 4c13bd545846700a58c5526c3e4e9a6fdf0afc87 /src/sockets.cpp | |
parent | 6859decfb8ed0430e946ff81eca4f9da879f69c9 (diff) |
Make sockaddrs/cidr not throw on invalid ips to give us an easier/cheaper way to test for a valid IP
Diffstat (limited to 'src/sockets.cpp')
-rw-r--r-- | src/sockets.cpp | 85 |
1 files changed, 52 insertions, 33 deletions
diff --git a/src/sockets.cpp b/src/sockets.cpp index b30932935..8729303bf 100644 --- a/src/sockets.cpp +++ b/src/sockets.cpp @@ -31,7 +31,7 @@ SocketIO NormalSocketIO; sockaddrs::sockaddrs(const Anope::string &address) { this->clear(); - if (!address.empty()) + if (!address.empty() && address.find_first_not_of_ci("0123456789abcdef.:") == Anope::string::npos) this->pton(address.find(':') != Anope::string::npos ? AF_INET6 : AF_INET, address); } @@ -72,28 +72,28 @@ int sockaddrs::port() const Anope::string sockaddrs::addr() const { - char address[INET6_ADDRSTRLEN + 1] = ""; + char address[INET6_ADDRSTRLEN]; switch (sa.sa_family) { case AF_INET: - if (!inet_ntop(AF_INET, &sa4.sin_addr, address, sizeof(address))) - throw SocketException(Anope::LastError()); - return address; + if (inet_ntop(AF_INET, &sa4.sin_addr, address, sizeof(address))) + return address; + break; case AF_INET6: - if (!inet_ntop(AF_INET6, &sa6.sin6_addr, address, sizeof(address))) - throw SocketException(Anope::LastError()); - return address; + if (inet_ntop(AF_INET6, &sa6.sin6_addr, address, sizeof(address))) + return address; + break; default: break; } - return address; + return ""; } bool sockaddrs::operator()() const { - return this->sa.sa_family != 0; + return valid(); } bool sockaddrs::operator==(const sockaddrs &other) const @@ -115,35 +115,37 @@ bool sockaddrs::operator==(const sockaddrs &other) const void sockaddrs::pton(int type, const Anope::string &address, int pport) { + this->clear(); + switch (type) { case AF_INET: { int i = inet_pton(type, address.c_str(), &sa4.sin_addr); - if (i == 0) - throw SocketException("Invalid IP"); - else if (i <= -1) - throw SocketException("Invalid IP: " + Anope::LastError()); - sa4.sin_family = type; - sa4.sin_port = htons(pport); - return; + if (i <= 0) + this->clear(); + else + { + sa4.sin_family = type; + sa4.sin_port = htons(pport); + } + break; } case AF_INET6: { int i = inet_pton(type, address.c_str(), &sa6.sin6_addr); - if (i == 0) - throw SocketException("Invalid IP"); - else if (i <= -1) - throw SocketException("Invalid IP: " + Anope::LastError()); - sa6.sin6_family = type; - sa6.sin6_port = htons(pport); - return; + if (i <= 0) + this->clear(); + else + { + sa6.sin6_family = type; + sa6.sin6_port = htons(pport); + } + break; } default: break; } - - throw CoreException("Invalid socket type"); } void sockaddrs::ntop(int type, const void *src) @@ -151,7 +153,10 @@ void sockaddrs::ntop(int type, const void *src) char buf[INET6_ADDRSTRLEN]; if (inet_ntop(type, src, buf, sizeof(buf)) != buf) - throw SocketException("Invalid addr"); + { + this->clear(); + return; + } switch (type) { @@ -167,7 +172,12 @@ void sockaddrs::ntop(int type, const void *src) break; } - throw CoreException("Invalid socket type"); + this->clear(); +} + +bool sockaddrs::valid() const +{ + return size() != 0; } cidr::cidr(const Anope::string &ip) @@ -185,11 +195,15 @@ cidr::cidr(const Anope::string &ip) { Anope::string real_ip = ip.substr(0, sl); Anope::string cidr_range = ip.substr(sl + 1); - if (!cidr_range.is_pos_number_only()) - throw SocketException("Invalid CIDR range"); this->cidr_ip = real_ip; - this->cidr_len = convertTo<unsigned int>(cidr_range); + this->cidr_len = ipv6 ? 128 : 32; + try + { + if (cidr_range.is_pos_number_only()) + this->cidr_len = convertTo<unsigned int>(cidr_range); + } + catch (const ConvertException &) { } this->addr.pton(ipv6 ? AF_INET6 : AF_INET, real_ip); } } @@ -209,7 +223,7 @@ Anope::string cidr::mask() const bool cidr::match(const sockaddrs &other) { - if (this->addr.sa.sa_family != other.sa.sa_family) + if (!valid() || !other.valid() || this->addr.sa.sa_family != other.sa.sa_family) return false; const unsigned char *ip, *their_ip; @@ -232,7 +246,7 @@ bool cidr::match(const sockaddrs &other) their_ip = reinterpret_cast<const unsigned char *>(&other.sa6.sin6_addr); break; default: - throw SocketException("Invalid address type"); + return false; } if (memcmp(ip, their_ip, byte)) @@ -290,6 +304,11 @@ bool cidr::operator!=(const cidr &other) const return !(*this == other); } +bool cidr::valid() const +{ + return this->addr.valid(); +} + size_t cidr::hash::operator()(const cidr &s) const { switch (s.addr.sa.sa_family) |