Skip to content

Commit 1454500

Browse files
committed
fix: fixed find path and hop_index in acks
1 parent 4f56e61 commit 1454500

3 files changed

Lines changed: 78 additions & 122 deletions

File tree

src/network.rs

Lines changed: 70 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -156,10 +156,9 @@ impl Network {
156156
}
157157

158158

159-
/// BFS to find path to destination
159+
/// Finds a path from `start` to `destination` where intermediate nodes must be drones.
160160
#[must_use]
161-
pub(crate) fn find_path(&self, destination: NodeId) -> Option<Vec<NodeId>> {
162-
let start = self.nodes[0].id;
161+
pub(crate) fn find_path(&self, start: NodeId, destination: NodeId) -> Option<Vec<NodeId>> {
163162
let mut visited = HashSet::new();
164163
let mut queue = VecDeque::new();
165164
let mut parent_map = HashMap::new();
@@ -169,22 +168,30 @@ impl Network {
169168

170169
while let Some(current) = queue.pop_front() {
171170
if current == destination {
171+
// reconstruct path
172172
let mut path = vec![destination];
173-
let mut current = destination;
174-
while let Some(&parent) = parent_map.get(&current) {
173+
let mut cur = destination;
174+
while let Some(&parent) = parent_map.get(&cur) {
175175
path.push(parent);
176-
current = parent;
176+
cur = parent;
177177
}
178178
path.reverse();
179179
return Some(path);
180180
}
181181

182182
if let Some(node) = self.nodes.iter().find(|n| n.id == current) {
183183
for neighbor in node.get_adjacents() {
184-
if !visited.contains(neighbor) {
185-
visited.insert(*neighbor);
186-
parent_map.insert(neighbor, current);
187-
queue.push_back(*neighbor);
184+
if visited.contains(neighbor) {
185+
continue;
186+
}
187+
188+
if let Some(neigh_node) = self.nodes.iter().find(|n| n.id == *neighbor) {
189+
// Only allow stepping into the destination or into a drone
190+
if *neighbor == destination || neigh_node.get_node_type() == NodeType::Drone {
191+
visited.insert(*neighbor);
192+
parent_map.insert(neighbor, current);
193+
queue.push_back(*neighbor);
194+
}
188195
}
189196
}
190197
}
@@ -289,115 +296,67 @@ mod tests {
289296
}
290297

291298
#[test]
292-
/// Tests the `find_path` method
293-
fn test_find_path() {
294-
let root = Node::new(1, NodeType::Client, vec![2, 3]);
295-
let mut network = Network::new(root);
296-
297-
let node2 = Node::new(2, NodeType::Client, vec![1, 4]);
298-
let node3 = Node::new(3, NodeType::Client, vec![1]);
299-
let node4 = Node::new(4, NodeType::Client, vec![2]);
300-
301-
network.add_node(node2);
302-
network.add_node(node3);
303-
network.add_node(node4);
304-
305-
let path = network.find_path(4).unwrap();
306-
307-
assert_eq!(path, vec![1, 2, 4]);
308-
}
309-
310-
#[test]
311-
/// Tests the `find_path` method with non-existing path
312-
fn test_find_path_not_found() {
313-
let root = Node::new(1, NodeType::Client, vec![2]);
314-
let mut network = Network::new(root);
315-
316-
let node2 = Node::new(2, NodeType::Client, vec![1]);
317-
network.add_node(node2);
318-
319-
let result = network.find_path(3);
320-
321-
assert!(result.is_none());
322-
}
323-
324-
#[test]
325-
/// Tests `find_path` method in a complex network
326-
fn test_complex_network_topology() {
327-
let root = Node::new(1, NodeType::Client, vec![2, 3]);
328-
let mut network = Network::new(root);
329-
330-
network.add_node(Node::new(2, NodeType::Drone, vec![1, 4, 5]));
331-
network.add_node(Node::new(3, NodeType::Drone, vec![1, 6]));
332-
network.add_node(Node::new(4, NodeType::Drone, vec![2, 7]));
333-
network.add_node(Node::new(5, NodeType::Server, vec![2]));
334-
network.add_node(Node::new(6, NodeType::Server, vec![3]));
335-
network.add_node(Node::new(7, NodeType::Client, vec![4]));
336-
337-
let path_to_server5 = network.find_path(5);
338-
assert!(path_to_server5.is_some());
339-
let path = path_to_server5.unwrap();
340-
assert_eq!(path[0], 1);
341-
assert_eq!(path[path.len() - 1], 5);
342-
let path_to_client7 = network.find_path(7);
343-
assert!(path_to_client7.is_some());
299+
fn test_direct_client_to_server() {
300+
let nodes = vec![
301+
Node { id: 1, kind: NodeType::Client, adjacents: vec![2] },
302+
Node { id: 2, kind: NodeType::Server, adjacents: vec![1] },
303+
];
304+
305+
306+
let mut graph = Network::default();
307+
for node in nodes {
308+
graph.add_node(node);
309+
}
310+
let path = graph.find_path(1, 2);
311+
assert_eq!(path, Some(vec![1, 2]));
344312
}
345313

346314
#[test]
347-
/// Tests `find_path` method in a partitioned network
348-
fn test_network_partition_handling() {
349-
let root = Node::new(1, NodeType::Client, vec![2]);
350-
let mut network = Network::new(root);
351-
352-
network.add_node(Node::new(2, NodeType::Drone, vec![1]));
353-
network.add_node(Node::new(3, NodeType::Server, vec![4])); // Isolated
354-
network.add_node(Node::new(4, NodeType::Drone, vec![3])); // Isolated
355-
356-
let path_to_2 = network.find_path(2);
357-
assert!(path_to_2.is_some());
358-
359-
let path_to_3 = network.find_path(3);
360-
assert!(path_to_3.is_none());
315+
fn test_path_with_drone() {
316+
let nodes = vec![
317+
Node { id: 1, kind: NodeType::Client, adjacents: vec![2] },
318+
Node { id: 2, kind: NodeType::Drone, adjacents: vec![1, 3] },
319+
Node { id: 3, kind: NodeType::Server, adjacents: vec![2] },
320+
];
321+
322+
let mut graph = Network::default();
323+
for node in nodes {
324+
graph.add_node(node);
325+
} let path = graph.find_path(1, 3);
326+
assert_eq!(path, Some(vec![1, 2, 3]));
361327
}
362328

363329
#[test]
364-
/// Tests `get_servers` and `get_clients` method in a network
365-
fn test_node_type_filtering() {
366-
let root = Node::new(1, NodeType::Client, vec![]);
367-
let mut network = Network::new(root);
368-
369-
network.add_node(Node::new(2, NodeType::Server, vec![]));
370-
network.add_node(Node::new(3, NodeType::Server, vec![]));
371-
network.add_node(Node::new(4, NodeType::Client, vec![]));
372-
network.add_node(Node::new(5, NodeType::Drone, vec![]));
373-
374-
let servers = network.get_servers().unwrap();
375-
assert_eq!(servers.len(), 2);
376-
assert!(servers.contains(&2));
377-
assert!(servers.contains(&3));
378-
379-
let clients = network.get_clients().unwrap();
380-
assert_eq!(clients.len(), 2);
381-
assert!(clients.contains(&1));
382-
assert!(clients.contains(&4));
330+
fn test_disallow_non_drone_intermediate() {
331+
let nodes = vec![
332+
Node { id: 1, kind: NodeType::Client, adjacents: vec![2] },
333+
Node { id: 2, kind: NodeType::Client, adjacents: vec![1, 3] }, // not a drone
334+
Node { id: 3, kind: NodeType::Server, adjacents: vec![2] },
335+
];
336+
337+
let mut graph = Network::default();
338+
for node in nodes {
339+
graph.add_node(node);
340+
}
341+
let path = graph.find_path(1, 3);
342+
assert_eq!(path, None); // should fail because node 2 is not a drone
383343
}
384344

385345
#[test]
386-
fn test_dynamic_network_updates() {
387-
let root = Node::new(1, NodeType::Client, vec![2]);
388-
let mut network = Network::new(root);
389-
390-
network.add_node(Node::new(2, NodeType::Drone, vec![1, 3]));
391-
network.add_node(Node::new(3, NodeType::Server, vec![2]));
392-
393-
network.update_node(1, vec![4]).unwrap();
394-
network.add_node(Node::new(4, NodeType::Drone, vec![1]));
395-
396-
let path = network.find_path(3);
397-
assert!(path.is_some());
398-
399-
network.remove_node(2);
400-
let path_after_removal = network.find_path(3);
401-
assert!(path_after_removal.is_none());
346+
fn test_multiple_paths_choose_valid() {
347+
let nodes = vec![
348+
Node { id: 1, kind: NodeType::Client, adjacents: vec![2, 4] },
349+
Node { id: 2, kind: NodeType::Client, adjacents: vec![1, 3] }, // not a drone
350+
Node { id: 3, kind: NodeType::Server, adjacents: vec![2, 5] },
351+
Node { id: 4, kind: NodeType::Drone, adjacents: vec![1, 5] },
352+
Node { id: 5, kind: NodeType::Server, adjacents: vec![3, 4] },
353+
];
354+
355+
let mut graph = Network::default();
356+
for node in nodes {
357+
graph.add_node(node);
358+
}
359+
let path = graph.find_path(1, 5);
360+
assert_eq!(path, Some(vec![1, 4, 5])); // must avoid node 2 because it's not a drone
402361
}
403362
}

src/packet_processor.rs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,7 @@ pub trait Processor: Send {
2727
let idx = fragment.fragment_index;
2828
let mut shr = pkt.routing_header.clone();
2929
shr.reverse();
30-
shr.increase_hop_index();
31-
assert!(
32-
shr.hop_index == 1,
33-
"hop_index should be 1, got {}",
34-
shr.hop_index
35-
);
30+
shr.hop_index = 1;
3631
self.routing_handler().send_ack(shr, pkt.session_id, idx)?;
3732
if let Some(msg) = self.assembler().add_fragment(
3833
fragment,

src/routing_handler.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ impl RoutingHandler {
243243

244244
if !self.flood_seen.insert(flood_session) || self.neighbors.len() == 1 {
245245
// generate flood response
246-
let route = if let Some(path) = self.network_view.find_path(flood_request.initiator_id)
246+
let route = if let Some(path) = self.network_view.find_path(self.id, flood_request.initiator_id)
247247
{
248248
SourceRoutingHeader::new(path, 1)
249249
} else {
@@ -338,7 +338,7 @@ impl RoutingHandler {
338338
return Ok(SourceRoutingHeader::empty_route());
339339
}
340340

341-
if let Some(path) = self.network_view.find_path(destination) {
341+
if let Some(path) = self.network_view.find_path(self.id, destination) {
342342
return Ok(SourceRoutingHeader::new(path, 1).without_loops());
343343
}
344344
Err(NetworkError::PathNotFound(destination))
@@ -398,7 +398,7 @@ impl RoutingHandler {
398398
pub fn send_message(
399399
&mut self,
400400
message: &[u8],
401-
destination: Option<NodeId>,
401+
dest: Option<NodeId>,
402402
session_id: Option<u64>,
403403
) -> Result<(), NetworkError> {
404404
// Split into 128-byte chunks
@@ -411,7 +411,7 @@ impl RoutingHandler {
411411
self.session_counter
412412
});
413413

414-
if let Some(destination) = destination {
414+
if let Some(destination) = dest {
415415
// Try to send directly
416416
if let Ok(shr) = self.try_find_path(destination) {
417417
for (i, chunk) in chunks.enumerate() {
@@ -436,6 +436,8 @@ impl RoutingHandler {
436436
to: Some(destination),
437437
data: message.to_vec(),
438438
}))?;
439+
440+
439441

440442
return Ok(());
441443
}
@@ -639,7 +641,7 @@ mod routing_handler_tests {
639641
};
640642
let _ = handler.handle_flood_response(&flood_response);
641643

642-
let path_to_server = handler.network_view.find_path(2);
644+
let path_to_server = handler.network_view.find_path(1, 2);
643645
assert_eq!(path_to_server, Some(vec![1, 3, 4, 2]));
644646
}
645647

0 commit comments

Comments
 (0)