From 1c456702f48c12c5e6dd91d8fe0007a2644040d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?0=25=20=5B=E2=96=88=20=E2=96=88=20=E2=96=88=20=E2=96=88=20?= =?UTF-8?q?=E2=96=88=20=E2=96=88=20=E2=96=88=20=E2=96=88=20=E2=96=88=20?= =?UTF-8?q?=E2=96=88=5D=20100=25?= Date: Tue, 16 Jun 2026 19:28:44 -0500 Subject: [PATCH] Fixed NAT table exhaustion possibly? --- Peercord Source/public/version.js | 4 +- Peercord Source/src/components/ChatArea.jsx | 6 +- .../src/components/GroupCallView.jsx | 2 +- .../src/components/ProfileSettingsModal.jsx | 63 +++++++++++++++++++ Peercord Source/src/p2p/index.js | 19 ++++-- 5 files changed, 86 insertions(+), 8 deletions(-) diff --git a/Peercord Source/public/version.js b/Peercord Source/public/version.js index ef0d610..c68a2b0 100644 --- a/Peercord Source/public/version.js +++ b/Peercord Source/public/version.js @@ -1,2 +1,2 @@ -window.APP_VERSION = '1.0.5'; -window.APP_VERSION_COLOR = 'hsl(122, 80%, 60%)'; \ No newline at end of file +window.APP_VERSION = '1.0.6'; +window.APP_VERSION_COLOR = 'hsl(123, 80%, 60%)'; diff --git a/Peercord Source/src/components/ChatArea.jsx b/Peercord Source/src/components/ChatArea.jsx index 2a0ff9f..232a43f 100644 --- a/Peercord Source/src/components/ChatArea.jsx +++ b/Peercord Source/src/components/ChatArea.jsx @@ -176,6 +176,7 @@ export default function ChatArea({ activeView, activeChannel, setActiveChannel, const editTextareaRef = useRef(null); const fileInputRef = useRef(null); const lastTypingTime = useRef(0); + const lastSentReadIdRef = useRef(null); const isDMView = activeView === 'dms'; const gcObj = isDMView ? servers.find(s => s.topicHex === activeChannel && s.isGroupChat) : null; @@ -384,7 +385,10 @@ export default function ChatArea({ activeView, activeChannel, setActiveChannel, const latestMsg = currentChannelMessages[currentChannelMessages.length - 1]; const latestMsgId = latestMsg ? latestMsg.id : null; - if (latestMsgId) network.sendReadReceipt(networkChannelId, latestMsgId); + if (latestMsgId && latestMsgId !== lastSentReadIdRef.current) { + network.sendReadReceipt(networkChannelId, latestMsgId); + lastSentReadIdRef.current = latestMsgId; + } markChannelRead(networkChannelId); }; diff --git a/Peercord Source/src/components/GroupCallView.jsx b/Peercord Source/src/components/GroupCallView.jsx index 68c9604..8cdbef2 100644 --- a/Peercord Source/src/components/GroupCallView.jsx +++ b/Peercord Source/src/components/GroupCallView.jsx @@ -58,7 +58,7 @@ export default function GroupCallView({ channel, serverTopicHex, vcChannelId, my }; broadcastState(); // Initial broadcast - const interval = setInterval(broadcastState, 3000); + const interval = setInterval(broadcastState, 10000); return () => { clearInterval(interval); diff --git a/Peercord Source/src/components/ProfileSettingsModal.jsx b/Peercord Source/src/components/ProfileSettingsModal.jsx index 97da305..5879471 100644 --- a/Peercord Source/src/components/ProfileSettingsModal.jsx +++ b/Peercord Source/src/components/ProfileSettingsModal.jsx @@ -340,6 +340,12 @@ export default function ProfileSettingsModal({ profile, myKey, onClose, onSave, > Storage Management + + + + + )} + {activeTab === 'settings' && (

App Settings

diff --git a/Peercord Source/src/p2p/index.js b/Peercord Source/src/p2p/index.js index cc80cc8..d4482cf 100644 --- a/Peercord Source/src/p2p/index.js +++ b/Peercord Source/src/p2p/index.js @@ -48,6 +48,7 @@ class P2PNetwork { this.syncTimeout = null; this._msgTimeout = null; this._identityTimeout = null; + this._reconnectTimeout = null; this.transfers = {}; this.webrtcListeners = new Set(); @@ -396,10 +397,14 @@ class P2PNetwork { async reconnect() { if (!this.swarm) return; + + if (this._reconnectTimeout) return; + this._reconnectTimeout = setTimeout(() => { + this._reconnectTimeout = null; + }, 5000); + console.log("[P2P] Network online event detected. Reconnecting..."); try { - // Hyperswarm handles reconnections automatically. - // Forcing a non-blocking flush is enough to kickstart the DHT without causing a UDP flood. this.swarm.flush().catch(()=>{}); } catch (e) { console.warn("[P2P] Reconnect flush failed:", e); @@ -530,7 +535,12 @@ class P2PNetwork { await Promise.all(corePromises); // SETUP SWARM - this.swarm = new Hyperswarm({ keyPair: { publicKey, secretKey } }); + this.swarm = new Hyperswarm({ + keyPair: { publicKey, secretKey }, + ephemeral: true, // CRITICAL FIX: Prevents node from becoming a routing node and exhausting router NAT table + maxPeers: 128 + }); + this.swarm.on('connection', (conn, info) => { conn.on('error', () => {}); // Prevent ECONNRESET crashes this.store.replicate(conn); @@ -577,7 +587,7 @@ class P2PNetwork { // BACKGROUND JOINS TO PREVENT UDP FLOOD / NAT EXHAUSTION (async () => { - const pace = () => new Promise(r => setTimeout(r, 400)); // 400ms between DHT lookups + const pace = () => new Promise(r => setTimeout(r, 1000)); // 1000ms between DHT lookups if (this.username && this.username !== 'unknown') { const myTopic = b4a.alloc(32); @@ -667,6 +677,7 @@ class P2PNetwork { this.webrtcListeners.clear(); if (this._msgTimeout) clearTimeout(this._msgTimeout); if (this._identityTimeout) clearTimeout(this._identityTimeout); + if (this._reconnectTimeout) clearTimeout(this._reconnectTimeout); } async wipeAllData() {