refactor: 将 DTLS 本地依赖迁移到 libs 目录

This commit is contained in:
mofeng-git
2026-10-01 22:46:36 +08:00
parent 2f60e61dd5
commit 4f59e78179
99 changed files with 2 additions and 2 deletions

View File

@@ -0,0 +1,50 @@
use std::io::{BufReader, BufWriter};
use super::*;
use crate::error::Error;
#[test]
fn test_alert() -> Result<()> {
let tests = vec![
(
"Valid Alert",
vec![0x02, 0x0A],
Alert {
alert_level: AlertLevel::Fatal,
alert_description: AlertDescription::UnexpectedMessage,
},
None,
),
(
"Invalid alert length",
vec![0x00],
Alert {
alert_level: AlertLevel::Invalid,
alert_description: AlertDescription::Invalid,
},
Some(Error::Other("io".to_owned())),
),
];
for (name, data, wanted, unmarshal_error) in tests {
let mut reader = BufReader::new(data.as_slice());
let result = Alert::unmarshal(&mut reader);
if let Some(err) = unmarshal_error {
assert!(result.is_err(), "{name} expected error: {err}");
} else if let Ok(alert) = result {
assert_eq!(wanted, alert, "{name} expected {wanted}, but got {alert}");
let mut data2: Vec<u8> = vec![];
{
let mut writer = BufWriter::<&mut Vec<u8>>::new(data2.as_mut());
alert.marshal(&mut writer)?;
}
assert_eq!(data, data2, "{name} expected {data:?}, but got {data2:?}");
} else {
assert!(result.is_ok(), "{name} expected Ok, but has error");
}
}
Ok(())
}

189
libs/dtls/src/alert/mod.rs Normal file
View File

