Relying on the "struct" module, you can create problems with type sizes and sizes and are simply not needed. Also there is no socket.inet_aton (). Python works great with dotted IPs:
def ip_to_u32(ip): return int(''.join('%02x' % int(d) for d in ip.split('.')), 16)
I need to match the IP addresses for each accept () socket call for the entire set of valid source networks, so I prefix the masks and networks as integers:
SNS_SOURCES = [ # US-EAST-1 '207.171.167.101', '207.171.167.25', '207.171.167.26', '207.171.172.6', '54.239.98.0/24', '54.240.217.16/29', '54.240.217.8/29', '54.240.217.64/28', '54.240.217.80/29', '72.21.196.64/29', '72.21.198.64/29', '72.21.198.72', '72.21.217.0/24', ] def build_masks(): masks = [ ] for cidr in SNS_SOURCES: if '/' in cidr: netstr, bits = cidr.split('/') mask = (0xffffffff << (32 - int(bits))) & 0xffffffff net = ip_to_u32(netstr) & mask else: mask = 0xffffffff net = ip_to_u32(cidr) masks.append((mask, net)) return masks
Then I can quickly find out if this IP is in one of these networks:
ip = ip_to_u32(ipstr) for mask, net in cached_masks: if ip & mask == net: # matched! break else: raise BadClientIP(ipstr)
Importing modules is not required, and the code is very fast when matching.
gstein Nov 06 '17 at 6:32 2017-11-06 06:32
source share