summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAdam <Adam@anope.org>2013-05-08 09:50:43 -0400
committerAdam <Adam@anope.org>2013-05-08 09:50:43 -0400
commit9b07e163c0e1ceed30e72aead2338b47ef2da1b2 (patch)
tree4c13bd545846700a58c5526c3e4e9a6fdf0afc87 /src
parent6859decfb8ed0430e946ff81eca4f9da879f69c9 (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')
-rw-r--r--src/hashcomp.cpp2
-rw-r--r--src/misc.cpp8
-rw-r--r--src/modes.cpp9
-rw-r--r--src/sockets.cpp85
-rw-r--r--src/users.cpp19
5 files changed, 69 insertions, 54 deletions
diff --git a/src/hashcomp.cpp b/src/hashcomp.cpp
index 3c6430330..7b3b906c2 100644
--- a/src/hashcomp.cpp
+++ b/src/hashcomp.cpp
@@ -82,7 +82,7 @@ int ci::ci_char_traits::compare(const char *str1, const char *str2, size_t n)
const char *ci::ci_char_traits::find(const char *s1, int n, char c)
{
- while (n-- > 0 && case_map_upper[static_cast<unsigned char>(*s1)] != static_cast<unsigned char>(c))
+ while (n-- > 0 && case_map_upper[static_cast<unsigned char>(*s1)] != case_map_upper[static_cast<unsigned char>(c)])
++s1;
return n >= 0 ? s1 : NULL;
}
diff --git a/src/misc.cpp b/src/misc.cpp
index 29d3a7121..b446ea711 100644
--- a/src/misc.cpp
+++ b/src/misc.cpp
@@ -707,12 +707,8 @@ Anope::string Anope::Resolve(const Anope::string &host, int type)
{
sockaddrs addr;
memcpy(&addr, addrresult->ai_addr, addrresult->ai_addrlen);
- try
- {
- result = addr.addr();
- Log(LOG_DEBUG_2) << "Resolver: " << host << " -> " << result;
- }
- catch (const SocketException &) { }
+ result = addr.addr();
+ Log(LOG_DEBUG_2) << "Resolver: " << host << " -> " << result;
freeaddrinfo(addrresult);
}
diff --git a/src/modes.cpp b/src/modes.cpp
index 9481f570e..1238df17d 100644
--- a/src/modes.cpp
+++ b/src/modes.cpp
@@ -671,12 +671,12 @@ Entry::Entry(const Anope::string &m, const Anope::string &fh) : name(m), mask(fh
{
const Anope::string &cidr_ip = this->host.substr(0, sl),
&cidr_range = this->host.substr(sl + 1);
+
+ sockaddrs addr(cidr_ip);
+
try
{
- sockaddrs addr(cidr_ip);
- /* If we got here, cidr_ip is a valid ip */
-
- if (cidr_range.is_pos_number_only())
+ if (addr.valid() && cidr_range.is_pos_number_only())
{
this->cidr_len = convertTo<unsigned short>(cidr_range);
/* If we got here, cidr_len is a valid number.
@@ -689,7 +689,6 @@ Entry::Entry(const Anope::string &m, const Anope::string &fh) : name(m), mask(fh
Log(LOG_DEBUG) << "Ban " << this->mask << " has cidr " << this->cidr_len;
}
}
- catch (const SocketException &) { }
catch (const ConvertException &) { }
}
}
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)
diff --git a/src/users.cpp b/src/users.cpp
index 58f586e27..bd376f6a1 100644
--- a/src/users.cpp
+++ b/src/users.cpp
@@ -22,6 +22,7 @@
#include "config.h"
#include "opertype.h"
#include "language.h"
+#include "sockets.h"
user_map UserListByNick, UserListByUID;
@@ -753,24 +754,24 @@ bool User::Quitting() const
Anope::string User::Mask() const
{
Anope::string mask;
- Anope::string mident = this->GetIdent();
- Anope::string mhost = this->GetDisplayedHost();
+ const Anope::string &mident = this->GetIdent();
+ const Anope::string &mhost = this->GetDisplayedHost();
if (mident[0] == '~')
mask = "*" + mident + "@";
else
mask = mident + "@";
- size_t dot;
- /* To make sure this is an IP, make sure the host contains only numbers and dots, and check to make sure it only contains 3 dots */
- if (mhost.find_first_not_of("0123456789.") == Anope::string::npos && (dot = mhost.find('.')) != Anope::string::npos && (dot = mhost.find('.', dot + 1)) != Anope::string::npos && (dot = mhost.find('.', dot + 1)) != Anope::string::npos && mhost.find('.', dot + 1) == Anope::string::npos)
- { /* IP addr */
- dot = mhost.find('.');
- mask += mhost.substr(0, dot) + ".*";
+ sockaddrs addr(mhost);
+ if (addr.valid() && addr.sa.sa_family == AF_INET)
+ {
+ size_t dot = mhost.find('.');
+ mask += mhost.substr(0, dot) + (dot == Anope::string::npos ? "" : ".*");
}
else
{
- if ((dot = mhost.find('.')) != Anope::string::npos && mhost.find('.', dot + 1) != Anope::string::npos)
+ size_t dot = mhost.find('.');
+ if (dot != Anope::string::npos && mhost.find('.', dot + 1) != Anope::string::npos)
mask += "*" + mhost.substr(dot);
else
mask += mhost;