This document describes the comprehensive error handling system implemented for DTLS v1.3 protocol compliance with RFC 9147. The system provides consistent error processing, secure diagnostic information, and RFC-compliant alert generation while maintaining security and performance requirements.
// RFC 9147: "In general, invalid records SHOULD be silently discarded"
auto result = error_handler->handle_invalid_record(ContentType::INVALID, context);
// Records are silently discarded, optionally logged for diagnostics
Key Requirements Implemented:
UDP Transport (Default):
ErrorHandler::Configuration udp_config;
udp_config.transport_type = ErrorHandler::Transport::UDP;
udp_config.generate_alerts_on_invalid_records = false; // NOT RECOMMENDED per RFC
Secure Transport (SCTP with SCTP-AUTH):
ErrorHandler::Configuration secure_config;
secure_config.transport_type = ErrorHandler::Transport::DTLS_OVER_SCTP;
secure_config.generate_alerts_on_invalid_records = true; // Safe for secure transports
When alerts are generated, they MUST be fatal per RFC 9147:
// All generated alerts are fatal to prevent probing attacks
auto alert = AlertManager::serialize_alert(AlertLevel::FATAL, AlertDescription::BAD_RECORD_MAC);
// RFC 9147: Track records that fail authentication
auto result = error_handler->handle_authentication_failure(epoch, context);
// Returns false if connection should be closed due to excessive failures
struct Configuration {
Transport transport_type = Transport::UDP;
SecurityLevel security_level = SecurityLevel::STANDARD;
// Alert generation policy
bool generate_alerts_on_invalid_records = false; // RFC 9147 default for UDP
bool log_invalid_records = true;
// DoS protection thresholds
uint32_t max_auth_failures_per_epoch = 10;
uint32_t max_invalid_records_per_second = 100;
// Privacy and security
bool log_sensitive_data = false;
bool log_network_addresses = false;
bool anonymize_peer_info = true;
};
// Process any DTLS error with context
Result<bool> process_error(DTLSError error, std::shared_ptr<ErrorContext> context);
// Handle invalid record per RFC 9147
Result<void> handle_invalid_record(ContentType record_type,
std::shared_ptr<ErrorContext> context);
// Track authentication failures with DoS protection
Result<bool> handle_authentication_failure(Epoch epoch,
std::shared_ptr<ErrorContext> context);
// Generate alert if appropriate for transport
Result<std::vector<uint8_t>> generate_alert_if_appropriate(
AlertDescription alert_desc, std::shared_ptr<ErrorContext> context);
// Record error with categorization
uint32_t record_error(DTLSError error, const std::string& category,
const std::string& description, bool is_security_relevant = false);
// Record security-specific error with confidence
uint32_t record_security_error(DTLSError error, const std::string& attack_type,
double confidence);
// Update connection state context
void update_connection_state(ConnectionState state, std::optional<Epoch> epoch);
// Check for excessive error rates (DoS detection)
bool is_error_rate_excessive(std::chrono::seconds time_window, uint32_t max_errors);
// Detect attack patterns with confidence scoring
double detect_attack_patterns() const;
// Get recent errors for analysis
std::vector<ErrorEvent> get_recent_errors(std::chrono::seconds time_window);
// Generate alert with RFC 9147 policy enforcement
Result<std::optional<std::vector<uint8_t>>> generate_alert_for_error(
DTLSError error, std::shared_ptr<ErrorContext> context);
// Handle invalid record per RFC 9147 (silent discard)
Result<void> handle_invalid_record(ContentType record_type,
const std::string& connection_id,
std::shared_ptr<ErrorContext> context);
struct AlertPolicy {
TransportSecurity transport_security = TransportSecurity::INSECURE;
bool generate_alerts_for_invalid_records = false; // NOT RECOMMENDED for UDP
bool generate_alerts_for_auth_failures = false;
uint32_t max_alerts_per_minute = 10;
bool randomize_alert_timing = true; // Prevent timing attacks
};
// Basic error reporting with privacy protection
Result<void> report_error(LogLevel level, DTLSError error,
const std::string& category, const std::string& message,
std::shared_ptr<ErrorContext> context = nullptr);
// Security incident reporting with threat assessment
Result<void> report_security_incident(DTLSError error, const std::string& incident_type,
double confidence,
std::shared_ptr<ErrorContext> context = nullptr);
auto result = error_reporter->create_report(LogLevel::SECURITY, DTLSError::TAMPERING_DETECTED)
.category("integrity_validation")
.message("Message tampering detected")
.security_incident(true)
.threat_confidence(0.92)
.attack_vector("message_modification")
.metadata("record_type", "handshake")
.tag("security").tag("attack")
.submit();
// RFC 9147 compliant configuration for UDP transport
ErrorHandler::Configuration config;
config.transport_type = ErrorHandler::Transport::UDP;
config.generate_alerts_on_invalid_records = false; // Per RFC recommendation
config.log_invalid_records = true; // Diagnostic logging allowed
config.max_auth_failures_per_epoch = 5; // Strict limit
auto error_handler = std::make_unique<ErrorHandler>(config);
// Configure alert manager for UDP
AlertManager::AlertPolicy alert_policy;
alert_policy.transport_security = AlertManager::TransportSecurity::INSECURE;
alert_policy.generate_alerts_for_invalid_records = false;
alert_policy.generate_alerts_for_auth_failures = false;
auto alert_manager = std::make_unique<AlertManager>(alert_policy);
error_handler->set_alert_manager(alert_manager);
auto context = error_handler->create_error_context("client_001");
// Invalid record received - handle per RFC 9147
auto result = error_handler->handle_invalid_record(ContentType::INVALID, context);
if (result.is_success()) {
// Record was silently discarded per RFC 9147
// Error was logged for diagnostic purposes
}
// Check if DoS attack detected
const auto& stats = error_handler->get_error_statistics();
if (stats.dos_attacks_detected > 0) {
// Take appropriate defensive action
}
// Detect potential replay attack
if (/* replay detection logic */) {
context->record_security_error(
DTLSError::REPLAY_ATTACK_DETECTED, "replay_pattern", 0.9);
// Report security incident
error_reporter->report_security_incident(
DTLSError::REPLAY_ATTACK_DETECTED, "replay_attack", 0.9, context);
// Check if connection should be terminated
if (error_handler->should_terminate_connection(DTLSError::REPLAY_ATTACK_DETECTED)) {
// Terminate connection
}
}
// Production configuration with strict security
ErrorHandler::Configuration prod_config;
prod_config.transport_type = ErrorHandler::Transport::UDP;
prod_config.security_level = ErrorHandler::SecurityLevel::STRICT;
prod_config.max_auth_failures_per_epoch = 3; // Strict for production
prod_config.enable_attack_detection = true;
prod_config.enable_error_correlation = true;
// Production error reporting
ErrorReporter::ReportingConfig reporter_config;
reporter_config.minimum_level = ErrorReporter::LogLevel::WARNING;
reporter_config.format = ErrorReporter::OutputFormat::SYSLOG;
reporter_config.log_file_path = "/var/log/dtls/error.log";
reporter_config.enable_audit_trail = true;
// Strict privacy settings
reporter_config.log_network_addresses = false;
reporter_config.log_connection_ids = false;
reporter_config.anonymize_peer_info = true;
reporter_config.log_sensitive_data = false;
#include <systemc/include/dtls_error_handling.h>
// Create SystemC error handler module
dtls_error_handler_sc error_handler("error_handler");
// Configure for SystemC simulation
error_handler.configure_for_simulation();
// Connect to other SystemC modules
error_handler.error_reporting_socket.bind(protocol_stack.error_port);
protocol_stack.alert_port.bind(error_handler.alert_output_socket);
// SystemC error injection module for testing
dtls_error_injector_sc injector("error_injector");
// Configure injection profile
injector.configure_injection_profile("dos_attack_simulation");
injector.enable_random_injection(0.05); // 5% error rate
injector.enable_burst_injection(10, sc_time(1, SC_MS));
cd build
./dtls_error_handling_test
cd build
./dtls_error_handling_test --gtest_filter="*RFC9147*"
# Run comprehensive error handling examples
cd build
./error_handling_example
# Include error handling in performance tests
cd build
./dtls_performance_test --include-error-handling
// Old approach
if (error != DTLSError::SUCCESS) {
return error;
}
// New approach with context
auto result = error_handler->process_error(error, context);
if (!result.is_success()) {
return result.error();
}
bool should_continue = result.value();
// Old approach
if (should_send_alert) {
send_alert(AlertLevel::FATAL, AlertDescription::BAD_RECORD_MAC);
}
// New approach (RFC 9147 compliant)
auto alert_result = error_handler->generate_alert_if_appropriate(
AlertDescription::BAD_RECORD_MAC, context);
if (alert_result.is_success()) {
// Alert generated according to transport policy
send_alert_data(alert_result.value());
}
max_events
limit in ErrorContextErrorHandler::Configuration debug_config;
debug_config.security_level = ErrorHandler::SecurityLevel::PARANOID;
debug_config.log_invalid_records = true;
debug_config.enable_attack_detection = true;
ErrorReporter::ReportingConfig debug_reporter;
debug_reporter.minimum_level = ErrorReporter::LogLevel::DEBUG;
debug_reporter.include_stack_traces = true; // Debug builds only
For questions or issues with the error handling system:
examples/error_handling_example.cpp