Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 20 additions & 3 deletions aikido_zen/helpers/ip_matcher_fallback/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,34 @@
MIT License - Copyright (c) 2019 alex
"""

import ipaddress
from .shared import parse_base_network, sort_networks, summarize_sorted_networks
from .sort import binary_search_for_insertion_index


def preparse(network: str) -> str:
"""
Canonicalize IPv4-mapped IPv6 addresses to their IPv4 form.
This ensures that ::ffff:169.254.169.254 matches 169.254.169.254 rules.
"""
# Remove the brackets around IPv6 addresses if they are there.
network = network.strip("[]")
try:
ip = ipaddress.IPv6Address(network)
if ip.ipv4_mapped:
return str(ip.ipv4_mapped)
except ValueError:
pass
return network


class IPMatcher:
def __init__(self, networks=None):
self.sorted = []
if networks is not None:
subnets = []
for s in networks:
net = parse_base_network(s, False)
net = parse_base_network(preparse(s), False)
if net and net.is_valid():
subnets.append(net)
sort_networks(subnets)
Expand All @@ -23,7 +40,7 @@ def has(self, network):
"""
Checks if the given IP address is in the list of networks.
"""
net = parse_base_network(network, False)
net = parse_base_network(preparse(network), False)
if not net or not net.is_valid():
return False
idx = binary_search_for_insertion_index(net, self.sorted)
Expand All @@ -36,7 +53,7 @@ def has(self, network):
return False

def add(self, network):
net = parse_base_network(network, False)
net = parse_base_network(preparse(network), False)
if not net or not net.is_valid():
return self
idx = binary_search_for_insertion_index(net, self.sorted)
Expand Down
Loading