mirror of https://github.com/fail2ban/fail2ban
allow using of IPv6 address style mask (analog to the IPv4), for example: `2606:28ff::/ffff:ff80::` -> `2606:2880::/25`
fast calculating of maskplen using map table MAP_ADDR2MASKPLEN, with pre-calculated addr->maskplen values; test cases extended;pull/1415/head
parent
0c2eeee8c7
commit
4b5b16cd9f
|
@ -171,7 +171,7 @@ class IPAddr(object):
|
||||||
# IP address without CIDR mask
|
# IP address without CIDR mask
|
||||||
if len(s) > 2:
|
if len(s) > 2:
|
||||||
raise ValueError("invalid ipstr %r, too many plen representation" % (ipstr,))
|
raise ValueError("invalid ipstr %r, too many plen representation" % (ipstr,))
|
||||||
if "." in s[1]: # 255.255.255.0 style mask
|
if "." in s[1] or ":" in s[1]: # 255.255.255.0 resp. ffff:: style mask
|
||||||
s[1] = IPAddr.masktoplen(s[1])
|
s[1] = IPAddr.masktoplen(s[1])
|
||||||
s[1] = long(s[1])
|
s[1] = long(s[1])
|
||||||
return s
|
return s
|
||||||
|
@ -235,7 +235,7 @@ class IPAddr(object):
|
||||||
return self.ntoa
|
return self.ntoa
|
||||||
|
|
||||||
def __reduce__(self):
|
def __reduce__(self):
|
||||||
"""IPAddr pickle-handler, that simple wrap IPAddr to the str
|
"""IPAddr pickle-handler, that simply wraps IPAddr to the str
|
||||||
|
|
||||||
Returns a string as instance to be pickled, because fail2ban-client can't
|
Returns a string as instance to be pickled, because fail2ban-client can't
|
||||||
unserialize IPAddr objects
|
unserialize IPAddr objects
|
||||||
|
@ -392,17 +392,29 @@ class IPAddr(object):
|
||||||
|
|
||||||
return (self.addr & mask) == net.addr
|
return (self.addr & mask) == net.addr
|
||||||
|
|
||||||
|
# Pre-calculated map: addr to maskplen
|
||||||
|
def __getMaskMap():
|
||||||
|
m6 = (1 << 128)-1
|
||||||
|
m4 = (1 << 32)-1
|
||||||
|
mmap = {m6: 128, m4: 32, 0: 0}
|
||||||
|
m = 0
|
||||||
|
for i in xrange(0, 128):
|
||||||
|
m |= 1 << i
|
||||||
|
if i < 32:
|
||||||
|
mmap[m ^ m4] = 32-1-i
|
||||||
|
mmap[m ^ m6] = 128-1-i
|
||||||
|
return mmap
|
||||||
|
|
||||||
|
MAP_ADDR2MASKPLEN = __getMaskMap()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def maskplen(self):
|
def maskplen(self):
|
||||||
mplen = 0
|
mplen = 0
|
||||||
if self._maskplen is not None:
|
if self._maskplen is not None:
|
||||||
return self._maskplen
|
return self._maskplen
|
||||||
maddr = self._addr
|
mplen = IPAddr.MAP_ADDR2MASKPLEN.get(self._addr)
|
||||||
while maddr:
|
if mplen is None:
|
||||||
if not (maddr & 0x80000000):
|
raise ValueError("invalid mask %r, no plen representation" % (str(self),))
|
||||||
raise ValueError("invalid mask %r, no plen representation" % (str(self),))
|
|
||||||
maddr = (maddr << 1) & 0xFFFFFFFFL
|
|
||||||
mplen += 1
|
|
||||||
self._maskplen = mplen
|
self._maskplen = mplen
|
||||||
return mplen
|
return mplen
|
||||||
|
|
||||||
|
|
|
@ -1452,11 +1452,24 @@ class DNSUtilsNetworkTests(unittest.TestCase):
|
||||||
self.assertEqual(IPAddr('93.184.0.1', 24).ntoa, '93.184.0.0/24')
|
self.assertEqual(IPAddr('93.184.0.1', 24).ntoa, '93.184.0.0/24')
|
||||||
self.assertEqual(IPAddr('192.168.1.0/255.255.255.128').ntoa, '192.168.1.0/25')
|
self.assertEqual(IPAddr('192.168.1.0/255.255.255.128').ntoa, '192.168.1.0/25')
|
||||||
|
|
||||||
|
self.assertEqual(IPAddr('93.184.0.1/32').ntoa, '93.184.0.1')
|
||||||
|
self.assertEqual(IPAddr('93.184.0.1/255.255.255.255').ntoa, '93.184.0.1')
|
||||||
|
|
||||||
self.assertEqual(str(IPAddr('2606:2800:220:1:248:1893:25c8::', 120)), '2606:2800:220:1:248:1893:25c8:0/120')
|
self.assertEqual(str(IPAddr('2606:2800:220:1:248:1893:25c8::', 120)), '2606:2800:220:1:248:1893:25c8:0/120')
|
||||||
self.assertEqual(IPAddr('2606:2800:220:1:248:1893:25c8::', 120).ntoa, '2606:2800:220:1:248:1893:25c8:0/120')
|
self.assertEqual(IPAddr('2606:2800:220:1:248:1893:25c8::', 120).ntoa, '2606:2800:220:1:248:1893:25c8:0/120')
|
||||||
self.assertEqual(str(IPAddr('2606:2800:220:1:248:1893:25c8:0/120')), '2606:2800:220:1:248:1893:25c8:0/120')
|
self.assertEqual(str(IPAddr('2606:2800:220:1:248:1893:25c8:0/120')), '2606:2800:220:1:248:1893:25c8:0/120')
|
||||||
self.assertEqual(IPAddr('2606:2800:220:1:248:1893:25c8:0/120').ntoa, '2606:2800:220:1:248:1893:25c8:0/120')
|
self.assertEqual(IPAddr('2606:2800:220:1:248:1893:25c8:0/120').ntoa, '2606:2800:220:1:248:1893:25c8:0/120')
|
||||||
|
|
||||||
|
self.assertEqual(str(IPAddr('2606:28ff:220:1:248:1893:25c8::', 25)), '2606:2880::/25')
|
||||||
|
self.assertEqual(str(IPAddr('2606:28ff:220:1:248:1893:25c8::/ffff:ff80::')), '2606:2880::/25')
|
||||||
|
self.assertEqual(str(IPAddr('2606:28ff:220:1:248:1893:25c8::/ffff:ffff:ffff:ffff:ffff:ffff:ffff::')),
|
||||||
|
'2606:28ff:220:1:248:1893:25c8:0/112')
|
||||||
|
|
||||||
|
self.assertEqual(str(IPAddr('2606:28ff:220:1:248:1893:25c8::/128')),
|
||||||
|
'2606:28ff:220:1:248:1893:25c8:0')
|
||||||
|
self.assertEqual(str(IPAddr('2606:28ff:220:1:248:1893:25c8::/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff')),
|
||||||
|
'2606:28ff:220:1:248:1893:25c8:0')
|
||||||
|
|
||||||
def testIPAddr_CIDR_Repr(self):
|
def testIPAddr_CIDR_Repr(self):
|
||||||
self.assertEqual(["127.0.0.0/8", "::/32", "2001:db8::/32"],
|
self.assertEqual(["127.0.0.0/8", "::/32", "2001:db8::/32"],
|
||||||
[IPAddr("127.0.0.0", 8), IPAddr("::1", 32), IPAddr("2001:db8::", 32)]
|
[IPAddr("127.0.0.0", 8), IPAddr("::1", 32), IPAddr("2001:db8::", 32)]
|
||||||
|
|
Loading…
Reference in New Issue