fix(rdp): send client capability instructions before CONNECT handshake
ROOT CAUSE: guacd showed "User resolution is 0x0 at 0 DPI" and immediately killed every RDP connection. The Guacamole protocol requires five client capability instructions (size, audio, video, image, timezone) BETWEEN receiving 'args' and sending 'connect'. Our handshake skipped all five and jumped straight to CONNECT. guacd never received the display dimensions, defaulted to 0x0, and terminated the connection. Now sends the complete handshake: select → (receive args) → size → audio → video → image → timezone → connect Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
34bea52e0b
commit
1bf225ae27
@ -64,11 +64,31 @@ export class GuacamoleService {
|
|||||||
}
|
}
|
||||||
this.logger.log(`guacd expects ${argNames.length} args: ${argNames.join(', ')}`);
|
this.logger.log(`guacd expects ${argNames.length} args: ${argNames.join(', ')}`);
|
||||||
|
|
||||||
// Phase 2: CONNECT — send values in the exact order guacd expects
|
// Phase 2: Client capability instructions — MUST be sent before CONNECT.
|
||||||
|
// The Guacamole protocol requires: size, audio, video, image, timezone
|
||||||
|
// between receiving 'args' and sending 'connect'. Without these, guacd
|
||||||
|
// sees 0x0 resolution and immediately kills the connection.
|
||||||
|
const width = String(params.width);
|
||||||
|
const height = String(params.height);
|
||||||
|
const dpi = String(params.dpi || 96);
|
||||||
|
socket.write(this.encode('size', width, height, dpi));
|
||||||
|
socket.write(this.encode('audio'));
|
||||||
|
socket.write(this.encode('video'));
|
||||||
|
socket.write(this.encode('image', 'image/png', 'image/jpeg', 'image/webp'));
|
||||||
|
|
||||||
|
let tz: string;
|
||||||
|
try {
|
||||||
|
tz = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
||||||
|
} catch {
|
||||||
|
tz = 'UTC';
|
||||||
|
}
|
||||||
|
socket.write(this.encode('timezone', tz));
|
||||||
|
|
||||||
|
// Phase 3: CONNECT — send values in the exact order guacd expects
|
||||||
const connectInstruction = this.buildConnectInstruction(params, argNames);
|
const connectInstruction = this.buildConnectInstruction(params, argNames);
|
||||||
this.logger.log(
|
this.logger.log(
|
||||||
`Sending CONNECT: host=${params.hostname}:${params.port} user=${params.username} domain=${params.domain || '(none)'} ` +
|
`Sending CONNECT: host=${params.hostname}:${params.port} user=${params.username} domain=${params.domain || '(none)'} ` +
|
||||||
`security=${params.security || 'any'} size=${params.width}x${params.height} ignoreCert=${params.ignoreCert !== false}`,
|
`security=${params.security || 'any'} size=${width}x${height}@${dpi}dpi ignoreCert=${params.ignoreCert !== false}`,
|
||||||
);
|
);
|
||||||
socket.write(connectInstruction);
|
socket.write(connectInstruction);
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user