Skip to content

Commit

Permalink
[master] unify workaround to half-open ranges
Browse files Browse the repository at this point in the history
  • Loading branch information
tomhrr committed Jan 31, 2018
1 parent 8ae5fe7 commit 3e31d2c
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 31 deletions.
12 changes: 6 additions & 6 deletions src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,8 @@ impl Context {
return;
}
let els: Vec<&str> = range.split("-").collect();
let start = u64::from_str(els.get(0).unwrap()).unwrap();
let end = u64::from_str(els.get(1).unwrap()).unwrap();
let start = u32::from_str(els.get(0).unwrap()).unwrap();
let end = u32::from_str(els.get(1).unwrap()).unwrap();
asn_entries.push(
(AsnRange { start: Asn { value: start },
end: Asn { value: end + 1 } },
Expand Down Expand Up @@ -165,8 +165,8 @@ impl Context {
if let Some(captures) = asn_regex.captures(value) {
if let Ok(asn_value) = u32::from_str(captures.get(1).unwrap().as_str()) {
return self.asn.get_longest_match_value(
AsnRange{ start: Asn { value: asn_value as u64 },
end: Asn { value: (asn_value as u64) + 1 }}
AsnRange{ start: Asn { value: asn_value as u32 },
end: Asn { value: (asn_value as u32) + 1 }}
);
}
}
Expand All @@ -176,8 +176,8 @@ impl Context {
if let Ok(asn_value_start) = u32::from_str(captures.get(1).unwrap().as_str()) {
if let Ok(asn_value_end) = u32::from_str(captures.get(2).unwrap().as_str()) {
return self.asn.get_longest_match_value(
AsnRange { start: Asn { value: asn_value_start as u64 },
end: Asn { value: asn_value_end as u64 } }
AsnRange { start: Asn { value: asn_value_start as u32 },
end: Asn { value: asn_value_end as u32 } }
);
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/data/delegated.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,8 @@ fn handle_asn<T: ResourceLookup<AsnRange, u32>>(

let asn_str = record.get(3).unwrap();
let count = record.get(4).unwrap();
if let Ok(start_asn) = u64::from_str(asn_str) {
let end_asn = start_asn + (u64::from_str(count).unwrap());
if let Ok(start_asn) = u32::from_str(asn_str) {
let end_asn = start_asn + (u32::from_str(count).unwrap());
let asn_range = AsnRange { start: Asn { value: start_asn },
end: Asn { value: end_asn } };
match asn_lookup.get_longest_match(asn_range) {
Expand Down
14 changes: 7 additions & 7 deletions src/data/iana.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,14 +81,14 @@ fn parse_asn16_iana_data(directory: &str,
match range.contains("-") {
true => {
let nums: Vec<&str> = range.split("-").collect();
let start = u64::from_str(nums.get(0).unwrap()).unwrap();
let end = u64::from_str(nums.get(1).unwrap()).unwrap();
let start = u32::from_str(nums.get(0).unwrap()).unwrap();
let end = u32::from_str(nums.get(1).unwrap()).unwrap();
entries.push((AsnRange { start: Asn { value: start },
end: Asn { value: end + 1 } },
index));
},
false => {
let num = u64::from_str(range).unwrap();
let num = u32::from_str(range).unwrap();
entries.push((AsnRange { start: Asn { value: num },
end: Asn { value: num + 1 } },
index));
Expand All @@ -114,19 +114,19 @@ fn parse_asn32_iana_data(directory: &str,
match range.contains("-") {
true => {
let nums: Vec<&str> = range.split("-").collect();
let start = u64::from_str(nums.get(0).unwrap()).unwrap();
let end = u64::from_str(nums.get(1).unwrap()).unwrap();
let start = u32::from_str(nums.get(0).unwrap()).unwrap();
let end = u32::from_str(nums.get(1).unwrap()).unwrap();
if start >= 65536 {
entries.push((AsnRange { start: Asn { value: start },
end: Asn { value: end + 1 } },
index));
}
},
false => {
let num = u64::from_str(range).unwrap();
let num = u32::from_str(range).unwrap();
if num >= 65536 {
entries.push((AsnRange { start: Asn { value: num },
end: Asn { value: num + 1 } },
end: Asn { value: num.wrapping_add(1) } },
index));
}
}
Expand Down
57 changes: 41 additions & 16 deletions src/lookup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ impl ResourceLookup<Ipv6Net, u32>

#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)]
pub struct Asn {
pub value: u64
pub value: u32
}

impl Add for Asn {
Expand All @@ -276,29 +276,44 @@ pub struct AsnRange {
pub end: Asn,
}

pub struct AsnIntervalTree {
interval_tree: IntervalTree<Asn, u32>,
last_values: Vec<(AsnRange, u32)>,
}

impl ResourceLookup<AsnRange, u32>
for IntervalTree<Asn, u32> {
for AsnIntervalTree {
fn get_longest_match(&self, asrange: AsnRange)
-> Option<(Option<AsnRange>, u32)> {
let tree = &self.interval_tree;
let difference = (asrange.end.value - 1) - asrange.start.value;
let iter =
match difference == 0 {
true => IntervalTree::query_point(self, asrange.start),
false => IntervalTree::query(self, Range {
true => IntervalTree::query_point(tree, asrange.start),
false => IntervalTree::query(tree, Range {
start: asrange.start,
end: asrange.end
})
};
let mut response: Vec<_> =
iter.map(|i| { (AsnRange { start: i.range.start,
end: i.range.end },
i.value) })
.filter(|i| { (i.0.start <= asrange.start)
&& (i.0.end >= asrange.end) })

let mut response: Vec<(AsnRange, u32)> =
iter.filter(|i| { (i.range.start <= asrange.start)
&& (i.range.end.value.wrapping_sub(1)
>= asrange.end.value.wrapping_sub(1)) })
.map(|i| { (AsnRange { start: i.range.start,
end: i.range.end }, i.value) })
.collect();
let mut matching_last_values =
self.last_values
.iter()
.filter(|i| { i.0.start <= asrange.start })
.map(|i| { i.clone() })
.collect();
response.append(&mut matching_last_values);
response.sort_by(|a, b| { let a_diff = a.0.end - a.0.start;
let b_diff = b.0.end - b.0.start;
a_diff.cmp(&b_diff) });

match response.len() >= 1 {
true => { Some((Some(response.get(0).unwrap().0),
response.get(0).unwrap().1)) }
Expand All @@ -315,14 +330,24 @@ impl ResourceLookup<AsnRange, u32>
}

fn from_iter<I: IntoIterator<Item=(AsnRange, u32)>>(values: I)
-> IntervalTree<Asn, u32> {
FromIterator::from_iter(
values.into_iter()
.map(|(r, v)| { (Range { start: r.start, end: r.end }, v)})
)
-> AsnIntervalTree {
let interval_tree: IntervalTree<Asn, u32> =
FromIterator::from_iter(
values.into_iter()
.map(|(r, v)| { (Range { start: r.start, end: r.end }, v)})
);
AsnIntervalTree {
last_values:
interval_tree.iter()
.filter(|i| { i.range.end == Asn { value: 0 } })
.map(|i| { (AsnRange { start: i.range.start,
end: i.range.end }, i.value) })
.collect(),
interval_tree: interval_tree,
}
}
}

pub type Ipv4ResourceLookup = Ipv4IntervalTree;
pub type Ipv6ResourceLookup = Ipv6IntervalTree;
pub type AsnResourceLookup = IntervalTree<Asn, u32>;
pub type AsnResourceLookup = AsnIntervalTree;

0 comments on commit 3e31d2c

Please sign in to comment.