From 224c9f65e1d417a3d828e4b63a33ce7e531580bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Chatlamet?= Date: Fri, 19 Jun 2026 06:05:22 +0000 Subject: [PATCH 1/2] fix(proxy): join spawned tasks before cleanup to prevent orphaning When run_external_acceptor exits (stream end or cancellation), defer!(nftables_clean()) used to fire immediately, removing nftables rules before the spawned DNS handler and local acceptor tasks could observe cancellation. Now we cancel and join both spawned tasks before returning, so nftables rules stay in place until all handlers stop. --- src/proxy.rs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/proxy.rs b/src/proxy.rs index 9a4950c..8fb21c9 100644 --- a/src/proxy.rs +++ b/src/proxy.rs @@ -101,7 +101,7 @@ impl Handle { defer!(nftables_clean()); // DNS handler - tokio::spawn({ + let dns_handle = tokio::spawn({ let cancel = cancel.clone(); let proxy = self.clone(); async move { @@ -110,7 +110,7 @@ impl Handle { }); // Local acceptor - tokio::spawn({ + let local_handle = tokio::spawn({ let cancel = cancel.clone(); let proxy = self.clone(); async move { @@ -119,7 +119,12 @@ impl Handle { }); // External acceptor for incoming mTLS from remote peers - self.run_external_acceptor(ext_sock, cancel).await; + self.run_external_acceptor(ext_sock, cancel.clone()).await; + + // Cancel spawned tasks and join them before returning, so that + // nftables_clean() only fires after all handlers have stopped. + cancel.cancel(); + let _ = tokio::join!(dns_handle, local_handle); Ok(()) } From 472e0f66a8c57182a2dc8d746fbd74bb68ba5823 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Chatlamet?= Date: Tue, 23 Jun 2026 07:27:49 +0000 Subject: [PATCH 2/2] rework: revert unrelated file renames, keep proxy task orphaning fix Reverted all source and interface doc renames back to modular structure (src/*/mod.rs, context/interfaces/src/*/mod.md). Restored .claude/CLAUDE.md. The proxy fix in src/proxy/mod.rs is preserved: clones CancellationToken before moving into run_external_acceptor, stores JoinHandles for spawned DNS and local acceptor tasks, and calls cancel.cancel() + tokio::join! before returning to ensure nftables_clean() only fires after handlers stop. --- .claude/CLAUDE.md | 2 +- context/interfaces/src/{dsl.md => dsl/mod.md} | 2 +- context/interfaces/src/{endor.md => endor/mod.md} | 2 +- context/interfaces/src/{gossip.md => gossip/mod.md} | 2 +- context/interfaces/src/modules/{adhoc.md => adhoc/mod.md} | 2 +- context/interfaces/src/{modules.md => modules/mod.md} | 2 +- context/interfaces/src/{proxy.md => proxy/mod.md} | 2 +- context/interfaces/src/{revocation.md => revocation/mod.md} | 2 +- context/interfaces/src/{state.md => state/mod.md} | 2 +- src/{dsl.rs => dsl/mod.rs} | 0 src/{endor.rs => endor/mod.rs} | 0 src/{gossip.rs => gossip/mod.rs} | 0 src/modules/{adhoc.rs => adhoc/mod.rs} | 0 src/{modules.rs => modules/mod.rs} | 0 src/{proxy.rs => proxy/mod.rs} | 0 src/{revocation.rs => revocation/mod.rs} | 0 src/{state.rs => state/mod.rs} | 0 src/{trust_engine_bench.rs => trust_engine_bench/mod.rs} | 0 18 files changed, 9 insertions(+), 9 deletions(-) rename context/interfaces/src/{dsl.md => dsl/mod.md} (98%) rename context/interfaces/src/{endor.md => endor/mod.md} (87%) rename context/interfaces/src/{gossip.md => gossip/mod.md} (98%) rename context/interfaces/src/modules/{adhoc.md => adhoc/mod.md} (98%) rename context/interfaces/src/{modules.md => modules/mod.md} (82%) rename context/interfaces/src/{proxy.md => proxy/mod.md} (96%) rename context/interfaces/src/{revocation.md => revocation/mod.md} (97%) rename context/interfaces/src/{state.md => state/mod.md} (99%) rename src/{dsl.rs => dsl/mod.rs} (100%) rename src/{endor.rs => endor/mod.rs} (100%) rename src/{gossip.rs => gossip/mod.rs} (100%) rename src/modules/{adhoc.rs => adhoc/mod.rs} (100%) rename src/{modules.rs => modules/mod.rs} (100%) rename src/{proxy.rs => proxy/mod.rs} (100%) rename src/{revocation.rs => revocation/mod.rs} (100%) rename src/{state.rs => state/mod.rs} (100%) rename src/{trust_engine_bench.rs => trust_engine_bench/mod.rs} (100%) diff --git a/.claude/CLAUDE.md b/.claude/CLAUDE.md index 8e62792..e660239 100644 --- a/.claude/CLAUDE.md +++ b/.claude/CLAUDE.md @@ -10,7 +10,7 @@ federated control between mesh participants. `context/interfaces/` contains one interface contract per Rust source file. Map source paths mechanically: `src/foo.rs` -> `context/interfaces/src/foo.md`, and -`src/foo/bar.rs` -> `context/interfaces/src/foo/bar.md`. +`src/foo/mod.rs` -> `context/interfaces/src/foo/mod.md`. - Read only the per-module interface docs relevant to the task. - Update the relevant `context/interfaces/**/*.md` file when public API, diff --git a/context/interfaces/src/dsl.md b/context/interfaces/src/dsl/mod.md similarity index 98% rename from context/interfaces/src/dsl.md rename to context/interfaces/src/dsl/mod.md index 5611d88..6ef2c09 100644 --- a/context/interfaces/src/dsl.md +++ b/context/interfaces/src/dsl/mod.md @@ -1,4 +1,4 @@ -# `src/dsl.rs` +# `src/dsl/mod.rs` ## Responsible for diff --git a/context/interfaces/src/endor.md b/context/interfaces/src/endor/mod.md similarity index 87% rename from context/interfaces/src/endor.md rename to context/interfaces/src/endor/mod.md index c9d6065..d87dbf3 100644 --- a/context/interfaces/src/endor.md +++ b/context/interfaces/src/endor/mod.md @@ -1,4 +1,4 @@ -# `src/endor.rs` +# `src/endor/mod.rs` ## Responsible for diff --git a/context/interfaces/src/gossip.md b/context/interfaces/src/gossip/mod.md similarity index 98% rename from context/interfaces/src/gossip.md rename to context/interfaces/src/gossip/mod.md index c1b2a98..5ae3d10 100644 --- a/context/interfaces/src/gossip.md +++ b/context/interfaces/src/gossip/mod.md @@ -1,4 +1,4 @@ -# `src/gossip.rs` +# `src/gossip/mod.rs` ## Responsible for diff --git a/context/interfaces/src/modules/adhoc.md b/context/interfaces/src/modules/adhoc/mod.md similarity index 98% rename from context/interfaces/src/modules/adhoc.md rename to context/interfaces/src/modules/adhoc/mod.md index 719fd61..652d0df 100644 --- a/context/interfaces/src/modules/adhoc.md +++ b/context/interfaces/src/modules/adhoc/mod.md @@ -1,4 +1,4 @@ -# `src/modules/adhoc.rs` +# `src/modules/adhoc/mod.rs` ## Responsible for diff --git a/context/interfaces/src/modules.md b/context/interfaces/src/modules/mod.md similarity index 82% rename from context/interfaces/src/modules.md rename to context/interfaces/src/modules/mod.md index e1dd219..418c28f 100644 --- a/context/interfaces/src/modules.md +++ b/context/interfaces/src/modules/mod.md @@ -1,4 +1,4 @@ -# `src/modules.rs` +# `src/modules/mod.rs` ## Responsible for diff --git a/context/interfaces/src/proxy.md b/context/interfaces/src/proxy/mod.md similarity index 96% rename from context/interfaces/src/proxy.md rename to context/interfaces/src/proxy/mod.md index bfc9815..2958fcd 100644 --- a/context/interfaces/src/proxy.md +++ b/context/interfaces/src/proxy/mod.md @@ -1,4 +1,4 @@ -# `src/proxy.rs` +# `src/proxy/mod.rs` ## Responsible for diff --git a/context/interfaces/src/revocation.md b/context/interfaces/src/revocation/mod.md similarity index 97% rename from context/interfaces/src/revocation.md rename to context/interfaces/src/revocation/mod.md index 6eab6a0..6c33b40 100644 --- a/context/interfaces/src/revocation.md +++ b/context/interfaces/src/revocation/mod.md @@ -1,4 +1,4 @@ -# `src/revocation.rs` +# `src/revocation/mod.rs` ## Responsible for diff --git a/context/interfaces/src/state.md b/context/interfaces/src/state/mod.md similarity index 99% rename from context/interfaces/src/state.md rename to context/interfaces/src/state/mod.md index 28311e0..048554c 100644 --- a/context/interfaces/src/state.md +++ b/context/interfaces/src/state/mod.md @@ -1,4 +1,4 @@ -# `src/state.rs` +# `src/state/mod.rs` ## Responsible for diff --git a/src/dsl.rs b/src/dsl/mod.rs similarity index 100% rename from src/dsl.rs rename to src/dsl/mod.rs diff --git a/src/endor.rs b/src/endor/mod.rs similarity index 100% rename from src/endor.rs rename to src/endor/mod.rs diff --git a/src/gossip.rs b/src/gossip/mod.rs similarity index 100% rename from src/gossip.rs rename to src/gossip/mod.rs diff --git a/src/modules/adhoc.rs b/src/modules/adhoc/mod.rs similarity index 100% rename from src/modules/adhoc.rs rename to src/modules/adhoc/mod.rs diff --git a/src/modules.rs b/src/modules/mod.rs similarity index 100% rename from src/modules.rs rename to src/modules/mod.rs diff --git a/src/proxy.rs b/src/proxy/mod.rs similarity index 100% rename from src/proxy.rs rename to src/proxy/mod.rs diff --git a/src/revocation.rs b/src/revocation/mod.rs similarity index 100% rename from src/revocation.rs rename to src/revocation/mod.rs diff --git a/src/state.rs b/src/state/mod.rs similarity index 100% rename from src/state.rs rename to src/state/mod.rs diff --git a/src/trust_engine_bench.rs b/src/trust_engine_bench/mod.rs similarity index 100% rename from src/trust_engine_bench.rs rename to src/trust_engine_bench/mod.rs