matterbridge 3.4.5 → 3.4.6-dev-20251228-76bd627

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.
Files changed (335) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/broadcastServer.js +0 -117
  3. package/dist/broadcastServerTypes.js +0 -24
  4. package/dist/cli.js +1 -97
  5. package/dist/cliEmitter.js +0 -37
  6. package/dist/cliHistory.js +0 -38
  7. package/dist/clusters/export.js +0 -2
  8. package/dist/deviceManager.js +1 -113
  9. package/dist/devices/airConditioner.js +0 -57
  10. package/dist/devices/batteryStorage.js +1 -48
  11. package/dist/devices/cooktop.js +0 -56
  12. package/dist/devices/dishwasher.js +0 -57
  13. package/dist/devices/evse.js +10 -74
  14. package/dist/devices/export.js +0 -5
  15. package/dist/devices/extractorHood.js +0 -43
  16. package/dist/devices/heatPump.js +2 -50
  17. package/dist/devices/laundryDryer.js +3 -62
  18. package/dist/devices/laundryWasher.js +4 -70
  19. package/dist/devices/microwaveOven.js +5 -88
  20. package/dist/devices/oven.js +0 -85
  21. package/dist/devices/refrigerator.js +0 -102
  22. package/dist/devices/roboticVacuumCleaner.js +9 -100
  23. package/dist/devices/solarPower.js +0 -38
  24. package/dist/devices/speaker.js +0 -84
  25. package/dist/devices/temperatureControl.js +3 -24
  26. package/dist/devices/waterHeater.js +2 -82
  27. package/dist/dgram/coap.js +13 -126
  28. package/dist/dgram/dgram.js +2 -114
  29. package/dist/dgram/mb_coap.js +3 -41
  30. package/dist/dgram/mb_mdns.js +25 -77
  31. package/dist/dgram/mdns.js +172 -366
  32. package/dist/dgram/mdnsReflectorClient.js +79 -39
  33. package/dist/dgram/mdnsReflectorServer.js +41 -56
  34. package/dist/dgram/mdnsReflectorTypes.js +1 -24
  35. package/dist/dgram/multicast.js +1 -62
  36. package/dist/dgram/unicast.js +0 -60
  37. package/dist/frontend.js +38 -485
  38. package/dist/frontendTypes.js +0 -45
  39. package/dist/helpers.js +0 -53
  40. package/dist/index.js +0 -25
  41. package/dist/jestutils/export.js +0 -1
  42. package/dist/jestutils/jestHelpers.js +14 -371
  43. package/dist/logger/export.js +0 -1
  44. package/dist/matter/behaviors.js +0 -2
  45. package/dist/matter/clusters.js +0 -2
  46. package/dist/matter/devices.js +0 -2
  47. package/dist/matter/endpoints.js +0 -2
  48. package/dist/matter/export.js +0 -3
  49. package/dist/matter/types.js +0 -3
  50. package/dist/matterNode.js +8 -369
  51. package/dist/matterbridge.js +46 -824
  52. package/dist/matterbridgeAccessoryPlatform.js +0 -38
  53. package/dist/matterbridgeBehaviors.js +5 -68
  54. package/dist/matterbridgeDeviceTypes.js +14 -635
  55. package/dist/matterbridgeDynamicPlatform.js +0 -38
  56. package/dist/matterbridgeEndpoint.js +53 -1457
  57. package/dist/matterbridgeEndpointHelpers.js +20 -483
  58. package/dist/matterbridgeEndpointTypes.js +0 -25
  59. package/dist/matterbridgePlatform.js +1 -451
  60. package/dist/matterbridgeTypes.js +0 -26
  61. package/dist/pluginManager.js +5 -341
  62. package/dist/shelly.js +7 -178
  63. package/dist/storage/export.js +0 -1
  64. package/dist/update.js +1 -93
  65. package/dist/utils/colorUtils.js +2 -97
  66. package/dist/utils/commandLine.js +0 -60
  67. package/dist/utils/copyDirectory.js +0 -37
  68. package/dist/utils/createDirectory.js +0 -33
  69. package/dist/utils/createZip.js +2 -47
  70. package/dist/utils/deepCopy.js +0 -39
  71. package/dist/utils/deepEqual.js +1 -72
  72. package/dist/utils/error.js +0 -42
  73. package/dist/utils/export.js +0 -1
  74. package/dist/utils/format.js +0 -49
  75. package/dist/utils/hex.js +0 -124
  76. package/dist/utils/inspector.js +1 -69
  77. package/dist/utils/isvalid.js +0 -101
  78. package/dist/utils/network.js +5 -103
  79. package/dist/utils/spawn.js +1 -71
  80. package/dist/utils/tracker.js +1 -64
  81. package/dist/utils/wait.js +8 -60
  82. package/dist/workerGlobalPrefix.js +5 -37
  83. package/dist/workerTypes.js +0 -24
  84. package/dist/workers.js +4 -68
  85. package/npm-shrinkwrap.json +2 -2
  86. package/package.json +1 -2
  87. package/dist/broadcastServer.d.ts +0 -144
  88. package/dist/broadcastServer.d.ts.map +0 -1
  89. package/dist/broadcastServer.js.map +0 -1
  90. package/dist/broadcastServerTypes.d.ts +0 -841
  91. package/dist/broadcastServerTypes.d.ts.map +0 -1
  92. package/dist/broadcastServerTypes.js.map +0 -1
  93. package/dist/cli.d.ts +0 -30
  94. package/dist/cli.d.ts.map +0 -1
  95. package/dist/cli.js.map +0 -1
  96. package/dist/cliEmitter.d.ts +0 -50
  97. package/dist/cliEmitter.d.ts.map +0 -1
  98. package/dist/cliEmitter.js.map +0 -1
  99. package/dist/cliHistory.d.ts +0 -48
  100. package/dist/cliHistory.d.ts.map +0 -1
  101. package/dist/cliHistory.js.map +0 -1
  102. package/dist/clusters/export.d.ts +0 -2
  103. package/dist/clusters/export.d.ts.map +0 -1
  104. package/dist/clusters/export.js.map +0 -1
  105. package/dist/deviceManager.d.ts +0 -135
  106. package/dist/deviceManager.d.ts.map +0 -1
  107. package/dist/deviceManager.js.map +0 -1
  108. package/dist/devices/airConditioner.d.ts +0 -98
  109. package/dist/devices/airConditioner.d.ts.map +0 -1
  110. package/dist/devices/airConditioner.js.map +0 -1
  111. package/dist/devices/batteryStorage.d.ts +0 -48
  112. package/dist/devices/batteryStorage.d.ts.map +0 -1
  113. package/dist/devices/batteryStorage.js.map +0 -1
  114. package/dist/devices/cooktop.d.ts +0 -61
  115. package/dist/devices/cooktop.d.ts.map +0 -1
  116. package/dist/devices/cooktop.js.map +0 -1
  117. package/dist/devices/dishwasher.d.ts +0 -71
  118. package/dist/devices/dishwasher.d.ts.map +0 -1
  119. package/dist/devices/dishwasher.js.map +0 -1
  120. package/dist/devices/evse.d.ts +0 -76
  121. package/dist/devices/evse.d.ts.map +0 -1
  122. package/dist/devices/evse.js.map +0 -1
  123. package/dist/devices/export.d.ts +0 -17
  124. package/dist/devices/export.d.ts.map +0 -1
  125. package/dist/devices/export.js.map +0 -1
  126. package/dist/devices/extractorHood.d.ts +0 -46
  127. package/dist/devices/extractorHood.d.ts.map +0 -1
  128. package/dist/devices/extractorHood.js.map +0 -1
  129. package/dist/devices/heatPump.d.ts +0 -47
  130. package/dist/devices/heatPump.d.ts.map +0 -1
  131. package/dist/devices/heatPump.js.map +0 -1
  132. package/dist/devices/laundryDryer.d.ts +0 -67
  133. package/dist/devices/laundryDryer.d.ts.map +0 -1
  134. package/dist/devices/laundryDryer.js.map +0 -1
  135. package/dist/devices/laundryWasher.d.ts +0 -81
  136. package/dist/devices/laundryWasher.d.ts.map +0 -1
  137. package/dist/devices/laundryWasher.js.map +0 -1
  138. package/dist/devices/microwaveOven.d.ts +0 -168
  139. package/dist/devices/microwaveOven.d.ts.map +0 -1
  140. package/dist/devices/microwaveOven.js.map +0 -1
  141. package/dist/devices/oven.d.ts +0 -105
  142. package/dist/devices/oven.d.ts.map +0 -1
  143. package/dist/devices/oven.js.map +0 -1
  144. package/dist/devices/refrigerator.d.ts +0 -118
  145. package/dist/devices/refrigerator.d.ts.map +0 -1
  146. package/dist/devices/refrigerator.js.map +0 -1
  147. package/dist/devices/roboticVacuumCleaner.d.ts +0 -112
  148. package/dist/devices/roboticVacuumCleaner.d.ts.map +0 -1
  149. package/dist/devices/roboticVacuumCleaner.js.map +0 -1
  150. package/dist/devices/solarPower.d.ts +0 -40
  151. package/dist/devices/solarPower.d.ts.map +0 -1
  152. package/dist/devices/solarPower.js.map +0 -1
  153. package/dist/devices/speaker.d.ts +0 -87
  154. package/dist/devices/speaker.d.ts.map +0 -1
  155. package/dist/devices/speaker.js.map +0 -1
  156. package/dist/devices/temperatureControl.d.ts +0 -166
  157. package/dist/devices/temperatureControl.d.ts.map +0 -1
  158. package/dist/devices/temperatureControl.js.map +0 -1
  159. package/dist/devices/waterHeater.d.ts +0 -111
  160. package/dist/devices/waterHeater.d.ts.map +0 -1
  161. package/dist/devices/waterHeater.js.map +0 -1
  162. package/dist/dgram/coap.d.ts +0 -205
  163. package/dist/dgram/coap.d.ts.map +0 -1
  164. package/dist/dgram/coap.js.map +0 -1
  165. package/dist/dgram/dgram.d.ts +0 -143
  166. package/dist/dgram/dgram.d.ts.map +0 -1
  167. package/dist/dgram/dgram.js.map +0 -1
  168. package/dist/dgram/mb_coap.d.ts +0 -24
  169. package/dist/dgram/mb_coap.d.ts.map +0 -1
  170. package/dist/dgram/mb_coap.js.map +0 -1
  171. package/dist/dgram/mb_mdns.d.ts +0 -24
  172. package/dist/dgram/mb_mdns.d.ts.map +0 -1
  173. package/dist/dgram/mb_mdns.js.map +0 -1
  174. package/dist/dgram/mdns.d.ts +0 -350
  175. package/dist/dgram/mdns.d.ts.map +0 -1
  176. package/dist/dgram/mdns.js.map +0 -1
  177. package/dist/dgram/mdnsReflectorClient.d.ts +0 -39
  178. package/dist/dgram/mdnsReflectorClient.d.ts.map +0 -1
  179. package/dist/dgram/mdnsReflectorClient.js.map +0 -1
  180. package/dist/dgram/mdnsReflectorServer.d.ts +0 -54
  181. package/dist/dgram/mdnsReflectorServer.d.ts.map +0 -1
  182. package/dist/dgram/mdnsReflectorServer.js.map +0 -1
  183. package/dist/dgram/mdnsReflectorTypes.d.ts +0 -28
  184. package/dist/dgram/mdnsReflectorTypes.d.ts.map +0 -1
  185. package/dist/dgram/mdnsReflectorTypes.js.map +0 -1
  186. package/dist/dgram/multicast.d.ts +0 -67
  187. package/dist/dgram/multicast.d.ts.map +0 -1
  188. package/dist/dgram/multicast.js.map +0 -1
  189. package/dist/dgram/unicast.d.ts +0 -64
  190. package/dist/dgram/unicast.d.ts.map +0 -1
  191. package/dist/dgram/unicast.js.map +0 -1
  192. package/dist/frontend.d.ts +0 -245
  193. package/dist/frontend.d.ts.map +0 -1
  194. package/dist/frontend.js.map +0 -1
  195. package/dist/frontendTypes.d.ts +0 -529
  196. package/dist/frontendTypes.d.ts.map +0 -1
  197. package/dist/frontendTypes.js.map +0 -1
  198. package/dist/helpers.d.ts +0 -48
  199. package/dist/helpers.d.ts.map +0 -1
  200. package/dist/helpers.js.map +0 -1
  201. package/dist/index.d.ts +0 -34
  202. package/dist/index.d.ts.map +0 -1
  203. package/dist/index.js.map +0 -1
  204. package/dist/jestutils/export.d.ts +0 -2
  205. package/dist/jestutils/export.d.ts.map +0 -1
  206. package/dist/jestutils/export.js.map +0 -1
  207. package/dist/jestutils/jestHelpers.d.ts +0 -345
  208. package/dist/jestutils/jestHelpers.d.ts.map +0 -1
  209. package/dist/jestutils/jestHelpers.js.map +0 -1
  210. package/dist/logger/export.d.ts +0 -2
  211. package/dist/logger/export.d.ts.map +0 -1
  212. package/dist/logger/export.js.map +0 -1
  213. package/dist/matter/behaviors.d.ts +0 -2
  214. package/dist/matter/behaviors.d.ts.map +0 -1
  215. package/dist/matter/behaviors.js.map +0 -1
  216. package/dist/matter/clusters.d.ts +0 -2
  217. package/dist/matter/clusters.d.ts.map +0 -1
  218. package/dist/matter/clusters.js.map +0 -1
  219. package/dist/matter/devices.d.ts +0 -2
  220. package/dist/matter/devices.d.ts.map +0 -1
  221. package/dist/matter/devices.js.map +0 -1
  222. package/dist/matter/endpoints.d.ts +0 -2
  223. package/dist/matter/endpoints.d.ts.map +0 -1
  224. package/dist/matter/endpoints.js.map +0 -1
  225. package/dist/matter/export.d.ts +0 -5
  226. package/dist/matter/export.d.ts.map +0 -1
  227. package/dist/matter/export.js.map +0 -1
  228. package/dist/matter/types.d.ts +0 -3
  229. package/dist/matter/types.d.ts.map +0 -1
  230. package/dist/matter/types.js.map +0 -1
  231. package/dist/matterNode.d.ts +0 -342
  232. package/dist/matterNode.d.ts.map +0 -1
  233. package/dist/matterNode.js.map +0 -1
  234. package/dist/matterbridge.d.ts +0 -505
  235. package/dist/matterbridge.d.ts.map +0 -1
  236. package/dist/matterbridge.js.map +0 -1
  237. package/dist/matterbridgeAccessoryPlatform.d.ts +0 -41
  238. package/dist/matterbridgeAccessoryPlatform.d.ts.map +0 -1
  239. package/dist/matterbridgeAccessoryPlatform.js.map +0 -1
  240. package/dist/matterbridgeBehaviors.d.ts +0 -2404
  241. package/dist/matterbridgeBehaviors.d.ts.map +0 -1
  242. package/dist/matterbridgeBehaviors.js.map +0 -1
  243. package/dist/matterbridgeDeviceTypes.d.ts +0 -698
  244. package/dist/matterbridgeDeviceTypes.d.ts.map +0 -1
  245. package/dist/matterbridgeDeviceTypes.js.map +0 -1
  246. package/dist/matterbridgeDynamicPlatform.d.ts +0 -41
  247. package/dist/matterbridgeDynamicPlatform.d.ts.map +0 -1
  248. package/dist/matterbridgeDynamicPlatform.js.map +0 -1
  249. package/dist/matterbridgeEndpoint.d.ts +0 -1507
  250. package/dist/matterbridgeEndpoint.d.ts.map +0 -1
  251. package/dist/matterbridgeEndpoint.js.map +0 -1
  252. package/dist/matterbridgeEndpointHelpers.d.ts +0 -787
  253. package/dist/matterbridgeEndpointHelpers.d.ts.map +0 -1
  254. package/dist/matterbridgeEndpointHelpers.js.map +0 -1
  255. package/dist/matterbridgeEndpointTypes.d.ts +0 -166
  256. package/dist/matterbridgeEndpointTypes.d.ts.map +0 -1
  257. package/dist/matterbridgeEndpointTypes.js.map +0 -1
  258. package/dist/matterbridgePlatform.d.ts +0 -539
  259. package/dist/matterbridgePlatform.d.ts.map +0 -1
  260. package/dist/matterbridgePlatform.js.map +0 -1
  261. package/dist/matterbridgeTypes.d.ts +0 -252
  262. package/dist/matterbridgeTypes.d.ts.map +0 -1
  263. package/dist/matterbridgeTypes.js.map +0 -1
  264. package/dist/pluginManager.d.ts +0 -372
  265. package/dist/pluginManager.d.ts.map +0 -1
  266. package/dist/pluginManager.js.map +0 -1
  267. package/dist/shelly.d.ts +0 -181
  268. package/dist/shelly.d.ts.map +0 -1
  269. package/dist/shelly.js.map +0 -1
  270. package/dist/storage/export.d.ts +0 -2
  271. package/dist/storage/export.d.ts.map +0 -1
  272. package/dist/storage/export.js.map +0 -1
  273. package/dist/update.d.ts +0 -84
  274. package/dist/update.d.ts.map +0 -1
  275. package/dist/update.js.map +0 -1
  276. package/dist/utils/colorUtils.d.ts +0 -101
  277. package/dist/utils/colorUtils.d.ts.map +0 -1
  278. package/dist/utils/colorUtils.js.map +0 -1
  279. package/dist/utils/commandLine.d.ts +0 -66
  280. package/dist/utils/commandLine.d.ts.map +0 -1
  281. package/dist/utils/commandLine.js.map +0 -1
  282. package/dist/utils/copyDirectory.d.ts +0 -35
  283. package/dist/utils/copyDirectory.d.ts.map +0 -1
  284. package/dist/utils/copyDirectory.js.map +0 -1
  285. package/dist/utils/createDirectory.d.ts +0 -34
  286. package/dist/utils/createDirectory.d.ts.map +0 -1
  287. package/dist/utils/createDirectory.js.map +0 -1
  288. package/dist/utils/createZip.d.ts +0 -39
  289. package/dist/utils/createZip.d.ts.map +0 -1
  290. package/dist/utils/createZip.js.map +0 -1
  291. package/dist/utils/deepCopy.d.ts +0 -32
  292. package/dist/utils/deepCopy.d.ts.map +0 -1
  293. package/dist/utils/deepCopy.js.map +0 -1
  294. package/dist/utils/deepEqual.d.ts +0 -54
  295. package/dist/utils/deepEqual.d.ts.map +0 -1
  296. package/dist/utils/deepEqual.js.map +0 -1
  297. package/dist/utils/error.d.ts +0 -45
  298. package/dist/utils/error.d.ts.map +0 -1
  299. package/dist/utils/error.js.map +0 -1
  300. package/dist/utils/export.d.ts +0 -13
  301. package/dist/utils/export.d.ts.map +0 -1
  302. package/dist/utils/export.js.map +0 -1
  303. package/dist/utils/format.d.ts +0 -53
  304. package/dist/utils/format.d.ts.map +0 -1
  305. package/dist/utils/format.js.map +0 -1
  306. package/dist/utils/hex.d.ts +0 -89
  307. package/dist/utils/hex.d.ts.map +0 -1
  308. package/dist/utils/hex.js.map +0 -1
  309. package/dist/utils/inspector.d.ts +0 -87
  310. package/dist/utils/inspector.d.ts.map +0 -1
  311. package/dist/utils/inspector.js.map +0 -1
  312. package/dist/utils/isvalid.d.ts +0 -103
  313. package/dist/utils/isvalid.d.ts.map +0 -1
  314. package/dist/utils/isvalid.js.map +0 -1
  315. package/dist/utils/network.d.ts +0 -117
  316. package/dist/utils/network.d.ts.map +0 -1
  317. package/dist/utils/network.js.map +0 -1
  318. package/dist/utils/spawn.d.ts +0 -33
  319. package/dist/utils/spawn.d.ts.map +0 -1
  320. package/dist/utils/spawn.js.map +0 -1
  321. package/dist/utils/tracker.d.ts +0 -108
  322. package/dist/utils/tracker.d.ts.map +0 -1
  323. package/dist/utils/tracker.js.map +0 -1
  324. package/dist/utils/wait.d.ts +0 -54
  325. package/dist/utils/wait.d.ts.map +0 -1
  326. package/dist/utils/wait.js.map +0 -1
  327. package/dist/workerGlobalPrefix.d.ts +0 -25
  328. package/dist/workerGlobalPrefix.d.ts.map +0 -1
  329. package/dist/workerGlobalPrefix.js.map +0 -1
  330. package/dist/workerTypes.d.ts +0 -52
  331. package/dist/workerTypes.d.ts.map +0 -1
  332. package/dist/workerTypes.js.map +0 -1
  333. package/dist/workers.d.ts +0 -69
  334. package/dist/workers.d.ts.map +0 -1
  335. package/dist/workers.js.map +0 -1
