encodeQuery static method

Uint8List encodeQuery(
  1. String domain, {
  2. required int id,
})

构造一个 A 记录查询报文 / Builds a standard A-record query message.

Implementation

static Uint8List encodeQuery(String domain, {required int id}) {
  final labels = domain
      .split('.')
      .where((label) => label.isNotEmpty)
      .toList(growable: false);
  final safeLabels = labels.isEmpty ? const <String>['localhost'] : labels;

  final builder = BytesBuilder(copy: false);
  final header = ByteData(12);
  header.setUint16(0, id & 0xFFFF);
  header.setUint16(2, 0x0100); // RD = 1 / recursion desired.
  header.setUint16(4, 1); // QDCOUNT
  header.setUint16(6, 0); // ANCOUNT
  header.setUint16(8, 0); // NSCOUNT
  header.setUint16(10, 0); // ARCOUNT
  builder.add(header.buffer.asUint8List());

  for (final label in safeLabels) {
    final bytes = Uint8List.fromList(label.codeUnits);
    if (bytes.length > 63) {
      throw ArgumentError.value(
        label,
        'domain',
        'DNS label exceeds 63 bytes',
      );
    }
    builder.addByte(bytes.length);
    builder.add(bytes);
  }
  builder.addByte(0); // Root label.

  final question = ByteData(4);
  question.setUint16(0, DnsRecordType.a);
  question.setUint16(2, 1); // IN class.
  builder.add(question.buffer.asUint8List());

  return builder.toBytes();
}