aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--rpkid/rpki/exceptions.py5
-rw-r--r--rpkid/rpki/resource_set.py36
2 files changed, 26 insertions, 15 deletions
diff --git a/rpkid/rpki/exceptions.py b/rpkid/rpki/exceptions.py
index 4e4bc42a..21410380 100644
--- a/rpkid/rpki/exceptions.py
+++ b/rpkid/rpki/exceptions.py
@@ -341,3 +341,8 @@ class MultipleCMSEECert(RPKI_Exception):
"""
Can't have more than one CMS EE certificate in validation chain.
"""
+
+class ResourceOverlap(RPKI_Exception):
+ """
+ Overlapping resources in resource_set.
+ """
diff --git a/rpkid/rpki/resource_set.py b/rpkid/rpki/resource_set.py
index 6301f1a5..0bc31ef2 100644
--- a/rpkid/rpki/resource_set.py
+++ b/rpkid/rpki/resource_set.py
@@ -301,7 +301,7 @@ class resource_set(list):
canonical = False
- def __init__(self, ini = None):
+ def __init__(self, ini = None, allow_overlap = False):
"""
Initialize a resource_set.
"""
@@ -316,24 +316,30 @@ class resource_set(list):
self.parse_rfc3779_tuple(ini)
elif isinstance(ini, list):
self.extend(ini)
- else:
- assert ini is None or (isinstance(ini, str) and ini == ""), "Unexpected initializer: %s" % str(ini)
- self.canonize()
+ elif ini is not None and ini != "":
+ raise ValueError("Unexpected initializer: %s" % str(ini))
+ self.canonize(allow_overlap)
- def canonize(self):
+ def canonize(self, allow_overlap = False):
"""
Whack this resource_set into canonical form.
"""
assert not self.inherit or not self
if not self.canonical:
self.sort()
- for i in xrange(len(self) - 2, -1, -1):
- if self[i].max + 1 == self[i+1].min:
+ i = 0
+ while i + 1 < len(self):
+ if allow_overlap and self[i].max + 1 >= self[i+1].min:
+ self[i] = type(self[i])(self[i].min, max(self[i].max, self[i+1].max))
+ del self[i+1]
+ elif self[i].max + 1 == self[i+1].min:
self[i] = type(self[i])(self[i].min, self[i+1].max)
- self.pop(i + 1)
- if __debug__:
- for i in xrange(0, len(self) - 1):
- assert self[i].max < self[i+1].min, "Resource overlap: %s %s" % (self[i], self[i+1])
+ del self[i+1]
+ else:
+ i += 1
+ for i in xrange(0, len(self) - 1):
+ if self[i].max >= self[i+1].min:
+ raise rpki.exceptions.ResourceOverlap("Resource overlap: %s %s" % (self[i], self[i+1]))
self.canonical = True
def append(self, item):
@@ -754,7 +760,7 @@ class resource_bag(object):
return self
@classmethod
- def from_str(cls, text):
+ def from_str(cls, text, allow_overlap = False):
"""
Parse a comma-separated text string into a resource_bag. Not
particularly efficient, fix that if and when it becomes an issue.
@@ -769,9 +775,9 @@ class resource_bag(object):
v6s.append(word)
else:
asns.append(word)
- return cls(asn = resource_set_as(",".join(asns)) if asns else None,
- v4 = resource_set_ipv4(",".join(v4s)) if v4s else None,
- v6 = resource_set_ipv6(",".join(v6s)) if v6s else None)
+ return cls(asn = resource_set_as(",".join(asns), allow_overlap) if asns else None,
+ v4 = resource_set_ipv4(",".join(v4s), allow_overlap) if v4s else None,
+ v6 = resource_set_ipv6(",".join(v6s), allow_overlap) if v6s else None)
@classmethod
def from_rfc3779_tuples(cls, exts):