parse static method

DnsResponse parse(
  1. Uint8List data
)

解析 DNS 响应报文 / Parses a DNS response message.

报文不合法时抛出 FormatException / Throws FormatException when the message is malformed.

Implementation

static DnsResponse parse(Uint8List data) {
  if (data.length < 12) {
    throw const FormatException(
      'DNS message shorter than the 12-byte header',
    );
  }
  final header = ByteData.sublistView(data, 0, 12);
  final id = header.getUint16(0);
  final flags = header.getUint16(2);
  final responseCode = flags & 0x000F;
  final truncated = (flags & 0x0200) != 0;
  final questionCount = header.getUint16(4);
  final answerCount = header.getUint16(6);

  var offset = 12;
  for (var i = 0; i < questionCount; i++) {
    offset = _skipName(data, offset);
    if (offset + 4 > data.length) {
      throw const FormatException('Truncated DNS question section');
    }
    offset += 4; // QTYPE + QCLASS.
  }

  final answers = <DnsAnswer>[];
  for (var i = 0; i < answerCount; i++) {
    final name = _readName(data, offset);
    offset = name.nextOffset;
    if (offset + 10 > data.length) {
      throw const FormatException('Truncated DNS answer section');
    }
    final record = ByteData.sublistView(data, offset, offset + 10);
    final type = record.getUint16(0);
    final ttl = record.getUint32(4);
    final length = record.getUint16(8);
    offset += 10;
    if (offset + length > data.length) {
      throw const FormatException('DNS record payload exceeds message size');
    }

    final value = _readRecordValue(data, offset, length, type);
    if (value != null) {
      answers.add(
        DnsAnswer(name: name.value, type: type, ttl: ttl, value: value),
      );
    }
    offset += length;
  }

  return DnsResponse(
    id: id,
    responseCode: responseCode,
    answers: answers,
    truncated: truncated,
  );
}