@@ -0,0 +1,189 @@
#[cfg(test)]
mod alert_test;
use std::fmt;
use std::io::{Read, Write};
use byteorder::{ReadBytesExt, WriteBytesExt};
use super::content::*;
use crate::error::Result;
#[derive(Copy, Clone, PartialEq, Debug)]
pub(crate) enum AlertLevel {
Warning = 1,
Fatal = 2,
Invalid,
}
impl fmt::Display for AlertLevel {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {
AlertLevel::Warning => write!(f, "LevelWarning"),
AlertLevel::Fatal => write!(f, "LevelFatal"),
_ => write!(f, "Invalid alert level"),
}
}
}
impl From<u8> for AlertLevel {
fn from(val: u8) -> Self {
match val {
1 => AlertLevel::Warning,
2 => AlertLevel::Fatal,
_ => AlertLevel::Invalid,
}
}
}
#[derive(Copy, Clone, PartialEq, Debug)]
pub(crate) enum AlertDescription {
CloseNotify = 0,
UnexpectedMessage = 10,
BadRecordMac = 20,
DecryptionFailed = 21,
RecordOverflow = 22,
DecompressionFailure = 30,
HandshakeFailure = 40,
NoCertificate = 41,
BadCertificate = 42,
UnsupportedCertificate = 43,
CertificateRevoked = 44,
CertificateExpired = 45,
CertificateUnknown = 46,
IllegalParameter = 47,
UnknownCa = 48,
AccessDenied = 49,
DecodeError = 50,
DecryptError = 51,
ExportRestriction = 60,
ProtocolVersion = 70,
InsufficientSecurity = 71,
InternalError = 80,
UserCanceled = 90,
NoRenegotiation = 100,
UnsupportedExtension = 110,
UnknownPskIdentity = 115,
Invalid,
}
impl fmt::Display for AlertDescription {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {
AlertDescription::CloseNotify => write!(f, "CloseNotify"),
AlertDescription::UnexpectedMessage => write!(f, "UnexpectedMessage"),
AlertDescription::BadRecordMac => write!(f, "BadRecordMac"),
AlertDescription::DecryptionFailed => write!(f, "DecryptionFailed"),
AlertDescription::RecordOverflow => write!(f, "RecordOverflow"),
AlertDescription::DecompressionFailure => write!(f, "DecompressionFailure"),
AlertDescription::HandshakeFailure => write!(f, "HandshakeFailure"),
AlertDescription::NoCertificate => write!(f, "NoCertificate"),
AlertDescription::BadCertificate => write!(f, "BadCertificate"),
AlertDescription::UnsupportedCertificate => write!(f, "UnsupportedCertificate"),
AlertDescription::CertificateRevoked => write!(f, "CertificateRevoked"),
AlertDescription::CertificateExpired => write!(f, "CertificateExpired"),
AlertDescription::CertificateUnknown => write!(f, "CertificateUnknown"),
AlertDescription::IllegalParameter => write!(f, "IllegalParameter"),
AlertDescription::UnknownCa => write!(f, "UnknownCA"),
AlertDescription::AccessDenied => write!(f, "AccessDenied"),
AlertDescription::DecodeError => write!(f, "DecodeError"),
AlertDescription::DecryptError => write!(f, "DecryptError"),
AlertDescription::ExportRestriction => write!(f, "ExportRestriction"),
AlertDescription::ProtocolVersion => write!(f, "ProtocolVersion"),
AlertDescription::InsufficientSecurity => write!(f, "InsufficientSecurity"),
AlertDescription::InternalError => write!(f, "InternalError"),
AlertDescription::UserCanceled => write!(f, "UserCanceled"),
AlertDescription::NoRenegotiation => write!(f, "NoRenegotiation"),
AlertDescription::UnsupportedExtension => write!(f, "UnsupportedExtension"),
AlertDescription::UnknownPskIdentity => write!(f, "UnknownPskIdentity"),
_ => write!(f, "Invalid alert description"),
}
}
}
impl From<u8> for AlertDescription {
fn from(val: u8) -> Self {
match val {
0 => AlertDescription::CloseNotify,
10 => AlertDescription::UnexpectedMessage,
20 => AlertDescription::BadRecordMac,
21 => AlertDescription::DecryptionFailed,
22 => AlertDescription::RecordOverflow,
30 => AlertDescription::DecompressionFailure,
40 => AlertDescription::HandshakeFailure,
41 => AlertDescription::NoCertificate,
42 => AlertDescription::BadCertificate,
43 => AlertDescription::UnsupportedCertificate,
44 => AlertDescription::CertificateRevoked,
45 => AlertDescription::CertificateExpired,
46 => AlertDescription::CertificateUnknown,
47 => AlertDescription::IllegalParameter,
48 => AlertDescription::UnknownCa,
49 => AlertDescription::AccessDenied,
50 => AlertDescription::DecodeError,
51 => AlertDescription::DecryptError,
60 => AlertDescription::ExportRestriction,
70 => AlertDescription::ProtocolVersion,
71 => AlertDescription::InsufficientSecurity,
80 => AlertDescription::InternalError,
90 => AlertDescription::UserCanceled,
100 => AlertDescription::NoRenegotiation,
110 => AlertDescription::UnsupportedExtension,
115 => AlertDescription::UnknownPskIdentity,
_ => AlertDescription::Invalid,
}
}
}
// One of the content types supported by the TLS record layer is the
// alert type. Alert messages convey the severity of the message
// (warning or fatal) and a description of the alert. Alert messages
// with a level of fatal result in the immediate termination of the
// connection. In this case, other connections corresponding to the
// session may continue, but the session identifier MUST be invalidated,
// preventing the failed session from being used to establish new
// connections. Like other messages, alert messages are encrypted and
// compressed, as specified by the current connection state.
/// ## Specifications
///
/// * [RFC 5246 §7.2]
///
/// [RFC 5246 §7.2]: https://tools.ietf.org/html/rfc5246#section-7.2
#[derive(Copy, Clone, PartialEq, Debug)]
pub struct Alert {
pub(crate) alert_level: AlertLevel,
pub(crate) alert_description: AlertDescription,
}
impl fmt::Display for Alert {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Alert {}: {}", self.alert_level, self.alert_description)
}
}
impl Alert {
pub fn content_type(&self) -> ContentType {
ContentType::Alert
}
pub fn size(&self) -> usize {
2
}
pub fn marshal<W: Write>(&self, writer: &mut W) -> Result<()> {
writer.write_u8(self.alert_level as u8)?;
writer.write_u8(self.alert_description as u8)?;
Ok(writer.flush()?)
}
pub fn unmarshal<R: Read>(reader: &mut R) -> Result<Self> {
let alert_level = reader.read_u8()?.into();
let alert_description = reader.read_u8()?.into();
Ok(Alert {
alert_level,
alert_description,
})
}
}