import Foundation public enum MeshDNSCodec { public static func response(to query: Data, aliases: [String: MeshAddress], ttl: UInt32 = 30) throws -> Data { guard query.count >= 12, read16(query, 4) == 1 else { throw UMNError.invalidFrame } var offset = 12; var visited = Set() let labels = try decodeName(query, offset: &offset, visited: &visited) guard offset + 4 <= query.count else { throw UMNError.invalidFrame } let type = read16(query, offset), qclass = read16(query, offset + 2); offset += 4 guard qclass == 1 else { throw UMNError.invalidFrame } let question = query.subdata(in: 12.., depth: Int = 0) throws -> [String] { guard depth < 16 else { throw UMNError.invalidFrame } var labels: [String] = [] while true { guard offset < data.count else { throw UMNError.invalidFrame } let length = Int(data[offset]); offset += 1 if length == 0 { return labels } if length & 0xc0 == 0xc0 { guard offset < data.count else { throw UMNError.invalidFrame } let pointer = ((length & 0x3f) << 8) | Int(data[offset]); offset += 1 guard pointer >= 12, pointer < data.count, visited.insert(pointer).inserted else { throw UMNError.invalidFrame } var nested = pointer labels += try decodeName(data, offset: &nested, visited: &visited, depth: depth + 1) return labels } guard length <= 63, offset + length <= data.count, let label = String(data: data.subdata(in: offset..<(offset + length)), encoding: .utf8), !label.isEmpty else { throw UMNError.invalidFrame } labels.append(label); offset += length } } private static func read16(_ data: Data, _ offset: Int) -> UInt16 { UInt16(data[offset]) << 8 | UInt16(data[offset + 1]) } private static func append16(_ value: UInt16, to data: inout Data) { data.append(UInt8(value >> 8)); data.append(UInt8(value & 255)) } private static func append32(_ value: UInt32, to data: inout Data) { data.append(UInt8(value >> 24)); data.append(UInt8((value >> 16) & 255)); data.append(UInt8((value >> 8) & 255)); data.append(UInt8(value & 255)) } }