@@ -1,30 +1,5 @@
1
- /**
2
- * @description This file contains the class Mdns.
3
- * @file mdns.ts
4
- * @author Luca Liguori
5
- * @created 2025-03-22
6
- * @version 1.0.0
7
- * @license Apache-2.0
8
- *
9
- * Copyright 2025, 2026, 2027 Luca Liguori.
10
- *
11
- * Licensed under the Apache License, Version 2.0 (the "License");
12
- * you may not use this file except in compliance with the License.
13
- * You may obtain a copy of the License at
14
- *
15
- * http://www.apache.org/licenses/LICENSE-2.0
16
- *
17
- * Unless required by applicable law or agreed to in writing, software
18
- * distributed under the License is distributed on an "AS IS" BASIS,
19
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20
- * See the License for the specific language governing permissions and
21
- * limitations under the License.
22
- */
23
- // AnsiLogger imports
24
- import { BLUE, CYAN, db, er, GREEN, idn, MAGENTA, nf, rs } from 'node-ansi-logger';
25
- // Utils imports
1
+ import { BLUE, CYAN, db, GREEN, idn, MAGENTA, nf, rs } from 'node-ansi-logger';
26
2
  import { hasParameter } from '../utils/commandLine.js';
27
- // Net imports
28
3
  import { Multicast } from './multicast.js';
