Compare commits

..

2 Commits

Author SHA1 Message Date
65b05eb449 Update types 2026-04-08 23:23:49 +08:00
777f92260e Bye buffer 2026-04-08 23:23:29 +08:00
4 changed files with 130 additions and 180 deletions

View File

@ -36,9 +36,9 @@ const inPacket: Packet = {
type: "query", type: "query",
}; };
const inputBuf = Buffer.alloc(0); const inputBuf = new Uint8Array(0);
const length: number = encodingLength(inPacket); const length: number = encodingLength(inPacket);
const out: Buffer = encode(inPacket, inputBuf, length - length); const out: Uint8Array = encode(inPacket, inputBuf, length - length);
const outPacket: DecodedPacket = decode(out, 0); const outPacket: DecodedPacket = decode(out, 0);
const flag_qr: boolean = outPacket.flag_qr; const flag_qr: boolean = outPacket.flag_qr;
const flag_aa: boolean = outPacket.flag_aa; const flag_aa: boolean = outPacket.flag_aa;

261
index.d.ts vendored
View File

@ -40,6 +40,7 @@ export type RecordType =
| "RP" | "RP"
| "SIG" | "SIG"
| "SOA" | "SOA"
| "SPF"
| "SRV" | "SRV"
| "SSHFP" | "SSHFP"
| "SVCB" | "SVCB"
@ -52,6 +53,10 @@ export type RecordType =
export type RecordClass = "IN" | "CS" | "CH" | "HS" | "ANY"; export type RecordClass = "IN" | "CS" | "CH" | "HS" | "ANY";
export type OpCode = "QUERY" | "IQUERY" | "STATUS" | "NOTIFY" | "UPDATE" | string;
export type RCode = "NOERROR" | "FORMERR" | "SERVFAIL" | "NXDOMAIN" | "NOTIMP" | "REFUSED" | "YXDOMAIN" | "YXRRSET" | "NXRRSET" | "NOTAUTH" | "NOTZONE" | string;
export interface Question { export interface Question {
type: RecordType; type: RecordType;
name: string; name: string;
@ -70,14 +75,14 @@ export interface CaaData {
export interface DnskeyData { export interface DnskeyData {
flags: number; flags: number;
algorithm: number; algorithm: number;
key: Buffer; key: string | Uint8Array;
} }
export interface DsData { export interface DsData {
keyTag: number; keyTag: number;
algorithm: number; algorithm: number;
digestType: number; digestType: number;
digest: Buffer; digest: string | Uint8Array;
} }
export interface HInfoData { export interface HInfoData {
@ -108,8 +113,8 @@ export interface Nsec3Data {
algorithm: number; algorithm: number;
flags: number; flags: number;
iterations: number; iterations: number;
salt: Buffer; salt: Uint8Array;
nextDomain: Buffer; nextDomain: Uint8Array;
rrtypes: string[]; rrtypes: string[];
} }
@ -119,7 +124,7 @@ export interface RpData {
} }
export interface RrsigData { export interface RrsigData {
typeCovered: string; typeCovered: RecordType | string;
algorithm: number; algorithm: number;
labels: number; labels: number;
originalTTL: number; originalTTL: number;
@ -127,7 +132,7 @@ export interface RrsigData {
inception: number; inception: number;
keyTag: number; keyTag: number;
signersName: string; signersName: string;
signature: Buffer; signature: string | Uint8Array;
} }
export interface SrvData { export interface SrvData {
@ -157,10 +162,10 @@ export interface TlsaData {
usage: number; usage: number;
selector: number; selector: number;
matchingType: number; matchingType: number;
certificate: Buffer; certificate: string | Uint8Array;
} }
export type TxtData = string | Buffer | Array<string | Buffer>; export type TxtData = string | Uint8Array | Array<string | Uint8Array>;
// SVCB/HTTPS Parameter types // SVCB/HTTPS Parameter types
export interface SvcParamMandatory { export interface SvcParamMandatory {
@ -190,7 +195,7 @@ export interface SvcParamIpv4Hint {
export interface SvcParamEchConfig { export interface SvcParamEchConfig {
key: "echconfig" | 5; key: "echconfig" | 5;
value: string; value: string | Uint8Array;
needBase64Decode?: boolean | undefined; needBase64Decode?: boolean | undefined;
} }
@ -206,14 +211,14 @@ export interface SvcParamDohPath {
export interface SvcParamOdoh { export interface SvcParamOdoh {
key: "odoh" | 32769; key: "odoh" | 32769;
value: string; value: string | Uint8Array;
needBase64Decode?: boolean | undefined; needBase64Decode?: boolean | undefined;
} }
export interface SvcParamUnknown { export interface SvcParamUnknown {
key: string | number; key: string | number;
value?: unknown | undefined; value?: unknown | undefined;
data?: Buffer | undefined; data?: Uint8Array | undefined;
} }
export type SvcParam = export type SvcParam =
@ -231,13 +236,13 @@ export type SvcParam =
export interface HttpsData { export interface HttpsData {
priority: number; priority: number;
name: string; name: string;
values?: Record<string, unknown> | undefined; values?: Record<string, SvcParam["value"]> | undefined;
} }
export interface SvcbData { export interface SvcbData {
priority: number; priority: number;
name: string; name: string;
values?: Record<string, unknown> | undefined; values?: Record<string, SvcParam["value"]> | undefined;
} }
// Generic answer types // Generic answer types
@ -281,7 +286,7 @@ export type OtherRecordType =
// Specific answer types // Specific answer types
export type StringAnswer = BaseAnswer<StringRecordType, string>; export type StringAnswer = BaseAnswer<StringRecordType, string>;
export type BufferAnswer = BaseAnswer<OtherRecordType, Buffer>; export type BufferAnswer = BaseAnswer<OtherRecordType, Uint8Array>;
export type CaaAnswer = BaseAnswer<"CAA", CaaData>; export type CaaAnswer = BaseAnswer<"CAA", CaaData>;
export type DnskeyAnswer = BaseAnswer<"DNSKEY", DnskeyData>; export type DnskeyAnswer = BaseAnswer<"DNSKEY", DnskeyData>;
export type DSAnswer = BaseAnswer<"DS", DsData>; export type DSAnswer = BaseAnswer<"DS", DsData>;
@ -327,14 +332,14 @@ type OptCode<K extends OptCodeType> = OptCodes[K];
interface GenericOpt<T extends OptCodeType> { interface GenericOpt<T extends OptCodeType> {
code: OptCode<T>; code: OptCode<T>;
type?: T | undefined; type?: T | undefined;
data?: Buffer | undefined; data?: Uint8Array | undefined;
} }
interface ClientSubnetOpt extends GenericOpt<"CLIENT_SUBNET"> { interface ClientSubnetOpt extends GenericOpt<"CLIENT_SUBNET"> {
family?: number | undefined; family?: number | undefined;
sourcePrefixLength?: number | undefined; sourcePrefixLength?: number | undefined;
scopePrefixLength?: number | undefined; scopePrefixLength?: number | undefined;
ip: string | undefined; ip?: string | undefined;
} }
interface KeepAliveOpt extends GenericOpt<"TCP_KEEPALIVE"> { interface KeepAliveOpt extends GenericOpt<"TCP_KEEPALIVE"> {
@ -410,8 +415,8 @@ export interface Packet {
*/ */
flags?: number | undefined; flags?: number | undefined;
opcode?: string | undefined; opcode?: OpCode | number | undefined;
rcode?: string | undefined; rcode?: RCode | number | undefined;
questions?: Question[] | undefined; questions?: Question[] | undefined;
answers?: Answer[] | undefined; answers?: Answer[] | undefined;
@ -444,13 +449,13 @@ export const DNSSEC_OK: number;
export const NXDOMAIN: number; export const NXDOMAIN: number;
// Main functions // Main functions
export function encode(packet: Packet, buf?: Buffer, offset?: number): Buffer; export function encode(packet: Packet, buf?: Uint8Array | ArrayBufferLike, offset?: number): Uint8Array;
export namespace encode { export namespace encode {
let bytes: number; let bytes: number;
} }
export function decode(buf: Buffer, offset?: number): DecodedPacket; export function decode(buf: Uint8Array | ArrayBufferLike, offset?: number): DecodedPacket;
export namespace decode { export namespace decode {
let bytes: number; let bytes: number;
@ -458,211 +463,135 @@ export namespace decode {
export function encodingLength(packet: Packet): number; export function encodingLength(packet: Packet): number;
export function streamEncode(packet: Packet): Buffer; export function streamEncode(packet: Packet): Uint8Array;
export namespace streamEncode { export namespace streamEncode {
let bytes: number; let bytes: number;
} }
export function streamDecode(buf: Buffer): DecodedPacket | null; export function streamDecode(buf: Uint8Array | ArrayBufferLike, offset?: number): DecodedPacket | null;
export namespace streamDecode { export namespace streamDecode {
let bytes: number; let bytes: number;
} }
// Utility/Helper exports // Utility/Helper exports
export const name: { export const name: Codec<string> & {
encode( encode(
str: string, str: string,
buf?: Buffer, buf?: Uint8Array | ArrayBufferLike,
offset?: number, offset?: number,
options?: { mail?: boolean } options?: { mail?: boolean }
): Buffer; ): Uint8Array;
decode(buf: Buffer, offset?: number, options?: { mail?: boolean }): string; decode(buf: Uint8Array | ArrayBufferLike, offset?: number, options?: { mail?: boolean }): string;
encodingLength(name: string): number; encodingLength(name: string): number;
}; };
export const question: { export const question: Codec<Question>;
encode(q: Question, buf?: Buffer, offset?: number): Buffer;
decode(buf: Buffer, offset?: number): Question;
encodingLength(q: Question): number;
};
export const answer: { export const answer: Codec<Answer>;
encode(a: Answer, buf?: Buffer, offset?: number): Buffer;
decode(buf: Buffer, offset?: number): Answer;
encodingLength(a: Answer): number;
};
export const svcparam: { export const svcparam: Codec<SvcParam> & {
encode(param: SvcParam, buf?: Buffer, offset?: number): Buffer;
decode(buf: Buffer, offset?: number): SvcParam;
encodingLength(param: SvcParam): number;
keyToNumber(keyName: string): number; keyToNumber(keyName: string): number;
numberToKeyName(number: number): string; numberToKeyName(number: number): string;
}; };
export const svcb: { export const svcb: Codec<SvcbData>;
encode(data: SvcbData, buf?: Buffer, offset?: number): Buffer;
decode(buf: Buffer, offset?: number): SvcbData;
encodingLength(data: SvcbData): number;
};
export const httpssvc: { export const httpssvc: Codec<HttpsData>;
encode(data: HttpsData, buf?: Buffer, offset?: number): Buffer;
decode(buf: Buffer, offset?: number): HttpsData;
encodingLength(data: HttpsData): number;
};
export const a: { export const a: Codec<string>;
encode(host: string, buf?: Buffer, offset?: number): Buffer;
decode(buf: Buffer, offset?: number): string;
encodingLength(): number;
};
export const aaaa: { export const aaaa: Codec<string>;
encode(host: string, buf?: Buffer, offset?: number): Buffer;
decode(buf: Buffer, offset?: number): string;
encodingLength(): number;
};
export const cname: { export const cname: Codec<string>;
encode(data: string, buf?: Buffer, offset?: number): Buffer;
decode(buf: Buffer, offset?: number): string;
encodingLength(data: string): number;
};
export const dname: { export const dname: Codec<string>;
encode(data: string, buf?: Buffer, offset?: number): Buffer;
decode(buf: Buffer, offset?: number): string;
encodingLength(data: string): number;
};
export const ptr: { export const ptr: Codec<string>;
encode(data: string, buf?: Buffer, offset?: number): Buffer;
decode(buf: Buffer, offset?: number): string;
encodingLength(data: string): number;
};
export const ns: { export const ns: Codec<string>;
encode(data: string, buf?: Buffer, offset?: number): Buffer;
decode(buf: Buffer, offset?: number): string;
encodingLength(data: string): number;
};
export const mx: { export const mx: Codec<MxData>;
encode(data: MxData, buf?: Buffer, offset?: number): Buffer;
decode(buf: Buffer, offset?: number): MxData;
encodingLength(data: MxData): number;
};
export const srv: { export const srv: Codec<SrvData>;
encode(data: SrvData, buf?: Buffer, offset?: number): Buffer;
decode(buf: Buffer, offset?: number): SrvData;
encodingLength(data: SrvData): number;
};
export const caa: { export const caa: Codec<CaaData> & {
encode(data: CaaData, buf?: Buffer, offset?: number): Buffer;
decode(buf: Buffer, offset?: number): CaaData;
encodingLength(data: CaaData): number;
ISSUER_CRITICAL: number; ISSUER_CRITICAL: number;
}; };
export const txt: { export const txt: Codec<Uint8Array[]> & {
encode(data: TxtData, buf?: Buffer, offset?: number): Buffer; encode(data: TxtData, buf?: Uint8Array, offset?: number): Uint8Array;
decode(buf: Buffer, offset?: number): Buffer[];
encodingLength(data: TxtData): number;
}; };
export const null_: { export const null_: Codec<Uint8Array> & {
encode(data: Buffer | string, buf?: Buffer, offset?: number): Buffer; encode(data: Uint8Array | string, buf?: Uint8Array, offset?: number): Uint8Array;
decode(buf: Buffer, offset?: number): Buffer; encodingLength(data?: Uint8Array | string): number;
encodingLength(data?: Buffer | string): number;
}; };
export const hinfo: { export const hinfo: Codec<HInfoData>;
encode(data: HInfoData, buf?: Buffer, offset?: number): Buffer;
decode(buf: Buffer, offset?: number): HInfoData;
encodingLength(data: HInfoData): number;
};
export const soa: { export const soa: Codec<SoaData>;
encode(data: SoaData, buf?: Buffer, offset?: number): Buffer;
decode(buf: Buffer, offset?: number): SoaData;
encodingLength(data: SoaData): number;
};
export const naptr: { export const naptr: Codec<NaptrData>;
encode(data: NaptrData, buf?: Buffer, offset?: number): Buffer;
decode(buf: Buffer, offset?: number): NaptrData;
encodingLength(data: NaptrData): number;
};
export const dnskey: { export const dnskey: Codec<DnskeyData> & {
encode(key: DnskeyData, buf?: Buffer, offset?: number): Buffer;
decode(buf: Buffer, offset?: number): DnskeyData;
encodingLength(key: DnskeyData): number;
PROTOCOL_DNSSEC: number; PROTOCOL_DNSSEC: number;
ZONE_KEY: number; ZONE_KEY: number;
SECURE_ENTRYPOINT: number; SECURE_ENTRYPOINT: number;
}; };
export const rrsig: { export const rrsig: Codec<RrsigData>;
encode(sig: RrsigData, buf?: Buffer, offset?: number): Buffer;
decode(buf: Buffer, offset?: number): RrsigData;
encodingLength(sig: RrsigData): number;
};
export const rp: { export const rp: Codec<RpData>;
encode(data: RpData, buf?: Buffer, offset?: number): Buffer;
decode(buf: Buffer, offset?: number): RpData;
encodingLength(data: RpData): number;
};
export const nsec: { export const nsec: Codec<NsecData>;
encode(record: NsecData, buf?: Buffer, offset?: number): Buffer;
decode(buf: Buffer, offset?: number): NsecData;
encodingLength(record: NsecData): number;
};
export const nsec3: { export const nsec3: Codec<Nsec3Data>;
encode(record: Nsec3Data, buf?: Buffer, offset?: number): Buffer;
decode(buf: Buffer, offset?: number): Nsec3Data;
encodingLength(record: Nsec3Data): number;
};
export const ds: { export const ds: Codec<DsData>;
encode(digest: DsData, buf?: Buffer, offset?: number): Buffer;
decode(buf: Buffer, offset?: number): DsData;
encodingLength(digest: DsData): number;
};
export const sshfp: { export const sshfp: Codec<SshfpData> & {
encode(record: SshfpData, buf?: Buffer, offset?: number): Buffer;
decode(buf: Buffer, offset?: number): SshfpData;
encodingLength(record: SshfpData): number;
getFingerprintLengthForHashType(hashType: number): number | undefined; getFingerprintLengthForHashType(hashType: number): number | undefined;
}; };
export const tlsa: { export const tlsa: Codec<TlsaData>;
encode(cert: TlsaData, buf?: Buffer, offset?: number): Buffer;
decode(buf: Buffer, offset?: number): TlsaData; export const opt: Codec<PacketOpt[]>;
encodingLength(cert: TlsaData): number;
export const option: Codec<PacketOpt>;
export const unknown: Codec<Uint8Array> & {
encode(data: Uint8Array | string, buf?: Uint8Array, offset?: number): Uint8Array;
encodingLength(data: Uint8Array | string): number;
}; };
export const opt: { // Codec interface for type-safe encode/decode implementations
encode(options: PacketOpt[], buf?: Buffer, offset?: number): Buffer; export interface Codec<T = any> {
decode(buf: Buffer, offset?: number): PacketOpt[]; encode(data: T, buf?: Uint8Array | ArrayBufferLike, offset?: number): Uint8Array;
encodingLength(options: PacketOpt[]): number; decode(buf: Uint8Array | ArrayBufferLike, offset?: number): T;
}; encodingLength(data: T): number;
}
export const unknown: { export function record(type: "A" | "AAAA" | "CNAME" | "DNAME" | "NS" | "PTR"): Codec<string>;
encode(data: Buffer, buf?: Buffer, offset?: number): Buffer; export function record(type: "MX"): Codec<MxData>;
decode(buf: Buffer, offset?: number): Buffer; export function record(type: "SRV"): Codec<SrvData>;
encodingLength(data: Buffer): number; export function record(type: "SOA"): Codec<SoaData>;
}; export function record(type: "TXT"): Codec<Uint8Array[]>;
export function record(type: "CAA"): Codec<CaaData>;
export function record(type: RecordType): any; export function record(type: "HINFO"): Codec<HInfoData>;
export function record(type: "NAPTR"): Codec<NaptrData>;
export function record(type: "RP"): Codec<RpData>;
export function record(type: "RRSIG"): Codec<RrsigData>;
export function record(type: "DS"): Codec<DsData>;
export function record(type: "DNSKEY"): Codec<DnskeyData>;
export function record(type: "NSEC"): Codec<NsecData>;
export function record(type: "NSEC3"): Codec<Nsec3Data>;
export function record(type: "SSHFP"): Codec<SshfpData>;
export function record(type: "TLSA"): Codec<TlsaData>;
export function record(type: "SVCB"): Codec<SvcbData>;
export function record(type: "HTTPS"): Codec<HttpsData>;
export function record(type: RecordType): Codec<any>;
export {}; export {};

View File

@ -954,7 +954,8 @@ rdnskey.decode = function (buf, offset) {
rdnskey.decode.bytes = 0 rdnskey.decode.bytes = 0
rdnskey.encodingLength = function (key) { rdnskey.encodingLength = function (key) {
return 6 + byteLength(key.key, 'base64') const keydata = fromBuffer(key.key, 'base64')
return 6 + keydata.length
} }
const rrrsig = exports.rrsig = {} const rrrsig = exports.rrsig = {}
@ -1025,9 +1026,10 @@ rrrsig.decode = function (buf, offset) {
rrrsig.decode.bytes = 0 rrrsig.decode.bytes = 0
rrrsig.encodingLength = function (sig) { rrrsig.encodingLength = function (sig) {
const signature = fromBuffer(sig.signature, 'base64')
return 20 + return 20 +
name.encodingLength(sig.signersName) + name.encodingLength(sig.signersName) +
byteLength(sig.signature, 'base64') signature.length
} }
const rrp = exports.rp = {} const rrp = exports.rp = {}
@ -1319,7 +1321,8 @@ rds.decode = function (buf, offset) {
rds.decode.bytes = 0 rds.decode.bytes = 0
rds.encodingLength = function (digest) { rds.encodingLength = function (digest) {
return 6 + byteLength(digest.digest, 'hex') const digestdata = fromBuffer(digest.digest, 'hex')
return 6 + digestdata.length
} }
const rsshfp = exports.sshfp = {} const rsshfp = exports.sshfp = {}
@ -1488,7 +1491,8 @@ rtlsa.decode = function (buf, offset) {
rtlsa.decode.bytes = 0 rtlsa.decode.bytes = 0
rtlsa.encodingLength = function (cert) { rtlsa.encodingLength = function (cert) {
return 5 + byteLength(cert.certificate) const certdata = cert.certificate
return 5 + (isBuffer(certdata) ? certdata.length : byteLength(certdata))
} }
const svcparam = exports.svcparam = {} const svcparam = exports.svcparam = {}

33
test.js
View File

@ -400,17 +400,30 @@ tape('name_decoding', function (t) {
// A name can be only 253 characters (when connected with dots) // A name can be only 253 characters (when connected with dots)
const maxLength = new Uint8Array(255) const maxLength = new Uint8Array(255)
maxLength.fill(new Uint8Array([0x01, 0x61]), 0, 254) for (let i = 0; i < 127; i++) {
maxLength[i * 2] = 0x01
maxLength[i * 2 + 1] = 0x61
}
maxLength[254] = 0x00
t.ok(packet.name.decode(maxLength) === new Array(127).fill('a').join('.')) t.ok(packet.name.decode(maxLength) === new Array(127).fill('a').join('.'))
const tooLong = new Uint8Array(256) const tooLong = new Uint8Array(256)
tooLong.fill(new Uint8Array([0x01, 0x61])) for (let i = 0; i < 128; i++) {
tooLong[i * 2] = 0x01
tooLong[i * 2 + 1] = 0x61
}
t.throws(function () { packet.name.decode(tooLong) }, /Cannot decode name \(name too long\)$/) t.throws(function () { packet.name.decode(tooLong) }, /Cannot decode name \(name too long\)$/)
// Ensure jumps don't reset the total length counter // Ensure jumps don't reset the total length counter
const tooLongWithJump = new Uint8Array(403) const tooLongWithJump = new Uint8Array(403)
tooLongWithJump.fill(new Uint8Array([0x01, 0x61]), 0, 200) for (let i = 0; i < 100; i++) {
tooLongWithJump.fill(new Uint8Array([0x01, 0x61]), 201, 401) tooLongWithJump[i * 2] = 0x01
tooLongWithJump[i * 2 + 1] = 0x61
}
for (let i = 0; i < 100; i++) {
tooLongWithJump[201 + i * 2] = 0x01
tooLongWithJump[201 + i * 2 + 1] = 0x61
}
tooLongWithJump.set([0xc0, 0x00], 401) tooLongWithJump.set([0xc0, 0x00], 401)
t.throws(function () { packet.name.decode(tooLongWithJump, 201) }, /Cannot decode name \(name too long\)$/) t.throws(function () { packet.name.decode(tooLongWithJump, 201) }, /Cannot decode name \(name too long\)$/)
@ -420,7 +433,9 @@ tape('name_decoding', function (t) {
// Ensure deeply nested pointers don't cause "Maximum call stack size exceeded" errors // Ensure deeply nested pointers don't cause "Maximum call stack size exceeded" errors
const buf = new Uint8Array(16386) const buf = new Uint8Array(16386)
for (let i = 0; i < 16384; i += 2) { for (let i = 0; i < 16384; i += 2) {
buf.writeUInt16BE(0xc000 | i, i + 2) const value = 0xc000 | i
buf[i + 2] = (value >> 8) & 0xff
buf[i + 3] = value & 0xff
} }
t.ok(packet.name.decode(buf, 16384) === '.') t.ok(packet.name.decode(buf, 16384) === '.')
@ -590,9 +605,9 @@ tape('nsec', function (t) {
}) })
// Test with the sample NSEC from https://tools.ietf.org/html/rfc4034#section-4.3 // Test with the sample NSEC from https://tools.ietf.org/html/rfc4034#section-4.3
var sampleNSEC = new Uint8Array('003704686f7374076578616d706c6503636f6d00' + var sampleNSEC = unhexlify('003704686f7374076578616d706c6503636f6d00' +
'0006400100000003041b000000000000000000000000000000000000000000000' + '0006400100000003041b000000000000000000000000000000000000000000000' +
'000000020', 'hex') '000000020')
var decoded = packet.nsec.decode(sampleNSEC) var decoded = packet.nsec.decode(sampleNSEC)
t.ok(compare(t, decoded, { t.ok(compare(t, decoded, {
nextDomain: 'host.example.com', nextDomain: 'host.example.com',
@ -835,7 +850,7 @@ tape('https svcb', function (t) {
priority: 1, priority: 1,
name: 'foo.example.com', name: 'foo.example.com',
values: { values: {
key667: unhexlify('68 65 6c 6c 6f d2 71 6f 6f').toString('utf-8') key667: new TextDecoder('utf-8').decode(unhexlify('68 65 6c 6c 6f d2 71 6f 6f'))
} }
}, },
true // skipEncode, we cannot encode an unknown key true // skipEncode, we cannot encode an unknown key
@ -978,6 +993,7 @@ tape('cloudflare real world svcb/https', (t) => {
{ {
name: 'community.cloudflare.com', name: 'community.cloudflare.com',
type: 'HTTPS', type: 'HTTPS',
qu_bit: false,
class: 'IN' class: 'IN'
} }
], ],
@ -1080,6 +1096,7 @@ tape('google resolver SVCB real world', function (t) {
{ {
name: '_dns.resolver.arpa', name: '_dns.resolver.arpa',
type: 'SVCB', type: 'SVCB',
qu_bit: false,
class: 'IN' class: 'IN'
} }
], ],