diff --git a/mycelium/src/routing_table.rs b/mycelium/src/routing_table.rs index 3e6be84..b037a04 100644 --- a/mycelium/src/routing_table.rs +++ b/mycelium/src/routing_table.rs @@ -336,7 +336,7 @@ impl RoutingTable { } let mut write_handle = self.writer.lock().expect("Can lock writer"); - write_handle.append(RoutingTableOplogEntry::Upsert( + write_handle.append(RoutingTableOplogEntry::Queried( subnet, Arc::new(SubnetEntry::Queried { query_timeout }), )); @@ -534,6 +534,8 @@ impl Drop for WriteGuard<'_> { enum RoutingTableOplogEntry { /// Insert or Update the value for the given subnet. Upsert(Subnet, Arc), + /// Mark a subnet as queried. + Queried(Subnet, Arc), /// Delete the entry for the given subnet. Delete(Subnet), /// The route request for a subnet expired, if it is still in query state mark it as not @@ -563,6 +565,24 @@ impl left_right::Absorb for RoutingTableInner { Arc::clone(list), ); } + + RoutingTableOplogEntry::Queried(subnet, se) => { + // Mark a query only if we don't have a valid entry + let entry = self + .table + .exact_match(expect_ipv6(subnet.address()), subnet.prefix_len().into()) + .map(Arc::deref); + + // If we have no route, transition to query, if we have a route or existing query, + // do nothing + if matches!(entry, None | Some(SubnetEntry::NoRoute { .. })) { + self.table.insert( + expect_ipv6(subnet.address()), + subnet.prefix_len().into(), + Arc::clone(se), + ); + } + } RoutingTableOplogEntry::Delete(subnet) => { self.table .remove(expect_ipv6(subnet.address()), subnet.prefix_len().into()); @@ -610,6 +630,23 @@ impl left_right::Absorb for RoutingTableInner { list, ); } + RoutingTableOplogEntry::Queried(subnet, se) => { + // Mark a query only if we don't have a valid entry + let entry = self + .table + .exact_match(expect_ipv6(subnet.address()), subnet.prefix_len().into()) + .map(Arc::deref); + + // If we have no route, transition to query, if we have a route or existing query, + // do nothing + if matches!(entry, None | Some(SubnetEntry::NoRoute { .. })) { + self.table.insert( + expect_ipv6(subnet.address()), + subnet.prefix_len().into(), + se, + ); + } + } RoutingTableOplogEntry::Delete(subnet) => { self.table .remove(expect_ipv6(subnet.address()), subnet.prefix_len().into());