@libp2p/mdns 0.18.0 → 1.0.2
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/README.md +2 -2
- package/dist/src/compat/index.d.ts +10 -12
- package/dist/src/compat/index.d.ts.map +1 -1
- package/dist/src/compat/index.js +10 -10
- package/dist/src/compat/index.js.map +1 -1
- package/dist/src/compat/querier.d.ts +9 -9
- package/dist/src/compat/querier.d.ts.map +1 -1
- package/dist/src/compat/querier.js +25 -68
- package/dist/src/compat/querier.js.map +1 -1
- package/dist/src/compat/responder.d.ts +5 -10
- package/dist/src/compat/responder.d.ts.map +1 -1
- package/dist/src/compat/responder.js +39 -40
- package/dist/src/compat/responder.js.map +1 -1
- package/dist/src/compat/utils.d.ts +5 -0
- package/dist/src/compat/utils.d.ts.map +1 -0
- package/dist/src/compat/utils.js +70 -0
- package/dist/src/compat/utils.js.map +1 -0
- package/dist/src/index.d.ts +8 -12
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +28 -21
- package/dist/src/index.js.map +1 -1
- package/dist/src/query.d.ts +1 -1
- package/dist/src/query.d.ts.map +1 -1
- package/dist/src/query.js +15 -15
- package/dist/src/query.js.map +1 -1
- package/package.json +11 -11
- package/src/compat/index.ts +19 -14
- package/src/compat/querier.ts +31 -80
- package/src/compat/responder.ts +46 -54
- package/src/compat/utils.ts +81 -0
- package/src/index.ts +36 -31
- package/src/query.ts +18 -15
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import type { PeerData } from '@libp2p/interfaces/peer-data'
|
|
2
|
+
import type { PeerId } from '@libp2p/interfaces/peer-id'
|
|
3
|
+
import { logger } from '@libp2p/logger'
|
|
4
|
+
import { peerIdFromString } from '@libp2p/peer-id'
|
|
5
|
+
import { Multiaddr } from '@multiformats/multiaddr'
|
|
6
|
+
import type { Answer } from 'dns-packet'
|
|
7
|
+
import { SERVICE_TAG_LOCAL } from './constants.js'
|
|
8
|
+
|
|
9
|
+
const log = logger('libp2p:mdns:compat:utils')
|
|
10
|
+
|
|
11
|
+
export function findPeerDataInAnswers (answers: Answer[], ourPeerId: PeerId): PeerData | undefined {
|
|
12
|
+
const ptrRecord = answers.find(a => a.type === 'PTR' && a.name === SERVICE_TAG_LOCAL)
|
|
13
|
+
|
|
14
|
+
// Only deal with responses for our service tag
|
|
15
|
+
if (ptrRecord == null) {
|
|
16
|
+
return
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
log.trace('got response', SERVICE_TAG_LOCAL)
|
|
20
|
+
|
|
21
|
+
const txtRecord = answers.find(a => a.type === 'TXT')
|
|
22
|
+
if (txtRecord == null || txtRecord.type !== 'TXT') {
|
|
23
|
+
log('missing TXT record in response')
|
|
24
|
+
return
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
let peerIdStr: string
|
|
28
|
+
try {
|
|
29
|
+
peerIdStr = txtRecord.data[0].toString()
|
|
30
|
+
} catch (err) {
|
|
31
|
+
log('failed to extract peer ID from TXT record data', txtRecord, err)
|
|
32
|
+
return
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
let peerId: PeerId
|
|
36
|
+
try {
|
|
37
|
+
peerId = peerIdFromString(peerIdStr)
|
|
38
|
+
} catch (err) {
|
|
39
|
+
log('failed to create peer ID from TXT record data', peerIdStr, err)
|
|
40
|
+
return
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (ourPeerId.equals(peerId)) {
|
|
44
|
+
log('ignoring reply to myself')
|
|
45
|
+
return
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const multiaddrs: Multiaddr[] = []
|
|
49
|
+
const hosts: { A: Record<string, string>, AAAA: Record<string, string> } = {
|
|
50
|
+
A: {},
|
|
51
|
+
AAAA: {}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
answers.forEach(answer => {
|
|
55
|
+
if (answer.type === 'A') {
|
|
56
|
+
hosts.A[answer.name] = answer.data
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (answer.type === 'AAAA') {
|
|
60
|
+
hosts.AAAA[answer.name] = answer.data
|
|
61
|
+
}
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
answers.forEach(answer => {
|
|
65
|
+
if (answer.type === 'SRV') {
|
|
66
|
+
if (hosts.A[answer.data.target] != null) {
|
|
67
|
+
multiaddrs.push(new Multiaddr(`/ip4/${hosts.A[answer.data.target]}/tcp/${answer.data.port}/p2p/${peerId.toString()}`))
|
|
68
|
+
} else if (hosts.AAAA[answer.data.target] != null) {
|
|
69
|
+
multiaddrs.push(new Multiaddr(`/ip6/${hosts.AAAA[answer.data.target]}/tcp/${answer.data.port}/p2p/${peerId.toString()}`))
|
|
70
|
+
} else {
|
|
71
|
+
multiaddrs.push(new Multiaddr(`/dnsaddr/${answer.data.target}/tcp/${answer.data.port}/p2p/${peerId.toString()}`))
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
return {
|
|
77
|
+
id: peerId,
|
|
78
|
+
multiaddrs,
|
|
79
|
+
protocols: []
|
|
80
|
+
}
|
|
81
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -1,30 +1,25 @@
|
|
|
1
1
|
import multicastDNS from 'multicast-dns'
|
|
2
|
-
import { EventEmitter } from '
|
|
3
|
-
import
|
|
2
|
+
import { CustomEvent, EventEmitter } from '@libp2p/interfaces'
|
|
3
|
+
import { logger } from '@libp2p/logger'
|
|
4
4
|
import * as query from './query.js'
|
|
5
5
|
import { GoMulticastDNS } from './compat/index.js'
|
|
6
|
-
import type {
|
|
7
|
-
import type PeerDiscovery from '@libp2p/interfaces/peer-discovery'
|
|
8
|
-
import type { Multiaddr } from '@multiformats/multiaddr'
|
|
6
|
+
import type { PeerDiscovery, PeerDiscoveryEvents } from '@libp2p/interfaces/peer-discovery'
|
|
9
7
|
import type { PeerData } from '@libp2p/interfaces/peer-data'
|
|
8
|
+
import { Components, Initializable } from '@libp2p/interfaces/components'
|
|
10
9
|
|
|
11
|
-
const log =
|
|
12
|
-
error: debug('libp2p:mdns:error')
|
|
13
|
-
})
|
|
10
|
+
const log = logger('libp2p:mdns')
|
|
14
11
|
|
|
15
12
|
export interface MulticastDNSOptions {
|
|
16
|
-
peerId: PeerId
|
|
17
13
|
broadcast?: boolean
|
|
18
14
|
interval?: number
|
|
19
15
|
serviceTag?: string
|
|
20
16
|
port?: number
|
|
21
|
-
multiaddrs?: Multiaddr[]
|
|
22
17
|
compat?: boolean
|
|
23
18
|
compatQueryPeriod?: number
|
|
24
19
|
compatQueryInterval?: number
|
|
25
20
|
}
|
|
26
21
|
|
|
27
|
-
export class MulticastDNS extends EventEmitter implements PeerDiscovery {
|
|
22
|
+
export class MulticastDNS extends EventEmitter<PeerDiscoveryEvents> implements PeerDiscovery, Initializable {
|
|
28
23
|
static tag = 'mdns'
|
|
29
24
|
|
|
30
25
|
public mdns?: multicastDNS.MulticastDNS
|
|
@@ -33,24 +28,17 @@ export class MulticastDNS extends EventEmitter implements PeerDiscovery {
|
|
|
33
28
|
private readonly interval: number
|
|
34
29
|
private readonly serviceTag: string
|
|
35
30
|
private readonly port: number
|
|
36
|
-
private
|
|
37
|
-
private readonly peerMultiaddrs: Multiaddr[] // TODO: update this when multiaddrs change?
|
|
38
|
-
private _queryInterval: NodeJS.Timer | null
|
|
31
|
+
private _queryInterval: ReturnType<typeof setInterval> | null
|
|
39
32
|
private readonly _goMdns?: GoMulticastDNS
|
|
33
|
+
private components: Components = new Components()
|
|
40
34
|
|
|
41
|
-
constructor (options: MulticastDNSOptions) {
|
|
35
|
+
constructor (options: MulticastDNSOptions = {}) {
|
|
42
36
|
super()
|
|
43
37
|
|
|
44
|
-
if (options.peerId == null) {
|
|
45
|
-
throw new Error('needs own PeerId to work')
|
|
46
|
-
}
|
|
47
|
-
|
|
48
38
|
this.broadcast = options.broadcast !== false
|
|
49
39
|
this.interval = options.interval ?? (1e3 * 10)
|
|
50
40
|
this.serviceTag = options.serviceTag ?? 'ipfs.local'
|
|
51
41
|
this.port = options.port ?? 5353
|
|
52
|
-
this.peerId = options.peerId
|
|
53
|
-
this.peerMultiaddrs = options.multiaddrs ?? []
|
|
54
42
|
this._queryInterval = null
|
|
55
43
|
this._onPeer = this._onPeer.bind(this)
|
|
56
44
|
this._onMdnsQuery = this._onMdnsQuery.bind(this)
|
|
@@ -58,15 +46,19 @@ export class MulticastDNS extends EventEmitter implements PeerDiscovery {
|
|
|
58
46
|
|
|
59
47
|
if (options.compat !== false) {
|
|
60
48
|
this._goMdns = new GoMulticastDNS({
|
|
61
|
-
multiaddrs: this.peerMultiaddrs,
|
|
62
|
-
peerId: options.peerId,
|
|
63
49
|
queryPeriod: options.compatQueryPeriod,
|
|
64
50
|
queryInterval: options.compatQueryInterval
|
|
65
51
|
})
|
|
66
|
-
this._goMdns.
|
|
52
|
+
this._goMdns.addEventListener('peer', this._onPeer)
|
|
67
53
|
}
|
|
68
54
|
}
|
|
69
55
|
|
|
56
|
+
init (components: Components): void {
|
|
57
|
+
this.components = components
|
|
58
|
+
|
|
59
|
+
this._goMdns?.init(components)
|
|
60
|
+
}
|
|
61
|
+
|
|
70
62
|
isStarted () {
|
|
71
63
|
return Boolean(this.mdns)
|
|
72
64
|
}
|
|
@@ -97,23 +89,36 @@ export class MulticastDNS extends EventEmitter implements PeerDiscovery {
|
|
|
97
89
|
return
|
|
98
90
|
}
|
|
99
91
|
|
|
100
|
-
|
|
92
|
+
log.trace('received incoming mDNS query')
|
|
93
|
+
query.gotQuery(event, this.mdns, this.components.getPeerId(), this.components.getAddressManager().getAddresses(), this.serviceTag, this.broadcast)
|
|
101
94
|
}
|
|
102
95
|
|
|
103
96
|
_onMdnsResponse (event: multicastDNS.ResponsePacket) {
|
|
97
|
+
log.trace('received mDNS query response')
|
|
98
|
+
|
|
104
99
|
try {
|
|
105
|
-
const foundPeer = query.gotResponse(event, this.
|
|
100
|
+
const foundPeer = query.gotResponse(event, this.components.getPeerId(), this.serviceTag)
|
|
106
101
|
|
|
107
102
|
if (foundPeer != null) {
|
|
108
|
-
|
|
103
|
+
log('discovered peer in mDNS qeury response %p', foundPeer.id)
|
|
104
|
+
|
|
105
|
+
this.dispatchEvent(new CustomEvent<PeerData>('peer', {
|
|
106
|
+
detail: foundPeer
|
|
107
|
+
}))
|
|
109
108
|
}
|
|
110
109
|
} catch (err) {
|
|
111
|
-
log('Error processing peer response', err)
|
|
110
|
+
log.error('Error processing peer response', err)
|
|
112
111
|
}
|
|
113
112
|
}
|
|
114
113
|
|
|
115
|
-
_onPeer (
|
|
116
|
-
(this.mdns
|
|
114
|
+
_onPeer (evt: CustomEvent<PeerData>) {
|
|
115
|
+
if (this.mdns == null) {
|
|
116
|
+
return
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
this.dispatchEvent(new CustomEvent<PeerData>('peer', {
|
|
120
|
+
detail: evt.detail
|
|
121
|
+
}))
|
|
117
122
|
}
|
|
118
123
|
|
|
119
124
|
/**
|
|
@@ -128,7 +133,7 @@ export class MulticastDNS extends EventEmitter implements PeerDiscovery {
|
|
|
128
133
|
|
|
129
134
|
this.mdns.removeListener('query', this._onMdnsQuery)
|
|
130
135
|
this.mdns.removeListener('response', this._onMdnsResponse)
|
|
131
|
-
this._goMdns?.
|
|
136
|
+
this._goMdns?.removeEventListener('peer', this._onPeer)
|
|
132
137
|
|
|
133
138
|
if (this._queryInterval != null) {
|
|
134
139
|
clearInterval(this._queryInterval)
|
package/src/query.ts
CHANGED
|
@@ -1,19 +1,18 @@
|
|
|
1
1
|
import os from 'os'
|
|
2
|
-
import
|
|
3
|
-
import { Multiaddr, MultiaddrObject } from '@multiformats/multiaddr'
|
|
4
|
-
import {
|
|
5
|
-
import { PeerId } from '@libp2p/peer-id'
|
|
2
|
+
import { logger } from '@libp2p/logger'
|
|
3
|
+
import { Multiaddr, MultiaddrObject, protocols } from '@multiformats/multiaddr'
|
|
4
|
+
import { peerIdFromString } from '@libp2p/peer-id'
|
|
5
|
+
import type { PeerId } from '@libp2p/interfaces/peer-id'
|
|
6
6
|
import type { PeerData } from '@libp2p/interfaces/peer-data'
|
|
7
7
|
import type { MulticastDNS, ResponsePacket, QueryPacket } from 'multicast-dns'
|
|
8
8
|
import type { SrvAnswer, StringAnswer, TxtAnswer, Answer } from 'dns-packet'
|
|
9
9
|
|
|
10
|
-
const log =
|
|
11
|
-
error: debug('libp2p:mdns:error')
|
|
12
|
-
})
|
|
10
|
+
const log = logger('libp2p:mdns:query')
|
|
13
11
|
|
|
14
12
|
export function queryLAN (mdns: MulticastDNS, serviceTag: string, interval: number) {
|
|
15
13
|
const query = () => {
|
|
16
14
|
log('query', serviceTag)
|
|
15
|
+
|
|
17
16
|
mdns.query({
|
|
18
17
|
questions: [{
|
|
19
18
|
name: serviceTag,
|
|
@@ -83,14 +82,16 @@ export function gotResponse (rsp: ResponsePacket, localPeerId: PeerId, serviceTa
|
|
|
83
82
|
}
|
|
84
83
|
})
|
|
85
84
|
|
|
86
|
-
if (localPeerId.toString(
|
|
85
|
+
if (localPeerId.toString() === b58Id) {
|
|
87
86
|
return // replied to myself, ignore
|
|
88
87
|
}
|
|
89
88
|
|
|
90
|
-
|
|
89
|
+
const id = peerIdFromString(b58Id)
|
|
90
|
+
|
|
91
|
+
log('peer found %p', id)
|
|
91
92
|
|
|
92
93
|
return {
|
|
93
|
-
id
|
|
94
|
+
id,
|
|
94
95
|
multiaddrs,
|
|
95
96
|
protocols: []
|
|
96
97
|
}
|
|
@@ -98,11 +99,12 @@ export function gotResponse (rsp: ResponsePacket, localPeerId: PeerId, serviceTa
|
|
|
98
99
|
|
|
99
100
|
export function gotQuery (qry: QueryPacket, mdns: MulticastDNS, peerId: PeerId, multiaddrs: Multiaddr[], serviceTag: string, broadcast: boolean) {
|
|
100
101
|
if (!broadcast) {
|
|
102
|
+
log('not responding to mDNS query as broadcast mode is false')
|
|
101
103
|
return
|
|
102
104
|
}
|
|
103
105
|
|
|
104
106
|
const addresses: MultiaddrObject[] = multiaddrs.reduce<MultiaddrObject[]>((acc, addr) => {
|
|
105
|
-
if (addr.isThinWaistAddress()) {
|
|
107
|
+
if (addr.decapsulateCode(protocols('p2p').code).isThinWaistAddress()) {
|
|
106
108
|
acc.push(addr.toOptions())
|
|
107
109
|
}
|
|
108
110
|
return acc
|
|
@@ -110,6 +112,7 @@ export function gotQuery (qry: QueryPacket, mdns: MulticastDNS, peerId: PeerId,
|
|
|
110
112
|
|
|
111
113
|
// Only announce TCP for now
|
|
112
114
|
if (addresses.length === 0) {
|
|
115
|
+
log('no thin waist addresses present, cannot respond to query')
|
|
113
116
|
return
|
|
114
117
|
}
|
|
115
118
|
|
|
@@ -121,14 +124,14 @@ export function gotQuery (qry: QueryPacket, mdns: MulticastDNS, peerId: PeerId,
|
|
|
121
124
|
type: 'PTR',
|
|
122
125
|
class: 'IN',
|
|
123
126
|
ttl: 120,
|
|
124
|
-
data: peerId.toString(
|
|
127
|
+
data: peerId.toString() + '.' + serviceTag
|
|
125
128
|
})
|
|
126
129
|
|
|
127
130
|
// Only announce TCP multiaddrs for now
|
|
128
131
|
const port = addresses[0].port
|
|
129
132
|
|
|
130
133
|
answers.push({
|
|
131
|
-
name: peerId.toString(
|
|
134
|
+
name: peerId.toString() + '.' + serviceTag,
|
|
132
135
|
type: 'SRV',
|
|
133
136
|
class: 'IN',
|
|
134
137
|
ttl: 120,
|
|
@@ -141,11 +144,11 @@ export function gotQuery (qry: QueryPacket, mdns: MulticastDNS, peerId: PeerId,
|
|
|
141
144
|
})
|
|
142
145
|
|
|
143
146
|
answers.push({
|
|
144
|
-
name: peerId.toString(
|
|
147
|
+
name: peerId.toString() + '.' + serviceTag,
|
|
145
148
|
type: 'TXT',
|
|
146
149
|
class: 'IN',
|
|
147
150
|
ttl: 120,
|
|
148
|
-
data: peerId.toString(
|
|
151
|
+
data: peerId.toString()
|
|
149
152
|
})
|
|
150
153
|
|
|
151
154
|
addresses.forEach((addr) => {
|