@libp2p/mdns 9.0.13 → 9.0.14-97ab31c0c
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/index.min.js +10 -14
- package/dist/src/index.d.ts +1 -30
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +1 -113
- package/dist/src/index.js.map +1 -1
- package/dist/src/mdns.d.ts +52 -0
- package/dist/src/mdns.d.ts.map +1 -0
- package/dist/src/mdns.js +120 -0
- package/dist/src/mdns.js.map +1 -0
- package/dist/src/query.d.ts +4 -3
- package/dist/src/query.d.ts.map +1 -1
- package/dist/src/query.js +11 -14
- package/dist/src/query.js.map +1 -1
- package/package.json +9 -9
- package/src/index.ts +3 -180
- package/src/mdns.ts +166 -0
- package/src/query.ts +12 -15
- package/dist/typedoc-urls.json +0 -8
package/src/mdns.ts
ADDED
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import { CustomEvent, EventEmitter } from '@libp2p/interface/events'
|
|
2
|
+
import { peerDiscovery } from '@libp2p/interface/peer-discovery'
|
|
3
|
+
import multicastDNS from 'multicast-dns'
|
|
4
|
+
import * as query from './query.js'
|
|
5
|
+
import { stringGen } from './utils.js'
|
|
6
|
+
import type { ComponentLogger, Logger } from '@libp2p/interface'
|
|
7
|
+
import type { PeerDiscovery, PeerDiscoveryEvents } from '@libp2p/interface/peer-discovery'
|
|
8
|
+
import type { PeerInfo } from '@libp2p/interface/peer-info'
|
|
9
|
+
import type { Startable } from '@libp2p/interface/src/startable.js'
|
|
10
|
+
import type { AddressManager } from '@libp2p/interface-internal/address-manager'
|
|
11
|
+
|
|
12
|
+
export interface MulticastDNSInit {
|
|
13
|
+
broadcast?: boolean
|
|
14
|
+
interval?: number
|
|
15
|
+
serviceTag?: string
|
|
16
|
+
peerName?: string
|
|
17
|
+
port?: number
|
|
18
|
+
ip?: string
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface MulticastDNSComponents {
|
|
22
|
+
addressManager: AddressManager
|
|
23
|
+
logger: ComponentLogger
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export class MulticastDNS extends EventEmitter<PeerDiscoveryEvents> implements PeerDiscovery, Startable {
|
|
27
|
+
public mdns?: multicastDNS.MulticastDNS
|
|
28
|
+
|
|
29
|
+
private readonly log: Logger
|
|
30
|
+
private readonly broadcast: boolean
|
|
31
|
+
private readonly interval: number
|
|
32
|
+
private readonly serviceTag: string
|
|
33
|
+
private readonly peerName: string
|
|
34
|
+
private readonly port: number
|
|
35
|
+
private readonly ip: string
|
|
36
|
+
private _queryInterval: ReturnType<typeof setInterval> | null
|
|
37
|
+
private readonly components: MulticastDNSComponents
|
|
38
|
+
|
|
39
|
+
constructor (components: MulticastDNSComponents, init: MulticastDNSInit = {}) {
|
|
40
|
+
super()
|
|
41
|
+
|
|
42
|
+
this.log = components.logger.forComponent('libp2p:mdns')
|
|
43
|
+
this.broadcast = init.broadcast !== false
|
|
44
|
+
this.interval = init.interval ?? (1e3 * 10)
|
|
45
|
+
this.serviceTag = init.serviceTag ?? '_p2p._udp.local'
|
|
46
|
+
this.ip = init.ip ?? '224.0.0.251'
|
|
47
|
+
this.peerName = init.peerName ?? stringGen(63)
|
|
48
|
+
// 63 is dns label limit
|
|
49
|
+
if (this.peerName.length >= 64) {
|
|
50
|
+
throw new Error('Peer name should be less than 64 chars long')
|
|
51
|
+
}
|
|
52
|
+
this.port = init.port ?? 5353
|
|
53
|
+
this.components = components
|
|
54
|
+
this._queryInterval = null
|
|
55
|
+
this._onMdnsQuery = this._onMdnsQuery.bind(this)
|
|
56
|
+
this._onMdnsResponse = this._onMdnsResponse.bind(this)
|
|
57
|
+
this._onMdnsWarning = this._onMdnsWarning.bind(this)
|
|
58
|
+
this._onMdnsError = this._onMdnsError.bind(this)
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
readonly [peerDiscovery] = this
|
|
62
|
+
|
|
63
|
+
readonly [Symbol.toStringTag] = '@libp2p/mdns'
|
|
64
|
+
|
|
65
|
+
isStarted (): boolean {
|
|
66
|
+
return Boolean(this.mdns)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Start sending queries to the LAN.
|
|
71
|
+
*
|
|
72
|
+
* @returns {void}
|
|
73
|
+
*/
|
|
74
|
+
async start (): Promise<void> {
|
|
75
|
+
if (this.mdns != null) {
|
|
76
|
+
return
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
this.mdns = multicastDNS({ port: this.port, ip: this.ip })
|
|
80
|
+
this.mdns.on('query', this._onMdnsQuery)
|
|
81
|
+
this.mdns.on('response', this._onMdnsResponse)
|
|
82
|
+
this.mdns.on('warning', this._onMdnsWarning)
|
|
83
|
+
this.mdns.on('error', this._onMdnsError)
|
|
84
|
+
|
|
85
|
+
this._queryInterval = query.queryLAN(this.mdns, this.serviceTag, this.interval, {
|
|
86
|
+
log: this.log
|
|
87
|
+
})
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
_onMdnsQuery (event: multicastDNS.QueryPacket): void {
|
|
91
|
+
if (this.mdns == null) {
|
|
92
|
+
return
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
this.log.trace('received incoming mDNS query')
|
|
96
|
+
query.gotQuery(
|
|
97
|
+
event,
|
|
98
|
+
this.mdns,
|
|
99
|
+
this.peerName,
|
|
100
|
+
this.components.addressManager.getAddresses(),
|
|
101
|
+
this.serviceTag,
|
|
102
|
+
this.broadcast, {
|
|
103
|
+
log: this.log
|
|
104
|
+
}
|
|
105
|
+
)
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
_onMdnsResponse (event: multicastDNS.ResponsePacket): void {
|
|
109
|
+
this.log.trace('received mDNS query response')
|
|
110
|
+
|
|
111
|
+
try {
|
|
112
|
+
const foundPeer = query.gotResponse(event, this.peerName, this.serviceTag, {
|
|
113
|
+
log: this.log
|
|
114
|
+
})
|
|
115
|
+
|
|
116
|
+
if (foundPeer != null) {
|
|
117
|
+
this.log('discovered peer in mDNS query response %p', foundPeer.id)
|
|
118
|
+
|
|
119
|
+
this.dispatchEvent(new CustomEvent<PeerInfo>('peer', {
|
|
120
|
+
detail: foundPeer
|
|
121
|
+
}))
|
|
122
|
+
}
|
|
123
|
+
} catch (err) {
|
|
124
|
+
this.log.error('Error processing peer response', err)
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
_onMdnsWarning (err: Error): void {
|
|
129
|
+
this.log.error('mdns warning', err)
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
_onMdnsError (err: Error): void {
|
|
133
|
+
this.log.error('mdns error', err)
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Stop sending queries to the LAN.
|
|
138
|
+
*
|
|
139
|
+
* @returns {Promise}
|
|
140
|
+
*/
|
|
141
|
+
async stop (): Promise<void> {
|
|
142
|
+
if (this.mdns == null) {
|
|
143
|
+
return
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
this.mdns.removeListener('query', this._onMdnsQuery)
|
|
147
|
+
this.mdns.removeListener('response', this._onMdnsResponse)
|
|
148
|
+
this.mdns.removeListener('warning', this._onMdnsWarning)
|
|
149
|
+
this.mdns.removeListener('error', this._onMdnsError)
|
|
150
|
+
|
|
151
|
+
if (this._queryInterval != null) {
|
|
152
|
+
clearInterval(this._queryInterval)
|
|
153
|
+
this._queryInterval = null
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
await new Promise<void>((resolve) => {
|
|
157
|
+
if (this.mdns != null) {
|
|
158
|
+
this.mdns.destroy(resolve)
|
|
159
|
+
} else {
|
|
160
|
+
resolve()
|
|
161
|
+
}
|
|
162
|
+
})
|
|
163
|
+
|
|
164
|
+
this.mdns = undefined
|
|
165
|
+
}
|
|
166
|
+
}
|
package/src/query.ts
CHANGED
|
@@ -1,16 +1,14 @@
|
|
|
1
|
-
import { logger } from '@libp2p/logger'
|
|
2
1
|
import { peerIdFromString } from '@libp2p/peer-id'
|
|
3
2
|
import { isPrivate } from '@libp2p/utils/multiaddr/is-private'
|
|
4
3
|
import { multiaddr, type Multiaddr, protocols } from '@multiformats/multiaddr'
|
|
4
|
+
import type { LoggerOptions } from '@libp2p/interface'
|
|
5
5
|
import type { PeerInfo } from '@libp2p/interface/peer-info'
|
|
6
6
|
import type { Answer, StringAnswer, TxtAnswer } from 'dns-packet'
|
|
7
7
|
import type { MulticastDNS, QueryPacket, ResponsePacket } from 'multicast-dns'
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
export function queryLAN (mdns: MulticastDNS, serviceTag: string, interval: number): ReturnType<typeof setInterval> {
|
|
9
|
+
export function queryLAN (mdns: MulticastDNS, serviceTag: string, interval: number, options?: LoggerOptions): ReturnType<typeof setInterval> {
|
|
12
10
|
const query = (): void => {
|
|
13
|
-
log.trace('query', serviceTag)
|
|
11
|
+
options?.log.trace('query', serviceTag)
|
|
14
12
|
|
|
15
13
|
mdns.query({
|
|
16
14
|
questions: [{
|
|
@@ -25,7 +23,7 @@ export function queryLAN (mdns: MulticastDNS, serviceTag: string, interval: numb
|
|
|
25
23
|
return setInterval(query, interval)
|
|
26
24
|
}
|
|
27
25
|
|
|
28
|
-
export function gotResponse (rsp: ResponsePacket, localPeerName: string, serviceTag: string): PeerInfo | undefined {
|
|
26
|
+
export function gotResponse (rsp: ResponsePacket, localPeerName: string, serviceTag: string, options?: LoggerOptions): PeerInfo | undefined {
|
|
29
27
|
if (rsp.answers == null) {
|
|
30
28
|
return
|
|
31
29
|
}
|
|
@@ -70,21 +68,20 @@ export function gotResponse (rsp: ResponsePacket, localPeerName: string, service
|
|
|
70
68
|
if (peerId == null) {
|
|
71
69
|
throw new Error("Multiaddr doesn't contain PeerId")
|
|
72
70
|
}
|
|
73
|
-
log('peer found %p', peerId)
|
|
71
|
+
options?.log('peer found %p', peerId)
|
|
74
72
|
|
|
75
73
|
return {
|
|
76
74
|
id: peerIdFromString(peerId),
|
|
77
|
-
multiaddrs: multiaddrs.map(addr => addr.decapsulateCode(protocols('p2p').code))
|
|
78
|
-
protocols: []
|
|
75
|
+
multiaddrs: multiaddrs.map(addr => addr.decapsulateCode(protocols('p2p').code))
|
|
79
76
|
}
|
|
80
77
|
} catch (e) {
|
|
81
|
-
log.error('failed to parse mdns response', e)
|
|
78
|
+
options?.log.error('failed to parse mdns response', e)
|
|
82
79
|
}
|
|
83
80
|
}
|
|
84
81
|
|
|
85
|
-
export function gotQuery (qry: QueryPacket, mdns: MulticastDNS, peerName: string, multiaddrs: Multiaddr[], serviceTag: string, broadcast: boolean): void {
|
|
82
|
+
export function gotQuery (qry: QueryPacket, mdns: MulticastDNS, peerName: string, multiaddrs: Multiaddr[], serviceTag: string, broadcast: boolean, options?: LoggerOptions): void {
|
|
86
83
|
if (!broadcast) {
|
|
87
|
-
log('not responding to mDNS query as broadcast mode is false')
|
|
84
|
+
options?.log('not responding to mDNS query as broadcast mode is false')
|
|
88
85
|
return
|
|
89
86
|
}
|
|
90
87
|
|
|
@@ -113,13 +110,13 @@ export function gotQuery (qry: QueryPacket, mdns: MulticastDNS, peerName: string
|
|
|
113
110
|
// TXT record fields have a max data length of 255 bytes
|
|
114
111
|
// see 6.1 - https://www.ietf.org/rfc/rfc6763.txt
|
|
115
112
|
if (data.length > 255) {
|
|
116
|
-
log('multiaddr %a is too long to use in mDNS query response', addr)
|
|
113
|
+
options?.log('multiaddr %a is too long to use in mDNS query response', addr)
|
|
117
114
|
return
|
|
118
115
|
}
|
|
119
116
|
|
|
120
117
|
// spec mandates multiaddr contains peer id
|
|
121
118
|
if (addr.getPeerId() == null) {
|
|
122
|
-
log('multiaddr %a did not have a peer ID so cannot be used in mDNS query response', addr)
|
|
119
|
+
options?.log('multiaddr %a did not have a peer ID so cannot be used in mDNS query response', addr)
|
|
123
120
|
return
|
|
124
121
|
}
|
|
125
122
|
|
|
@@ -132,7 +129,7 @@ export function gotQuery (qry: QueryPacket, mdns: MulticastDNS, peerName: string
|
|
|
132
129
|
})
|
|
133
130
|
})
|
|
134
131
|
|
|
135
|
-
log.trace('responding to query')
|
|
132
|
+
options?.log.trace('responding to query')
|
|
136
133
|
mdns.respond(answers)
|
|
137
134
|
}
|
|
138
135
|
}
|
package/dist/typedoc-urls.json
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"MulticastDNSComponents": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_mdns.MulticastDNSComponents.html",
|
|
3
|
-
".:MulticastDNSComponents": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_mdns.MulticastDNSComponents.html",
|
|
4
|
-
"MulticastDNSInit": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_mdns.MulticastDNSInit.html",
|
|
5
|
-
".:MulticastDNSInit": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_mdns.MulticastDNSInit.html",
|
|
6
|
-
"mdns": "https://libp2p.github.io/js-libp2p/functions/_libp2p_mdns.mdns.html",
|
|
7
|
-
".:mdns": "https://libp2p.github.io/js-libp2p/functions/_libp2p_mdns.mdns.html"
|
|
8
|
-
}
|