finally getting the ip to name relation properly

This commit is contained in:
jenz 2026-07-02 15:19:23 +01:00
parent 19d33951cc
commit 2024f4cbe0
2 changed files with 30 additions and 11 deletions

View File

@ -408,10 +408,10 @@
setStatus('Connecting...'); setStatus('Connecting...');
sigWs = new WebSocket(SIG_URL); sigWs = new WebSocket(SIG_URL);
sigWs.onopen = () => { sigWs.onopen = async () => {
setStatus('Connected — setting up stream...'); setStatus('Connected — setting up stream...');
initVisitorName(); await initVisitorName();
setupPeerConnection(); await setupPeerConnection();
}; };
sigWs.onmessage = async e => { sigWs.onmessage = async e => {

View File

@ -248,7 +248,14 @@ function stopPacat(browserSessId) {
} }
// ── WebSocket handler ───────────────────────────────────────────────────────── // ── WebSocket handler ─────────────────────────────────────────────────────────
wss.on('connection', ws => { wss.on('connection', (ws, req) => {
// Capture the real visitor IP at connection time from nginx headers.
// ws._socket.remoteAddress would be nginx's local IP for everyone.
const forwarded = req.headers['x-real-ip'] ||
req.headers['x-forwarded-for'] || '';
ws._realIp = forwarded.split(',')[0].trim() ||
req.socket.remoteAddress.replace('::ffff:', '');
let role = null; let role = null;
let agentSessionId = null; let agentSessionId = null;
let browserSessId = null; let browserSessId = null;
@ -280,7 +287,13 @@ wss.on('connection', ws => {
} }
else if (msg.type === 'request_control') { else if (msg.type === 'request_control') {
visitorName = msg.visitorName; // Use the server-assigned name only — never trust the client-supplied one.
// If get_ip hasn't been called yet, reject the request.
if (!ws._assignedName) {
console.log('[sig] request_control rejected — no server-assigned name yet');
return;
}
visitorName = ws._assignedName;
if (containerRestarting) return; if (containerRestarting) return;
@ -291,14 +304,17 @@ wss.on('connection', ws => {
if (controlQueue.find(e => e.ws === ws)) return; if (controlQueue.find(e => e.ws === ws)) return;
// Prevent someone with the same IP as the current controller from
// queuing behind themselves (duplicate tab or same-IP reconnect).
if (currentController && currentController.visitorName === visitorName) {
console.log(`[sig] ${visitorName} already controlling, ignoring duplicate request_control`);
return;
}
const entry = { ws, visitorName, browserSessId }; const entry = { ws, visitorName, browserSessId };
if (!currentController) { if (!currentController) {
applyController(entry); applyController(entry);
} else if (currentController.visitorName === visitorName) {
// Same identity already controlling (e.g. duplicate tab) — don't queue
// behind yourself.
return;
} else { } else {
controlQueue.push(entry); controlQueue.push(entry);
console.log(`[sig] ${visitorName} joined queue position ${controlQueue.length}`); console.log(`[sig] ${visitorName} joined queue position ${controlQueue.length}`);
@ -317,8 +333,11 @@ wss.on('connection', ws => {
} }
else if (msg.type === 'get_ip') { else if (msg.type === 'get_ip') {
const ip = ws._socket.remoteAddress.replace('::ffff:', ''); const name = ipToName(ws._realIp);
const name = ipToName(ip); // Store server-assigned name on the socket so request_control can use
// it exclusively — the client-supplied visitorName is never trusted.
ws._assignedName = name;
visitorName = name;
ws.send(JSON.stringify({ type: 'your_ip', ip: name })); ws.send(JSON.stringify({ type: 'your_ip', ip: name }));
} }