From e2eea7bc25f4a371f52adf583b9e28e002471fd8 Mon Sep 17 00:00:00 2001
From: Lee *!* Clagett <code@leeclagett.com>
Date: Thu, 19 Dec 2024 15:26:29 -0500
Subject: [PATCH] Fix --anonymous-inbound data leak

---
 src/p2p/net_node.inl | 25 ++++++++++++++-----------
 1 file changed, 14 insertions(+), 11 deletions(-)

diff --git a/src/p2p/net_node.inl b/src/p2p/net_node.inl
index a34cf2e9d..c990fbc6d 100644
--- a/src/p2p/net_node.inl
+++ b/src/p2p/net_node.inl
@@ -2489,6 +2489,20 @@ namespace nodetool
     std::vector<peerlist_entry> local_peerlist_new;
     zone.m_peerlist.get_peerlist_head(local_peerlist_new, true, max_peerlist_size);
 
+    /* Tor/I2P nodes receiving connections via forwarding (from tor/i2p daemon)
+    do not know the address of the connecting peer. This is relayed to them,
+    iff the node has setup an inbound hidden service.
+
+    \note Insert into `local_peerlist_new` so that it is only sent once like
+      the other peers. */
+    if(outgoing_to_same_zone)
+    {
+      local_peerlist_new.insert(
+        local_peerlist_new.begin() + crypto::rand_range(std::size_t(0), local_peerlist_new.size()),
+        peerlist_entry{zone.m_our_address, zone.m_config.m_peer_id, 0}
+      );
+    }
+
     //only include out peers we did not already send
     rsp.local_peerlist_new.reserve(local_peerlist_new.size());
     for (auto &pe: local_peerlist_new)
@@ -2499,17 +2513,6 @@ namespace nodetool
     }
     m_payload_handler.get_payload_sync_data(rsp.payload_data);
 
-    /* Tor/I2P nodes receiving connections via forwarding (from tor/i2p daemon)
-    do not know the address of the connecting peer. This is relayed to them,
-    iff the node has setup an inbound hidden service. The other peer will have
-    to use the random peer_id value to link the two. My initial thought is that
-    the inbound peer should leave the other side marked as `<unknown tor host>`,
-    etc., because someone could give faulty addresses over Tor/I2P to get the
-    real peer with that identity banned/blacklisted. */
-
-    if(outgoing_to_same_zone)
-      rsp.local_peerlist_new.push_back(peerlist_entry{zone.m_our_address, zone.m_config.m_peer_id, std::time(nullptr)});
-
     LOG_DEBUG_CC(context, "COMMAND_TIMED_SYNC");
     return 1;
   }