summaryrefslogtreecommitdiff
path: root/src/sockets.cpp
diff options
context:
space:
mode:
authorAdam <Adam@anope.org>2013-03-13 14:40:49 -0500
committerAdam <Adam@anope.org>2013-03-13 14:40:49 -0500
commit1ff7a7c1f1cee2dfe26a0a72026176202e2e4e6a (patch)
treea492ee7bc3dc23a9ffae40ca1e643d664608e929 /src/sockets.cpp
parent1d16629a6da2f1d5b65557028e75abc7de51cad5 (diff)
Refactor mask/entry code, allow full matching (against users real host/ip) if their displayed host is their real real host. Also match against cloaked host even if full matching is not being done
Diffstat (limited to 'src/sockets.cpp')
-rw-r--r--src/sockets.cpp36
1 files changed, 22 insertions, 14 deletions
diff --git a/src/sockets.cpp b/src/sockets.cpp
index 53ca40f80..b30932935 100644
--- a/src/sockets.cpp
+++ b/src/sockets.cpp
@@ -207,24 +207,29 @@ Anope::string cidr::mask() const
return Anope::printf("%s/%d", this->cidr_ip.c_str(), this->cidr_len);
}
-bool cidr::match(sockaddrs &other)
+bool cidr::match(const sockaddrs &other)
{
if (this->addr.sa.sa_family != other.sa.sa_family)
return false;
- unsigned char *ip, *their_ip, byte;
+ const unsigned char *ip, *their_ip;
+ unsigned char byte, len = this->cidr_len;
switch (this->addr.sa.sa_family)
{
case AF_INET:
- ip = reinterpret_cast<unsigned char *>(&this->addr.sa4.sin_addr);
- byte = this->cidr_len / 8;
- their_ip = reinterpret_cast<unsigned char *>(&other.sa4.sin_addr);
+ ip = reinterpret_cast<const unsigned char *>(&this->addr.sa4.sin_addr);
+ if (len > 32)
+ len = 32;
+ byte = len / 8;
+ their_ip = reinterpret_cast<const unsigned char *>(&other.sa4.sin_addr);
break;
case AF_INET6:
- ip = reinterpret_cast<unsigned char *>(&this->addr.sa6.sin6_addr);
- byte = this->cidr_len / 8;
- their_ip = reinterpret_cast<unsigned char *>(&other.sa6.sin6_addr);
+ ip = reinterpret_cast<const unsigned char *>(&this->addr.sa6.sin6_addr);
+ if (len > 128)
+ len = 128;
+ byte = len / 8;
+ their_ip = reinterpret_cast<const unsigned char *>(&other.sa6.sin6_addr);
break;
default:
throw SocketException("Invalid address type");
@@ -233,11 +238,14 @@ bool cidr::match(sockaddrs &other)
if (memcmp(ip, their_ip, byte))
return false;
- ip += byte;
- their_ip += byte;
- byte = this->cidr_len % 8;
- if ((*ip & byte) != (*their_ip & byte))
- return false;
+ byte = len % 8;
+ if (byte)
+ {
+ ip += byte;
+ their_ip += byte;
+ if ((*ip & byte) != (*their_ip & byte))
+ return false;
+ }
return true;
}
@@ -295,7 +303,7 @@ size_t cidr::hash::operator()(const cidr &s) const
{
size_t h = 0;
- for (int i = 0; i < s.cidr_len / 8; ++i)
+ for (unsigned i = 0; i < s.cidr_len / 8; ++i)
h ^= (s.addr.sa6.sin6_addr.s6_addr[i] << ((i * 8) % sizeof(size_t)));
int remaining = s.cidr_len % 8;