feat(protocol): carry complete encoded media frames
This commit is contained in:
@@ -129,23 +129,30 @@ func validFECStatus(_ body: [UInt8]) -> Bool {
|
||||
|
||||
func classifyDatagram(_ encoded: String) -> String {
|
||||
guard let raw = decodeHex(encoded) else { return "invalid:hex" }
|
||||
guard raw.count >= 21 else { return "invalid:truncated" }
|
||||
guard raw.count >= 3 else { return "invalid:truncated" }
|
||||
guard raw[0] == 0x56 && raw[1] == 0x44 else { return "invalid:magic" }
|
||||
guard raw[2] == 1 else { return "invalid:unsupported_version" }
|
||||
guard raw[2] == 1 || raw[2] == 2 else { return "invalid:unsupported_version" }
|
||||
let headerBytes = raw[2] == 1 ? 21 : 23
|
||||
guard raw.count >= headerBytes else { return "invalid:truncated" }
|
||||
let limit: Int
|
||||
switch raw[3] {
|
||||
case 1: limit = 1024
|
||||
case 2: limit = 2048
|
||||
case 3: limit = 65515
|
||||
case 10, 11, 12: limit = 1179
|
||||
switch (raw[2], raw[3]) {
|
||||
case (1, 1): limit = 1024
|
||||
case (1, 2): limit = 2048
|
||||
case (1, 3): limit = 65515
|
||||
case (1, 10), (1, 11), (1, 12): limit = 1179
|
||||
case (2, 10), (2, 11): limit = 1177
|
||||
default: return "invalid:unknown_channel"
|
||||
}
|
||||
guard raw[4] == 0 else { return "invalid:flags" }
|
||||
guard raw[18] > 0 && raw[17] < raw[18] else { return "invalid:fragment" }
|
||||
let payloadLength = Int(raw[19]) * 256 + Int(raw[20])
|
||||
let fragmentIndex = raw[2] == 1 ? Int(raw[17]) : Int(raw[17]) * 256 + Int(raw[18])
|
||||
let fragmentCount = raw[2] == 1 ? Int(raw[18]) : Int(raw[19]) * 256 + Int(raw[20])
|
||||
if raw[2] == 2 && fragmentCount > 891 { return "invalid:fragment_limit" }
|
||||
guard fragmentCount > 0 && fragmentIndex < fragmentCount else { return "invalid:fragment" }
|
||||
let payloadOffset = raw[2] == 1 ? 19 : 21
|
||||
let payloadLength = Int(raw[payloadOffset]) * 256 + Int(raw[payloadOffset + 1])
|
||||
guard payloadLength <= limit else { return "invalid:payload_limit" }
|
||||
guard raw.count == 21 + payloadLength else { return "invalid:length_mismatch" }
|
||||
guard raw.count <= 65536 else { return "invalid:frame_limit" }
|
||||
guard raw.count == headerBytes + payloadLength else { return "invalid:length_mismatch" }
|
||||
guard raw[2] == 1 ? raw.count <= 65536 : raw.count <= 1200 else { return "invalid:frame_limit" }
|
||||
return "valid"
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user