Skip to content
This repository has been archived by the owner on Jul 21, 2023. It is now read-only.

Commit

Permalink
fix: update interfaces (#116)
Browse files Browse the repository at this point in the history
Updates to latest code from libp2p/js-libp2p-interfaces#180
  • Loading branch information
achingbrain committed Mar 16, 2022
1 parent 86a74a9 commit 30ec23a
Show file tree
Hide file tree
Showing 13 changed files with 365 additions and 324 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@
## Usage

```JavaScript
const MDNS = require('libp2p-mdns')
import { MDNS } from '@libp2p/mdns'

const mdns = new MDNS(options)

mdns.on('peer', (peerData) => {
console.log('Found a peer in the local network', peerData.id.toString(base58btc), peerData.multiaddrs)
console.log('Found a peer in the local network', peerData.id.toString(), peerData.multiaddrs)
})

// Broadcast for 20 seconds
Expand Down
19 changes: 10 additions & 9 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -123,26 +123,27 @@
"dep-check": "aegir dep-check dist/src/**/*.js dist/test/**/*.js",
"build": "tsc",
"pretest": "npm run build",
"test": "aegir test -f ./dist/test",
"test": "aegir test -f ./dist/test/*.js -f ./dist/test/*/*.js",
"test:node": "npm run test -- -t node --cov",
"test:electron-main": "npm run test -- -t electron-main",
"release": "semantic-release"
},
"dependencies": {
"@libp2p/logger": "^1.0.2",
"@libp2p/peer-id": "^1.1.1",
"@multiformats/multiaddr": "^10.0.0",
"@libp2p/logger": "^1.1.2",
"@libp2p/peer-id": "^1.1.8",
"@multiformats/multiaddr": "^10.1.5",
"multicast-dns": "^7.2.0",
"multiformats": "^9.6.3"
},
"devDependencies": {
"@libp2p/interface-compliance-tests": "^1.1.3",
"@libp2p/interfaces": "^1.3.3",
"@libp2p/peer-id-factory": "^1.0.4",
"@libp2p/interface-compliance-tests": "^1.1.16",
"@libp2p/interfaces": "^1.3.14",
"@libp2p/peer-id-factory": "^1.0.8",
"@types/multicast-dns": "^7.2.1",
"aegir": "^36.1.0",
"aegir": "^36.1.3",
"delay": "^5.0.0",
"p-defer": "^4.0.0",
"p-wait-for": "^4.1.0"
"p-wait-for": "^4.1.0",
"ts-sinon": "^2.0.2"
}
}
25 changes: 15 additions & 10 deletions src/compat/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,27 @@
import { EventEmitter, CustomEvent } from '@libp2p/interfaces'
import { Responder } from './responder.js'
import { Querier } from './querier.js'
import type { Multiaddr } from '@multiformats/multiaddr'
import type { PeerId } from '@libp2p/interfaces/peer-id'
import type { PeerDiscovery, PeerDiscoveryEvents } from '@libp2p/interfaces/peer-discovery'
import type { Components, Initializable } from '@libp2p/interfaces/components'

export class GoMulticastDNS extends EventEmitter<PeerDiscoveryEvents> implements PeerDiscovery {
export interface GoMulticastDNSInit {
queryPeriod?: number
queryInterval?: number
}

export class GoMulticastDNS extends EventEmitter<PeerDiscoveryEvents> implements PeerDiscovery, Initializable {
private _started: boolean
private readonly _responder: Responder
private readonly _querier: Querier

constructor (options: { peerId: PeerId, multiaddrs: Multiaddr[], queryPeriod?: number, queryInterval?: number }) {
constructor (options: GoMulticastDNSInit = {}) {
super()
const { peerId, multiaddrs, queryPeriod, queryInterval } = options
const { queryPeriod, queryInterval } = options

this._started = false

this._responder = new Responder({
peerId,
multiaddrs
})
this._responder = new Responder()
this._querier = new Querier({
peerId,
queryInterval,
queryPeriod
})
Expand All @@ -32,6 +32,11 @@ export class GoMulticastDNS extends EventEmitter<PeerDiscoveryEvents> implements
})
}

init (components: Components): void {
this._responder.init(components)
this._querier.init(components)
}

isStarted () {
return this._started
}
Expand Down
103 changes: 26 additions & 77 deletions src/compat/querier.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,16 @@
import { EventEmitter } from '@libp2p/interfaces'
import { CustomEvent, EventEmitter } from '@libp2p/interfaces'
import MDNS from 'multicast-dns'
import { Multiaddr } from '@multiformats/multiaddr'
import type { PeerId } from '@libp2p/interfaces/peer-id'
import { logger } from '@libp2p/logger'
import { SERVICE_TAG_LOCAL, MULTICAST_IP, MULTICAST_PORT } from './constants.js'
import { base58btc } from 'multiformats/bases/base58'
import { peerIdFromString } from '@libp2p/peer-id'
import type { PeerDiscovery, PeerDiscoveryEvents } from '@libp2p/interfaces/peer-discovery'
import type { ResponsePacket } from 'multicast-dns'
import type { RemoteInfo } from 'dgram'
import { Components, Initializable } from '@libp2p/interfaces/components'
import { findPeerDataInAnswers } from './utils.js'

const log = logger('libp2p:mdns:compat:querier')

export interface QuerierOptions {
peerId: PeerId
export interface QuerierInit {
queryInterval?: number
queryPeriod?: number
}
Expand All @@ -22,24 +19,17 @@ export interface Handle {
stop: () => Promise<void>
}

export class Querier extends EventEmitter<PeerDiscoveryEvents> implements PeerDiscovery {
private readonly _peerIdStr: string
private readonly _options: Required<QuerierOptions>
export class Querier extends EventEmitter<PeerDiscoveryEvents> implements PeerDiscovery, Initializable {
private readonly _init: Required<QuerierInit>
private _handle?: Handle
private components: Components = new Components()

constructor (options: QuerierOptions) {
constructor (init: QuerierInit = {}) {
super()

const { peerId, queryInterval, queryPeriod } = options

if (peerId == null) {
throw new Error('missing peerId parameter')
}

this._peerIdStr = peerId.toString(base58btc)
this._options = {
peerId,
const { queryInterval, queryPeriod } = init

this._init = {
// Re-query in leu of network change detection (every 60s by default)
queryInterval: queryInterval ?? 60000,
// Time for which the MDNS server will stay alive waiting for responses
Expand All @@ -52,6 +42,10 @@ export class Querier extends EventEmitter<PeerDiscoveryEvents> implements PeerDi
this._onResponse = this._onResponse.bind(this)
}

init (components: Components): void {
this.components = components
}

isStarted () {
return Boolean(this._handle)
}
Expand Down Expand Up @@ -83,76 +77,31 @@ export class Querier extends EventEmitter<PeerDiscoveryEvents> implements PeerDi
}
}
}, {
period: this._options.queryPeriod,
interval: this._options.queryInterval
period: this._init.queryPeriod,
interval: this._init.queryInterval
})
}

_onResponse (event: ResponsePacket, info: RemoteInfo) {
log.trace('received mDNS query response')
const answers = event.answers ?? []
const ptrRecord = answers.find(a => a.type === 'PTR' && a.name === SERVICE_TAG_LOCAL)

// Only deal with responses for our service tag
if (ptrRecord == null) return

log('got response', event, info)

const txtRecord = answers.find(a => a.type === 'TXT')
if (txtRecord == null || txtRecord.type !== 'TXT') {
return log('missing TXT record in response')
}

let peerIdStr
try {
peerIdStr = txtRecord.data[0].toString()
} catch (err) {
return log('failed to extract peer ID from TXT record data', txtRecord, err)
}

if (this._peerIdStr === peerIdStr) {
return log('ignoring reply to myself')
}
const peerData = findPeerDataInAnswers(answers, this.components.getPeerId())

let peerId
try {
peerId = peerIdFromString(peerIdStr)
} catch (err) {
return log('failed to create peer ID from TXT record data', peerIdStr, err)
if (peerData == null) {
log('could not read peer data from query response')
return
}

const srvRecord = answers.find(a => a.type === 'SRV')
if (srvRecord == null || srvRecord.type !== 'SRV') {
return log('missing SRV record in response')
if (peerData.multiaddrs.length === 0) {
log('could not parse multiaddrs from mDNS response')
return
}

log('peer found', peerIdStr)

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

const multiaddrs = answers
.filter(a => ['A', 'AAAA'].includes(a.type))
.reduce<Multiaddr[]>((addrs, a) => {
if (a.type !== 'A' && a.type !== 'AAAA') {
return addrs
}

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
}, [])
log('discovered peer in mDNS qeury response %p', peerData.id)

this.dispatchEvent(new CustomEvent('peer', {
detail: {
id: peerId,
multiaddrs,
protcols: []
}
detail: peerData
}))
}

Expand Down
Loading

0 comments on commit 30ec23a

Please sign in to comment.