Compare commits
4 Commits
Author | SHA1 | Date | |
---|---|---|---|
985031e9ac | |||
4c0105ad09 | |||
06896b3102 | |||
7fe455b4df |
16
changelog.md
16
changelog.md
@ -1,5 +1,21 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## 2025-03-12 - 3.41.8 - fix(portproxy)
|
||||||
|
Improve TLS handshake timeout handling and connection piping in PortProxy
|
||||||
|
|
||||||
|
- Increase the default initial handshake timeout from 60 seconds to 120 seconds
|
||||||
|
- Add a 30-second grace period before terminating connections waiting for initial TLS data
|
||||||
|
- Refactor piping logic by removing redundant callback and establishing piping immediately after flushing buffered data
|
||||||
|
- Enhance debug logging during TLS ClientHello processing for improved SNI extraction insights
|
||||||
|
|
||||||
|
## 2025-03-12 - 3.41.7 - fix(core)
|
||||||
|
Refactor PortProxy and SniHandler: improve configuration handling, logging, and whitespace consistency
|
||||||
|
|
||||||
|
- Standardized indentation and spacing for configuration properties in PortProxy settings (e.g. ACME options, keepAliveProbes, allowSessionTicket)
|
||||||
|
- Simplified conditional formatting and improved inline comments in PortProxy
|
||||||
|
- Enhanced logging messages in SniHandler for TLS handshake and session resumption detection
|
||||||
|
- Improved debugging output (e.g. hexdump of initial TLS packet) and consistency of multi-line expressions
|
||||||
|
|
||||||
## 2025-03-12 - 3.41.6 - fix(SniHandler)
|
## 2025-03-12 - 3.41.6 - fix(SniHandler)
|
||||||
Refactor SniHandler: update whitespace, comment formatting, and consistent type definitions
|
Refactor SniHandler: update whitespace, comment formatting, and consistent type definitions
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@push.rocks/smartproxy",
|
"name": "@push.rocks/smartproxy",
|
||||||
"version": "3.41.6",
|
"version": "3.41.8",
|
||||||
"private": false,
|
"private": false,
|
||||||
"description": "A powerful proxy package that effectively handles high traffic, with features such as SSL/TLS support, port proxying, WebSocket handling, dynamic routing with authentication options, and automatic ACME certificate management.",
|
"description": "A powerful proxy package that effectively handles high traffic, with features such as SSL/TLS support, port proxying, WebSocket handling, dynamic routing with authentication options, and automatic ACME certificate management.",
|
||||||
"main": "dist_ts/index.js",
|
"main": "dist_ts/index.js",
|
||||||
|
@ -3,6 +3,6 @@
|
|||||||
*/
|
*/
|
||||||
export const commitinfo = {
|
export const commitinfo = {
|
||||||
name: '@push.rocks/smartproxy',
|
name: '@push.rocks/smartproxy',
|
||||||
version: '3.41.6',
|
version: '3.41.8',
|
||||||
description: 'A powerful proxy package that effectively handles high traffic, with features such as SSL/TLS support, port proxying, WebSocket handling, dynamic routing with authentication options, and automatic ACME certificate management.'
|
description: 'A powerful proxy package that effectively handles high traffic, with features such as SSL/TLS support, port proxying, WebSocket handling, dynamic routing with authentication options, and automatic ACME certificate management.'
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1321,6 +1321,7 @@ export class SniHandler {
|
|||||||
* @param cachedSni - Optional cached SNI from previous connections (for racing detection)
|
* @param cachedSni - Optional cached SNI from previous connections (for racing detection)
|
||||||
* @returns The extracted server name or undefined if not found or more data needed
|
* @returns The extracted server name or undefined if not found or more data needed
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public static processTlsPacket(
|
public static processTlsPacket(
|
||||||
buffer: Buffer,
|
buffer: Buffer,
|
||||||
connectionInfo: {
|
connectionInfo: {
|
||||||
@ -1373,6 +1374,74 @@ export class SniHandler {
|
|||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Enhanced session resumption detection
|
||||||
|
if (this.isClientHello(buffer)) {
|
||||||
|
const resumptionInfo = this.hasSessionResumption(buffer, enableLogging);
|
||||||
|
|
||||||
|
if (resumptionInfo.isResumption) {
|
||||||
|
log(`Session resumption detected in TLS packet`);
|
||||||
|
|
||||||
|
// Always try standard SNI extraction first
|
||||||
|
const standardSni = this.extractSNI(buffer, enableLogging);
|
||||||
|
if (standardSni) {
|
||||||
|
log(`Found standard SNI in session resumption: ${standardSni}`);
|
||||||
|
|
||||||
|
// Cache this SNI
|
||||||
|
this.cacheSession(connectionInfo.sourceIp, standardSni);
|
||||||
|
return standardSni;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enhanced session resumption SNI extraction
|
||||||
|
// Try extracting from PSK identity
|
||||||
|
const pskSni = this.extractSNIFromPSKExtension(buffer, enableLogging);
|
||||||
|
if (pskSni) {
|
||||||
|
log(`Extracted SNI from PSK extension: ${pskSni}`);
|
||||||
|
this.cacheSession(connectionInfo.sourceIp, pskSni);
|
||||||
|
return pskSni;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Additional check for SNI in session tickets
|
||||||
|
if (enableLogging) {
|
||||||
|
log(`Checking for session ticket information to extract server name...`);
|
||||||
|
// Log more details for debugging
|
||||||
|
try {
|
||||||
|
// Look at the raw buffer for patterns
|
||||||
|
log(`Buffer hexdump (first 100 bytes): ${buffer.slice(0, 100).toString('hex')}`);
|
||||||
|
|
||||||
|
// Try to find hostname-like patterns in the buffer
|
||||||
|
const bufferStr = buffer.toString('utf8', 0, buffer.length);
|
||||||
|
const hostnamePattern =
|
||||||
|
/([a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?/gi;
|
||||||
|
const hostMatches = bufferStr.match(hostnamePattern);
|
||||||
|
|
||||||
|
if (hostMatches && hostMatches.length > 0) {
|
||||||
|
log(`Possible hostnames found in buffer: ${hostMatches.join(', ')}`);
|
||||||
|
|
||||||
|
// Check if any match looks like a valid domain
|
||||||
|
for (const match of hostMatches) {
|
||||||
|
if (match.includes('.') && match.length > 3) {
|
||||||
|
log(`Potential SNI found in session data: ${match}`);
|
||||||
|
// Don't automatically use this - just log for debugging
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
log(`Error scanning for patterns: ${e}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we still don't have SNI, check for cached sessions
|
||||||
|
const cachedSni = this.getCachedSession(connectionInfo.sourceIp);
|
||||||
|
if (cachedSni) {
|
||||||
|
log(`Using cached SNI for session resumption: ${cachedSni}`);
|
||||||
|
return cachedSni;
|
||||||
|
}
|
||||||
|
|
||||||
|
log(`Session resumption without extractable SNI`);
|
||||||
|
// If allowSessionTicket=false, should be rejected by caller
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// For handshake messages, try the full extraction process
|
// For handshake messages, try the full extraction process
|
||||||
const sni = this.extractSNIWithResumptionSupport(buffer, connectionInfo, enableLogging);
|
const sni = this.extractSNIWithResumptionSupport(buffer, connectionInfo, enableLogging);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user