fix(PortProxy): Improve TLS handshake buffering and enhance debug logging for SNI forwarding in PortProxy
This commit is contained in:
parent
0ea0f02428
commit
d6022c8f8a
@ -1,5 +1,13 @@
|
||||
# Changelog
|
||||
|
||||
## 2025-03-11 - 3.31.1 - fix(PortProxy)
|
||||
Improve TLS handshake buffering and enhance debug logging for SNI forwarding in PortProxy
|
||||
|
||||
- Explicitly copy the initial TLS handshake data to prevent mutation before buffering
|
||||
- Log buffered TLS handshake data with SNI information for better diagnostics
|
||||
- Add detailed error logs on TLS connection failures, including server and domain config status
|
||||
- Output additional debug messages during ClientHello forwarding to verify proper TLS handshake processing
|
||||
|
||||
## 2025-03-11 - 3.31.0 - feat(PortProxy)
|
||||
Improve TLS handshake SNI extraction and add session resumption tracking in PortProxy
|
||||
|
||||
|
@ -3,6 +3,6 @@
|
||||
*/
|
||||
export const commitinfo = {
|
||||
name: '@push.rocks/smartproxy',
|
||||
version: '3.31.0',
|
||||
version: '3.31.1',
|
||||
description: 'A powerful proxy package that effectively handles high traffic, with features such as SSL/TLS support, port proxying, WebSocket handling, and dynamic routing with authentication options.'
|
||||
}
|
||||
|
@ -804,11 +804,22 @@ export class PortProxy {
|
||||
// Add the temp handler to capture all incoming data during connection setup
|
||||
socket.on('data', tempDataHandler);
|
||||
|
||||
// Add initial chunk to pending data if present
|
||||
// Add initial chunk to pending data if present - this is critical for SNI forwarding
|
||||
if (initialChunk) {
|
||||
record.bytesReceived += initialChunk.length;
|
||||
record.pendingData.push(Buffer.from(initialChunk));
|
||||
record.pendingDataSize = initialChunk.length;
|
||||
// Make explicit copy of the buffer to ensure it doesn't get modified
|
||||
const initialDataCopy = Buffer.from(initialChunk);
|
||||
record.bytesReceived += initialDataCopy.length;
|
||||
record.pendingData.push(initialDataCopy);
|
||||
record.pendingDataSize = initialDataCopy.length;
|
||||
|
||||
// Log TLS handshake for debug purposes
|
||||
if (isTlsHandshake(initialChunk)) {
|
||||
record.isTLS = true;
|
||||
console.log(`[${connectionId}] Buffered TLS handshake data: ${initialDataCopy.length} bytes, SNI: ${serverName || 'none'}`);
|
||||
}
|
||||
} else if (record.isTLS) {
|
||||
// This shouldn't happen, but log a warning if we have a TLS connection with no initial data
|
||||
console.log(`[${connectionId}] WARNING: TLS connection without initial handshake data`);
|
||||
}
|
||||
|
||||
// Create the target socket but don't set up piping immediately
|
||||
@ -874,6 +885,11 @@ export class PortProxy {
|
||||
// Log additional diagnostics
|
||||
console.log(`[${connectionId}] Connection details - SNI: ${serverName || 'none'}, HasChunk: ${!!initialChunk}, ChunkSize: ${initialChunk ? initialChunk.length : 0}`);
|
||||
|
||||
// For TLS connections, provide even more detailed diagnostics
|
||||
if (record.isTLS) {
|
||||
console.log(`[${connectionId}] TLS connection failure details - TLS detected: ${record.isTLS}, Server: ${targetHost}:${connectionOptions.port}, Domain config: ${domainConfig ? 'Present' : 'Missing'}`);
|
||||
}
|
||||
|
||||
// For connection refusal or timeouts, try a more aggressive error response
|
||||
// This helps browsers quickly realize there's an issue rather than waiting
|
||||
if (code === 'ECONNREFUSED' || code === 'ETIMEDOUT' || code === 'EHOSTUNREACH') {
|
||||
@ -999,12 +1015,29 @@ export class PortProxy {
|
||||
// Flush all pending data to target
|
||||
if (record.pendingData.length > 0) {
|
||||
const combinedData = Buffer.concat(record.pendingData);
|
||||
|
||||
// Add critical debugging for SNI forwarding issues
|
||||
if (record.isTLS && this.settings.enableTlsDebugLogging) {
|
||||
console.log(`[${connectionId}] Forwarding TLS handshake data: ${combinedData.length} bytes, SNI: ${serverName || 'none'}`);
|
||||
|
||||
// Additional check to verify we're forwarding the ClientHello properly
|
||||
if (combinedData[0] === 22) { // TLS handshake
|
||||
console.log(`[${connectionId}] Initial data is a TLS handshake record`);
|
||||
}
|
||||
}
|
||||
|
||||
// Write the combined data to the target
|
||||
targetSocket.write(combinedData, (err) => {
|
||||
if (err) {
|
||||
console.log(`[${connectionId}] Error writing pending data to target: ${err.message}`);
|
||||
return this.initiateCleanupOnce(record, 'write_error');
|
||||
}
|
||||
|
||||
if (record.isTLS) {
|
||||
// Log successful forwarding of initial TLS data
|
||||
console.log(`[${connectionId}] Successfully forwarded initial TLS data to backend`);
|
||||
}
|
||||
|
||||
// Set up the renegotiation listener *before* piping if this is a TLS connection with SNI
|
||||
if (serverName && record.isTLS) {
|
||||
// This listener handles TLS renegotiation detection
|
||||
@ -1956,6 +1989,15 @@ export class PortProxy {
|
||||
)
|
||||
: undefined;
|
||||
|
||||
// Enhanced logging to diagnose domain config selection issues
|
||||
if (serverName && !domainConfig) {
|
||||
console.log(`[${connectionId}] WARNING: No domain config found for SNI: ${serverName}`);
|
||||
console.log(`[${connectionId}] Available domains:`,
|
||||
this.settings.domainConfigs.map(config => config.domains.join(',')).join(' | '));
|
||||
} else if (serverName && domainConfig) {
|
||||
console.log(`[${connectionId}] Found domain config for SNI: ${serverName} -> ${domainConfig.domains.join(',')}`);
|
||||
}
|
||||
|
||||
// For session resumption, ensure we use the domain config matching the resumed domain
|
||||
// The resumed domain will be in serverName if this is a session resumption
|
||||
if (serverName && connectionRecord.lockedDomain === serverName && serverName !== '') {
|
||||
|
Loading…
x
Reference in New Issue
Block a user