encodeQuery static method
构造一个 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();
}