@push.rocks/smartproxy 3.37.3 → 3.38.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,17 +1,24 @@
1
1
  import { Buffer } from 'buffer';
2
2
  /**
3
3
  * SNI (Server Name Indication) handler for TLS connections.
4
- * Provides robust extraction of SNI values from TLS ClientHello messages.
4
+ * Provides robust extraction of SNI values from TLS ClientHello messages
5
+ * with support for fragmented packets, TLS 1.3 resumption, and Chrome-specific
6
+ * connection behaviors.
5
7
  */
6
8
  export class SniHandler {
7
9
  // TLS record types and constants
8
10
  static { this.TLS_HANDSHAKE_RECORD_TYPE = 22; }
11
+ static { this.TLS_APPLICATION_DATA_TYPE = 23; } // TLS Application Data record type
9
12
  static { this.TLS_CLIENT_HELLO_HANDSHAKE_TYPE = 1; }
10
13
  static { this.TLS_SNI_EXTENSION_TYPE = 0x0000; }
11
14
  static { this.TLS_SESSION_TICKET_EXTENSION_TYPE = 0x0023; }
12
15
  static { this.TLS_SNI_HOST_NAME_TYPE = 0; }
13
16
  static { this.TLS_PSK_EXTENSION_TYPE = 0x0029; } // Pre-Shared Key extension type for TLS 1.3
14
17
  static { this.TLS_PSK_KE_MODES_EXTENSION_TYPE = 0x002D; } // PSK Key Exchange Modes
18
+ static { this.TLS_EARLY_DATA_EXTENSION_TYPE = 0x002A; } // Early Data (0-RTT) extension
19
+ // Buffer for handling fragmented ClientHello messages
20
+ static { this.fragmentedBuffers = new Map(); }
21
+ static { this.fragmentTimeout = 1000; } // ms to wait for fragments before cleanup
15
22
  /**
16
23
  * Checks if a buffer contains a TLS handshake message (record type 22)
17
24
  * @param buffer - The buffer to check
@@ -20,6 +27,91 @@ export class SniHandler {
20
27
  static isTlsHandshake(buffer) {
21
28
  return buffer.length > 0 && buffer[0] === this.TLS_HANDSHAKE_RECORD_TYPE;
22
29
  }
30
+ /**
31
+ * Checks if a buffer contains TLS application data (record type 23)
32
+ * @param buffer - The buffer to check
33
+ * @returns true if the buffer starts with a TLS application data record type
34
+ */
35
+ static isTlsApplicationData(buffer) {
36
+ return buffer.length > 0 && buffer[0] === this.TLS_APPLICATION_DATA_TYPE;
37
+ }
38
+ /**
39
+ * Creates a connection ID based on source/destination information
40
+ * Used to track fragmented ClientHello messages across multiple packets
41
+ *
42
+ * @param connectionInfo - Object containing connection identifiers (IP/port)
43
+ * @returns A string ID for the connection
44
+ */
45
+ static createConnectionId(connectionInfo) {
46
+ const { sourceIp, sourcePort, destIp, destPort } = connectionInfo;
47
+ return `${sourceIp}:${sourcePort}-${destIp}:${destPort}`;
48
+ }
49
+ /**
50
+ * Handles potential fragmented ClientHello messages by buffering and reassembling
51
+ * TLS record fragments that might span multiple TCP packets.
52
+ *
53
+ * @param buffer - The current buffer fragment
54
+ * @param connectionId - Unique identifier for the connection
55
+ * @param enableLogging - Whether to enable logging
56
+ * @returns A complete buffer if reassembly is successful, or undefined if more fragments are needed
57
+ */
58
+ static handleFragmentedClientHello(buffer, connectionId, enableLogging = false) {
59
+ const log = (message) => {
60
+ if (enableLogging) {
61
+ console.log(`[SNI Fragment] ${message}`);
62
+ }
63
+ };
64
+ // Check if we've seen this connection before
65
+ if (!this.fragmentedBuffers.has(connectionId)) {
66
+ // New connection, start with this buffer
67
+ this.fragmentedBuffers.set(connectionId, buffer);
68
+ // Set timeout to clean up if we don't get a complete ClientHello
69
+ setTimeout(() => {
70
+ if (this.fragmentedBuffers.has(connectionId)) {
71
+ this.fragmentedBuffers.delete(connectionId);
72
+ log(`Connection ${connectionId} timed out waiting for complete ClientHello`);
73
+ }
74
+ }, this.fragmentTimeout);
75
+ // Evaluate if this buffer already contains a complete ClientHello
76
+ try {
77
+ if (buffer.length >= 5) {
78
+ const recordLength = (buffer[3] << 8) + buffer[4];
79
+ if (buffer.length >= recordLength + 5) {
80
+ log(`Initial buffer contains complete ClientHello, length: ${buffer.length}`);
81
+ return buffer;
82
+ }
83
+ }
84
+ }
85
+ catch (e) {
86
+ log(`Error checking initial buffer completeness: ${e}`);
87
+ }
88
+ log(`Started buffering connection ${connectionId}, initial size: ${buffer.length}`);
89
+ return undefined; // Need more fragments
90
+ }
91
+ else {
92
+ // Existing connection, append this buffer
93
+ const existingBuffer = this.fragmentedBuffers.get(connectionId);
94
+ const newBuffer = Buffer.concat([existingBuffer, buffer]);
95
+ this.fragmentedBuffers.set(connectionId, newBuffer);
96
+ log(`Appended to buffer for ${connectionId}, new size: ${newBuffer.length}`);
97
+ // Check if we now have a complete ClientHello
98
+ try {
99
+ if (newBuffer.length >= 5) {
100
+ const recordLength = (newBuffer[3] << 8) + newBuffer[4];
101
+ if (newBuffer.length >= recordLength + 5) {
102
+ log(`Assembled complete ClientHello, length: ${newBuffer.length}`);
103
+ // Complete message received, remove from tracking
104
+ this.fragmentedBuffers.delete(connectionId);
105
+ return newBuffer;
106
+ }
107
+ }
108
+ }
109
+ catch (e) {
110
+ log(`Error checking reassembled buffer completeness: ${e}`);
111
+ }
112
+ return undefined; // Still need more fragments
113
+ }
114
+ }
23
115
  /**
24
116
  * Checks if a buffer contains a TLS ClientHello message
25
117
  * @param buffer - The buffer to check
@@ -395,6 +487,78 @@ export class SniHandler {
395
487
  return undefined;
396
488
  }
397
489
  }
490
+ /**
491
+ * Checks if the buffer contains TLS 1.3 early data (0-RTT)
492
+ * @param buffer - The buffer to check
493
+ * @param enableLogging - Whether to enable logging
494
+ * @returns true if early data is detected
495
+ */
496
+ static hasEarlyData(buffer, enableLogging = false) {
497
+ const log = (message) => {
498
+ if (enableLogging) {
499
+ console.log(`[Early Data] ${message}`);
500
+ }
501
+ };
502
+ try {
503
+ // Check if this is a valid ClientHello first
504
+ if (!this.isClientHello(buffer)) {
505
+ return false;
506
+ }
507
+ // Find the extensions section
508
+ let pos = 5; // Start after record header
509
+ // Skip handshake type (1 byte)
510
+ pos += 1;
511
+ // Skip handshake length (3 bytes)
512
+ pos += 3;
513
+ // Skip client version (2 bytes)
514
+ pos += 2;
515
+ // Skip client random (32 bytes)
516
+ pos += 32;
517
+ // Skip session ID
518
+ if (pos + 1 > buffer.length)
519
+ return false;
520
+ const sessionIdLength = buffer[pos];
521
+ pos += 1 + sessionIdLength;
522
+ // Skip cipher suites
523
+ if (pos + 2 > buffer.length)
524
+ return false;
525
+ const cipherSuitesLength = (buffer[pos] << 8) + buffer[pos + 1];
526
+ pos += 2 + cipherSuitesLength;
527
+ // Skip compression methods
528
+ if (pos + 1 > buffer.length)
529
+ return false;
530
+ const compressionMethodsLength = buffer[pos];
531
+ pos += 1 + compressionMethodsLength;
532
+ // Check if we have extensions
533
+ if (pos + 2 > buffer.length)
534
+ return false;
535
+ // Get extensions length
536
+ const extensionsLength = (buffer[pos] << 8) + buffer[pos + 1];
537
+ pos += 2;
538
+ // Extensions end position
539
+ const extensionsEnd = pos + extensionsLength;
540
+ if (extensionsEnd > buffer.length)
541
+ return false;
542
+ // Look for early data extension
543
+ while (pos + 4 <= extensionsEnd) {
544
+ const extensionType = (buffer[pos] << 8) + buffer[pos + 1];
545
+ pos += 2;
546
+ const extensionLength = (buffer[pos] << 8) + buffer[pos + 1];
547
+ pos += 2;
548
+ if (extensionType === this.TLS_EARLY_DATA_EXTENSION_TYPE) {
549
+ log('Early Data (0-RTT) extension detected');
550
+ return true;
551
+ }
552
+ // Skip to next extension
553
+ pos += extensionLength;
554
+ }
555
+ return false;
556
+ }
557
+ catch (error) {
558
+ log(`Error checking for early data: ${error}`);
559
+ return false;
560
+ }
561
+ }
398
562
  /**
399
563
  * Attempts to extract SNI from an initial ClientHello packet and handles
400
564
  * session resumption edge cases more robustly than the standard extraction.
@@ -403,40 +567,120 @@ export class SniHandler {
403
567
  * 1. Standard SNI extraction
404
568
  * 2. TLS 1.3 PSK-based resumption (Chrome, Firefox, etc.)
405
569
  * 3. Session ticket-based resumption
570
+ * 4. Fragmented ClientHello messages
571
+ * 5. TLS 1.3 Early Data (0-RTT)
572
+ * 6. Chrome's connection racing behaviors
406
573
  *
407
574
  * @param buffer - The buffer containing the TLS ClientHello message
575
+ * @param connectionInfo - Optional connection information for fragment handling
408
576
  * @param enableLogging - Whether to enable detailed debug logging
409
577
  * @returns The extracted server name or undefined if not found
410
578
  */
411
- static extractSNIWithResumptionSupport(buffer, enableLogging = false) {
412
- // First try the standard SNI extraction
413
- const standardSni = this.extractSNI(buffer, enableLogging);
414
- if (standardSni) {
579
+ static extractSNIWithResumptionSupport(buffer, connectionInfo, enableLogging = false) {
580
+ const log = (message) => {
415
581
  if (enableLogging) {
416
- console.log(`[SNI Extraction] Found standard SNI: ${standardSni}`);
582
+ console.log(`[SNI Extraction] ${message}`);
583
+ }
584
+ };
585
+ // Check if we need to handle fragmented packets
586
+ let processBuffer = buffer;
587
+ if (connectionInfo) {
588
+ const connectionId = this.createConnectionId(connectionInfo);
589
+ const reassembledBuffer = this.handleFragmentedClientHello(buffer, connectionId, enableLogging);
590
+ if (!reassembledBuffer) {
591
+ log(`Waiting for more fragments on connection ${connectionId}`);
592
+ return undefined; // Need more fragments to complete ClientHello
417
593
  }
594
+ processBuffer = reassembledBuffer;
595
+ log(`Using reassembled buffer of length ${processBuffer.length}`);
596
+ }
597
+ // First try the standard SNI extraction
598
+ const standardSni = this.extractSNI(processBuffer, enableLogging);
599
+ if (standardSni) {
600
+ log(`Found standard SNI: ${standardSni}`);
418
601
  return standardSni;
419
602
  }
603
+ // Check for TLS 1.3 early data (0-RTT)
604
+ const hasEarly = this.hasEarlyData(processBuffer, enableLogging);
605
+ if (hasEarly) {
606
+ log('TLS 1.3 Early Data detected, using special handling');
607
+ // In 0-RTT, Chrome often relies on server remembering the SNI from previous sessions
608
+ // We could implement session tracking here if necessary
609
+ }
420
610
  // If standard extraction failed and we have a valid ClientHello,
421
611
  // this might be a session resumption with non-standard format
422
- if (this.isClientHello(buffer)) {
423
- if (enableLogging) {
424
- console.log('[SNI Extraction] Detected ClientHello without standard SNI, possible session resumption');
425
- }
612
+ if (this.isClientHello(processBuffer)) {
613
+ log('Detected ClientHello without standard SNI, possible session resumption');
426
614
  // Try to extract from PSK extension (TLS 1.3 resumption)
427
- const pskSni = this.extractSNIFromPSKExtension(buffer, enableLogging);
615
+ const pskSni = this.extractSNIFromPSKExtension(processBuffer, enableLogging);
428
616
  if (pskSni) {
429
- if (enableLogging) {
430
- console.log(`[SNI Extraction] Extracted SNI from PSK extension: ${pskSni}`);
431
- }
617
+ log(`Extracted SNI from PSK extension: ${pskSni}`);
432
618
  return pskSni;
433
619
  }
434
- // Could add more browser-specific heuristics here if needed
620
+ // Special handling for Chrome connection racing
621
+ // Chrome often opens multiple connections in parallel with different
622
+ // characteristics to improve performance
623
+ // Here we would look for specific patterns in ClientHello that indicate
624
+ // it's part of a connection race
625
+ // Detect if this is likely a secondary connection in a race
626
+ // by examining the cipher suites and extensions
627
+ // This would require session state tracking across connections
628
+ log('Failed to extract SNI from resumption mechanisms');
629
+ }
630
+ return undefined;
631
+ }
632
+ /**
633
+ * Main entry point for SNI extraction that handles all edge cases.
634
+ * This should be called for each TLS packet received from a client.
635
+ *
636
+ * The method uses connection tracking to handle fragmented ClientHello
637
+ * messages and various TLS 1.3 behaviors, including Chrome's connection
638
+ * racing patterns.
639
+ *
640
+ * @param buffer - The buffer containing TLS data
641
+ * @param connectionInfo - Connection metadata (IPs and ports)
642
+ * @param enableLogging - Whether to enable detailed debug logging
643
+ * @param cachedSni - Optional cached SNI from previous connections (for racing detection)
644
+ * @returns The extracted server name or undefined if not found or more data needed
645
+ */
646
+ static processTlsPacket(buffer, connectionInfo, enableLogging = false, cachedSni) {
647
+ const log = (message) => {
435
648
  if (enableLogging) {
436
- console.log('[SNI Extraction] Failed to extract SNI from resumption mechanisms');
649
+ console.log(`[TLS Packet] ${message}`);
437
650
  }
651
+ };
652
+ // Add timestamp if not provided
653
+ if (!connectionInfo.timestamp) {
654
+ connectionInfo.timestamp = Date.now();
655
+ }
656
+ // Check if this is a TLS handshake
657
+ if (!this.isTlsHandshake(buffer) && !this.isTlsApplicationData(buffer)) {
658
+ log('Not a TLS handshake or application data packet');
659
+ return undefined;
660
+ }
661
+ // Create connection ID for tracking
662
+ const connectionId = this.createConnectionId(connectionInfo);
663
+ log(`Processing TLS packet for connection ${connectionId}, buffer length: ${buffer.length}`);
664
+ // Handle special case: if we already have a cached SNI from a previous
665
+ // connection from the same client IP within a short time window,
666
+ // this might be a connection racing situation
667
+ if (cachedSni && this.isTlsApplicationData(buffer)) {
668
+ log(`Using cached SNI from connection racing: ${cachedSni}`);
669
+ return cachedSni;
670
+ }
671
+ // Try to extract SNI with full resumption support and fragment handling
672
+ const sni = this.extractSNIWithResumptionSupport(buffer, connectionInfo, enableLogging);
673
+ if (sni) {
674
+ log(`Successfully extracted SNI: ${sni}`);
675
+ return sni;
676
+ }
677
+ // If we couldn't extract an SNI, check if this is a valid ClientHello
678
+ // If it is, but we couldn't get an SNI, it might be a fragment or
679
+ // a connection race situation
680
+ if (this.isClientHello(buffer)) {
681
+ log('Valid ClientHello detected, but no SNI extracted - might need more data');
438
682
  }
439
683
  return undefined;
440
684
  }
441
685
  }
442
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5zbmloYW5kbGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvY2xhc3Nlcy5zbmloYW5kbGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxRQUFRLENBQUM7QUFFaEM7OztHQUdHO0FBQ0gsTUFBTSxPQUFPLFVBQVU7SUFDckIsaUNBQWlDO2FBQ1QsOEJBQXlCLEdBQUcsRUFBRSxDQUFDO2FBQy9CLG9DQUErQixHQUFHLENBQUMsQ0FBQzthQUNwQywyQkFBc0IsR0FBRyxNQUFNLENBQUM7YUFDaEMsc0NBQWlDLEdBQUcsTUFBTSxDQUFDO2FBQzNDLDJCQUFzQixHQUFHLENBQUMsQ0FBQzthQUMzQiwyQkFBc0IsR0FBRyxNQUFNLENBQUMsR0FBQyw0Q0FBNEM7YUFDN0Usb0NBQStCLEdBQUcsTUFBTSxDQUFDLEdBQUMseUJBQXlCO0lBRTNGOzs7O09BSUc7SUFDSSxNQUFNLENBQUMsY0FBYyxDQUFDLE1BQWM7UUFDekMsT0FBTyxNQUFNLENBQUMsTUFBTSxHQUFHLENBQUMsSUFBSSxNQUFNLENBQUMsQ0FBQyxDQUFDLEtBQUssSUFBSSxDQUFDLHlCQUF5QixDQUFDO0lBQzNFLENBQUM7SUFFRDs7OztPQUlHO0lBQ0ksTUFBTSxDQUFDLGFBQWEsQ0FBQyxNQUFjO1FBQ3hDLGtFQUFrRTtRQUNsRSxJQUFJLE1BQU0sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDdEIsT0FBTyxLQUFLLENBQUM7UUFDZixDQUFDO1FBRUQsd0RBQXdEO1FBQ3hELElBQUksTUFBTSxDQUFDLENBQUMsQ0FBQyxLQUFLLElBQUksQ0FBQyx5QkFBeUIsRUFBRSxDQUFDO1lBQ2pELE9BQU8sS0FBSyxDQUFDO1FBQ2YsQ0FBQztRQUVELCtEQUErRDtRQUMvRCx3REFBd0Q7UUFDeEQsT0FBTyxNQUFNLENBQUMsQ0FBQyxDQUFDLEtBQUssSUFBSSxDQUFDLCtCQUErQixDQUFDO0lBQzVE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
686
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5zbmloYW5kbGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvY2xhc3Nlcy5zbmloYW5kbGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxRQUFRLENBQUM7QUFFaEM7Ozs7O0dBS0c7QUFDSCxNQUFNLE9BQU8sVUFBVTtJQUNyQixpQ0FBaUM7YUFDVCw4QkFBeUIsR0FBRyxFQUFFLENBQUM7YUFDL0IsOEJBQXlCLEdBQUcsRUFBRSxDQUFDLEdBQUUsbUNBQW1DO2FBQ3BFLG9DQUErQixHQUFHLENBQUMsQ0FBQzthQUNwQywyQkFBc0IsR0FBRyxNQUFNLENBQUM7YUFDaEMsc0NBQWlDLEdBQUcsTUFBTSxDQUFDO2FBQzNDLDJCQUFzQixHQUFHLENBQUMsQ0FBQzthQUMzQiwyQkFBc0IsR0FBRyxNQUFNLENBQUMsR0FBQyw0Q0FBNEM7YUFDN0Usb0NBQStCLEdBQUcsTUFBTSxDQUFDLEdBQUMseUJBQXlCO2FBQ25FLGtDQUE2QixHQUFHLE1BQU0sQ0FBQyxHQUFDLCtCQUErQjtJQUUvRixzREFBc0Q7YUFDdkMsc0JBQWlCLEdBQXdCLElBQUksR0FBRyxFQUFFLENBQUM7YUFDbkQsb0JBQWUsR0FBVyxJQUFJLENBQUMsR0FBQywwQ0FBMEM7SUFFekY7Ozs7T0FJRztJQUNJLE1BQU0sQ0FBQyxjQUFjLENBQUMsTUFBYztRQUN6QyxPQUFPLE1BQU0sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxJQUFJLE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyxJQUFJLENBQUMseUJBQXlCLENBQUM7SUFDM0UsQ0FBQztJQUVEOzs7O09BSUc7SUFDSSxNQUFNLENBQUMsb0JBQW9CLENBQUMsTUFBYztRQUMvQyxPQUFPLE1BQU0sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxJQUFJLE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyxJQUFJLENBQUMseUJBQXlCLENBQUM7SUFDM0UsQ0FBQztJQUVEOzs7Ozs7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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@push.rocks/smartproxy",
3
- "version": "3.37.3",
3
+ "version": "3.38.2",
4
4
  "private": false,
5
5
  "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.",
6
6
  "main": "dist_ts/index.js",
@@ -3,6 +3,6 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@push.rocks/smartproxy',
6
- version: '3.37.3',
6
+ version: '3.38.2',
7
7
  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.'
8
8
  }
@@ -920,7 +920,15 @@ export class PortProxy {
920
920
  if (SniHandler.isClientHello(renegChunk)) {
921
921
  try {
922
922
  // Extract SNI from ClientHello
923
- const newSNI = SniHandler.extractSNIWithResumptionSupport(renegChunk, this.settings.enableTlsDebugLogging);
923
+ // Create a connection info object for the existing connection
924
+ const connInfo = {
925
+ sourceIp: record.remoteIP,
926
+ sourcePort: record.incoming.remotePort || 0,
927
+ destIp: record.incoming.localAddress || '',
928
+ destPort: record.incoming.localPort || 0
929
+ };
930
+
931
+ const newSNI = SniHandler.extractSNIWithResumptionSupport(renegChunk, connInfo, this.settings.enableTlsDebugLogging);
924
932
 
925
933
  // Skip if no SNI was found
926
934
  if (!newSNI) return;
@@ -1590,7 +1598,15 @@ export class PortProxy {
1590
1598
  `[${connectionId}] TLS handshake detected from ${remoteIP}, ${chunk.length} bytes`
1591
1599
  );
1592
1600
  // Try to extract SNI and log detailed debug info
1593
- SniHandler.extractSNIWithResumptionSupport(chunk, true);
1601
+ // Create connection info for debug logging
1602
+ const debugConnInfo = {
1603
+ sourceIp: remoteIP,
1604
+ sourcePort: socket.remotePort || 0,
1605
+ destIp: socket.localAddress || '',
1606
+ destPort: socket.localPort || 0
1607
+ };
1608
+
1609
+ SniHandler.extractSNIWithResumptionSupport(chunk, debugConnInfo, true);
1594
1610
  }
1595
1611
  }
1596
1612
  });
@@ -1797,7 +1813,21 @@ export class PortProxy {
1797
1813
  );
1798
1814
  }
1799
1815
 
1800
- serverName = SniHandler.extractSNIWithResumptionSupport(chunk, this.settings.enableTlsDebugLogging) || '';
1816
+ // Create connection info object for SNI extraction
1817
+ const connInfo = {
1818
+ sourceIp: remoteIP,
1819
+ sourcePort: socket.remotePort || 0,
1820
+ destIp: socket.localAddress || '',
1821
+ destPort: socket.localPort || 0
1822
+ };
1823
+
1824
+ // Use the new processTlsPacket method for comprehensive handling
1825
+ serverName = SniHandler.processTlsPacket(
1826
+ chunk,
1827
+ connInfo,
1828
+ this.settings.enableTlsDebugLogging,
1829
+ connectionRecord.lockedDomain // Pass any previously negotiated domain as a hint
1830
+ ) || '';
1801
1831
  }
1802
1832
 
1803
1833
  // Lock the connection to the negotiated SNI.