29
4
  export var DnsRecordType;
30
5
  (function (DnsRecordType) {
@@ -116,7 +91,6 @@ export var DnsRecordType;
116
91
  DnsRecordType[DnsRecordType["DOA"] = 259] = "DOA";
117
92
  DnsRecordType[DnsRecordType["AMTRELAY"] = 260] = "AMTRELAY";
118
93
  DnsRecordType[DnsRecordType["ZONEVERSION"] = 261] = "ZONEVERSION";
119
- // 262-32767 are unassigned/reserved
120
94
  DnsRecordType[DnsRecordType["TA"] = 32768] = "TA";
121
95
  DnsRecordType[DnsRecordType["DLV"] = 32769] = "DLV";
122
96
  })(DnsRecordType || (DnsRecordType = {}));
@@ -130,25 +104,34 @@ export var DnsClass;
130
104
  export var DnsClassFlag;
131
105
  (function (DnsClassFlag) {
132
106
  DnsClassFlag[DnsClassFlag["FLUSH"] = 32768] = "FLUSH";
133
- // eslint-disable-next-line @typescript-eslint/no-duplicate-enum-values
134
107
  DnsClassFlag[DnsClassFlag["QU"] = 32768] = "QU";
135
108
  })(DnsClassFlag || (DnsClassFlag = {}));
