@libp2p/mdns 9.0.14 → 10.0.0-06e6d235f

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/src/index.ts CHANGED
@@ -76,186 +76,9 @@
76
76
  * ```
77
77
  */
78
78
 
79
- import { CustomEvent, TypedEventEmitter } from '@libp2p/interface/events'
80
- import { peerDiscovery } from '@libp2p/interface/peer-discovery'
81
- import { logger } from '@libp2p/logger'
82
- import multicastDNS from 'multicast-dns'
83
- import * as query from './query.js'
84
- import { stringGen } from './utils.js'
85
- import type { PeerDiscovery, PeerDiscoveryEvents } from '@libp2p/interface/peer-discovery'
86
- import type { PeerInfo } from '@libp2p/interface/peer-info'
87
- import type { Startable } from '@libp2p/interface/src/startable.js'
88
- import type { AddressManager } from '@libp2p/interface-internal/address-manager'
89
-
90
- const log = logger('libp2p:mdns')
91
-
92
- export interface MulticastDNSInit {
93
- /**
94
- * (true/false) announce our presence through mDNS, default `true`
95
- */
96
- broadcast?: boolean
97
-
98
- /**
99
- * query interval, default 10 \* 1000 (10 seconds)
100
- */
101
- interval?: number
102
-
103
- /**
104
- * name of the service announce , default '_p2p._udp.local\`
105
- */
106
- serviceTag?: string
107
- /**
108
- * Peer name to announce (should not be peeer id), default random string
109
- */
110
- peerName?: string
111
-
112
- /**
113
- * UDP port to broadcast to
114
- */
115
- port?: number
116
-
117
- /**
118
- * UDP IP to broadcast to
119
- */
120
- ip?: string
121
- }
122
-
123
- export interface MulticastDNSComponents {
124
- addressManager: AddressManager
125
- }
126
-
127
- class MulticastDNS extends TypedEventEmitter<PeerDiscoveryEvents> implements PeerDiscovery, Startable {
128
- public mdns?: multicastDNS.MulticastDNS
129
-
130
- private readonly broadcast: boolean
131
- private readonly interval: number
132
- private readonly serviceTag: string
133
- private readonly peerName: string
134
- private readonly port: number
135
- private readonly ip: string
136
- private _queryInterval: ReturnType<typeof setInterval> | null
137
- private readonly components: MulticastDNSComponents
138
-
139
- constructor (components: MulticastDNSComponents, init: MulticastDNSInit = {}) {
140
- super()
141
-
142
- this.broadcast = init.broadcast !== false
143
- this.interval = init.interval ?? (1e3 * 10)
144
- this.serviceTag = init.serviceTag ?? '_p2p._udp.local'
145
- this.ip = init.ip ?? '224.0.0.251'
146
- this.peerName = init.peerName ?? stringGen(63)
147
- // 63 is dns label limit
148
- if (this.peerName.length >= 64) {
149
- throw new Error('Peer name should be less than 64 chars long')
150
- }
151
- this.port = init.port ?? 5353
152
- this.components = components
153
- this._queryInterval = null
154
- this._onMdnsQuery = this._onMdnsQuery.bind(this)
155
- this._onMdnsResponse = this._onMdnsResponse.bind(this)
156
- this._onMdnsWarning = this._onMdnsWarning.bind(this)
157
- this._onMdnsError = this._onMdnsError.bind(this)
158
- }
159
-
160
- readonly [peerDiscovery] = this
161
-
162
- readonly [Symbol.toStringTag] = '@libp2p/mdns'
163
-
164
- isStarted (): boolean {
165
- return Boolean(this.mdns)
166
- }
167
-
168
- /**
169
- * Start sending queries to the LAN.
170
- *
171
- * @returns {void}
172
- */
173
- async start (): Promise<void> {
174
- if (this.mdns != null) {
175
- return
176
- }
177
-
178
- this.mdns = multicastDNS({ port: this.port, ip: this.ip })
179
- this.mdns.on('query', this._onMdnsQuery)
180
- this.mdns.on('response', this._onMdnsResponse)
181
- this.mdns.on('warning', this._onMdnsWarning)
182
- this.mdns.on('error', this._onMdnsError)
183
-
184
- this._queryInterval = query.queryLAN(this.mdns, this.serviceTag, this.interval)
185
- }
186
-
187
- _onMdnsQuery (event: multicastDNS.QueryPacket): void {
188
- if (this.mdns == null) {
189
- return
190
- }
191
-
192
- log.trace('received incoming mDNS query')
193
- query.gotQuery(
194
- event,
195
- this.mdns,
196
- this.peerName,
197
- this.components.addressManager.getAddresses(),
198
- this.serviceTag,
199
- this.broadcast)
200
- }
201
-
202
- _onMdnsResponse (event: multicastDNS.ResponsePacket): void {
203
- log.trace('received mDNS query response')
204
-
205
- try {
206
- const foundPeer = query.gotResponse(event, this.peerName, this.serviceTag)
207
-
208
- if (foundPeer != null) {
209
- log('discovered peer in mDNS query response %p', foundPeer.id)
210
-
211
- this.dispatchEvent(new CustomEvent<PeerInfo>('peer', {
212
- detail: foundPeer
213
- }))
214
- }
215
- } catch (err) {
216
- log.error('Error processing peer response', err)
217
- }
218
- }
219
-
220
- _onMdnsWarning (err: Error): void {
221
- log.error('mdns warning', err)
222
- }
223
-
224
- _onMdnsError (err: Error): void {
225
- log.error('mdns error', err)
226
- }
227
-
228
- /**
229
- * Stop sending queries to the LAN.
230
- *
231
- * @returns {Promise}
232
- */
233
- async stop (): Promise<void> {
234
- if (this.mdns == null) {
235
- return
236
- }
237
-
238
- this.mdns.removeListener('query', this._onMdnsQuery)
239
- this.mdns.removeListener('response', this._onMdnsResponse)
240
- this.mdns.removeListener('warning', this._onMdnsWarning)
241
- this.mdns.removeListener('error', this._onMdnsError)
242
-
243
- if (this._queryInterval != null) {
244
- clearInterval(this._queryInterval)
245
- this._queryInterval = null
246
- }
247
-
248
- await new Promise<void>((resolve) => {
249
- if (this.mdns != null) {
250
- this.mdns.destroy(resolve)
251
- } else {
252
- resolve()
253
- }
254
- })
255
-
256
- this.mdns = undefined
257
- }
258
- }
79
+ import { MulticastDNS } from './mdns.js'
80
+ import type { MulticastDNSInit, MulticastDNSComponents } from './mdns.js'
81
+ import type { PeerDiscovery } from '@libp2p/interface'
259
82
 
260
83
  export function mdns (init: MulticastDNSInit = {}): (components: MulticastDNSComponents) => PeerDiscovery {
261
84
  return (components: MulticastDNSComponents) => new MulticastDNS(components, init)
package/src/mdns.ts ADDED
@@ -0,0 +1,162 @@
1
+ import { CustomEvent, TypedEventEmitter, peerDiscoverySymbol } from '@libp2p/interface'
2
+ import multicastDNS from 'multicast-dns'
3
+ import * as query from './query.js'
4
+ import { stringGen } from './utils.js'
5
+ import type { ComponentLogger, Logger, PeerDiscovery, PeerDiscoveryEvents, PeerInfo, Startable } from '@libp2p/interface'
6
+ import type { AddressManager } from '@libp2p/interface-internal'
7
+
8
+ export interface MulticastDNSInit {
9
+ broadcast?: boolean
10
+ interval?: number
11
+ serviceTag?: string
12
+ peerName?: string
13
+ port?: number
14
+ ip?: string
15
+ }
16
+
17
+ export interface MulticastDNSComponents {
18
+ addressManager: AddressManager
19
+ logger: ComponentLogger
20
+ }
21
+
22
+ export class MulticastDNS extends TypedEventEmitter<PeerDiscoveryEvents> implements PeerDiscovery, Startable {
23
+ public mdns?: multicastDNS.MulticastDNS
24
+
25
+ private readonly log: Logger
26
+ private readonly broadcast: boolean
27
+ private readonly interval: number
28
+ private readonly serviceTag: string
29
+ private readonly peerName: string
30
+ private readonly port: number
31
+ private readonly ip: string
32
+ private _queryInterval: ReturnType<typeof setInterval> | null
33
+ private readonly components: MulticastDNSComponents
34
+
35
+ constructor (components: MulticastDNSComponents, init: MulticastDNSInit = {}) {
36
+ super()
37
+
38
+ this.log = components.logger.forComponent('libp2p:mdns')
39
+ this.broadcast = init.broadcast !== false
40
+ this.interval = init.interval ?? (1e3 * 10)
41
+ this.serviceTag = init.serviceTag ?? '_p2p._udp.local'
42
+ this.ip = init.ip ?? '224.0.0.251'
43
+ this.peerName = init.peerName ?? stringGen(63)
44
+ // 63 is dns label limit
45
+ if (this.peerName.length >= 64) {
46
+ throw new Error('Peer name should be less than 64 chars long')
47
+ }
48
+ this.port = init.port ?? 5353
49
+ this.components = components
50
+ this._queryInterval = null
51
+ this._onMdnsQuery = this._onMdnsQuery.bind(this)
52
+ this._onMdnsResponse = this._onMdnsResponse.bind(this)
53
+ this._onMdnsWarning = this._onMdnsWarning.bind(this)
54
+ this._onMdnsError = this._onMdnsError.bind(this)
55
+ }
56
+
57
+ readonly [peerDiscoverySymbol] = this
58
+
59
+ readonly [Symbol.toStringTag] = '@libp2p/mdns'
60
+
61
+ isStarted (): boolean {
62
+ return Boolean(this.mdns)
63
+ }
64
+
65
+ /**
66
+ * Start sending queries to the LAN.
67
+ *
68
+ * @returns {void}
69
+ */
70
+ async start (): Promise<void> {
71
+ if (this.mdns != null) {
72
+ return
73
+ }
74
+
75
+ this.mdns = multicastDNS({ port: this.port, ip: this.ip })
76
+ this.mdns.on('query', this._onMdnsQuery)
77
+ this.mdns.on('response', this._onMdnsResponse)
78
+ this.mdns.on('warning', this._onMdnsWarning)
79
+ this.mdns.on('error', this._onMdnsError)
80
+
81
+ this._queryInterval = query.queryLAN(this.mdns, this.serviceTag, this.interval, {
82
+ log: this.log
83
+ })
84
+ }
85
+
86
+ _onMdnsQuery (event: multicastDNS.QueryPacket): void {
87
+ if (this.mdns == null) {
88
+ return
89
+ }
90
+
91
+ this.log.trace('received incoming mDNS query')
92
+ query.gotQuery(
93
+ event,
94
+ this.mdns,
95
+ this.peerName,
96
+ this.components.addressManager.getAddresses(),
97
+ this.serviceTag,
98
+ this.broadcast, {
99
+ log: this.log
100
+ }
101
+ )
102
+ }
103
+
104
+ _onMdnsResponse (event: multicastDNS.ResponsePacket): void {
105
+ this.log.trace('received mDNS query response')
106
+
107
+ try {
108
+ const foundPeer = query.gotResponse(event, this.peerName, this.serviceTag, {
109
+ log: this.log
110
+ })
111
+
112
+ if (foundPeer != null) {
113
+ this.log('discovered peer in mDNS query response %p', foundPeer.id)
114
+
115
+ this.dispatchEvent(new CustomEvent<PeerInfo>('peer', {
116
+ detail: foundPeer
117
+ }))
118
+ }
119
+ } catch (err) {
120
+ this.log.error('Error processing peer response', err)
121
+ }
122
+ }
123
+
124
+ _onMdnsWarning (err: Error): void {
125
+ this.log.error('mdns warning', err)
126
+ }
127
+
128
+ _onMdnsError (err: Error): void {
129
+ this.log.error('mdns error', err)
130
+ }
131
+
132
+ /**
133
+ * Stop sending queries to the LAN.
134
+ *
135
+ * @returns {Promise}
136
+ */
137
+ async stop (): Promise<void> {
138
+ if (this.mdns == null) {
139
+ return
140
+ }
141
+
142
+ this.mdns.removeListener('query', this._onMdnsQuery)
143
+ this.mdns.removeListener('response', this._onMdnsResponse)
144
+ this.mdns.removeListener('warning', this._onMdnsWarning)
145
+ this.mdns.removeListener('error', this._onMdnsError)
146
+
147
+ if (this._queryInterval != null) {
148
+ clearInterval(this._queryInterval)
149
+ this._queryInterval = null
150
+ }
151
+
152
+ await new Promise<void>((resolve) => {
153
+ if (this.mdns != null) {
154
+ this.mdns.destroy(resolve)
155
+ } else {
156
+ resolve()
157
+ }
158
+ })
159
+
160
+ this.mdns = undefined
161
+ }
162
+ }
package/src/query.ts CHANGED
@@ -1,16 +1,13 @@
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'
5
- import type { PeerInfo } from '@libp2p/interface/peer-info'
4
+ import type { LoggerOptions, PeerInfo } from '@libp2p/interface'
6
5
  import type { Answer, StringAnswer, TxtAnswer } from 'dns-packet'
7
6
  import type { MulticastDNS, QueryPacket, ResponsePacket } from 'multicast-dns'
8
7
 
9
- const log = logger('libp2p:mdns:query')
10
-
11
- export function queryLAN (mdns: MulticastDNS, serviceTag: string, interval: number): ReturnType<typeof setInterval> {
8
+ export function queryLAN (mdns: MulticastDNS, serviceTag: string, interval: number, options?: LoggerOptions): ReturnType<typeof setInterval> {
12
9
  const query = (): void => {
13
- log.trace('query', serviceTag)
10
+ options?.log.trace('query', serviceTag)
14
11
 
15
12
  mdns.query({
16
13
  questions: [{
@@ -25,7 +22,7 @@ export function queryLAN (mdns: MulticastDNS, serviceTag: string, interval: numb
25
22
  return setInterval(query, interval)
26
23
  }
27
24
 
28
- export function gotResponse (rsp: ResponsePacket, localPeerName: string, serviceTag: string): PeerInfo | undefined {
25
+ export function gotResponse (rsp: ResponsePacket, localPeerName: string, serviceTag: string, options?: LoggerOptions): PeerInfo | undefined {
29
26
  if (rsp.answers == null) {
30
27
  return
31
28
  }
@@ -70,21 +67,20 @@ export function gotResponse (rsp: ResponsePacket, localPeerName: string, service
70
67
  if (peerId == null) {
71
68
  throw new Error("Multiaddr doesn't contain PeerId")
72
69
  }
73
- log('peer found %p', peerId)
70
+ options?.log('peer found %p', peerId)
74
71
 
75
72
  return {
76
73
  id: peerIdFromString(peerId),
77
- multiaddrs: multiaddrs.map(addr => addr.decapsulateCode(protocols('p2p').code)),
78
- protocols: []
74
+ multiaddrs: multiaddrs.map(addr => addr.decapsulateCode(protocols('p2p').code))
79
75
  }
80
76
  } catch (e) {
81
- log.error('failed to parse mdns response', e)
77
+ options?.log.error('failed to parse mdns response', e)
82
78
  }
83
79
  }
84
80
 
85
- export function gotQuery (qry: QueryPacket, mdns: MulticastDNS, peerName: string, multiaddrs: Multiaddr[], serviceTag: string, broadcast: boolean): void {
81
+ export function gotQuery (qry: QueryPacket, mdns: MulticastDNS, peerName: string, multiaddrs: Multiaddr[], serviceTag: string, broadcast: boolean, options?: LoggerOptions): void {
86
82
  if (!broadcast) {
87
- log('not responding to mDNS query as broadcast mode is false')
83
+ options?.log('not responding to mDNS query as broadcast mode is false')
88
84
  return
89
85
  }
90
86
 
@@ -113,13 +109,13 @@ export function gotQuery (qry: QueryPacket, mdns: MulticastDNS, peerName: string
113
109
  // TXT record fields have a max data length of 255 bytes
114
110
  // see 6.1 - https://www.ietf.org/rfc/rfc6763.txt
115
111
  if (data.length > 255) {
116
- log('multiaddr %a is too long to use in mDNS query response', addr)
112
+ options?.log('multiaddr %a is too long to use in mDNS query response', addr)
117
113
  return
118
114
  }
119
115
 
120
116
  // spec mandates multiaddr contains peer id
121
117
  if (addr.getPeerId() == null) {
122
- log('multiaddr %a did not have a peer ID so cannot be used in mDNS query response', addr)
118
+ options?.log('multiaddr %a did not have a peer ID so cannot be used in mDNS query response', addr)
123
119
  return
124
120
  }
125
121
 
@@ -132,7 +128,7 @@ export function gotQuery (qry: QueryPacket, mdns: MulticastDNS, peerName: string
132
128
  })
133
129
  })
134
130
 
135
- log.trace('responding to query')
131
+ options?.log.trace('responding to query')
136
132
  mdns.respond(answers)
137
133
  }
138
134
  }
@@ -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
- }