fix: align native daemon port hash with client on Windows (#734)

The client (connection.rs) and native daemon (native/daemon.rs) used
different get_port_for_session() implementations on Windows:

- Client:  i32, .chars(), djb2  — (hash << 5) - hash + c
- Daemon:  i64, .bytes(), Java hashCode — hash * 31 + b

For session name "default", client computes port 50838 while the
daemon binds on 51174, causing a 5-second timeout and startup failure.

Fix: align native/daemon.rs to use the identical djb2 algorithm from
connection.rs (i32, chars, djb2), so both sides agree on the port.

Unix is unaffected (uses Unix domain sockets, no port hashing).

Tests: add port hash regression tests to all three implementations
(native/daemon.rs, connection.rs, daemon.ts) to prevent future drift.

Fixes #705
This commit is contained in:
mikewong23571
2026-03-12 14:15:35 -05:00
committed by GitHub
parent 2fb2a51c82
commit d4f7fbc718
4 changed files with 55 additions and 6 deletions
+24 -1
View File
@@ -3,7 +3,7 @@ import * as os from 'os';
import * as path from 'path';
import * as net from 'net';
import { EventEmitter } from 'events';
import { getSocketDir, safeWrite } from './daemon.js';
import { getSocketDir, safeWrite, getPortForSession } from './daemon.js';
/**
* HTTP request detection pattern used in daemon.ts to prevent cross-origin attacks.
@@ -159,3 +159,26 @@ describe('safeWrite', () => {
expect(socket.listenerCount('close')).toBe(0);
});
});
describe('getPortForSession', () => {
it('returns consistent port for "default"', () => {
expect(getPortForSession('default')).toBe(50838);
});
it('returns consistent port for named sessions', () => {
expect(getPortForSession('my-session')).toBe(63105);
expect(getPortForSession('work')).toBe(51184);
});
it('returns base port for empty session', () => {
expect(getPortForSession('')).toBe(49152);
});
it('returns port within dynamic range (49152-65535)', () => {
for (const name of ['default', 'my-session', 'work', 'test', 'a']) {
const port = getPortForSession(name);
expect(port).toBeGreaterThanOrEqual(49152);
expect(port).toBeLessThanOrEqual(65535);
}
});
});
+1 -1
View File
@@ -185,7 +185,7 @@ export function getSession(): string {
* Get port number for TCP mode (Windows)
* Uses a hash of the session name to get a consistent port
*/
function getPortForSession(session: string): number {
export function getPortForSession(session: string): number {
let hash = 0;
for (let i = 0; i < session.length; i++) {
hash = (hash << 5) - hash + session.charCodeAt(i);