mirror of
https://github.com/threefoldtech/mycelium.git
synced 2026-10-23 06:01:16 +00:00
Make sure we have a selected route before accepting a TUN packet
Related to #614 Signed-off-by: Lee Smet <lee.smet@hotmail.com>
This commit is contained in:
3 files changed
+49
-1
No files matched your search
@@ -19,6 +19,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
for instance when using `traceroute`.
|
||||
- Check the local seqno request cache before sending a seqno request to a peer,
|
||||
to avoid spamming in certain occasions.
|
||||
- Don't accept packet for a destination if we only have fallback routes for said
|
||||
destination.
|
||||
|
||||
## [0.6.0] - 2025-04-25
|
||||
|
||||
|
||||
@@ -274,7 +274,7 @@ where
|
||||
}
|
||||
|
||||
// Get shared secret from node and dest address
|
||||
let shared_secret = match self.router.get_shared_secret_from_dest(dst_ip.into()) {
|
||||
let shared_secret = match self.router.get_shared_secret_if_selected(dst_ip.into()) {
|
||||
Some(ss) => ss,
|
||||
// If we don't have a route to the destination subnet, reply with ICMP no route to
|
||||
// host. Do this here as well to avoid encrypting the ICMP to ourselves.
|
||||
|
||||
@@ -260,6 +260,52 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
/// Get a [`SharedSecret`] for a remote, if a selected route exists to the remote.
|
||||
// TODO: Naming
|
||||
pub fn get_shared_secret_if_selected(&self, dest: IpAddr) -> Option<SharedSecret> {
|
||||
// TODO: proper fix
|
||||
match self.routing_table.best_routes(dest) {
|
||||
Routes::Exist(routes) => {
|
||||
if routes.selected().is_some() {
|
||||
Some(routes.shared_secret().clone())
|
||||
} else {
|
||||
// Optimistically try to fetch a new route for the subnet for next time.
|
||||
// TODO: this can likely be handled better, but that relies on continuously
|
||||
// quering routes in use, and handling unfeasible routes
|
||||
if let Some(route_entry) = routes.iter().next() {
|
||||
// We have a fallback route, use the source key from that to do a seqno
|
||||
// request. Since the next hop might be dead, just do a broadcast. This
|
||||
// might be blocked by the seqno request cache.
|
||||
self.send_seqno_request(route_entry.source(), None, None);
|
||||
} else {
|
||||
// We don't have any routes, so send a route request. this might fail due
|
||||
// to the source table.
|
||||
self.send_route_request(
|
||||
Subnet::new(dest, 64)
|
||||
.expect("64 is a valid subnet size for an IPv6 address; qed"),
|
||||
);
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
}
|
||||
Routes::Queried => {
|
||||
tokio::task::block_in_place(|| std::thread::sleep(QUERY_CHECK_DURATION));
|
||||
self.get_shared_secret_if_selected(dest)
|
||||
}
|
||||
Routes::NoRoute => None,
|
||||
Routes::None => {
|
||||
// NOTE: we request the full /64 subnet
|
||||
self.send_route_request(
|
||||
Subnet::new(dest, 64)
|
||||
.expect("64 is a valid subnet size for an IPv6 address; qed"),
|
||||
);
|
||||
tokio::task::block_in_place(|| std::thread::sleep(QUERY_CHECK_DURATION));
|
||||
self.get_shared_secret_if_selected(dest)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Gets the cached [`SharedSecret`] based on the associated [`PublicKey`] of the remote.
|
||||
#[inline]
|
||||
pub fn get_shared_secret_by_pubkey(&self, dest: &PublicKey) -> Option<SharedSecret> {
|
||||
|
||||
Reference in new issue
Block a user