chat.html: drop self-echo frames at onRxFrame entry
zebrad reads @DEFAULT_MONITOR@ which mixes every PA stream on a machine, so each browser tab hears its own carrier echoed back. without a filter, every outbound message would render twice in the chat log (once as 'me' at send time, once as 'peer' on echo arrival). filter: compare frame.sid (carried in DATA + HELLO) against our own senderIdBytes(). if equal, drop frame before any UI work. loopback mode unaffected since BroadcastChannel never echoes to sender by spec. senderIdBytes returns a stable per-tab id: * passphrase mode: random 4 bytes cached for tab lifetime * pubkey mode: first 4 of SHA-256(pubkey), stable across reloads
This commit is contained in:
parent
c8a755513f
commit
dcb1c8e5a1
1 changed files with 9 additions and 0 deletions
|
|
@ -772,6 +772,15 @@ async function onRxFrame(bytes) {
|
||||||
logLine('err', `rx: malformed frame (type=${f.type}, ${f.error})`);
|
logLine('err', `rx: malformed frame (type=${f.type}, ${f.error})`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
/* same-machine PA mix echoes our own carrier back to us. drop any frame
|
||||||
|
* whose sender id matches our own so we don't double-render. loopback
|
||||||
|
* mode is unaffected because BroadcastChannel never echoes to sender. */
|
||||||
|
if (f.sid) {
|
||||||
|
const mine = await senderIdBytes();
|
||||||
|
let isSelf = true;
|
||||||
|
for (let i = 0; i < 4; i++) if (f.sid[i] !== mine[i]) { isSelf = false; break; }
|
||||||
|
if (isSelf) return;
|
||||||
|
}
|
||||||
if (f.type === T_OFFER) {
|
if (f.type === T_OFFER) {
|
||||||
logLine('sys', `rx: OFFER from peer — ${f.baud} baud`);
|
logLine('sys', `rx: OFFER from peer — ${f.baud} baud`);
|
||||||
/* respond with READY at handshake baud */
|
/* respond with READY at handshake baud */
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue