matterbridge 3.4.5-dev-20251224-1bb63cb → 3.4.5-dev-20251224-ea793b4
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/CHANGELOG.md +3 -1
- package/dist/dgram/mb_mdns.js +71 -82
- package/dist/dgram/mdns.js +11 -2
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -34,9 +34,11 @@ Advantages:
|
|
|
34
34
|
|
|
35
35
|
- [DevContainer]: Refactored Dev Container setup. The Matterbridge instance can now be paired on native Linux hosts or WSL 2 with Docker engine CLI integration. On Docker Desktop on Windows or macOS is not possible cause Docker Desktop runs inside a VM and not directly on the host so mDNS is not supported.
|
|
36
36
|
- [DevContainer]: Since is now possible to pair from Dev Container, named volumes have been added to persist storage and plugins across rebuilds.
|
|
37
|
-
- [mb_mdns]:
|
|
37
|
+
- [mb_mdns]: Added query and advertise interval. Improved help for easy mDNS testing.
|
|
38
38
|
- [mb_mdns]: Advertise full DNS-SD record set (PTR/SRV/TXT/A/AAAA) for matterbridge.\_http.\_tcp.local on port 8283.
|
|
39
39
|
- [mdns]: Added TXT/SRV/A/AAAA encoders into the Mdns class.
|
|
40
|
+
- [mb_mdns]: Added broadcast parameter to allow advertising when multicast is not available.
|
|
41
|
+
- [mb_mdns]: Added \_matterbridge.\_tcp.local to query and advertise.
|
|
40
42
|
|
|
41
43
|
### Changed
|
|
42
44
|
|
package/dist/dgram/mb_mdns.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { getIntParameter, getParameter, getStringArrayParameter, hasParameter } from '../utils/commandLine.js';
|
|
2
|
-
import { getIpv4InterfaceAddress, getIpv6InterfaceAddress } from '../utils/network.js';
|
|
3
2
|
import { MDNS_MULTICAST_IPV4_ADDRESS, MDNS_MULTICAST_IPV6_ADDRESS, MDNS_MULTICAST_PORT } from './multicast.js';
|
|
4
3
|
import { Mdns } from './mdns.js';
|
|
5
4
|
{
|
|
@@ -60,119 +59,109 @@ Examples:
|
|
|
60
59
|
mdnsIpv4.filters.push(...filters);
|
|
61
60
|
mdnsIpv6.filters.push(...filters);
|
|
62
61
|
}
|
|
63
|
-
function cleanupAndLogAndExit() {
|
|
62
|
+
async function cleanupAndLogAndExit() {
|
|
63
|
+
if (hasParameter('advertise')) {
|
|
64
|
+
advertise(mdnsIpv4, 0);
|
|
65
|
+
advertise(mdnsIpv6, 0);
|
|
66
|
+
}
|
|
67
|
+
await new Promise((resolve) => setTimeout(resolve, 250));
|
|
64
68
|
mdnsIpv4.stop();
|
|
65
69
|
mdnsIpv6.stop();
|
|
70
|
+
await new Promise((resolve) => setTimeout(resolve, 250));
|
|
66
71
|
mdnsIpv4.logDevices();
|
|
67
72
|
mdnsIpv6.logDevices();
|
|
68
73
|
process.exit(0);
|
|
69
74
|
}
|
|
70
|
-
const
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
{ name: '_matterc._udp.local', type: 12, class: 1, unicastResponse: false },
|
|
74
|
-
{ name: '_matter._tcp.local', type: 12, class: 1, unicastResponse: false },
|
|
75
|
-
{ name: '_shelly._tcp.local', type: 12, class: 1, unicastResponse: false },
|
|
76
|
-
{ name: '_http._tcp.local', type: 12, class: 1, unicastResponse: false },
|
|
77
|
-
{ name: '_services._dns-sd._udp.local', type: 12, class: 1, unicastResponse: false },
|
|
78
|
-
]);
|
|
79
|
-
};
|
|
80
|
-
const advertiseUdp4 = () => {
|
|
81
|
-
mdnsIpv4.log.info('Sending mDNS advertisement for matterbridge service...');
|
|
82
|
-
const serviceType = '_http._tcp.local';
|
|
83
|
-
const instanceName = 'matterbridge._http._tcp.local';
|
|
84
|
-
const hostName = 'matterbridge.local';
|
|
85
|
-
const port = 8283;
|
|
86
|
-
const ttl = 120;
|
|
87
|
-
const ptrInstanceRdata = mdnsIpv4.encodeDnsName(instanceName);
|
|
88
|
-
const ptrServiceTypeRdata = mdnsIpv4.encodeDnsName(serviceType);
|
|
89
|
-
const srvRdata = mdnsIpv4.encodeSrvRdata(0, 0, port, hostName);
|
|
90
|
-
const txtRdata = mdnsIpv4.encodeTxtRdata([`version=${pkg.version}`, 'path=/']);
|
|
91
|
-
const answers = [
|
|
92
|
-
{ name: '_services._dns-sd._udp.local', rtype: 12, rclass: 1, ttl, rdata: ptrServiceTypeRdata },
|
|
93
|
-
{ name: serviceType, rtype: 12, rclass: 1, ttl, rdata: ptrInstanceRdata },
|
|
94
|
-
{ name: instanceName, rtype: 33, rclass: 1 | 32768, ttl, rdata: srvRdata },
|
|
95
|
-
{ name: instanceName, rtype: 16, rclass: 1 | 32768, ttl, rdata: txtRdata },
|
|
96
|
-
];
|
|
97
|
-
try {
|
|
98
|
-
const ipv4 = getIpv4InterfaceAddress();
|
|
99
|
-
if (ipv4 && ipv4 !== '0.0.0.0') {
|
|
100
|
-
answers.push({ name: hostName, rtype: 1, rclass: 1 | 32768, ttl, rdata: mdnsIpv4.encodeA(ipv4) });
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
catch {
|
|
104
|
-
}
|
|
105
|
-
try {
|
|
106
|
-
const ipv6 = getIpv6InterfaceAddress();
|
|
107
|
-
if (ipv6 && ipv6 !== '::') {
|
|
108
|
-
answers.push({ name: hostName, rtype: 28, rclass: 1 | 32768, ttl, rdata: mdnsIpv4.encodeAAAA(ipv6) });
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
catch {
|
|
112
|
-
}
|
|
113
|
-
mdnsIpv4.sendResponse(answers);
|
|
114
|
-
};
|
|
115
|
-
const queryUdp6 = () => {
|
|
116
|
-
mdnsIpv6.log.info('Sending mDNS query for services...');
|
|
117
|
-
mdnsIpv6.sendQuery([
|
|
75
|
+
const query = (mdns) => {
|
|
76
|
+
mdns.log.info('Sending mDNS query for services...');
|
|
77
|
+
mdns.sendQuery([
|
|
118
78
|
{ name: '_matterc._udp.local', type: 12, class: 1, unicastResponse: true },
|
|
119
79
|
{ name: '_matter._tcp.local', type: 12, class: 1, unicastResponse: true },
|
|
80
|
+
{ name: '_matterbridge._tcp.local', type: 12, class: 1, unicastResponse: true },
|
|
120
81
|
{ name: '_shelly._tcp.local', type: 12, class: 1, unicastResponse: true },
|
|
121
82
|
{ name: '_http._tcp.local', type: 12, class: 1, unicastResponse: true },
|
|
122
83
|
{ name: '_services._dns-sd._udp.local', type: 12, class: 1, unicastResponse: true },
|
|
123
84
|
]);
|
|
124
85
|
};
|
|
125
|
-
const
|
|
126
|
-
|
|
127
|
-
const
|
|
128
|
-
const
|
|
86
|
+
const advertise = (mdns, ttl = 120) => {
|
|
87
|
+
mdns.log.info(`Sending mDNS advertisement for matterbridge service with TTL ${ttl ? ttl.toString() : 'goodbye'}...`);
|
|
88
|
+
const httpServiceType = '_http._tcp.local';
|
|
89
|
+
const matterbridgeServiceType = '_matterbridge._tcp.local';
|
|
90
|
+
const httpInstanceName = 'matterbridge._http._tcp.local';
|
|
91
|
+
const matterbridgeInstanceName = 'matterbridge._matterbridge._tcp.local';
|
|
129
92
|
const hostName = 'matterbridge.local';
|
|
130
93
|
const port = 8283;
|
|
131
|
-
const
|
|
132
|
-
const
|
|
133
|
-
const
|
|
134
|
-
const
|
|
135
|
-
const
|
|
94
|
+
const ptrHttpServiceTypeRdata = mdns.encodeDnsName(httpServiceType);
|
|
95
|
+
const ptrMatterbridgeServiceTypeRdata = mdns.encodeDnsName(matterbridgeServiceType);
|
|
96
|
+
const ptrHttpInstanceRdata = mdns.encodeDnsName(httpInstanceName);
|
|
97
|
+
const ptrMatterbridgeInstanceRdata = mdns.encodeDnsName(matterbridgeInstanceName);
|
|
98
|
+
const srvRdata = mdns.encodeSrvRdata(0, 0, port, hostName);
|
|
99
|
+
const txtRdata = mdns.encodeTxtRdata([`version=${pkg.version}`, 'path=/']);
|
|
136
100
|
const answers = [
|
|
137
|
-
{ name: '_services._dns-sd._udp.local', rtype: 12, rclass: 1, ttl, rdata:
|
|
138
|
-
{ name:
|
|
139
|
-
{ name:
|
|
140
|
-
{ name:
|
|
101
|
+
{ name: '_services._dns-sd._udp.local', rtype: 12, rclass: 1, ttl, rdata: ptrHttpServiceTypeRdata },
|
|
102
|
+
{ name: httpServiceType, rtype: 12, rclass: 1, ttl, rdata: ptrHttpInstanceRdata },
|
|
103
|
+
{ name: '_services._dns-sd._udp.local', rtype: 12, rclass: 1, ttl, rdata: ptrMatterbridgeServiceTypeRdata },
|
|
104
|
+
{ name: matterbridgeServiceType, rtype: 12, rclass: 1, ttl, rdata: ptrMatterbridgeInstanceRdata },
|
|
105
|
+
{ name: httpInstanceName, rtype: 33, rclass: 1 | 32768, ttl, rdata: srvRdata },
|
|
106
|
+
{ name: matterbridgeInstanceName, rtype: 33, rclass: 1 | 32768, ttl, rdata: srvRdata },
|
|
107
|
+
{ name: httpInstanceName, rtype: 16, rclass: 1 | 32768, ttl, rdata: txtRdata },
|
|
108
|
+
{ name: matterbridgeInstanceName, rtype: 16, rclass: 1 | 32768, ttl, rdata: txtRdata },
|
|
141
109
|
];
|
|
142
110
|
try {
|
|
143
|
-
const ipv4 = getIpv4InterfaceAddress();
|
|
111
|
+
const ipv4 = mdns.getIpv4InterfaceAddress(mdns.interfaceName);
|
|
144
112
|
if (ipv4) {
|
|
145
|
-
answers.push({ name: hostName, rtype: 1, rclass: 1 | 32768, ttl, rdata:
|
|
113
|
+
answers.push({ name: hostName, rtype: 1, rclass: 1 | 32768, ttl, rdata: mdns.encodeA(ipv4) });
|
|
146
114
|
}
|
|
147
115
|
}
|
|
148
|
-
catch {
|
|
116
|
+
catch (error) {
|
|
117
|
+
mdns.log.warn(`Error sending mDNS advertisement for matterbridge service A record: ${error.message}`);
|
|
149
118
|
}
|
|
150
119
|
try {
|
|
151
|
-
const ipv6 = getIpv6InterfaceAddress();
|
|
120
|
+
const ipv6 = mdns.getIpv6InterfaceAddress(mdns.interfaceName);
|
|
152
121
|
if (ipv6) {
|
|
153
|
-
answers.push({ name: hostName, rtype: 28, rclass: 1 | 32768, ttl, rdata:
|
|
122
|
+
answers.push({ name: hostName, rtype: 28, rclass: 1 | 32768, ttl, rdata: mdns.encodeAAAA(ipv6) });
|
|
154
123
|
}
|
|
155
124
|
}
|
|
156
|
-
catch {
|
|
125
|
+
catch (error) {
|
|
126
|
+
mdns.log.warn(`Error sending mDNS advertisement for matterbridge service AAAA record: ${error.message}`);
|
|
127
|
+
}
|
|
128
|
+
const response = mdns.sendResponse(answers);
|
|
129
|
+
if (hasParameter('broadcast')) {
|
|
130
|
+
try {
|
|
131
|
+
const address = mdns.socketType === 'udp4' ? mdns.getIpv4InterfaceAddress(mdns.interfaceName) : mdns.getIpv6InterfaceAddress(mdns.interfaceName);
|
|
132
|
+
const mask = mdns.socketType === 'udp4' ? mdns.getNetmask(address) : undefined;
|
|
133
|
+
const broadcastAddress = mdns.socketType === 'udp4' ? mdns.getIpv4BroadcastAddress(address, mask) : mdns.getIpv6BroadcastAddress();
|
|
134
|
+
mdns.log.info(`Broadcasting mDNS advertisement for matterbridge service to ${broadcastAddress}...`);
|
|
135
|
+
mdns.socket.send(response, 0, response.length, mdns.multicastPort, broadcastAddress, (error) => {
|
|
136
|
+
if (error) {
|
|
137
|
+
mdns.log.error(`Error broadcasting mDNS advertisement: ${error.message}`);
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
mdns.log.info(`mDNS advertisement broadcasted successfully to ${broadcastAddress}`);
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
catch (error) {
|
|
145
|
+
mdns.log.error(`Error broadcasting mDNS advertisement: ${error.message}`);
|
|
146
|
+
}
|
|
157
147
|
}
|
|
158
|
-
mdnsIpv6.sendResponse(answers);
|
|
159
148
|
};
|
|
160
|
-
process.on('SIGINT', () => {
|
|
161
|
-
cleanupAndLogAndExit();
|
|
149
|
+
process.on('SIGINT', async () => {
|
|
150
|
+
await cleanupAndLogAndExit();
|
|
162
151
|
});
|
|
163
152
|
mdnsIpv4.start();
|
|
164
153
|
mdnsIpv4.on('ready', (address) => {
|
|
165
154
|
mdnsIpv4.log.info(`mdnsIpv4 server ready on ${address.family} ${address.address}:${address.port}`);
|
|
166
155
|
if (hasParameter('advertise')) {
|
|
167
|
-
|
|
156
|
+
advertise(mdnsIpv4);
|
|
168
157
|
setInterval(() => {
|
|
169
|
-
|
|
158
|
+
advertise(mdnsIpv4);
|
|
170
159
|
}, getIntParameter('advertise') || 10000).unref();
|
|
171
160
|
}
|
|
172
161
|
if (hasParameter('query')) {
|
|
173
|
-
|
|
162
|
+
query(mdnsIpv4);
|
|
174
163
|
setInterval(() => {
|
|
175
|
-
|
|
164
|
+
query(mdnsIpv4);
|
|
176
165
|
}, getIntParameter('query') || 10000).unref();
|
|
177
166
|
}
|
|
178
167
|
});
|
|
@@ -180,19 +169,19 @@ Examples:
|
|
|
180
169
|
mdnsIpv6.on('ready', (address) => {
|
|
181
170
|
mdnsIpv6.log.info(`mdnsIpv6 server ready on ${address.family} ${address.address}:${address.port}`);
|
|
182
171
|
if (hasParameter('advertise')) {
|
|
183
|
-
|
|
172
|
+
advertise(mdnsIpv6);
|
|
184
173
|
setInterval(() => {
|
|
185
|
-
|
|
174
|
+
advertise(mdnsIpv6);
|
|
186
175
|
}, getIntParameter('advertise') || 10000).unref();
|
|
187
176
|
}
|
|
188
177
|
if (hasParameter('query')) {
|
|
189
|
-
|
|
178
|
+
query(mdnsIpv6);
|
|
190
179
|
setInterval(() => {
|
|
191
|
-
|
|
180
|
+
query(mdnsIpv6);
|
|
192
181
|
}, getIntParameter('query') || 10000).unref();
|
|
193
182
|
}
|
|
194
183
|
});
|
|
195
|
-
setTimeout(() => {
|
|
196
|
-
cleanupAndLogAndExit();
|
|
184
|
+
setTimeout(async () => {
|
|
185
|
+
await cleanupAndLogAndExit();
|
|
197
186
|
}, 600000);
|
|
198
187
|
}
|
package/dist/dgram/mdns.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { BLUE, CYAN, db, er, GREEN, idn, MAGENTA, nf, rs } from 'node-ansi-logger';
|
|
2
|
+
import { hasParameter } from '../utils/commandLine.js';
|
|
2
3
|
import { Multicast } from './multicast.js';
|
|
3
4
|
export var DnsRecordType;
|
|
4
5
|
(function (DnsRecordType) {
|
|
@@ -433,8 +434,10 @@ export class Mdns extends Multicast {
|
|
|
433
434
|
return Buffer.concat([qname, qfields]);
|
|
434
435
|
});
|
|
435
436
|
const query = Buffer.concat([header, ...questionBuffers]);
|
|
436
|
-
|
|
437
|
-
|
|
437
|
+
if (hasParameter('v') || hasParameter('verbose')) {
|
|
438
|
+
const decoded = this.decodeMdnsMessage(query);
|
|
439
|
+
this.logMdnsMessage(decoded);
|
|
440
|
+
}
|
|
438
441
|
this.socket.send(query, 0, query.length, this.multicastPort, this.multicastAddress, (error) => {
|
|
439
442
|
if (error) {
|
|
440
443
|
this.log.error(`Dgram mDNS server failed to send query message: ${error.message}`);
|
|
@@ -448,6 +451,7 @@ export class Mdns extends Multicast {
|
|
|
448
451
|
this.emit('sent', query, this.multicastAddress, this.multicastPort);
|
|
449
452
|
}
|
|
450
453
|
});
|
|
454
|
+
return query;
|
|
451
455
|
}
|
|
452
456
|
sendResponse(answers) {
|
|
453
457
|
if (!Array.isArray(answers) || answers.length === 0) {
|
|
@@ -470,6 +474,10 @@ export class Mdns extends Multicast {
|
|
|
470
474
|
return Buffer.concat([aname, answerFixed, rdata]);
|
|
471
475
|
});
|
|
472
476
|
const response = Buffer.concat([header, ...answerBuffers]);
|
|
477
|
+
if (hasParameter('v') || hasParameter('verbose')) {
|
|
478
|
+
const decoded = this.decodeMdnsMessage(response);
|
|
479
|
+
this.logMdnsMessage(decoded);
|
|
480
|
+
}
|
|
473
481
|
this.socket.send(response, 0, response.length, this.multicastPort, this.multicastAddress, (error) => {
|
|
474
482
|
if (error) {
|
|
475
483
|
const items = answers.map((a) => `- name ${MAGENTA}${a.name}${er} type ${MAGENTA}${this.dnsTypeToString(a.rtype)}${er} class ${MAGENTA}${this.dnsResponseClassToString(a.rclass)}${er} ttl ${MAGENTA}${a.ttl}${er}`).join('\n');
|
|
@@ -482,6 +490,7 @@ export class Mdns extends Multicast {
|
|
|
482
490
|
this.emit('sent', response, this.multicastAddress, this.multicastPort);
|
|
483
491
|
}
|
|
484
492
|
});
|
|
493
|
+
return response;
|
|
485
494
|
}
|
|
486
495
|
dnsTypeToString(type) {
|
|
487
496
|
const typeMap = {
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "matterbridge",
|
|
3
|
-
"version": "3.4.5-dev-20251224-
|
|
3
|
+
"version": "3.4.5-dev-20251224-ea793b4",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "matterbridge",
|
|
9
|
-
"version": "3.4.5-dev-20251224-
|
|
9
|
+
"version": "3.4.5-dev-20251224-ea793b4",
|
|
10
10
|
"license": "Apache-2.0",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"@matter/main": "0.15.6",
|
package/package.json
CHANGED