Skip to content
This repository was archived by the owner on Jul 21, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,20 @@ stages:

node_js:
- '10'
- '12'

os:
- linux
- osx
- windows

script: npx nyc -s npm run test:node -- --bail
after_success: npx nyc report --reporter=text-lcov > coverage.lcov && npx codecov

jobs:
include:
- os: windows
cache: false

- stage: check
script:
- npx aegir commitlint --travis
- npx aegir dep-check
- npm run lint

Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ mdns.on('peer', (peerInfo) => {
})

// Broadcast for 20 seconds
mdns.start(() => setTimeout(() => mdns.stop(() => {}), 20 * 1000))
mdns.start()
setTimeout(() => mdns.stop(), 20 * 1000)
```

- options
Expand Down
14 changes: 8 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,18 +34,20 @@
},
"homepage": "https://github.com/libp2p/js-libp2p-mdns",
"devDependencies": {
"aegir": "^18.2.2",
"aegir": "^20.3.1",
"chai": "^4.2.0",
"dirty-chai": "^2.0.1"
"delay": "^4.3.0",
"dirty-chai": "^2.0.1",
"interface-discovery": "^0.1.1",
"p-defer": "^3.0.0"
},
"dependencies": {
"async": "^2.6.2",
"debug": "^4.1.1",
"libp2p-tcp": "~0.13.0",
"multiaddr": "^6.0.6",
"multiaddr": "^7.1.0",
"multicast-dns": "^7.2.0",
"peer-id": "~0.12.2",
"peer-info": "~0.15.1"
"peer-id": "~0.13.3",
"peer-info": "~0.17.0"
},
"contributors": [
"Alan Shaw <alan.shaw@protocol.ai>",
Expand Down
27 changes: 12 additions & 15 deletions src/compat/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
// Compatibility with Go libp2p MDNS

const EE = require('events')
const parallel = require('async/parallel')
const Responder = require('./responder')
const Querier = require('./querier')

Expand All @@ -15,9 +14,9 @@ class GoMulticastDNS extends EE {
this._onPeer = this._onPeer.bind(this)
}

start (callback) {
async start () {
if (this._started) {
return callback(new Error('MulticastDNS service is already started'))
return
}

this._started = true
Expand All @@ -26,20 +25,18 @@ class GoMulticastDNS extends EE {

this._querier.on('peer', this._onPeer)

parallel([
cb => this._responder.start(cb),
cb => this._querier.start(cb)
], callback)
await Promise.all([
this._responder.start(),
this._querier.start()
])
}

_onPeer (peerInfo) {
this.emit('peer', peerInfo)
}

stop (callback) {
if (!this._started) {
return callback(new Error('MulticastDNS service is not started'))
}
stop () {
if (!this._started) return

const responder = this._responder
const querier = this._querier
Expand All @@ -50,10 +47,10 @@ class GoMulticastDNS extends EE {

querier.removeListener('peer', this._onPeer)

parallel([
cb => responder.stop(cb),
cb => querier.stop(cb)
], callback)
return Promise.all([
responder.stop(),
querier.stop()
])
}
}

Expand Down
84 changes: 41 additions & 43 deletions src/compat/querier.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@ const MDNS = require('multicast-dns')
const Multiaddr = require('multiaddr')
const PeerInfo = require('peer-info')
const PeerId = require('peer-id')
const nextTick = require('async/nextTick')
const log = require('debug')('libp2p:mdns:compat:querier')
const debug = require('debug')
const log = debug('libp2p:mdns:compat:querier')
log.error = debug('libp2p:mdns:compat:querier:error')
const { SERVICE_TAG_LOCAL, MULTICAST_IP, MULTICAST_PORT } = require('./constants')

class Querier extends EE {
Expand All @@ -28,7 +29,7 @@ class Querier extends EE {
this._onResponse = this._onResponse.bind(this)
}

start (callback) {
start () {
this._handle = periodically(() => {
// Create a querier that queries multicast but gets responses unicast
const mdns = MDNS({ multicast: false, interface: '0.0.0.0', port: 0 })
Expand All @@ -44,20 +45,18 @@ class Querier extends EE {
})

return {
stop: callback => {
stop: () => {
mdns.removeListener('response', this._onResponse)
mdns.destroy(callback)
return new Promise(resolve => mdns.destroy(resolve))
}
}
}, {
period: this._options.queryPeriod,
interval: this._options.queryInterval
})

nextTick(() => callback())
}

_onResponse (event, info) {
async _onResponse (event, info) {
const answers = event.answers || []
const ptrRecord = answers.find(a => a.type === 'PTR' && a.name === SERVICE_TAG_LOCAL)

Expand Down Expand Up @@ -87,37 +86,40 @@ class Querier extends EE {
return log('failed to create peer ID from TXT record data', peerIdStr, err)
}

PeerInfo.create(peerId, (err, info) => {
if (err) return log('failed to create peer info from peer ID', peerId, err)
let peerInfo
try {
peerInfo = await PeerInfo.create(peerId)
} catch (err) {
return log.error('failed to create peer info from peer ID', peerId, err)
}

const srvRecord = answers.find(a => a.type === 'SRV')
if (!srvRecord) return log('missing SRV record in response')
const srvRecord = answers.find(a => a.type === 'SRV')
if (!srvRecord) return log('missing SRV record in response')

log('peer found', peerIdStr)
log('peer found', peerIdStr)

const { port } = srvRecord.data || {}
const protos = { A: 'ip4', AAAA: 'ip6' }
const { port } = srvRecord.data || {}
const protos = { A: 'ip4', AAAA: 'ip6' }

const multiaddrs = answers
.filter(a => ['A', 'AAAA'].includes(a.type))
.reduce((addrs, a) => {
const maStr = `/${protos[a.type]}/${a.data}/tcp/${port}`
try {
addrs.push(new Multiaddr(maStr))
log(maStr)
} catch (err) {
log(`failed to create multiaddr from ${a.type} record data`, maStr, port, err)
}
return addrs
}, [])
const multiaddrs = answers
.filter(a => ['A', 'AAAA'].includes(a.type))
.reduce((addrs, a) => {
const maStr = `/${protos[a.type]}/${a.data}/tcp/${port}`
try {
addrs.push(new Multiaddr(maStr))
log(maStr)
} catch (err) {
log(`failed to create multiaddr from ${a.type} record data`, maStr, port, err)
}
return addrs
}, [])

multiaddrs.forEach(addr => info.multiaddrs.add(addr))
this.emit('peer', info)
})
multiaddrs.forEach(addr => peerInfo.multiaddrs.add(addr))
this.emit('peer', peerInfo)
}

stop (callback) {
this._handle.stop(callback)
stop () {
return this._handle.stop()
}
}

Expand All @@ -140,27 +142,23 @@ function periodically (fn, options) {

const reRun = () => {
handle = fn()
timeoutId = setTimeout(() => {
handle.stop(err => {
if (err) log(err)
if (!stopped) {
timeoutId = setTimeout(reRun, options.interval)
}
})
timeoutId = setTimeout(async () => {
await handle.stop().catch(log)
if (!stopped) {
timeoutId = setTimeout(reRun, options.interval)
}
handle = null
}, options.period)
}

reRun()

return {
stop (callback) {
stop () {
stopped = true
clearTimeout(timeoutId)
if (handle) {
handle.stop(callback)
} else {
callback()
return handle.stop()
}
}
}
Expand Down
26 changes: 10 additions & 16 deletions src/compat/responder.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,8 @@ const OS = require('os')
const assert = require('assert')
const MDNS = require('multicast-dns')
const log = require('debug')('libp2p:mdns:compat:responder')
const TCP = require('libp2p-tcp')
const nextTick = require('async/nextTick')
const { SERVICE_TAG_LOCAL } = require('./constants')

const tcp = new TCP()

class Responder {
constructor (peerInfo) {
assert(peerInfo, 'missing peerInfo parameter')
Expand All @@ -18,16 +14,15 @@ class Responder {
this._onQuery = this._onQuery.bind(this)
}

start (callback) {
start () {
this._mdns = MDNS()
this._mdns.on('query', this._onQuery)
nextTick(() => callback())
}

_onQuery (event, info) {
const multiaddrs = tcp.filter(this._peerInfo.multiaddrs.toArray())
const addresses = this._peerInfo.multiaddrs.toArray().map(ma => ma.toOptions())
// Only announce TCP for now
if (!multiaddrs.length) return
if (!addresses.length) return

const questions = event.questions || []

Expand All @@ -48,7 +43,7 @@ class Responder {
})

// Only announce TCP multiaddrs for now
const port = multiaddrs[0].toString().split('/')[4]
const port = addresses[0].port

answers.push({
name: peerServiceTagLocal,
Expand All @@ -71,15 +66,14 @@ class Responder {
data: [Buffer.from(this._peerIdStr)]
})

multiaddrs.forEach((ma) => {
const proto = ma.protoNames()[0]
if (proto === 'ip4' || proto === 'ip6') {
addresses.forEach((ma) => {
if (['ipv4', 'ipv6'].includes(ma.family)) {
answers.push({
name: OS.hostname(),
type: proto === 'ip4' ? 'A' : 'AAAA',
type: ma.family === 'ipv4' ? 'A' : 'AAAA',
class: 'IN',
ttl: 120,
data: ma.toString().split('/')[2]
data: ma.host
})
}
})
Expand All @@ -88,9 +82,9 @@ class Responder {
this._mdns.respond(answers, info)
}

stop (callback) {
stop () {
this._mdns.removeListener('query', this._onQuery)
this._mdns.destroy(callback)
return new Promise(resolve => this._mdns.destroy(resolve))
}
}

Expand Down
Loading