@homebridge/ciao
Version:
ciao is a RFC 6763 compliant dns-sd library, advertising on multicast dns (RFC 6762) implemented in plain Typescript/JavaScript
122 lines • 5.02 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.OPTRecord = void 0;
const tslib_1 = require("tslib");
const assert_1 = tslib_1.__importDefault(require("assert"));
const fast_deep_equal_1 = tslib_1.__importDefault(require("fast-deep-equal"));
const ResourceRecord_1 = require("../ResourceRecord");
class OPTRecord extends ResourceRecord_1.ResourceRecord {
constructor(udpPayloadSize, options, extendedRCode, flags, ednsVersion, ttl) {
if (typeof udpPayloadSize === "number") {
super(".", 41 /* RType.OPT */, ttl, false, udpPayloadSize);
this.udpPayloadSize = udpPayloadSize;
}
else {
(0, assert_1.default)(udpPayloadSize.type === 41 /* RType.OPT */);
super(udpPayloadSize);
this.udpPayloadSize = udpPayloadSize.class;
}
this.extendedRCode = extendedRCode || 0;
this.ednsVersion = ednsVersion || OPTRecord.EDNS_VERSION;
this.flags = {
dnsSecOK: (flags === null || flags === void 0 ? void 0 : flags.dnsSecOK) || false,
zero: (flags === null || flags === void 0 ? void 0 : flags.zero) || 0,
...flags,
};
this.options = options || [];
}
getRDataEncodingLength() {
let length = 0;
for (const option of this.options) {
length += 2 + 2 + option.data.length; // 2 byte code; 2 byte length prefix; binary data
}
return length;
}
encodeRData(coder, buffer, offset) {
const oldOffset = offset;
const classOffset = offset - 8;
const ttlOffset = offset - 6;
// just to be sure
buffer.writeUInt16BE(this.udpPayloadSize, classOffset);
buffer.writeUInt8(this.extendedRCode, ttlOffset);
buffer.writeUInt8(this.ednsVersion, ttlOffset + 1);
let flags = this.flags.zero || 0;
if (this.flags.dnsSecOK) {
flags |= OPTRecord.DNS_SEC_OK_MASK;
}
buffer.writeUInt16BE(flags, ttlOffset + 2);
for (const option of this.options) {
buffer.writeUInt16BE(option.code, offset);
offset += 2;
buffer.writeUInt16BE(option.data.length, offset);
offset += 2;
option.data.copy(buffer, offset);
offset += option.data.length;
}
return offset - oldOffset; // written bytes
}
static decodeData(coder, header, buffer, offset) {
const oldOffset = offset;
const classOffset = offset - 8;
const ttlOffset = offset - 6;
const udpPayloadSize = buffer.readUInt16BE(classOffset);
const extendedRCode = buffer.readUInt8(ttlOffset);
const ednsVersion = buffer.readUInt8(ttlOffset + 1);
const flagsField = buffer.readUInt16BE(ttlOffset + 2);
const flags = {
dnsSecOK: !!(flagsField & OPTRecord.DNS_SEC_OK_MASK),
zero: flagsField & OPTRecord.NOT_DNS_SEC_OK_MASK,
};
const options = [];
while (offset < buffer.length) {
const code = buffer.readUInt16BE(offset);
offset += 2;
const length = buffer.readUInt16BE(offset);
offset += 2;
const data = buffer.subarray(offset, offset + length);
offset += length;
options.push({
code: code,
data: data,
});
}
header.class = udpPayloadSize;
header.ttl = 4500; // default
return {
data: new OPTRecord(header, options, extendedRCode, flags, ednsVersion),
readBytes: offset - oldOffset,
};
}
clone() {
return new OPTRecord(this.getRecordRepresentation(), this.options, this.extendedRCode, this.flags, this.ednsVersion);
}
dataAsString() {
return `${this.udpPayloadSize} ${this.extendedRCode} ${this.ednsVersion} ${JSON.stringify(this.flags)} [${this.options
.map(opt => `${opt.code} ${opt.data.toString("base64")}`).join(",")}]`;
}
dataEquals(record) {
return this.udpPayloadSize === record.udpPayloadSize && this.extendedRCode === record.extendedRCode
&& this.ednsVersion === record.ednsVersion
&& OPTRecord.optionsEquality(this.options, record.options) && (0, fast_deep_equal_1.default)(this.flags, record.flags);
}
static optionsEquality(a, b) {
// deepEquals on buffers doesn't really work
if (a.length !== b.length) {
return false;
}
for (let i = 0; i < a.length; i++) {
if (a[i].code !== b[i].code) {
return false;
}
else if (a[i].data.toString("hex") !== b[i].data.toString("hex")) {
return false;
}
}
return true;
}
}
exports.OPTRecord = OPTRecord;
OPTRecord.EDNS_VERSION = 0;
OPTRecord.DNS_SEC_OK_MASK = 0x8000; // 2 bytes, first bit set
OPTRecord.NOT_DNS_SEC_OK_MASK = 0x7FFF;
//# sourceMappingURL=OPTRecord.js.map