This commit is contained in:
Juergen Kunz
2025-07-22 10:35:39 +00:00
parent b6d8b73599
commit a459d77b6f
7 changed files with 362 additions and 52 deletions

View File

@@ -5,7 +5,7 @@
// TLS detector doesn't need plugins imports
import type { IProtocolDetector } from '../models/interfaces.js';
import type { IDetectionResult, IDetectionOptions, IConnectionInfo } from '../models/detection-types.js';
import { readUInt16BE, BufferAccumulator } from '../utils/buffer-utils.js';
import { readUInt16BE } from '../utils/buffer-utils.js';
import { tlsVersionToString } from '../utils/parser-utils.js';
// Import from protocols
@@ -24,17 +24,6 @@ export class TlsDetector implements IProtocolDetector {
*/
private static readonly MIN_TLS_HEADER_SIZE = 5;
/**
* Fragment tracking for incomplete handshakes
*/
private static fragmentedBuffers = new Map<string, BufferAccumulator>();
/**
* Create connection ID from context
*/
private createConnectionId(context: { sourceIp?: string; sourcePort?: number; destIp?: string; destPort?: number }): string {
return `${context.sourceIp || 'unknown'}:${context.sourcePort || 0}->${context.destIp || 'unknown'}:${context.destPort || 0}`;
}
/**
* Detect TLS protocol from buffer
@@ -224,29 +213,11 @@ export class TlsDetector implements IProtocolDetector {
*/
detectWithContext(
buffer: Buffer,
context: { sourceIp?: string; sourcePort?: number; destIp?: string; destPort?: number },
_context: { sourceIp?: string; sourcePort?: number; destIp?: string; destPort?: number },
options?: IDetectionOptions
): IDetectionResult | null {
const connectionId = this.createConnectionId(context);
// Get or create buffer accumulator for this connection
let accumulator = TlsDetector.fragmentedBuffers.get(connectionId);
if (!accumulator) {
accumulator = new BufferAccumulator();
TlsDetector.fragmentedBuffers.set(connectionId, accumulator);
}
// Add new data
accumulator.append(buffer);
// Try detection on accumulated data
const result = this.detect(accumulator.getBuffer(), options);
// If detection is complete or we have too much data, clean up
if (result?.isComplete || accumulator.length() > 65536) {
TlsDetector.fragmentedBuffers.delete(connectionId);
}
return result;
// This method is deprecated - TLS detection should use the fragment manager
// from the parent detector system, not maintain its own fragments
return this.detect(buffer, options);
}
}

View File

@@ -120,10 +120,28 @@ export class ProtocolDetector {
};
}
const connectionId = DetectionFragmentManager.createConnectionId(context);
// First peek to determine protocol type
if (this.tlsDetector.canHandle(buffer)) {
const result = this.tlsDetector.detectWithContext(buffer, context, options);
// Handle TLS with fragment accumulation
const handler = this.fragmentManager.getHandler('tls');
const fragmentResult = handler.addFragment(connectionId, buffer);
if (fragmentResult.error) {
handler.complete(connectionId);
return {
protocol: 'unknown',
connectionInfo: { protocol: 'unknown' },
isComplete: true
};
}
const result = this.tlsDetector.detect(fragmentResult.buffer!, options);
if (result) {
if (result.isComplete) {
handler.complete(connectionId);
}
return result;
}
}
@@ -173,13 +191,25 @@ export class ProtocolDetector {
/**
* Clean up old connection tracking entries
*
* @param maxAge Maximum age in milliseconds (default: 30 seconds)
* @param _maxAge Maximum age in milliseconds (default: 30 seconds)
*/
static cleanupConnections(maxAge: number = 30000): void {
static cleanupConnections(_maxAge: number = 30000): void {
// Cleanup is now handled internally by the fragment manager
this.getInstance().fragmentManager.cleanup();
}
/**
* Clean up fragments for a specific connection
*/
static cleanupConnection(context: IConnectionContext): void {
const instance = this.getInstance();
const connectionId = DetectionFragmentManager.createConnectionId(context);
// Clean up both TLS and HTTP fragments for this connection
instance.fragmentManager.getHandler('tls').complete(connectionId);
instance.fragmentManager.getHandler('http').complete(connectionId);
}
/**
* Extract domain from connection info
*/