@matterbridge/dgram 3.10.12-dev-20260925-36fa6cb → 3.10.12-dev-20260928-9345dd7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/mdns.d.ts +61 -3
- package/dist/mdns.js +89 -34
- package/package.json +2 -2
package/dist/mdns.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type dgram from 'node:dgram';
|
|
2
2
|
import { type AnsiLogger } from 'node-ansi-logger';
|
|
3
3
|
import { Multicast } from './multicast.js';
|
|
4
|
+
export declare const MDNS_MAX_MESSAGE_LENGTH: number;
|
|
5
|
+
export declare const MDNS_MAX_RESOURCE_RECORD_LENGTH: number;
|
|
4
6
|
export declare enum DnsRecordType {
|
|
5
7
|
A = 1,
|
|
6
8
|
NS = 2,
|
|
@@ -103,6 +105,18 @@ export declare enum DnsClassFlag {
|
|
|
103
105
|
FLUSH = 32768,
|
|
104
106
|
QU = 32768
|
|
105
107
|
}
|
|
108
|
+
export declare enum DnsHeaderFlag {
|
|
109
|
+
QR = 32768,
|
|
110
|
+
OPCODE = 30720,
|
|
111
|
+
AA = 1024,
|
|
112
|
+
TC = 512,
|
|
113
|
+
RD = 256,
|
|
114
|
+
RA = 128,
|
|
115
|
+
Z = 64,
|
|
116
|
+
AD = 32,
|
|
117
|
+
CD = 16,
|
|
118
|
+
RCODE = 15
|
|
119
|
+
}
|
|
106
120
|
export interface MdnsMessage {
|
|
107
121
|
id: number;
|
|
108
122
|
qr: number;
|
|
@@ -124,8 +138,8 @@ export interface MdnsMessage {
|
|
|
124
138
|
}
|
|
125
139
|
interface DnsQuestion {
|
|
126
140
|
name: string;
|
|
127
|
-
type:
|
|
128
|
-
class:
|
|
141
|
+
type: DnsRecordType;
|
|
142
|
+
class: DnsClass;
|
|
129
143
|
}
|
|
130
144
|
interface MdnsRecord {
|
|
131
145
|
name: string;
|
|
@@ -158,11 +172,19 @@ export declare class Mdns extends Multicast {
|
|
|
158
172
|
name: string;
|
|
159
173
|
newOffset: number;
|
|
160
174
|
};
|
|
161
|
-
encodeDnsName(name: string): Buffer;
|
|
175
|
+
encodeDnsName(name: string, compression?: Map<string, number>, offset?: number): Buffer;
|
|
162
176
|
encodeTxtRdata(txt: string[]): Buffer;
|
|
163
177
|
encodeSrvRdata(priority: number, weight: number, port: number, target: string): Buffer;
|
|
164
178
|
encodeA(ipv4: string): Buffer;
|
|
165
179
|
encodeAAAA(ipv6WithOptionalScope: string): Buffer;
|
|
180
|
+
encodeResourceRecord({ name, rtype, rclass, flush, ttl, rdata }: {
|
|
181
|
+
name: string;
|
|
182
|
+
rtype: number;
|
|
183
|
+
rclass: number;
|
|
184
|
+
flush?: boolean;
|
|
185
|
+
ttl: number;
|
|
186
|
+
rdata: Buffer;
|
|
187
|
+
}, compression?: Map<string, number>, offset?: number): Buffer;
|
|
166
188
|
decodeResourceRecord(msg: Buffer, offset: number): {
|
|
167
189
|
record: MdnsRecord;
|
|
168
190
|
newOffset: number;
|
|
@@ -172,11 +194,47 @@ export declare class Mdns extends Multicast {
|
|
|
172
194
|
type: number;
|
|
173
195
|
class: number;
|
|
174
196
|
unicastResponse?: boolean;
|
|
197
|
+
}[], answers?: {
|
|
198
|
+
name: string;
|
|
199
|
+
rtype: number;
|
|
200
|
+
rclass: number;
|
|
201
|
+
flush?: boolean;
|
|
202
|
+
ttl: number;
|
|
203
|
+
rdata: Buffer;
|
|
204
|
+
}[], authorities?: {
|
|
205
|
+
name: string;
|
|
206
|
+
rtype: number;
|
|
207
|
+
rclass: number;
|
|
208
|
+
flush?: boolean;
|
|
209
|
+
ttl: number;
|
|
210
|
+
rdata: Buffer;
|
|
211
|
+
}[], additionals?: {
|
|
212
|
+
name: string;
|
|
213
|
+
rtype: number;
|
|
214
|
+
rclass: number;
|
|
215
|
+
flush?: boolean;
|
|
216
|
+
ttl: number;
|
|
217
|
+
rdata: Buffer;
|
|
175
218
|
}[]): Buffer<ArrayBuffer>;
|
|
176
219
|
sendResponse(answers: {
|
|
177
220
|
name: string;
|
|
178
221
|
rtype: number;
|
|
179
222
|
rclass: number;
|
|
223
|
+
flush?: boolean;
|
|
224
|
+
ttl: number;
|
|
225
|
+
rdata: Buffer;
|
|
226
|
+
}[], authorities?: {
|
|
227
|
+
name: string;
|
|
228
|
+
rtype: number;
|
|
229
|
+
rclass: number;
|
|
230
|
+
flush?: boolean;
|
|
231
|
+
ttl: number;
|
|
232
|
+
rdata: Buffer;
|
|
233
|
+
}[], additionals?: {
|
|
234
|
+
name: string;
|
|
235
|
+
rtype: number;
|
|
236
|
+
rclass: number;
|
|
237
|
+
flush?: boolean;
|
|
180
238
|
ttl: number;
|
|
181
239
|
rdata: Buffer;
|
|
182
240
|
}[]): Buffer<ArrayBuffer>;
|
package/dist/mdns.js
CHANGED
|
@@ -2,6 +2,8 @@ import { hasParameter } from '@matterbridge/utils/cli';
|
|
|
2
2
|
import { getErrorMessage } from '@matterbridge/utils/error';
|
|
3
3
|
import { BLUE, CYAN, db, GREEN, idn, MAGENTA, nf, rs } from 'node-ansi-logger';
|
|
4
4
|
import { Multicast } from './multicast.js';
|
|
5
|
+
export const MDNS_MAX_MESSAGE_LENGTH = 1500 - 40 - 8;
|
|
6
|
+
export const MDNS_MAX_RESOURCE_RECORD_LENGTH = MDNS_MAX_MESSAGE_LENGTH - 12;
|
|
5
7
|
export var DnsRecordType;
|
|
6
8
|
(function (DnsRecordType) {
|
|
7
9
|
DnsRecordType[DnsRecordType["A"] = 1] = "A";
|
|
@@ -107,6 +109,19 @@ export var DnsClassFlag;
|
|
|
107
109
|
DnsClassFlag[DnsClassFlag["FLUSH"] = 32768] = "FLUSH";
|
|
108
110
|
DnsClassFlag[DnsClassFlag["QU"] = 32768] = "QU";
|
|
109
111
|
})(DnsClassFlag || (DnsClassFlag = {}));
|
|
112
|
+
export var DnsHeaderFlag;
|
|
113
|
+
(function (DnsHeaderFlag) {
|
|
114
|
+
DnsHeaderFlag[DnsHeaderFlag["QR"] = 32768] = "QR";
|
|
115
|
+
DnsHeaderFlag[DnsHeaderFlag["OPCODE"] = 30720] = "OPCODE";
|
|
116
|
+
DnsHeaderFlag[DnsHeaderFlag["AA"] = 1024] = "AA";
|
|
117
|
+
DnsHeaderFlag[DnsHeaderFlag["TC"] = 512] = "TC";
|
|
118
|
+
DnsHeaderFlag[DnsHeaderFlag["RD"] = 256] = "RD";
|
|
119
|
+
DnsHeaderFlag[DnsHeaderFlag["RA"] = 128] = "RA";
|
|
120
|
+
DnsHeaderFlag[DnsHeaderFlag["Z"] = 64] = "Z";
|
|
121
|
+
DnsHeaderFlag[DnsHeaderFlag["AD"] = 32] = "AD";
|
|
122
|
+
DnsHeaderFlag[DnsHeaderFlag["CD"] = 16] = "CD";
|
|
123
|
+
DnsHeaderFlag[DnsHeaderFlag["RCODE"] = 15] = "RCODE";
|
|
124
|
+
})(DnsHeaderFlag || (DnsHeaderFlag = {}));
|
|
110
125
|
export function isMdns(message) {
|
|
111
126
|
if (!message || message.length < 12)
|
|
112
127
|
return false;
|
|
@@ -118,7 +133,7 @@ export function isMdnsQuery(message) {
|
|
|
118
133
|
return false;
|
|
119
134
|
const id = message.readUInt16BE(0);
|
|
120
135
|
const flags = message.readUInt16BE(2);
|
|
121
|
-
const qr = (flags &
|
|
136
|
+
const qr = (flags & DnsHeaderFlag.QR) >> 15;
|
|
122
137
|
return id == 0 && qr === 0;
|
|
123
138
|
}
|
|
124
139
|
export function isMdnsResponse(message) {
|
|
@@ -126,7 +141,7 @@ export function isMdnsResponse(message) {
|
|
|
126
141
|
return false;
|
|
127
142
|
const id = message.readUInt16BE(0);
|
|
128
143
|
const flags = message.readUInt16BE(2);
|
|
129
|
-
const qr = (flags &
|
|
144
|
+
const qr = (flags & DnsHeaderFlag.QR) >> 15;
|
|
130
145
|
return id == 0 && qr === 1;
|
|
131
146
|
}
|
|
132
147
|
export class Mdns extends Multicast {
|
|
@@ -196,14 +211,14 @@ export class Mdns extends Multicast {
|
|
|
196
211
|
}
|
|
197
212
|
const id = msg.readUInt16BE(0);
|
|
198
213
|
const flags = msg.readUInt16BE(2);
|
|
199
|
-
const qr = (flags &
|
|
200
|
-
const opcode = (flags &
|
|
201
|
-
const aa = Boolean(flags &
|
|
202
|
-
const tc = Boolean(flags &
|
|
203
|
-
const rd = Boolean(flags &
|
|
204
|
-
const ra = Boolean(flags &
|
|
205
|
-
const z = (flags &
|
|
206
|
-
const rcode = flags &
|
|
214
|
+
const qr = (flags & DnsHeaderFlag.QR) >> 15;
|
|
215
|
+
const opcode = (flags & DnsHeaderFlag.OPCODE) >> 11;
|
|
216
|
+
const aa = Boolean(flags & DnsHeaderFlag.AA);
|
|
217
|
+
const tc = Boolean(flags & DnsHeaderFlag.TC);
|
|
218
|
+
const rd = Boolean(flags & DnsHeaderFlag.RD);
|
|
219
|
+
const ra = Boolean(flags & DnsHeaderFlag.RA);
|
|
220
|
+
const z = (flags & (DnsHeaderFlag.Z | DnsHeaderFlag.AD | DnsHeaderFlag.CD)) >> 4;
|
|
221
|
+
const rcode = flags & DnsHeaderFlag.RCODE;
|
|
207
222
|
const qdCount = msg.readUInt16BE(4);
|
|
208
223
|
const anCount = msg.readUInt16BE(6);
|
|
209
224
|
const nsCount = msg.readUInt16BE(8);
|
|
@@ -293,13 +308,25 @@ export class Mdns extends Multicast {
|
|
|
293
308
|
}
|
|
294
309
|
return { name: labels.join('.'), newOffset: jumped ? originalOffset : offset };
|
|
295
310
|
}
|
|
296
|
-
encodeDnsName(name) {
|
|
311
|
+
encodeDnsName(name, compression, offset = 0) {
|
|
297
312
|
const labels = name.split('.');
|
|
298
|
-
const buffers =
|
|
313
|
+
const buffers = [];
|
|
314
|
+
let length = 0;
|
|
315
|
+
for (const [index, label] of labels.entries()) {
|
|
316
|
+
if (compression && label !== '') {
|
|
317
|
+
const suffix = labels.slice(index).join('.');
|
|
318
|
+
const pointer = compression.get(suffix);
|
|
319
|
+
if (pointer !== undefined)
|
|
320
|
+
return Buffer.concat([...buffers, Buffer.from([0xc0 | (pointer >> 8), pointer & 0xff])]);
|
|
321
|
+
if (offset + length < 0x4000)
|
|
322
|
+
compression.set(suffix, offset + length);
|
|
323
|
+
}
|
|
324
|
+
const labelBuf = Buffer.from(label, 'utf8');
|
|
299
325
|
const lenBuf = Buffer.alloc(1);
|
|
300
|
-
lenBuf.writeUInt8(
|
|
301
|
-
|
|
302
|
-
|
|
326
|
+
lenBuf.writeUInt8(labelBuf.length, 0);
|
|
327
|
+
buffers.push(lenBuf, labelBuf);
|
|
328
|
+
length += 1 + labelBuf.length;
|
|
329
|
+
}
|
|
303
330
|
return Buffer.concat([...buffers, Buffer.from([0])]);
|
|
304
331
|
}
|
|
305
332
|
encodeTxtRdata(txt) {
|
|
@@ -355,6 +382,28 @@ export class Mdns extends Multicast {
|
|
|
355
382
|
return [(word >> 8) & 0xff, word & 0xff];
|
|
356
383
|
}));
|
|
357
384
|
}
|
|
385
|
+
encodeResourceRecord({ name, rtype, rclass, flush = false, ttl, rdata }, compression, offset = 0) {
|
|
386
|
+
const rname = this.encodeDnsName(name, compression, offset);
|
|
387
|
+
const nameStart = rtype === DnsRecordType.PTR ? 0 : rtype === DnsRecordType.SRV ? 6 : -1;
|
|
388
|
+
if (compression && nameStart >= 0) {
|
|
389
|
+
let rdataName;
|
|
390
|
+
try {
|
|
391
|
+
rdataName = this.decodeDnsName(rdata, nameStart).name;
|
|
392
|
+
}
|
|
393
|
+
catch {
|
|
394
|
+
rdataName = undefined;
|
|
395
|
+
}
|
|
396
|
+
if (rdataName !== undefined && this.encodeDnsName(rdataName).equals(rdata.subarray(nameStart))) {
|
|
397
|
+
rdata = Buffer.concat([rdata.subarray(0, nameStart), this.encodeDnsName(rdataName, compression, offset + rname.length + 10 + nameStart)]);
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
const recordFixed = Buffer.alloc(10);
|
|
401
|
+
recordFixed.writeUInt16BE(rtype, 0);
|
|
402
|
+
recordFixed.writeUInt16BE(flush ? rclass | DnsClassFlag.FLUSH : rclass, 2);
|
|
403
|
+
recordFixed.writeUInt32BE(ttl, 4);
|
|
404
|
+
recordFixed.writeUInt16BE(rdata.length, 8);
|
|
405
|
+
return Buffer.concat([rname, recordFixed, rdata]);
|
|
406
|
+
}
|
|
358
407
|
decodeResourceRecord(msg, offset) {
|
|
359
408
|
const nameResult = this.decodeDnsName(msg, offset);
|
|
360
409
|
const name = nameResult.name;
|
|
@@ -451,22 +500,30 @@ export class Mdns extends Multicast {
|
|
|
451
500
|
newOffset: offset,
|
|
452
501
|
};
|
|
453
502
|
}
|
|
454
|
-
sendQuery(questions) {
|
|
503
|
+
sendQuery(questions, answers = [], authorities = [], additionals = []) {
|
|
455
504
|
const header = Buffer.alloc(12);
|
|
456
505
|
header.writeUInt16BE(0, 0);
|
|
457
506
|
header.writeUInt16BE(0, 2);
|
|
458
507
|
header.writeUInt16BE(questions.length, 4);
|
|
459
|
-
header.writeUInt16BE(
|
|
460
|
-
header.writeUInt16BE(
|
|
461
|
-
header.writeUInt16BE(
|
|
508
|
+
header.writeUInt16BE(answers.length, 6);
|
|
509
|
+
header.writeUInt16BE(authorities.length, 8);
|
|
510
|
+
header.writeUInt16BE(additionals.length, 10);
|
|
511
|
+
const compression = new Map();
|
|
512
|
+
let offset = 12;
|
|
462
513
|
const questionBuffers = questions.map(({ name, type: qtype, class: qclass, unicastResponse = false }) => {
|
|
463
|
-
const qname = this.encodeDnsName(name);
|
|
514
|
+
const qname = this.encodeDnsName(name, compression, offset);
|
|
464
515
|
const qfields = Buffer.alloc(4);
|
|
465
516
|
qfields.writeUInt16BE(qtype, 0);
|
|
466
517
|
qfields.writeUInt16BE(unicastResponse ? qclass | DnsClassFlag.QU : qclass, 2);
|
|
518
|
+
offset += qname.length + 4;
|
|
467
519
|
return Buffer.concat([qname, qfields]);
|
|
468
520
|
});
|
|
469
|
-
const
|
|
521
|
+
const recordBuffers = [...answers, ...authorities, ...additionals].map((record) => {
|
|
522
|
+
const recordBuffer = this.encodeResourceRecord(record, compression, offset);
|
|
523
|
+
offset += recordBuffer.length;
|
|
524
|
+
return recordBuffer;
|
|
525
|
+
});
|
|
526
|
+
const query = Buffer.concat([header, ...questionBuffers, ...recordBuffers]);
|
|
470
527
|
if (hasParameter('v') || hasParameter('verbose')) {
|
|
471
528
|
const decoded = this.decodeMdnsMessage(query);
|
|
472
529
|
this.logMdnsMessage(decoded, undefined, `Sending query mDNS message (${query.length} bytes)`);
|
|
@@ -483,27 +540,25 @@ export class Mdns extends Multicast {
|
|
|
483
540
|
});
|
|
484
541
|
return query;
|
|
485
542
|
}
|
|
486
|
-
sendResponse(answers) {
|
|
543
|
+
sendResponse(answers, authorities = [], additionals = []) {
|
|
487
544
|
if (!Array.isArray(answers) || answers.length === 0) {
|
|
488
545
|
throw new Error('sendResponse requires a non-empty answers array');
|
|
489
546
|
}
|
|
490
547
|
const header = Buffer.alloc(12);
|
|
491
548
|
header.writeUInt16BE(0, 0);
|
|
492
|
-
header.writeUInt16BE(
|
|
549
|
+
header.writeUInt16BE(DnsHeaderFlag.QR | DnsHeaderFlag.AA, 2);
|
|
493
550
|
header.writeUInt16BE(0, 4);
|
|
494
551
|
header.writeUInt16BE(answers.length, 6);
|
|
495
|
-
header.writeUInt16BE(
|
|
496
|
-
header.writeUInt16BE(
|
|
497
|
-
const
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
answerFixed.writeUInt16BE(rdata.length, 8);
|
|
504
|
-
return Buffer.concat([aname, answerFixed, rdata]);
|
|
552
|
+
header.writeUInt16BE(authorities.length, 8);
|
|
553
|
+
header.writeUInt16BE(additionals.length, 10);
|
|
554
|
+
const compression = new Map();
|
|
555
|
+
let offset = 12;
|
|
556
|
+
const recordBuffers = [...answers, ...authorities, ...additionals].map((record) => {
|
|
557
|
+
const recordBuffer = this.encodeResourceRecord(record, compression, offset);
|
|
558
|
+
offset += recordBuffer.length;
|
|
559
|
+
return recordBuffer;
|
|
505
560
|
});
|
|
506
|
-
const response = Buffer.concat([header, ...
|
|
561
|
+
const response = Buffer.concat([header, ...recordBuffers]);
|
|
507
562
|
if (hasParameter('v') || hasParameter('verbose')) {
|
|
508
563
|
const decoded = this.decodeMdnsMessage(response);
|
|
509
564
|
this.logMdnsMessage(decoded, undefined, `Sending response mDNS message (${response.length} bytes)`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@matterbridge/dgram",
|
|
3
|
-
"version": "3.10.12-dev-
|
|
3
|
+
"version": "3.10.12-dev-20260928-9345dd7",
|
|
4
4
|
"description": "Matterbridge dgram library",
|
|
5
5
|
"author": "https://github.com/Luligu",
|
|
6
6
|
"homepage": "https://matterbridge.io/",
|
|
@@ -67,7 +67,7 @@
|
|
|
67
67
|
"skipTsconfig": true
|
|
68
68
|
},
|
|
69
69
|
"dependencies": {
|
|
70
|
-
"@matterbridge/utils": "3.10.12-dev-
|
|
70
|
+
"@matterbridge/utils": "3.10.12-dev-20260928-9345dd7",
|
|
71
71
|
"node-ansi-logger": "3.3.1"
|
|
72
72
|
}
|
|
73
73
|
}
|