109
+ export function isMdns(message) {
110
+ if (!message || message.length < 12)
111
+ return false;
112
+ const id = message.readUInt16BE(0);
113
+ return id === 0;
114
+ }
115
+ export function isMdnsQuery(message) {
116
+ if (message.length < 12)
117
+ return false;
118
+ const id = message.readUInt16BE(0);
119
+ const flags = message.readUInt16BE(2);
120
+ const qr = (flags & 0x8000) >> 15;
121
+ return id == 0 && qr === 0;
122
+ }
123
+ export function isMdnsResponse(message) {
124
+ if (message.length < 12)
125
+ return false;
126
+ const id = message.readUInt16BE(0);
127
+ const flags = message.readUInt16BE(2);
128
+ const qr = (flags & 0x8000) >> 15;
129
+ return id == 0 && qr === 1;
130
+ }
136
131
  export class Mdns extends Multicast {
137
132
  deviceQueries = new Map();
138
133
  deviceResponses = new Map();
139
134
  filters = [];
140
- /**
141
- * Creates an instance of the Mdns class.
142
- *
143
- * @param {string} name - The internal name of the mDNS server for the logs.
144
- * @param {string} multicastAddress - The multicast address for mDNS (i.e. 224.0.0.251 for udp4 or ff02::fb for udp6).
145
- * @param {number} multicastPort - The port for mDNS (i.e. 5353).
146
- * @param {('udp4' | 'udp6')} socketType - The type of socket to create (either 'udp4' or 'udp6').
147
- * @param {boolean} [reuseAddr] - Whether to reuse the address. Defaults to true.
148
- * @param {string} [interfaceName] - The optional name of the network interface to use.
149
- * @param {string} [interfaceAddress] - The optional IP address of the network interface to use.
150
- * @param {string} [outgoingInterfaceAddress] - The address of the outgoing network interface.
151
- */
152
135
  constructor(name, multicastAddress, multicastPort, socketType, reuseAddr = true, interfaceName, interfaceAddress, outgoingInterfaceAddress) {
153
136
  super(name, multicastAddress, multicastPort, socketType, reuseAddr, interfaceName, interfaceAddress, outgoingInterfaceAddress);
154
137
  }
@@ -168,17 +151,16 @@ export class Mdns extends Multicast {
168
151
  this.onQuery(rinfo, result);
169
152
  }
170
153
  else {
171
- const ptr = result.answers?.find((record) => record.name === '_shelly._tcp.local' && record.type === 12 /* DnsRecordType.PTR */) ||
172
- result.answers?.find((record) => record.name === '_http._tcp.local' && record.type === 12 /* DnsRecordType.PTR */) ||
173
- result.answers?.find((record) => record.type === 12 /* DnsRecordType.PTR */) ||
174
- result.answers?.find((record) => record.type === 16 /* DnsRecordType.TXT */) ||
154
+ const ptr = result.answers?.find((record) => record.name === '_shelly._tcp.local' && record.type === 12) ||
155
+ result.answers?.find((record) => record.name === '_http._tcp.local' && record.type === 12) ||
156
+ result.answers?.find((record) => record.type === 12) ||
157
+ result.answers?.find((record) => record.type === 16) ||
175
158
  result.answers
176
159
  ? result.answers[0]
177
- : undefined; // Fallback to the first answer if no PTR or TXT found
178
- this.deviceResponses.set(rinfo.address, { rinfo, response: result, dataPTR: ptr?.type === 12 /* DnsRecordType.PTR */ ? ptr?.data : ptr?.name });
160
+ : undefined;
161
+ this.deviceResponses.set(rinfo.address, { rinfo, response: result, dataPTR: ptr?.type === 12 ? ptr?.data : ptr?.name });
179
162
  this.onResponse(rinfo, result);
180
163
  }
181
- // Apply filters if any
182
164
  if (this.filters.length > 0) {
183
165
  this.log.debug(`mDNS message filtered out by filters: ${this.filters.join(', ')}`);
184
166
  for (const filter of this.filters) {
@@ -200,28 +182,20 @@ export class Mdns extends Multicast {
200
182
  this.log.error(`Error decoding mDNS message: ${error instanceof Error ? error.message : error}`);
201
183
  }
202
184
  }
203
- /**
204
- * Decodes an mDNS message, including the header, question section, answer section,
205
- * authority section, and additional section.
206
- *
207
- * @param {Buffer} msg - The raw mDNS message buffer.
208
- * @returns {MdnsMessage} An object representing the decoded mDNS message.
209
- * @throws {Error} if the message is too short.
210
- */
211
185
  decodeMdnsMessage(msg) {
212
186
  if (msg.length < 12) {
213
187
  throw new Error('mDNS message too short');
214
188
  }
215
189
  const id = msg.readUInt16BE(0);
216
190
  const flags = msg.readUInt16BE(2);
217
- const qr = (flags & 0x8000) >> 15; // Bit 15: 0=query, 1=response.
218
- const opcode = (flags & 0x7800) >> 11; // Bits 14-11.
219
- const aa = Boolean(flags & 0x0400); // Bit 10.
220
- const tc = Boolean(flags & 0x0200); // Bit 9.
221
- const rd = Boolean(flags & 0x0100); // Bit 8.
222
- const ra = Boolean(flags & 0x0080); // Bit 7.
223
- const z = (flags & 0x0070) >> 4; // Bits 6-4.
224
- const rcode = flags & 0x000f; // Bits 3-0.
191
+ const qr = (flags & 0x8000) >> 15;
192
+ const opcode = (flags & 0x7800) >> 11;
193
+ const aa = Boolean(flags & 0x0400);
194
+ const tc = Boolean(flags & 0x0200);
195
+ const rd = Boolean(flags & 0x0100);
196
+ const ra = Boolean(flags & 0x0080);
197
+ const z = (flags & 0x0070) >> 4;
198
+ const rcode = flags & 0x000f;
225
199
  const qdCount = msg.readUInt16BE(4);
226
200
  const anCount = msg.readUInt16BE(6);
227
201
  const nsCount = msg.readUInt16BE(8);
@@ -246,7 +220,6 @@ export class Mdns extends Multicast {
246
220
  additionals: [],
247
221
  };
248
222
  let offset = 12;
249
- // Decode the question section.
250
223
  for (let i = 0; i < qdCount; i++) {
251
224
  const qnameResult = this.decodeDnsName(msg, offset);
252
225
  const qname = qnameResult.name;
@@ -257,19 +230,16 @@ export class Mdns extends Multicast {
257
230
  offset += 2;
258
231
  mdnsMessage.questions?.push({ name: qname, type: qtype, class: qclass });
259
232
  }
260
- // Decode the answer section.
261
233
  for (let i = 0; i < anCount; i++) {
262
234
  const rrResult = this.decodeResourceRecord(msg, offset);
263
235
  mdnsMessage.answers?.push(rrResult.record);
264
236
  offset = rrResult.newOffset;
265
237
  }
266
- // Decode the authority (NS) section.
267
238
  for (let i = 0; i < nsCount; i++) {
268
239
  const rrResult = this.decodeResourceRecord(msg, offset);
269
240
  mdnsMessage.authorities?.push(rrResult.record);
270
241
  offset = rrResult.newOffset;
271
242
  }
272
- // Decode the additional records section.
273
243
  for (let i = 0; i < arCount; i++) {
274
244
  const rrResult = this.decodeResourceRecord(msg, offset);
275
245
  mdnsMessage.additionals?.push(rrResult.record);
@@ -277,25 +247,15 @@ export class Mdns extends Multicast {
277
247
  }
278
248
  return mdnsMessage;
279
249
  }
280
- /**
281
- * Decodes a DNS name from a buffer, handling compression.
282
- *
283
- * @param {Buffer} msg - The full mDNS message buffer.
284
- * @param {number} offset - The offset at which the DNS name starts.
285
- * @returns {{ name: string; newOffset: number }} An object with the decoded name and the new offset.
286
- * @throws {Error} if the offset exceeds the buffer length or too many iterations are performed.
287
- */
288
250
  decodeDnsName(msg, offset) {
289
251
  const labels = [];
290
252
  let jumped = false;
291
253
  let originalOffset = offset;
292
- let iterations = 0; // Prevent infinite loops
254
+ let iterations = 0;
293
255
  while (true) {
294
- // Safety guard: prevent infinite loops in malformed messages.
295
256
  if (iterations++ > 1000) {
296
257
  throw new Error('Too many iterations while decoding DNS name. Possible malformed message.');
297
258
  }
298
- // Check that offset is within buffer bounds.
299
259
  if (offset >= msg.length) {
300
260
  throw new Error('Offset exceeds buffer length while decoding DNS name.');
301
261
  }
@@ -304,9 +264,7 @@ export class Mdns extends Multicast {
304
264
  offset++;
305
265
  break;
306
266
  }
307
- // Check for pointer (first two bits are 11)
308
267
  if ((len & 0xc0) === 0xc0) {
309
- // Ensure the pointer has two bytes available.
310
268
  if (offset + 1 >= msg.length) {
311
269
  throw new Error('Incomplete pointer encountered while decoding DNS name.');
312
270
  }
@@ -319,7 +277,6 @@ export class Mdns extends Multicast {
319
277
  continue;
320
278
  }
321
279
  offset++;
322
- // Check that the label length doesn't go beyond the buffer.
323
280
  if (offset + len > msg.length) {
324
281
  throw new Error('Label length exceeds buffer bounds while decoding DNS name.');
325
282
  }
@@ -328,15 +285,6 @@ export class Mdns extends Multicast {
328
285
  }
329
286
  return { name: labels.join('.'), newOffset: jumped ? originalOffset : offset };
330
287
  }
331
- /**
332
- * Encodes a domain name into the DNS label format.
333
- *
334
- * For example, "example.local" becomes:
335
- * [7] "example" [5] "local" [0]
336
- *
337
- * @param {string} name - The domain name to encode.
338
- * @returns {Buffer} The encoded domain name as a Buffer.
339
- */
340
288
  encodeDnsName(name) {
341
289
  const labels = name.split('.');
342
290
  const buffers = labels.map((label) => {
@@ -344,25 +292,8 @@ export class Mdns extends Multicast {
344
292
  lenBuf.writeUInt8(label.length, 0);
345
293
  return Buffer.concat([lenBuf, Buffer.from(label)]);
346
294
  });
347
- // Append the null byte to terminate the name.
348
295
  return Buffer.concat([...buffers, Buffer.from([0])]);
349
296
  }
350
- /**
351
- * Encodes TXT record RDATA.
352
- *
353
- * In DNS/mDNS, TXT RDATA is a sequence of one or more <character-string>,
354
- * each encoded as: [length byte][UTF-8 bytes].
355
- *
356
- * @param {string[]} txt - Array of TXT entries, e.g. ["key=value", "path=/"].
357
- * @returns {Buffer} Encoded TXT RDATA.
358
- * @throws {Error} If any entry exceeds 255 bytes.
359
- *
360
- * @example
361
- * const txtRdata = mdns.encodeTxtRdata(['txtvers=1', 'path=/']);
362
- * mdns.sendResponse([
363
- * { name: 'example._http._tcp.local', rtype: DnsRecordType.TXT, rclass: DnsClass.IN | DnsClassFlag.FLUSH, ttl: 120, rdata: txtRdata },
364
- * ]);
365
- */
366
297
  encodeTxtRdata(txt) {
367
298
  const parts = txt.map((entry) => {
368
299
  const value = Buffer.from(entry, 'utf8');
@@ -372,21 +303,6 @@ export class Mdns extends Multicast {
372
303
  });
373
304
  return Buffer.concat(parts);
374
305
  }
375
- /**
376
- * Encodes SRV record RDATA.
377
- *
378
- * SRV RDATA layout (RFC 2782):
379
- * - priority (2 bytes)
380
- * - weight (2 bytes)
381
- * - port (2 bytes)
382
- * - target (DNS name)
383
- *
384
- * @param {number} priority - SRV priority.
385
- * @param {number} weight - SRV weight.
386
- * @param {number} port - Service port.
387
- * @param {string} target - Target hostname (e.g. "matterbridge.local").
388
- * @returns {Buffer} Encoded SRV RDATA.
389
- */
390
306
  encodeSrvRdata(priority, weight, port, target) {
391
307
  const fixed = Buffer.alloc(6);
392
308
  fixed.writeUInt16BE(priority, 0);
@@ -394,13 +310,6 @@ export class Mdns extends Multicast {
394
310
  fixed.writeUInt16BE(port, 4);
395
311
  return Buffer.concat([fixed, this.encodeDnsName(target)]);
396
312
  }
397
- /**
398
- * Encodes an IPv4 address for an A record RDATA (4 bytes).
399
- *
400
- * @param {string} ipv4 - IPv4 address, e.g. "192.168.1.10".
401
- * @returns {Buffer} 4-byte buffer.
402
- * @throws {Error} If the address is not a valid dotted-quad.
403
- */
404
313
  encodeA(ipv4) {
405
314
  const parts = ipv4.split('.').map((p) => Number(p));
406
315
  if (parts.length !== 4 || parts.some((n) => !Number.isInteger(n) || n < 0 || n > 255)) {
@@ -408,19 +317,8 @@ export class Mdns extends Multicast {
408
317
  }
409
318
  return Buffer.from(parts);
410
319
  }
411
- /**
412
- * Encodes an IPv6 address for an AAAA record RDATA (16 bytes).
413
- *
414
- * Supports the "::" zero-compression form and ignores an optional scope id
415
- * suffix (e.g. "fe80::1%12" or "fe80::1%eth0").
416
- *
417
- * @param {string} ipv6WithOptionalScope - IPv6 address (optionally with scope id).
418
- * @returns {Buffer} 16-byte buffer.
419
- * @throws {Error} If the address is not a valid IPv6 literal.
420
- */
421
320
  encodeAAAA(ipv6WithOptionalScope) {
422
321
  const ipv6 = ipv6WithOptionalScope.split('%')[0];
423
- // Expand IPv6 to 8 groups of 16-bit words.
424
322
  const [left, right] = ipv6.split('::');
425
323
  const leftParts = left ? left.split(':').filter(Boolean) : [];
426
324
  const rightParts = right ? right.split(':').filter(Boolean) : [];
@@ -430,9 +328,10 @@ export class Mdns extends Multicast {
430
328
  throw new Error(`Invalid IPv6 address: ${ipv6WithOptionalScope}`);
431
329
  const groups = [...leftParts, ...Array(missing).fill('0'), ...rightParts];
432
330
  return Buffer.from(groups.flatMap((g) => {
433
- const word = parseInt(g || '0', 16);
434
- if (!Number.isFinite(word) || word < 0 || word > 0xffff)
331
+ const word = parseInt(g, 16);
332
+ if (!Number.isFinite(word) || word < 0 || word > 0xffff) {
435
333
  throw new Error(`Invalid IPv6 group: ${g}`);
334
+ }
436
335
  return [(word >> 8) & 0xff, word & 0xff];
437
336
  }));
438
337
  }
@@ -440,25 +339,18 @@ export class Mdns extends Multicast {
440
339
  if (groups.length !== 8)
441
340
  throw new Error(`Invalid IPv6 address: ${ipv6WithOptionalScope}`);
442
341
  return Buffer.from(groups.flatMap((g) => {
443
- const word = parseInt(g || '0', 16);
342
+ if (!g)
343
+ throw new Error(`Invalid IPv6 group: ${g}`);
344
+ const word = parseInt(g, 16);
444
345
  if (!Number.isFinite(word) || word < 0 || word > 0xffff)
445
346
  throw new Error(`Invalid IPv6 group: ${g}`);
446
347
  return [(word >> 8) & 0xff, word & 0xff];
447
348
  }));
448
349
  }
449
- /**
450
- * Decodes a DNS resource record.
451
- *
452
- * @param {Buffer} msg - The full mDNS message buffer.
453
- * @param {number} offset - The offset at which the resource record starts.
454
- * @returns {{ record: MdnsRecord; newOffset: number }} An object containing the decoded record and the new offset.
455
- */
456
350
  decodeResourceRecord(msg, offset) {
457
- // Decode the NAME field (which may be compressed)
458
351
  const nameResult = this.decodeDnsName(msg, offset);
459
352
  const name = nameResult.name;
460
353
  offset = nameResult.newOffset;
461
- // Read TYPE (16 bits), CLASS (16 bits), TTL (32 bits), and RDLENGTH (16 bits)
462
354
  const type = msg.readUInt16BE(offset);
463
355
  offset += 2;
464
356
  const rrclass = msg.readUInt16BE(offset);
@@ -468,14 +360,12 @@ export class Mdns extends Multicast {
468
360
  const rdlength = msg.readUInt16BE(offset);
469
361
  offset += 2;
470
362
  let data = '';
471
- if (type === 12 /* DnsRecordType.PTR */) {
472
- // PTR record (type 12): decode its RDATA as a domain name.
363
+ if (type === 12) {
473
364
  const ptrResult = this.decodeDnsName(msg, offset);
474
365
  data = ptrResult.name;
475
366
  offset += rdlength;
476
367
  }
477
- else if (type === 16 /* DnsRecordType.TXT */) {
478
- // TXT record: may consist of one or more length-prefixed strings.
368
+ else if (type === 16) {
479
369
  const txtStrings = [];
480
370
  const end = offset + rdlength;
481
371
  while (offset < end) {
@@ -487,8 +377,7 @@ export class Mdns extends Multicast {
487
377
  }
488
378
  data = txtStrings.join(', ');
489
379
  }
490
- else if (type === 33 /* DnsRecordType.SRV */) {
491
- // SRV record (type === 33): consists of 2 bytes for priority, 2 for weight, 2 for port, followed by the target domain name.
380
+ else if (type === 33) {
492
381
  const priority = msg.readUInt16BE(offset);
493
382
  const weight = msg.readUInt16BE(offset + 2);
494
383
  const port = msg.readUInt16BE(offset + 4);
@@ -502,16 +391,13 @@ export class Mdns extends Multicast {
502
391
  });
503
392
  offset = srvTargetResult.newOffset;
504
393
  }
505
- else if (type === 1 /* DnsRecordType.A */) {
506
- // A record (type 1): an IPv4 address stored in 4 bytes.
394
+ else if (type === 1) {
507
395
  const ipBytes = msg.slice(offset, offset + 4);
508
396
  data = Array.from(ipBytes).join('.');
509
397
  offset += 4;
510
398
  }
511
- else if (type === 28 /* DnsRecordType.AAAA */) {
512
- // AAAA record (type 28): IPv6 address stored in 16 bytes.
399
+ else if (type === 28) {
513
400
  const ipBytes = msg.slice(offset, offset + 16);
514
- // Convert the 16 bytes into an IPv6 address string (colon-separated)
515
401
  const ipv6Parts = [];
516
402
  for (let i = 0; i < 16; i += 2) {
517
403
  ipv6Parts.push(ipBytes.readUInt16BE(i).toString(16));
@@ -519,14 +405,10 @@ export class Mdns extends Multicast {
519
405
  data = ipv6Parts.join(':');
520
406
  offset += 16;
521
407
  }
522
- else if (type === 47 /* DnsRecordType.NSEC */) {
523
- // NSEC record: RDATA consists of:
524
- // - Next Domain Name (in DNS label format)
525
- // - Type Bit Maps (variable length)
408
+ else if (type === 47) {
526
409
  const { name: nextDomain, newOffset } = this.decodeDnsName(msg, offset);
527
410
  const nextDomainLength = newOffset - offset;
528
411
  offset = newOffset;
529
- // Calculate the remaining length for the type bit maps.
530
412
  const bitmapLength = rdlength - nextDomainLength;
531
413
  const bitmapData = msg.slice(offset, offset + bitmapLength);
532
414
  const types = [];
@@ -553,7 +435,6 @@ export class Mdns extends Multicast {
553
435
  offset += bitmapLength;
554
436
  }
555
437
  else {
556
- // Fall back
557
438
  data = msg.slice(offset, offset + rdlength).toString('hex');
558
439
  offset += rdlength;
559
440
  }
@@ -562,234 +443,185 @@ export class Mdns extends Multicast {
562
443
  newOffset: offset,
563
444
  };
564
445
  }
565
- /**
566
- * Sends a DNS query with multiple questions.
567
- *
568
- * @param {Array<{ name: string; type: number; class: number; unicastResponse?: boolean }>} questions - Array of questions
569
- * to include in the query.
570
- * @returns {Buffer<ArrayBuffer>} The constructed query buffer.
571
- *
572
- * @remarks
573
- * Each question should have a name (e.g., "_http._tcp.local"), type (e.g., DnsRecordType.PTR), class (e.g., DnsClass.IN),
574
- * and an optional unicastResponse flag (this will add the DnsClassFlag.QU flag to the query).
575
- */
576
446
  sendQuery(questions) {
577
447
  const header = Buffer.alloc(12);
578
- header.writeUInt16BE(0, 0); // ID
579
- header.writeUInt16BE(0, 2); // Flags
580
- header.writeUInt16BE(questions.length, 4); // QDCOUNT
581
- header.writeUInt16BE(0, 6); // ANCOUNT
582
- header.writeUInt16BE(0, 8); // NSCOUNT
583
- header.writeUInt16BE(0, 10); // ARCOUNT
448
+ header.writeUInt16BE(0, 0);
449
+ header.writeUInt16BE(0, 2);
450
+ header.writeUInt16BE(questions.length, 4);
451
+ header.writeUInt16BE(0, 6);
452
+ header.writeUInt16BE(0, 8);
453
+ header.writeUInt16BE(0, 10);
584
454
  const questionBuffers = questions.map(({ name, type: qtype, class: qclass, unicastResponse = false }) => {
585
455
  const qname = this.encodeDnsName(name);
586
456
  const qfields = Buffer.alloc(4);
587
457
  qfields.writeUInt16BE(qtype, 0);
588
- qfields.writeUInt16BE(unicastResponse ? qclass | 32768 /* DnsClassFlag.QU */ : qclass, 2);
458
+ qfields.writeUInt16BE(unicastResponse ? qclass | 32768 : qclass, 2);
589
459
  return Buffer.concat([qname, qfields]);
590
460
  });
591
461
  const query = Buffer.concat([header, ...questionBuffers]);
592
462
  if (hasParameter('v') || hasParameter('verbose')) {
593
463
  const decoded = this.decodeMdnsMessage(query);
594
- this.logMdnsMessage(decoded);
464
+ this.logMdnsMessage(decoded, undefined, 'Sending query mDNS message');
595
465
  }
596
466
  this.socket.send(query, 0, query.length, this.multicastPort, this.multicastAddress, (error) => {
597
467
  if (error) {
598
- this.log.error(`Dgram mDNS server failed to send query message: ${error.message}`);
468
+ this.log.error(`Dgram mDNS server failed to send query message: ${error instanceof Error ? error.message : error}`);
599
469
  this.emit('error', error);
600
470
  }
601
471
  else {
602
- const names = questions
603
- .map((q) => `- name ${MAGENTA}${q.name}${db} type ${MAGENTA}${this.dnsTypeToString(q.type)}${db} class ${MAGENTA}${this.dnsQuestionClassToString(q.class)}${db} unicastResponse ${MAGENTA}${q.unicastResponse}${db}`)
604
- .join('\n');
605
- this.log.debug(`Dgram mDNS server sent query message:\n${names}`);
472
+ this.log.debug(`Dgram mDNS server sent query message`);
606
473
  this.emit('sent', query, this.multicastAddress, this.multicastPort);
607
474
  }
608
475
  });
609
476
  return query;
610
477
  }
611
- /**
612
- * Constructs an mDNS response packet and sends it to the multicast address and port.
613
- *
614
- * @param {Array<{ name: string; rtype: number; rclass: number; ttl: number; rdata: Buffer }>} answers - Array of answer records.
615
- * @returns {Buffer<ArrayBuffer>} The constructed response buffer.
616
- *
617
- * @example
618
- * const ptrRdata = mdnsIpv4.encodeDnsName('matterbridge._http._tcp.local');
619
- * mdnsIpv4.sendResponse([{ name: '_http._tcp.local', rtype: DnsRecordType.PTR, rclass: DnsClass.IN, ttl: 120, rdata: ptrRdata }]);
620
- */
621
478
  sendResponse(answers) {
622
479
  if (!Array.isArray(answers) || answers.length === 0) {
623
480
  throw new Error('sendResponse requires a non-empty answers array');
624
481
  }
625
- // Create a 12-byte DNS header.
626
482
  const header = Buffer.alloc(12);
627
- header.writeUInt16BE(0, 0); // ID is set to 0 in mDNS.
628
- // Set flags: QR (response) bit and AA (authoritative answer) bit.
483
+ header.writeUInt16BE(0, 0);
629
484
  header.writeUInt16BE(0x8400, 2);
630
- header.writeUInt16BE(0, 4); // QDCOUNT: 0 questions in response.
631
- header.writeUInt16BE(answers.length, 6); // ANCOUNT: number of answer records.
632
- header.writeUInt16BE(0, 8); // NSCOUNT: 0 authority records.
633
- header.writeUInt16BE(0, 10); // ARCOUNT: 0 additional records.
485
+ header.writeUInt16BE(0, 4);
486
+ header.writeUInt16BE(answers.length, 6);
487
+ header.writeUInt16BE(0, 8);
488
+ header.writeUInt16BE(0, 10);
634
489
  const answerBuffers = answers.map(({ name, rtype, rclass, ttl, rdata }) => {
635
- // Encode the domain name in DNS label format.
636
490
  const aname = this.encodeDnsName(name);
637
- // Prepare the fixed part of the answer record:
638
- // - 2 bytes for qtype,
639
- // - 2 bytes for qclass,
640
- // - 4 bytes for TTL,
641
- // - 2 bytes for RDLENGTH (length of the rdata).
642
491
  const answerFixed = Buffer.alloc(10);
643
- answerFixed.writeUInt16BE(rtype, 0); // Record type.
644
- answerFixed.writeUInt16BE(rclass, 2); // Record class.
645
- answerFixed.writeUInt32BE(ttl, 4); // Time-to-live.
646
- answerFixed.writeUInt16BE(rdata.length, 8); // RDLENGTH.
647
- // Concatenate the answer: encoded name, fixed fields, and resource data.
492
+ answerFixed.writeUInt16BE(rtype, 0);
493
+ answerFixed.writeUInt16BE(rclass, 2);
494
+ answerFixed.writeUInt32BE(ttl, 4);
495
+ answerFixed.writeUInt16BE(rdata.length, 8);
648
496
  return Buffer.concat([aname, answerFixed, rdata]);
649
497
  });
650
- // Concatenate header and answers to form the complete mDNS response packet.
651
498
  const response = Buffer.concat([header, ...answerBuffers]);
652
499
  if (hasParameter('v') || hasParameter('verbose')) {
653
500
  const decoded = this.decodeMdnsMessage(response);
654
- this.logMdnsMessage(decoded);
501
+ this.logMdnsMessage(decoded, undefined, 'Sending response mDNS message');
655
502
  }
656
- // Send the response packet via the socket.
657
503
  this.socket.send(response, 0, response.length, this.multicastPort, this.multicastAddress, (error) => {
658
504
  if (error) {
659
- 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');
660
- this.log.error(`Dgram mDNS server failed to send response message (${MAGENTA}${answers.length}${er} answers): ${error instanceof Error ? error.message : error}\n${items}`);
505
+ this.log.error(`Dgram mDNS server failed to send response message: ${error instanceof Error ? error.message : error}`);
661
506
  this.emit('error', error);
662
507
  }
663
508
  else {
664
- const items = answers.map((a) => `- name ${MAGENTA}${a.name}${db} type ${MAGENTA}${this.dnsTypeToString(a.rtype)}${db} class ${MAGENTA}${this.dnsResponseClassToString(a.rclass)}${db} ttl ${MAGENTA}${a.ttl}${db}`).join('\n');
665
- this.log.debug(`Dgram mDNS server sent response message:\n${items}`);
509
+ this.log.debug(`Dgram mDNS server sent response message`);
666
510
  this.emit('sent', response, this.multicastAddress, this.multicastPort);
667
511
  }
668
512
  });
669
513
  return response;
670
514
  }
671
- /**
672
- * Converts a DNS record type numeric value to its string representation.
673
- *
674
- * @param {number} type - The numeric DNS record type.
675
- * @returns {string} The string representation of the record type.
676
- */
677
515
  dnsTypeToString(type) {
678
516
  const typeMap = {
679
- [1 /* DnsRecordType.A */]: 'A',
680
- [2 /* DnsRecordType.NS */]: 'NS',
681
- [3 /* DnsRecordType.MD */]: 'MD',
682
- [4 /* DnsRecordType.MF */]: 'MF',
683
- [5 /* DnsRecordType.CNAME */]: 'CNAME',
684
- [6 /* DnsRecordType.SOA */]: 'SOA',
685
- [7 /* DnsRecordType.MB */]: 'MB',
686
- [8 /* DnsRecordType.MG */]: 'MG',
687
- [9 /* DnsRecordType.MR */]: 'MR',
688
- [10 /* DnsRecordType.NULL */]: 'NULL',
689
- [11 /* DnsRecordType.WKS */]: 'WKS',
690
- [12 /* DnsRecordType.PTR */]: 'PTR',
691
- [13 /* DnsRecordType.HINFO */]: 'HINFO',
692
- [14 /* DnsRecordType.MINFO */]: 'MINFO',
693
- [15 /* DnsRecordType.MX */]: 'MX',
694
- [16 /* DnsRecordType.TXT */]: 'TXT',
695
- [17 /* DnsRecordType.RP */]: 'RP',
696
- [18 /* DnsRecordType.AFSDB */]: 'AFSDB',
697
- [19 /* DnsRecordType.X25 */]: 'X25',
698
- [20 /* DnsRecordType.ISDN */]: 'ISDN',
699
- [21 /* DnsRecordType.RT */]: 'RT',
700
- [22 /* DnsRecordType.NSAP */]: 'NSAP',
701
- [23 /* DnsRecordType.NSAP_PTR */]: 'NSAP_PTR',
702
- [24 /* DnsRecordType.SIG */]: 'SIG',
703
- [25 /* DnsRecordType.KEY */]: 'KEY',
704
- [26 /* DnsRecordType.PX */]: 'PX',
705
- [27 /* DnsRecordType.GPOS */]: 'GPOS',
706
- [28 /* DnsRecordType.AAAA */]: 'AAAA',
707
- [29 /* DnsRecordType.LOC */]: 'LOC',
708
- [30 /* DnsRecordType.NXT */]: 'NXT',
709
- [31 /* DnsRecordType.EID */]: 'EID',
710
- [32 /* DnsRecordType.NIMLOC */]: 'NIMLOC',
711
- [33 /* DnsRecordType.SRV */]: 'SRV',
712
- [34 /* DnsRecordType.ATMA */]: 'ATMA',
713
- [35 /* DnsRecordType.NAPTR */]: 'NAPTR',
714
- [36 /* DnsRecordType.KX */]: 'KX',
715
- [37 /* DnsRecordType.CERT */]: 'CERT',
716
- [38 /* DnsRecordType.A6 */]: 'A6',
717
- [39 /* DnsRecordType.DNAME */]: 'DNAME',
718
- [40 /* DnsRecordType.SINK */]: 'SINK',
719
- [41 /* DnsRecordType.OPT */]: 'OPT',
720
- [42 /* DnsRecordType.APL */]: 'APL',
721
- [43 /* DnsRecordType.DS */]: 'DS',
722
- [44 /* DnsRecordType.SSHFP */]: 'SSHFP',
723
- [45 /* DnsRecordType.IPSECKEY */]: 'IPSECKEY',
724
- [46 /* DnsRecordType.RRSIG */]: 'RRSIG',
725
- [47 /* DnsRecordType.NSEC */]: 'NSEC',
726
- [48 /* DnsRecordType.DNSKEY */]: 'DNSKEY',
727
- [49 /* DnsRecordType.DHCID */]: 'DHCID',
728
- [50 /* DnsRecordType.NSEC3 */]: 'NSEC3',
729
- [51 /* DnsRecordType.NSEC3PARAM */]: 'NSEC3PARAM',
730
- [52 /* DnsRecordType.TLSA */]: 'TLSA',
731
- [53 /* DnsRecordType.SMIMEA */]: 'SMIMEA',
732
- [55 /* DnsRecordType.HIP */]: 'HIP',
733
- [56 /* DnsRecordType.NINFO */]: 'NINFO',
734
- [57 /* DnsRecordType.RKEY */]: 'RKEY',
735
- [58 /* DnsRecordType.TALINK */]: 'TALINK',
736
- [59 /* DnsRecordType.CDS */]: 'CDS',
737
- [60 /* DnsRecordType.CDNSKEY */]: 'CDNSKEY',
738
- [61 /* DnsRecordType.OPENPGPKEY */]: 'OPENPGPKEY',
739
- [62 /* DnsRecordType.CSYNC */]: 'CSYNC',
740
- [63 /* DnsRecordType.ZONEMD */]: 'ZONEMD',
741
- [64 /* DnsRecordType.SVCB */]: 'SVCB',
742
- [65 /* DnsRecordType.HTTPS */]: 'HTTPS',
743
- [99 /* DnsRecordType.SPF */]: 'SPF',
744
- [100 /* DnsRecordType.UINFO */]: 'UINFO',
745
- [101 /* DnsRecordType.UID */]: 'UID',
746
- [102 /* DnsRecordType.GID */]: 'GID',
747
- [103 /* DnsRecordType.UNSPEC */]: 'UNSPEC',
748
- [104 /* DnsRecordType.NID */]: 'NID',
749
- [105 /* DnsRecordType.L32 */]: 'L32',
750
- [106 /* DnsRecordType.L64 */]: 'L64',
751
- [107 /* DnsRecordType.LP */]: 'LP',
752
- [108 /* DnsRecordType.EUI48 */]: 'EUI48',
753
- [109 /* DnsRecordType.EUI64 */]: 'EUI64',
754
- [249 /* DnsRecordType.TKEY */]: 'TKEY',
755
- [250 /* DnsRecordType.TSIG */]: 'TSIG',
756
- [251 /* DnsRecordType.IXFR */]: 'IXFR',
757
- [252 /* DnsRecordType.AXFR */]: 'AXFR',
758
- [253 /* DnsRecordType.MAILB */]: 'MAILB',
759
- [254 /* DnsRecordType.MAILA */]: 'MAILA',
760
- [255 /* DnsRecordType.ANY */]: 'ANY',
761
- [256 /* DnsRecordType.URI */]: 'URI',
762
- [257 /* DnsRecordType.CAA */]: 'CAA',
763
- [258 /* DnsRecordType.AVC */]: 'AVC',
764
- [259 /* DnsRecordType.DOA */]: 'DOA',
765
- [260 /* DnsRecordType.AMTRELAY */]: 'AMTRELAY',
766
- [261 /* DnsRecordType.ZONEVERSION */]: 'ZONEVERSION',
767
- [32768 /* DnsRecordType.TA */]: 'TA',
768
- [32769 /* DnsRecordType.DLV */]: 'DLV',
517
+ [1]: 'A',
518
+ [2]: 'NS',
519
+ [3]: 'MD',
520
+ [4]: 'MF',
521
+ [5]: 'CNAME',
522
+ [6]: 'SOA',
523
+ [7]: 'MB',
524
+ [8]: 'MG',
525
+ [9]: 'MR',
526
+ [10]: 'NULL',
527
+ [11]: 'WKS',
528
+ [12]: 'PTR',
529
+ [13]: 'HINFO',
530
+ [14]: 'MINFO',
531
+ [15]: 'MX',
532
+ [16]: 'TXT',
533
+ [17]: 'RP',
534
+ [18]: 'AFSDB',
535
+ [19]: 'X25',
536
+ [20]: 'ISDN',
537
+ [21]: 'RT',
538
+ [22]: 'NSAP',
539
+ [23]: 'NSAP_PTR',
540
+ [24]: 'SIG',
541
+ [25]: 'KEY',
542
+ [26]: 'PX',
543
+ [27]: 'GPOS',
544
+ [28]: 'AAAA',
545
+ [29]: 'LOC',
546
+ [30]: 'NXT',
547
+ [31]: 'EID',
548
+ [32]: 'NIMLOC',
549
+ [33]: 'SRV',
550
+ [34]: 'ATMA',
551
+ [35]: 'NAPTR',
552
+ [36]: 'KX',
553
+ [37]: 'CERT',
554
+ [38]: 'A6',
555
+ [39]: 'DNAME',
556
+ [40]: 'SINK',
557
+ [41]: 'OPT',
558
+ [42]: 'APL',
559
+ [43]: 'DS',
560
+ [44]: 'SSHFP',
561
+ [45]: 'IPSECKEY',
562
+ [46]: 'RRSIG',
563
+ [47]: 'NSEC',
564
+ [48]: 'DNSKEY',
565
+ [49]: 'DHCID',
566
+ [50]: 'NSEC3',
567
+ [51]: 'NSEC3PARAM',
568
+ [52]: 'TLSA',
569
+ [53]: 'SMIMEA',
570
+ [55]: 'HIP',
571
+ [56]: 'NINFO',
572
+ [57]: 'RKEY',
573
+ [58]: 'TALINK',
574
+ [59]: 'CDS',
575
+ [60]: 'CDNSKEY',
576
+ [61]: 'OPENPGPKEY',
577
+ [62]: 'CSYNC',
578
+ [63]: 'ZONEMD',
579
+ [64]: 'SVCB',
580
+ [65]: 'HTTPS',
581
+ [99]: 'SPF',
582
+ [100]: 'UINFO',
583
+ [101]: 'UID',
584
+ [102]: 'GID',
585
+ [103]: 'UNSPEC',
586
+ [104]: 'NID',
587
+ [105]: 'L32',
588
+ [106]: 'L64',
589
+ [107]: 'LP',
590
+ [108]: 'EUI48',
591
+ [109]: 'EUI64',
592
+ [249]: 'TKEY',
593
+ [250]: 'TSIG',
594
+ [251]: 'IXFR',
595
+ [252]: 'AXFR',
596
+ [253]: 'MAILB',
597
+ [254]: 'MAILA',
598
+ [255]: 'ANY',
599
+ [256]: 'URI',
600
+ [257]: 'CAA',
601
+ [258]: 'AVC',
602
+ [259]: 'DOA',
603
+ [260]: 'AMTRELAY',
604
+ [261]: 'ZONEVERSION',
605
+ [32768]: 'TA',
606
+ [32769]: 'DLV',
769
607
  };
770
608
  return typeMap[type] ?? `TYPE${type}`;
771
609
  }
772
- /**
773
- * Converts a DNS response class numeric value to its string representation.
774
- *
775
- * @param {number} cls - The numeric DNS class.
776
- * @returns {string} The string representation of the DNS class.
777
- */
778
610
  dnsResponseClassToString(cls) {
779
- const isFlush = !!(cls & 32768 /* DnsClassFlag.FLUSH */);
611
+ const isFlush = !!(cls & 32768);
780
612
  const baseClass = cls & 0x7fff;
781
613
  let classStr;
782
614
  switch (baseClass) {
783
- case 1 /* DnsClass.IN */:
615
+ case 1:
784
616
  classStr = 'IN';
785
617
  break;
786
- case 3 /* DnsClass.CH */:
618
+ case 3:
787
619
  classStr = 'CH';
788
620
  break;
789
- case 4 /* DnsClass.HS */:
621
+ case 4:
790
622
  classStr = 'HS';
791
623
  break;
792
- case 255 /* DnsClass.ANY */:
624
+ case 255:
793
625
  classStr = 'ANY';
794
626
  break;
795
627
  default:
@@ -797,28 +629,21 @@ export class Mdns extends Multicast {
797
629
  }
798
630
  return isFlush ? `${classStr}|FLUSH` : classStr;
799
631
  }
800
- /**
801
- * Converts a DNS question class to a human-readable string.
802
- * Adds support for mDNS QU (unicast-response) bit.
803
- *
804
- * @param {number} cls - The numeric question class.
805
- * @returns {string} The string representation, e.g. "IN|QU"
806
- */
807
632
  dnsQuestionClassToString(cls) {
808
- const isQU = !!(cls & 32768 /* DnsClassFlag.QU */);
633
+ const isQU = !!(cls & 32768);
809
634
  const baseClass = cls & 0x7fff;
810
635
  let classStr;
811
636
  switch (baseClass) {
812
- case 1 /* DnsClass.IN */:
637
+ case 1:
813
638
  classStr = 'IN';
814
639
  break;
815
- case 3 /* DnsClass.CH */:
640
+ case 3:
816
641
  classStr = 'CH';
817
642
  break;
818
- case 4 /* DnsClass.HS */:
643
+ case 4:
819
644
  classStr = 'HS';
820
645
  break;
821
- case 255 /* DnsClass.ANY */:
646
+ case 255:
822
647
  classStr = 'ANY';
823
648
  break;
824
649
  default:
@@ -826,13 +651,6 @@ export class Mdns extends Multicast {
826
651
  }
827
652
  return isQU ? `${classStr}|QU` : classStr;
828
653
  }
829
- /**
830
- * Logs the decoded mDNS message header.
831
- *
832
- * @param {MdnsMessage} msg - The mDNS message header object.
833
- * @param {AnsiLogger} [log] - The logger to use (defaults to this.log).
834
- * @param {string} [text] - Optional additional text to include in the log.
835
- */
836
654
  logMdnsMessage(msg, log = this.log, text = 'Decoded mDNS message') {
837
655
  log.info(`${text}: ID ${MAGENTA}${msg.id}${nf}, QR ${GREEN}${msg.qr === 0 ? 'Query' : 'Response'}${nf}, OPCODE ${MAGENTA}${msg.opcode}${nf}, AA ${MAGENTA}${msg.aa}${nf}, TC ${MAGENTA}${msg.tc}${nf}, RD ${MAGENTA}${msg.rd}${nf}, RA ${MAGENTA}${msg.ra}${nf}, Z ${MAGENTA}${msg.z}${nf}, RCODE ${MAGENTA}${msg.rcode}${nf}, QDCount ${MAGENTA}${msg.qdCount}${nf}, ANCount ${MAGENTA}${msg.anCount}${nf}, NSCount ${MAGENTA}${msg.nsCount}${nf}, ARCount ${MAGENTA}${msg.arCount}${nf}`);
838
656
  msg.questions?.forEach((question) => {
@@ -849,14 +667,9 @@ export class Mdns extends Multicast {
849
667
  });
850
668
  log.info(`---\n`);
851
669
  }
852
- /**
853
- * Logs the discovered devices from the mDNS queries and responses.
854
- */
855
670
  logDevices() {
856
671
  this.log.info(`Discovered query devices: ${MAGENTA}${this.deviceQueries.size}${nf}`);
857
- // Collect devices into an array
858
672
  const deviceQueryArray = Array.from(this.deviceQueries.entries());
859
- // Sort the array by numeric value of the IP address
860
673
  deviceQueryArray.sort(([addressA], [addressB]) => {
861
674
  const partsA = addressA.split('.').map(Number);
862
675
  const partsB = addressB.split('.').map(Number);
@@ -865,17 +678,13 @@ export class Mdns extends Multicast {
865
678
  if (diff !== 0)
866
679
  return diff;
867
680
  }
868
- // istanbul ignore next
869
681
  return 0;
870
682
  });
871
- // Log the sorted devices
872
683
  deviceQueryArray.forEach(([rinfo, response]) => {
873
684
  this.log.info(`- ${MAGENTA}${rinfo}${nf} family ${BLUE}${response.rinfo.family}${nf} address ${BLUE}${response.rinfo.address}${nf} port ${BLUE}${response.rinfo.port}${nf}`);
874
685
  });
875
686
  this.log.info(`Discovered response devices: ${MAGENTA}${this.deviceResponses.size}${nf}`);
876
- // Collect devices into an array
877
687
  const deviceResponseArray = Array.from(this.deviceResponses.entries());
878
- // Sort the array by numeric value of the IP address
879
688
  deviceResponseArray.sort(([addressA], [addressB]) => {
880
689
  const partsA = addressA.split(/[:.]/).map((part) => parseInt(part, 16));
881
690
  const partsB = addressB.split(/[:.]/).map((part) => parseInt(part, 16));
@@ -884,13 +693,10 @@ export class Mdns extends Multicast {
884
693
  if (diff !== 0)
885
694
  return diff;
886
695
  }
887
- // istanbul ignore next
888
696
  return 0;
889
697
  });
890
- // Log the sorted devices
891
698
  deviceResponseArray.forEach(([rinfo, response]) => {
892
699
  this.log.info(`- ${MAGENTA}${rinfo}${nf} family ${BLUE}${response.rinfo.family}${nf} address ${BLUE}${response.rinfo.address}${nf} port ${BLUE}${response.rinfo.port}${nf} PTR ${GREEN}${response.dataPTR}${nf}`);
893
700
  });
894
701
  }
895
702
  }
896
- //# sourceMappingURL=mdns.js.map