0
# Multicast DNS
1
2
Multicast DNS provides a low-level multicast DNS (mDNS) implementation in pure JavaScript for Node.js applications. It enables service discovery on local networks by implementing the mDNS protocol (RFC 6762) which allows devices to discover services without requiring a centralized DNS server.
3
4
## Package Information
5
6
- **Package Name**: multicast-dns
7
- **Package Type**: npm
8
- **Language**: JavaScript
9
- **Installation**: `npm install multicast-dns`
10
11
## Core Imports
12
13
```javascript
14
const mdns = require('multicast-dns');
15
```
16
17
## Basic Usage
18
19
```javascript
20
const mdns = require('multicast-dns')();
21
22
// Listen for DNS responses
23
mdns.on('response', function(response) {
24
console.log('got a response packet:', response);
25
});
26
27
// Listen for DNS queries
28
mdns.on('query', function(query) {
29
console.log('got a query packet:', query);
30
31
// Respond to A record queries for 'example.local'
32
query.questions.forEach(function(q) {
33
if (q.type === 'A' && q.name === 'example.local') {
34
mdns.respond({
35
answers: [{
36
name: 'example.local',
37
type: 'A',
38
ttl: 300,
39
data: '192.168.1.5'
40
}]
41
});
42
}
43
});
44
});
45
46
// Query for an A record
47
mdns.query({
48
questions: [{
49
name: 'example.local',
50
type: 'A'
51
}]
52
});
53
```
54
55
## CLI Interface
56
57
The package includes a command-line tool for basic mDNS operations.
58
59
**Installation for global use:**
60
```bash
61
npm install -g multicast-dns
62
```
63
64
**Usage:**
65
```bash
66
# Query for a hostname (resolve to IP)
67
multicast-dns example.local
68
# Output: 192.168.1.5
69
70
# Announce a hostname (advertise current machine)
71
multicast-dns --announce example.local
72
```
73
74
The CLI tool automatically detects the local IP address for announcements and provides a simple interface for common mDNS operations.
75
76
## Architecture
77
78
Multicast DNS is built around several key components:
79
80
- **Factory Function**: Main module export creates configured mDNS instances
81
- **EventEmitter Interface**: All instances inherit from Node.js EventEmitter for event-driven communication
82
- **UDP Socket Management**: Handles IPv4/IPv6 multicast socket creation and membership management
83
- **DNS Packet Processing**: Uses dns-packet library for encoding/decoding DNS messages
84
- **Network Interface Discovery**: Automatically discovers and manages multicast group memberships across network interfaces
85
86
## Capabilities
87
88
### mDNS Instance Creation
89
90
Creates a new multicast DNS instance with configurable network and protocol options.
91
92
```javascript { .api }
93
/**
94
* Creates a new multicast DNS instance
95
* @param {Object} [options] - Configuration options
96
* @param {number} [options.port=5353] - UDP port number
97
* @param {string} [options.type='udp4'] - Socket type ('udp4' or 'udp6')
98
* @param {string} [options.ip='224.0.0.251'] - Multicast IP address
99
* @param {string} [options.host] - Alias for ip option
100
* @param {string|string[]} [options.interface] - Network interface(s) to bind to
101
* @param {boolean} [options.multicast=true] - Enable multicast functionality
102
* @param {number} [options.ttl=255] - Multicast TTL value
103
* @param {boolean} [options.loopback=true] - Receive own multicast packets
104
* @param {boolean} [options.reuseAddr=true] - Enable SO_REUSEADDR socket option
105
* @param {string|boolean} [options.bind] - Bind address or false to disable binding
106
* @param {dgram.Socket} [options.socket] - Pre-existing socket to use
107
* @returns {EventEmitter} mDNS instance with query/response capabilities
108
*/
109
function multicastdns(options)
110
```
111
112
### DNS Query Operations
113
114
Send DNS queries to discover services and devices on the local network.
115
116
```javascript { .api }
117
/**
118
* Send a DNS query packet
119
* @param {string|Object|Object[]} query - Query specification
120
* @param {string} [type] - DNS record type when query is a string
121
* @param {Object} [rinfo] - Target address information
122
* @param {Function} [callback] - Completion callback
123
*/
124
mdns.query(query, type, rinfo, callback)
125
```
126
127
**Query Format Options:**
128
129
```javascript { .api }
130
// String format with explicit type
131
mdns.query('example.local', 'A');
132
133
// String format with callback (defaults to 'ANY' type)
134
mdns.query('example.local', callback);
135
136
// String format with type and callback
137
mdns.query('example.local', 'A', callback);
138
139
// Array of question objects
140
mdns.query([{name: 'example.local', type: 'A'}]);
141
142
// Full packet object
143
mdns.query({
144
questions: [{name: 'example.local', type: 'A'}]
145
});
146
```
147
148
### DNS Response Operations
149
150
Send DNS responses to advertise services and answer queries from other devices.
151
152
```javascript { .api }
153
/**
154
* Send a DNS response packet
155
* @param {Object[]|Object} response - Response data
156
* @param {Object} [rinfo] - Target address information
157
* @param {Function} [callback] - Completion callback
158
*/
159
mdns.respond(response, rinfo, callback)
160
161
/**
162
* Alias for respond method - identical signature
163
* @param {Object[]|Object} response - Response data
164
* @param {Object} [rinfo] - Target address information
165
* @param {Function} [callback] - Completion callback
166
*/
167
mdns.response(response, rinfo, callback)
168
```
169
170
**Response Format Options:**
171
172
```javascript { .api }
173
// Array of answer records
174
mdns.respond([{
175
name: 'example.local',
176
type: 'A',
177
ttl: 300,
178
data: '192.168.1.5'
179
}]);
180
181
// Full packet object
182
mdns.respond({
183
answers: [{name: 'example.local', type: 'A', data: '192.168.1.5'}]
184
});
185
```
186
187
### Packet Transmission
188
189
Low-level packet sending for custom DNS operations.
190
191
```javascript { .api }
192
/**
193
* Send a raw DNS packet
194
* @param {Object} packet - DNS packet object
195
* @param {Object} [rinfo] - Target address information
196
* @param {Function} [callback] - Completion callback
197
*/
198
mdns.send(packet, rinfo, callback)
199
```
200
201
### Instance Management
202
203
Control the lifecycle and network configuration of mDNS instances.
204
205
```javascript { .api }
206
/**
207
* Destroy the mDNS instance and close the UDP socket
208
* @param {Function} [callback] - Completion callback
209
*/
210
mdns.destroy(callback)
211
212
/**
213
* Update multicast group memberships for current network interfaces
214
*/
215
mdns.update()
216
```
217
218
## Events
219
220
### DNS Packet Events
221
222
```javascript { .api }
223
/**
224
* Emitted for all incoming DNS packets
225
* @param {Object} packet - Decoded DNS packet
226
* @param {Object} rinfo - Remote address information
227
*/
228
mdns.on('packet', function(packet, rinfo) {})
229
230
/**
231
* Emitted for incoming DNS query packets
232
* @param {Object} query - DNS query packet
233
* @param {Object} rinfo - Remote address information
234
*/
235
mdns.on('query', function(query, rinfo) {})
236
237
/**
238
* Emitted for incoming DNS response packets
239
* @param {Object} response - DNS response packet
240
* @param {Object} rinfo - Remote address information
241
*/
242
mdns.on('response', function(response, rinfo) {})
243
```
244
245
### Lifecycle Events
246
247
```javascript { .api }
248
/**
249
* Emitted when the socket is bound and ready to send/receive
250
*/
251
mdns.on('ready', function() {})
252
253
/**
254
* Emitted when network interface memberships are updated
255
*/
256
mdns.on('networkInterface', function() {})
257
```
258
259
### Error Events
260
261
```javascript { .api }
262
/**
263
* Emitted for critical socket errors (EACCES, EADDRINUSE)
264
* @param {Error} error - Error object
265
*/
266
mdns.on('error', function(error) {})
267
268
/**
269
* Emitted for non-critical errors and warnings
270
* @param {Error} error - Error object
271
*/
272
mdns.on('warning', function(error) {})
273
```
274
275
## Data Structures
276
277
### DNS Packet Structure
278
279
```javascript { .api }
280
interface DNSPacket {
281
type: 'query' | 'response';
282
questions: Question[];
283
answers: Record[];
284
authorities: Record[];
285
additionals: Record[];
286
flags?: number;
287
flag_aa?: boolean; // Authoritative Answer flag
288
}
289
```
290
291
### Question Structure
292
293
```javascript { .api }
294
interface Question {
295
name: string; // Domain name (e.g., 'example.local')
296
type: string; // Record type ('A', 'AAAA', 'SRV', 'PTR', 'TXT', 'HINFO', 'ANY')
297
class: string; // Usually 'IN'
298
}
299
```
300
301
### Record Structure
302
303
```javascript { .api }
304
interface Record {
305
name: string; // Domain name
306
type: string; // Record type
307
class: string; // Usually 'IN'
308
ttl: number; // Time to live in seconds
309
data: any; // Record-specific data (see Record Data Types)
310
flush?: boolean; // Cache flush bit for mDNS
311
}
312
```
313
314
### Record Data Types
315
316
```javascript { .api }
317
// A Record - IPv4 address
318
// data: string (e.g., '192.168.1.5')
319
320
// AAAA Record - IPv6 address
321
// data: string (e.g., 'fe80::5ef9:38ff:fe8c:ceaa')
322
323
// SRV Record - Service record
324
// data: {
325
// port: number, // Service port number
326
// target: string, // Target hostname
327
// priority: number, // Priority value (lower = higher priority)
328
// weight: number // Weight for same priority services
329
// }
330
331
// TXT Record - Text data
332
// data: Buffer[] | string[] // Array of text strings or buffers
333
334
// PTR Record - Pointer record
335
// data: string // Target domain name
336
337
// HINFO Record - Host information
338
// data: {
339
// cpu: string, // CPU type
340
// os: string // Operating system
341
// }
342
```
343
344
### Remote Info Structure
345
346
```javascript { .api }
347
interface RemoteInfo {
348
address: string; // Remote IP address
349
port: number; // Remote port number
350
family: string; // 'IPv4' or 'IPv6'
351
size: number; // Message size in bytes
352
}
353
```
354
355
## Usage Examples
356
357
### Service Discovery
358
359
```javascript
360
const mdns = require('multicast-dns')();
361
362
// Discover all services
363
mdns.query('_services._dns-sd._udp.local', 'PTR');
364
365
mdns.on('response', function(response) {
366
response.answers.forEach(function(answer) {
367
if (answer.type === 'PTR') {
368
console.log('Found service:', answer.data);
369
}
370
});
371
});
372
```
373
374
### Service Advertisement
375
376
```javascript
377
const mdns = require('multicast-dns')();
378
379
mdns.on('query', function(query) {
380
query.questions.forEach(function(question) {
381
if (question.name === '_http._tcp.local' && question.type === 'PTR') {
382
mdns.respond({
383
answers: [{
384
name: '_http._tcp.local',
385
type: 'PTR',
386
ttl: 120,
387
data: 'My Web Server._http._tcp.local'
388
}],
389
additionals: [{
390
name: 'My Web Server._http._tcp.local',
391
type: 'SRV',
392
ttl: 120,
393
data: {
394
port: 8080,
395
target: 'my-server.local',
396
priority: 0,
397
weight: 5
398
}
399
}, {
400
name: 'my-server.local',
401
type: 'A',
402
ttl: 120,
403
data: '192.168.1.100'
404
}]
405
});
406
}
407
});
408
});
409
```
410
411
### IPv6 Configuration
412
413
**Important**: IPv6 multicast requires both `ip` and `interface` options to be specified or it will throw an error.
414
415
```javascript
416
const mdns = require('multicast-dns')({
417
type: 'udp6',
418
ip: 'ff02::fb', // Required for IPv6
419
interface: 'eth0' // Required for IPv6
420
});
421
422
mdns.query('example.local', 'AAAA');
423
424
// This will throw an error:
425
// const mdns = require('multicast-dns')({type: 'udp6'}); // Missing ip and interface
426
```
427
428
### Custom Network Interface
429
430
```javascript
431
const mdns = require('multicast-dns')({
432
interface: '192.168.1.100', // Bind to specific interface
433
port: 5353
434
});
435
436
// Listen on multiple interfaces
437
const mdns2 = require('multicast-dns')({
438
interface: ['192.168.1.100', '10.0.0.100']
439
});
440
```
441
442
## Error Handling
443
444
The library categorizes errors into critical and non-critical types:
445
446
- **Critical errors** (emit 'error'): EACCES (permission denied), EADDRINUSE (port in use)
447
- **Non-critical errors** (emit 'warning'): Invalid DNS packets, network interface issues, socket warnings
448
449
```javascript
450
const mdns = require('multicast-dns')();
451
452
mdns.on('error', function(err) {
453
console.error('Critical error:', err.message);
454
// Handle critical errors - may need to recreate instance
455
});
456
457
mdns.on('warning', function(err) {
458
console.warn('Warning:', err.message);
459
// Handle warnings - instance continues operating
460
});
461
```