@libp2p/mdns 0.18.0
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/LICENSE +4 -0
- package/README.md +98 -0
- package/dist/src/compat/constants.d.ts +5 -0
- package/dist/src/compat/constants.d.ts.map +1 -0
- package/dist/src/compat/constants.js +5 -0
- package/dist/src/compat/constants.js.map +1 -0
- package/dist/src/compat/index.d.ts +20 -0
- package/dist/src/compat/index.d.ts.map +1 -0
- package/dist/src/compat/index.js +47 -0
- package/dist/src/compat/index.js.map +1 -0
- package/dist/src/compat/querier.d.ts +25 -0
- package/dist/src/compat/querier.d.ts.map +1 -0
- package/dist/src/compat/querier.js +163 -0
- package/dist/src/compat/querier.js.map +1 -0
- package/dist/src/compat/responder.d.ts +19 -0
- package/dist/src/compat/responder.d.ts.map +1 -0
- package/dist/src/compat/responder.js +99 -0
- package/dist/src/compat/responder.js.map +1 -0
- package/dist/src/index.d.ts +48 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +145 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/query.d.ts +9 -0
- package/dist/src/query.d.ts.map +1 -0
- package/dist/src/query.js +141 -0
- package/dist/src/query.js.map +1 -0
- package/package.json +149 -0
- package/src/compat/constants.ts +4 -0
- package/src/compat/index.ts +64 -0
- package/src/compat/querier.ts +209 -0
- package/src/compat/responder.ts +127 -0
- package/src/index.ts +191 -0
- package/src/query.ts +166 -0
package/LICENSE
ADDED
package/README.md
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# libp2p-mdns JavaScript implementation
|
|
2
|
+
|
|
3
|
+
[](http://protocol.ai)
|
|
4
|
+
[](http://libp2p.io/)
|
|
5
|
+
[](http://webchat.freenode.net/?channels=%23libp2p)
|
|
6
|
+
[](https://discuss.libp2p.io)
|
|
7
|
+
[](https://codecov.io/gh/libp2p/js-libp2p-mdns)
|
|
8
|
+
[](https://github.com/libp2p/js-libp2p-mdns/actions/workflows/js-test-and-release.yml)
|
|
9
|
+
[](https://david-dm.org/libp2p/js-libp2p-mdns)
|
|
10
|
+
[](https://github.com/feross/standard)
|
|
11
|
+
|
|
12
|
+
> JavaScript libp2p MulticastDNS discovery implementation
|
|
13
|
+
|
|
14
|
+
## Usage
|
|
15
|
+
|
|
16
|
+
```JavaScript
|
|
17
|
+
const MDNS = require('libp2p-mdns')
|
|
18
|
+
|
|
19
|
+
const mdns = new MDNS(options)
|
|
20
|
+
|
|
21
|
+
mdns.on('peer', (peerData) => {
|
|
22
|
+
console.log('Found a peer in the local network', peerData.id.toString(base58btc), peerData.multiaddrs)
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
// Broadcast for 20 seconds
|
|
26
|
+
mdns.start()
|
|
27
|
+
setTimeout(() => mdns.stop(), 20 * 1000)
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
- options
|
|
31
|
+
- `peerId` - PeerId to announce
|
|
32
|
+
- `multiaddrs` - multiaddrs to announce
|
|
33
|
+
- `broadcast` - (true/false) announce our presence through mDNS, default `false`
|
|
34
|
+
- `interval` - query interval, default 10 * 1000 (10 seconds)
|
|
35
|
+
- `serviceTag` - name of the service announce , default 'ipfs.local`
|
|
36
|
+
- `compat` - enable/disable compatibility with go-libp2p-mdns, default `true`
|
|
37
|
+
|
|
38
|
+
## MDNS messages
|
|
39
|
+
|
|
40
|
+
A query is sent to discover the IPFS nodes on the local network
|
|
41
|
+
|
|
42
|
+
```
|
|
43
|
+
{ type: 'query',
|
|
44
|
+
questions: [ { name: 'ipfs.local', type: 'PTR' } ]
|
|
45
|
+
}
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
When a query is detected, each IPFS node sends an answer about itself
|
|
49
|
+
|
|
50
|
+
```
|
|
51
|
+
[ { name: 'ipfs.local',
|
|
52
|
+
type: 'PTR',
|
|
53
|
+
class: 'IN',
|
|
54
|
+
ttl: 120,
|
|
55
|
+
data: 'QmNPubsDWATVngE3d5WDSNe7eVrFLuk38qb9t6vdLnu2aK.ipfs.local' },
|
|
56
|
+
{ name: 'QmNPubsDWATVngE3d5WDSNe7eVrFLuk38qb9t6vdLnu2aK.ipfs.local',
|
|
57
|
+
type: 'SRV',
|
|
58
|
+
class: 'IN',
|
|
59
|
+
ttl: 120,
|
|
60
|
+
data:
|
|
61
|
+
{ priority: 10,
|
|
62
|
+
weight: 1,
|
|
63
|
+
port: '20002',
|
|
64
|
+
target: 'LAPTOP-G5LJ7VN9' } },
|
|
65
|
+
{ name: 'QmNPubsDWATVngE3d5WDSNe7eVrFLuk38qb9t6vdLnu2aK.ipfs.local',
|
|
66
|
+
type: 'TXT',
|
|
67
|
+
class: 'IN',
|
|
68
|
+
ttl: 120,
|
|
69
|
+
data: ['QmNPubsDWATVngE3d5WDSNe7eVrFLuk38qb9t6vdLnu2aK'] },
|
|
70
|
+
{ name: 'LAPTOP-G5LJ7VN9',
|
|
71
|
+
type: 'A',
|
|
72
|
+
class: 'IN',
|
|
73
|
+
ttl: 120,
|
|
74
|
+
data: '127.0.0.1' },
|
|
75
|
+
{ name: 'LAPTOP-G5LJ7VN9',
|
|
76
|
+
type: 'AAAA',
|
|
77
|
+
class: 'IN',
|
|
78
|
+
ttl: 120,
|
|
79
|
+
data: '::1' } ]
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Contribute
|
|
83
|
+
|
|
84
|
+
The libp2p implementation in JavaScript is a work in progress. As such, there are a few things you can do right now to help out:
|
|
85
|
+
|
|
86
|
+
- Go through the modules and **check out existing issues**. This is especially useful for modules in active development. Some knowledge of IPFS/libp2p may be required, as well as the infrastructure behind it - for instance, you may need to read up on p2p and more complex operations like muxing to be able to help technically.
|
|
87
|
+
- **Perform code reviews**. More eyes will help a) speed the project along b) ensure quality and c) reduce possible future bugs.
|
|
88
|
+
|
|
89
|
+
## License
|
|
90
|
+
|
|
91
|
+
Licensed under either of
|
|
92
|
+
|
|
93
|
+
* Apache 2.0, ([LICENSE-APACHE](LICENSE-APACHE) / http://www.apache.org/licenses/LICENSE-2.0)
|
|
94
|
+
* MIT ([LICENSE-MIT](LICENSE-MIT) / http://opensource.org/licenses/MIT)
|
|
95
|
+
|
|
96
|
+
### Contribution
|
|
97
|
+
|
|
98
|
+
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../src/compat/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,WAAW,yBAAyB,CAAA;AACjD,eAAO,MAAM,iBAAiB,QAAyB,CAAA;AACvD,eAAO,MAAM,YAAY,gBAAgB,CAAA;AACzC,eAAO,MAAM,cAAc,OAAO,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../src/compat/constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,WAAW,GAAG,sBAAsB,CAAA;AACjD,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAG,WAAW,QAAQ,CAAA;AACvD,MAAM,CAAC,MAAM,YAAY,GAAG,aAAa,CAAA;AACzC,MAAM,CAAC,MAAM,cAAc,GAAG,IAAI,CAAA"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { EventEmitter } from 'events';
|
|
3
|
+
import type { Multiaddr } from '@multiformats/multiaddr';
|
|
4
|
+
import type { PeerId } from '@libp2p/interfaces/peer-id';
|
|
5
|
+
import type { PeerDiscovery } from '@libp2p/interfaces/peer-discovery';
|
|
6
|
+
export declare class GoMulticastDNS extends EventEmitter implements PeerDiscovery {
|
|
7
|
+
private _started;
|
|
8
|
+
private readonly _responder;
|
|
9
|
+
private readonly _querier;
|
|
10
|
+
constructor(options: {
|
|
11
|
+
peerId: PeerId;
|
|
12
|
+
multiaddrs: Multiaddr[];
|
|
13
|
+
queryPeriod?: number;
|
|
14
|
+
queryInterval?: number;
|
|
15
|
+
});
|
|
16
|
+
isStarted(): boolean;
|
|
17
|
+
start(): Promise<void>;
|
|
18
|
+
stop(): Promise<void>;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/compat/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAA;AAGrC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAA;AACxD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAA;AACxD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mCAAmC,CAAA;AAEtE,qBAAa,cAAe,SAAQ,YAAa,YAAW,aAAa;IACvE,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAW;IACtC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;gBAErB,OAAO,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,SAAS,EAAE,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,aAAa,CAAC,EAAE,MAAM,CAAA;KAAE;IAqB/G,SAAS;IAIH,KAAK;IAaL,IAAI;CAYX"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
// Compatibility with Go libp2p MDNS
|
|
2
|
+
import { EventEmitter } from 'events';
|
|
3
|
+
import { Responder } from './responder.js';
|
|
4
|
+
import { Querier } from './querier.js';
|
|
5
|
+
export class GoMulticastDNS extends EventEmitter {
|
|
6
|
+
constructor(options) {
|
|
7
|
+
super();
|
|
8
|
+
const { peerId, multiaddrs, queryPeriod, queryInterval } = options;
|
|
9
|
+
this._started = false;
|
|
10
|
+
this._responder = new Responder({
|
|
11
|
+
peerId,
|
|
12
|
+
multiaddrs
|
|
13
|
+
});
|
|
14
|
+
this._querier = new Querier({
|
|
15
|
+
peerId,
|
|
16
|
+
queryInterval,
|
|
17
|
+
queryPeriod
|
|
18
|
+
});
|
|
19
|
+
this._querier.on('peer', (peerData) => {
|
|
20
|
+
this.emit('peer', peerData);
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
isStarted() {
|
|
24
|
+
return this._started;
|
|
25
|
+
}
|
|
26
|
+
async start() {
|
|
27
|
+
if (this.isStarted()) {
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
this._started = true;
|
|
31
|
+
await Promise.all([
|
|
32
|
+
this._responder.start(),
|
|
33
|
+
this._querier.start()
|
|
34
|
+
]);
|
|
35
|
+
}
|
|
36
|
+
async stop() {
|
|
37
|
+
if (!this.isStarted()) {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
this._started = false;
|
|
41
|
+
await Promise.all([
|
|
42
|
+
this._responder.stop(),
|
|
43
|
+
this._querier.stop()
|
|
44
|
+
]);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/compat/index.ts"],"names":[],"mappings":"AAAA,oCAAoC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAA;AACrC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC1C,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAKtC,MAAM,OAAO,cAAe,SAAQ,YAAY;IAK9C,YAAa,OAAkG;QAC7G,KAAK,EAAE,CAAA;QACP,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,WAAW,EAAE,aAAa,EAAE,GAAG,OAAO,CAAA;QAElE,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAA;QAErB,IAAI,CAAC,UAAU,GAAG,IAAI,SAAS,CAAC;YAC9B,MAAM;YACN,UAAU;SACX,CAAC,CAAA;QACF,IAAI,CAAC,QAAQ,GAAG,IAAI,OAAO,CAAC;YAC1B,MAAM;YACN,aAAa;YACb,WAAW;SACZ,CAAC,CAAA;QAEF,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAE;YACpC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAA;QAC7B,CAAC,CAAC,CAAA;IACJ,CAAC;IAED,SAAS;QACP,OAAO,IAAI,CAAC,QAAQ,CAAA;IACtB,CAAC;IAED,KAAK,CAAC,KAAK;QACT,IAAI,IAAI,CAAC,SAAS,EAAE,EAAE;YACpB,OAAM;SACP;QAED,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAA;QAEpB,MAAM,OAAO,CAAC,GAAG,CAAC;YAChB,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE;YACvB,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE;SACtB,CAAC,CAAA;IACJ,CAAC;IAED,KAAK,CAAC,IAAI;QACR,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,EAAE;YACrB,OAAM;SACP;QAED,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAA;QAErB,MAAM,OAAO,CAAC,GAAG,CAAC;YAChB,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE;YACtB,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE;SACrB,CAAC,CAAA;IACJ,CAAC;CACF"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { EventEmitter } from 'events';
|
|
3
|
+
import { PeerId } from '@libp2p/peer-id';
|
|
4
|
+
import type { PeerDiscovery } from '@libp2p/interfaces/peer-discovery';
|
|
5
|
+
import type { ResponsePacket } from 'multicast-dns';
|
|
6
|
+
import type { RemoteInfo } from 'dgram';
|
|
7
|
+
export interface QuerierOptions {
|
|
8
|
+
peerId: PeerId;
|
|
9
|
+
queryInterval?: number;
|
|
10
|
+
queryPeriod?: number;
|
|
11
|
+
}
|
|
12
|
+
export interface Handle {
|
|
13
|
+
stop: () => Promise<void>;
|
|
14
|
+
}
|
|
15
|
+
export declare class Querier extends EventEmitter implements PeerDiscovery {
|
|
16
|
+
private readonly _peerIdStr;
|
|
17
|
+
private readonly _options;
|
|
18
|
+
private _handle?;
|
|
19
|
+
constructor(options: QuerierOptions);
|
|
20
|
+
isStarted(): boolean;
|
|
21
|
+
start(): void;
|
|
22
|
+
_onResponse(event: ResponsePacket, info: RemoteInfo): void;
|
|
23
|
+
stop(): Promise<void>;
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=querier.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"querier.d.ts","sourceRoot":"","sources":["../../../src/compat/querier.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAA;AAGrC,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAA;AAIxC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mCAAmC,CAAA;AACtE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AACnD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,OAAO,CAAA;AAMvC,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAA;IACd,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB;AAED,MAAM,WAAW,MAAM;IACrB,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAC1B;AAED,qBAAa,OAAQ,SAAQ,YAAa,YAAW,aAAa;IAChE,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAQ;IACnC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA0B;IACnD,OAAO,CAAC,OAAO,CAAC,CAAQ;gBAEX,OAAO,EAAE,cAAc;IAyBpC,SAAS;IAIT,KAAK;IAgCL,WAAW,CAAE,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,UAAU;IAiE9C,IAAI;CAKX"}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import { EventEmitter } from 'events';
|
|
2
|
+
import MDNS from 'multicast-dns';
|
|
3
|
+
import { Multiaddr } from '@multiformats/multiaddr';
|
|
4
|
+
import { PeerId } from '@libp2p/peer-id';
|
|
5
|
+
import debug from 'debug';
|
|
6
|
+
import { SERVICE_TAG_LOCAL, MULTICAST_IP, MULTICAST_PORT } from './constants.js';
|
|
7
|
+
import { base58btc } from 'multiformats/bases/base58';
|
|
8
|
+
const log = Object.assign(debug('libp2p:mdns:compat:querier'), {
|
|
9
|
+
error: debug('libp2p:mdns:compat:querier:error')
|
|
10
|
+
});
|
|
11
|
+
export class Querier extends EventEmitter {
|
|
12
|
+
constructor(options) {
|
|
13
|
+
super();
|
|
14
|
+
const { peerId, queryInterval, queryPeriod } = options;
|
|
15
|
+
if (peerId == null) {
|
|
16
|
+
throw new Error('missing peerId parameter');
|
|
17
|
+
}
|
|
18
|
+
this._peerIdStr = peerId.toString(base58btc);
|
|
19
|
+
this._options = {
|
|
20
|
+
peerId,
|
|
21
|
+
// Re-query in leu of network change detection (every 60s by default)
|
|
22
|
+
queryInterval: queryInterval ?? 60000,
|
|
23
|
+
// Time for which the MDNS server will stay alive waiting for responses
|
|
24
|
+
// Must be less than options.queryInterval!
|
|
25
|
+
queryPeriod: Math.min(queryInterval ?? 60000, queryPeriod ?? 5000)
|
|
26
|
+
};
|
|
27
|
+
this._onResponse = this._onResponse.bind(this);
|
|
28
|
+
}
|
|
29
|
+
isStarted() {
|
|
30
|
+
return Boolean(this._handle);
|
|
31
|
+
}
|
|
32
|
+
start() {
|
|
33
|
+
this._handle = periodically(() => {
|
|
34
|
+
// Create a querier that queries multicast but gets responses unicast
|
|
35
|
+
const mdns = MDNS({ multicast: false, interface: '0.0.0.0', port: 0 });
|
|
36
|
+
mdns.on('response', this._onResponse);
|
|
37
|
+
// @ts-expect-error @types/multicast-dns are wrong
|
|
38
|
+
mdns.query({
|
|
39
|
+
id: nextId(),
|
|
40
|
+
questions: [{
|
|
41
|
+
name: SERVICE_TAG_LOCAL,
|
|
42
|
+
type: 'PTR',
|
|
43
|
+
class: 'IN'
|
|
44
|
+
}]
|
|
45
|
+
}, null, {
|
|
46
|
+
address: MULTICAST_IP,
|
|
47
|
+
port: MULTICAST_PORT
|
|
48
|
+
});
|
|
49
|
+
return {
|
|
50
|
+
stop: async () => {
|
|
51
|
+
mdns.removeListener('response', this._onResponse);
|
|
52
|
+
return await new Promise(resolve => mdns.destroy(resolve));
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
}, {
|
|
56
|
+
period: this._options.queryPeriod,
|
|
57
|
+
interval: this._options.queryInterval
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
_onResponse(event, info) {
|
|
61
|
+
const answers = event.answers ?? [];
|
|
62
|
+
const ptrRecord = answers.find(a => a.type === 'PTR' && a.name === SERVICE_TAG_LOCAL);
|
|
63
|
+
// Only deal with responses for our service tag
|
|
64
|
+
if (ptrRecord == null)
|
|
65
|
+
return;
|
|
66
|
+
log('got response', event, info);
|
|
67
|
+
const txtRecord = answers.find(a => a.type === 'TXT');
|
|
68
|
+
if (txtRecord == null || txtRecord.type !== 'TXT') {
|
|
69
|
+
return log('missing TXT record in response');
|
|
70
|
+
}
|
|
71
|
+
let peerIdStr;
|
|
72
|
+
try {
|
|
73
|
+
peerIdStr = txtRecord.data[0].toString();
|
|
74
|
+
}
|
|
75
|
+
catch (err) {
|
|
76
|
+
return log('failed to extract peer ID from TXT record data', txtRecord, err);
|
|
77
|
+
}
|
|
78
|
+
if (this._peerIdStr === peerIdStr) {
|
|
79
|
+
return log('ignoring reply to myself');
|
|
80
|
+
}
|
|
81
|
+
let peerId;
|
|
82
|
+
try {
|
|
83
|
+
peerId = PeerId.fromString(peerIdStr);
|
|
84
|
+
}
|
|
85
|
+
catch (err) {
|
|
86
|
+
return log('failed to create peer ID from TXT record data', peerIdStr, err);
|
|
87
|
+
}
|
|
88
|
+
const srvRecord = answers.find(a => a.type === 'SRV');
|
|
89
|
+
if (srvRecord == null || srvRecord.type !== 'SRV') {
|
|
90
|
+
return log('missing SRV record in response');
|
|
91
|
+
}
|
|
92
|
+
log('peer found', peerIdStr);
|
|
93
|
+
const { port } = srvRecord.data ?? {};
|
|
94
|
+
const protos = { A: 'ip4', AAAA: 'ip6' };
|
|
95
|
+
const multiaddrs = answers
|
|
96
|
+
.filter(a => ['A', 'AAAA'].includes(a.type))
|
|
97
|
+
.reduce((addrs, a) => {
|
|
98
|
+
if (a.type !== 'A' && a.type !== 'AAAA') {
|
|
99
|
+
return addrs;
|
|
100
|
+
}
|
|
101
|
+
const maStr = `/${protos[a.type]}/${a.data}/tcp/${port}`;
|
|
102
|
+
try {
|
|
103
|
+
addrs.push(new Multiaddr(maStr));
|
|
104
|
+
log(maStr);
|
|
105
|
+
}
|
|
106
|
+
catch (err) {
|
|
107
|
+
log(`failed to create multiaddr from ${a.type} record data`, maStr, port, err);
|
|
108
|
+
}
|
|
109
|
+
return addrs;
|
|
110
|
+
}, []);
|
|
111
|
+
this.emit('peer', {
|
|
112
|
+
id: peerId,
|
|
113
|
+
multiaddrs
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
async stop() {
|
|
117
|
+
if (this._handle != null) {
|
|
118
|
+
await this._handle.stop();
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Run `fn` for a certain period of time, and then wait for an interval before
|
|
124
|
+
* running it again. `fn` must return an object with a stop function, which is
|
|
125
|
+
* called when the period expires.
|
|
126
|
+
*/
|
|
127
|
+
function periodically(fn, options) {
|
|
128
|
+
let handle;
|
|
129
|
+
let timeoutId;
|
|
130
|
+
let stopped = false;
|
|
131
|
+
const reRun = () => {
|
|
132
|
+
handle = fn();
|
|
133
|
+
timeoutId = setTimeout(() => {
|
|
134
|
+
if (handle != null) {
|
|
135
|
+
handle.stop().catch(log);
|
|
136
|
+
}
|
|
137
|
+
if (!stopped) {
|
|
138
|
+
timeoutId = setTimeout(reRun, options.interval);
|
|
139
|
+
}
|
|
140
|
+
handle = null;
|
|
141
|
+
}, options.period);
|
|
142
|
+
};
|
|
143
|
+
reRun();
|
|
144
|
+
return {
|
|
145
|
+
async stop() {
|
|
146
|
+
stopped = true;
|
|
147
|
+
clearTimeout(timeoutId);
|
|
148
|
+
if (handle != null) {
|
|
149
|
+
await handle.stop();
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
const nextId = (() => {
|
|
155
|
+
let id = 0;
|
|
156
|
+
return () => {
|
|
157
|
+
id++;
|
|
158
|
+
if (id === Number.MAX_SAFE_INTEGER)
|
|
159
|
+
id = 1;
|
|
160
|
+
return id;
|
|
161
|
+
};
|
|
162
|
+
})();
|
|
163
|
+
//# sourceMappingURL=querier.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"querier.js","sourceRoot":"","sources":["../../../src/compat/querier.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { QueryPacket } from 'multicast-dns';
|
|
3
|
+
import type { PeerId } from '@libp2p/interfaces/peer-id';
|
|
4
|
+
import type { Multiaddr } from '@multiformats/multiaddr';
|
|
5
|
+
import type { RemoteInfo } from 'dgram';
|
|
6
|
+
export interface ResponderOptions {
|
|
7
|
+
peerId: PeerId;
|
|
8
|
+
multiaddrs: Multiaddr[];
|
|
9
|
+
}
|
|
10
|
+
export declare class Responder {
|
|
11
|
+
private readonly _peerIdStr;
|
|
12
|
+
private readonly _multiaddrs;
|
|
13
|
+
private _mdns?;
|
|
14
|
+
constructor(options: ResponderOptions);
|
|
15
|
+
start(): void;
|
|
16
|
+
_onQuery(event: QueryPacket, info: RemoteInfo): void;
|
|
17
|
+
stop(): Promise<void> | undefined;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=responder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"responder.d.ts","sourceRoot":"","sources":["../../../src/compat/responder.ts"],"names":[],"mappings":";AACA,OAAa,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAGjD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAA;AACxD,OAAO,KAAK,EAAE,SAAS,EAAmB,MAAM,yBAAyB,CAAA;AAEzE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,OAAO,CAAA;AAOvC,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAA;IACd,UAAU,EAAE,SAAS,EAAE,CAAA;CACxB;AAED,qBAAa,SAAS;IACpB,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAQ;IACnC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAa;IACzC,OAAO,CAAC,KAAK,CAAC,CAAmB;gBAEpB,OAAO,EAAE,gBAAgB;IAYtC,KAAK;IAKL,QAAQ,CAAE,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,UAAU;IAyE9C,IAAI;CAYL"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import OS from 'os';
|
|
2
|
+
import MDNS from 'multicast-dns';
|
|
3
|
+
import debug from 'debug';
|
|
4
|
+
import { SERVICE_TAG_LOCAL } from './constants.js';
|
|
5
|
+
import { base58btc } from 'multiformats/bases/base58';
|
|
6
|
+
const log = Object.assign(debug('libp2p:mdns:compat:responder'), {
|
|
7
|
+
error: debug('libp2p:mdns:compat:responder:error')
|
|
8
|
+
});
|
|
9
|
+
export class Responder {
|
|
10
|
+
constructor(options) {
|
|
11
|
+
const { peerId, multiaddrs } = options;
|
|
12
|
+
if (peerId == null) {
|
|
13
|
+
throw new Error('missing peerId parameter');
|
|
14
|
+
}
|
|
15
|
+
this._peerIdStr = peerId.toString(base58btc);
|
|
16
|
+
this._multiaddrs = multiaddrs;
|
|
17
|
+
this._onQuery = this._onQuery.bind(this);
|
|
18
|
+
}
|
|
19
|
+
start() {
|
|
20
|
+
this._mdns = MDNS();
|
|
21
|
+
this._mdns.on('query', this._onQuery);
|
|
22
|
+
}
|
|
23
|
+
_onQuery(event, info) {
|
|
24
|
+
const addresses = this._multiaddrs.reduce((acc, addr) => {
|
|
25
|
+
if (addr.isThinWaistAddress()) {
|
|
26
|
+
acc.push(addr.toOptions());
|
|
27
|
+
}
|
|
28
|
+
return acc;
|
|
29
|
+
}, []);
|
|
30
|
+
// Only announce TCP for now
|
|
31
|
+
if (addresses.length === 0) {
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
const questions = event.questions ?? [];
|
|
35
|
+
// Only respond to queries for our service tag
|
|
36
|
+
if (!questions.some(q => q.name === SERVICE_TAG_LOCAL))
|
|
37
|
+
return;
|
|
38
|
+
log('got query', event, info);
|
|
39
|
+
const answers = [];
|
|
40
|
+
const peerServiceTagLocal = `${this._peerIdStr}.${SERVICE_TAG_LOCAL}`;
|
|
41
|
+
answers.push({
|
|
42
|
+
name: SERVICE_TAG_LOCAL,
|
|
43
|
+
type: 'PTR',
|
|
44
|
+
class: 'IN',
|
|
45
|
+
ttl: 120,
|
|
46
|
+
data: peerServiceTagLocal
|
|
47
|
+
});
|
|
48
|
+
// Only announce TCP multiaddrs for now
|
|
49
|
+
const port = addresses[0].port;
|
|
50
|
+
answers.push({
|
|
51
|
+
name: peerServiceTagLocal,
|
|
52
|
+
type: 'SRV',
|
|
53
|
+
class: 'IN',
|
|
54
|
+
ttl: 120,
|
|
55
|
+
data: {
|
|
56
|
+
priority: 10,
|
|
57
|
+
weight: 1,
|
|
58
|
+
port,
|
|
59
|
+
target: OS.hostname()
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
answers.push({
|
|
63
|
+
name: peerServiceTagLocal,
|
|
64
|
+
type: 'TXT',
|
|
65
|
+
class: 'IN',
|
|
66
|
+
ttl: 120,
|
|
67
|
+
data: [Buffer.from(this._peerIdStr)]
|
|
68
|
+
});
|
|
69
|
+
addresses.forEach((ma) => {
|
|
70
|
+
if ([4, 6].includes(ma.family)) {
|
|
71
|
+
answers.push({
|
|
72
|
+
name: OS.hostname(),
|
|
73
|
+
type: ma.family === 4 ? 'A' : 'AAAA',
|
|
74
|
+
class: 'IN',
|
|
75
|
+
ttl: 120,
|
|
76
|
+
data: ma.host
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
if (this._mdns != null) {
|
|
81
|
+
log('responding to query', answers);
|
|
82
|
+
this._mdns.respond(answers, info);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
stop() {
|
|
86
|
+
if (this._mdns != null) {
|
|
87
|
+
this._mdns.removeListener('query', this._onQuery);
|
|
88
|
+
return new Promise(resolve => {
|
|
89
|
+
if (this._mdns != null) {
|
|
90
|
+
this._mdns.destroy(resolve);
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
resolve();
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=responder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"responder.js","sourceRoot":"","sources":["../../../src/compat/responder.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import multicastDNS from 'multicast-dns';
|
|
3
|
+
import { EventEmitter } from 'events';
|
|
4
|
+
import type { PeerId } from '@libp2p/interfaces/peer-id';
|
|
5
|
+
import type PeerDiscovery from '@libp2p/interfaces/peer-discovery';
|
|
6
|
+
import type { Multiaddr } from '@multiformats/multiaddr';
|
|
7
|
+
import type { PeerData } from '@libp2p/interfaces/peer-data';
|
|
8
|
+
export interface MulticastDNSOptions {
|
|
9
|
+
peerId: PeerId;
|
|
10
|
+
broadcast?: boolean;
|
|
11
|
+
interval?: number;
|
|
12
|
+
serviceTag?: string;
|
|
13
|
+
port?: number;
|
|
14
|
+
multiaddrs?: Multiaddr[];
|
|
15
|
+
compat?: boolean;
|
|
16
|
+
compatQueryPeriod?: number;
|
|
17
|
+
compatQueryInterval?: number;
|
|
18
|
+
}
|
|
19
|
+
export declare class MulticastDNS extends EventEmitter implements PeerDiscovery {
|
|
20
|
+
static tag: string;
|
|
21
|
+
mdns?: multicastDNS.MulticastDNS;
|
|
22
|
+
private readonly broadcast;
|
|
23
|
+
private readonly interval;
|
|
24
|
+
private readonly serviceTag;
|
|
25
|
+
private readonly port;
|
|
26
|
+
private readonly peerId;
|
|
27
|
+
private readonly peerMultiaddrs;
|
|
28
|
+
private _queryInterval;
|
|
29
|
+
private readonly _goMdns?;
|
|
30
|
+
constructor(options: MulticastDNSOptions);
|
|
31
|
+
isStarted(): boolean;
|
|
32
|
+
/**
|
|
33
|
+
* Start sending queries to the LAN.
|
|
34
|
+
*
|
|
35
|
+
* @returns {void}
|
|
36
|
+
*/
|
|
37
|
+
start(): Promise<void>;
|
|
38
|
+
_onMdnsQuery(event: multicastDNS.QueryPacket): void;
|
|
39
|
+
_onMdnsResponse(event: multicastDNS.ResponsePacket): void;
|
|
40
|
+
_onPeer(peerData: PeerData): void;
|
|
41
|
+
/**
|
|
42
|
+
* Stop sending queries to the LAN.
|
|
43
|
+
*
|
|
44
|
+
* @returns {Promise}
|
|
45
|
+
*/
|
|
46
|
+
stop(): Promise<void>;
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";AAAA,OAAO,YAAY,MAAM,eAAe,CAAA;AACxC,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAA;AAIrC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAA;AACxD,OAAO,KAAK,aAAa,MAAM,mCAAmC,CAAA;AAClE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAA;AACxD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAA;AAM5D,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,UAAU,CAAC,EAAE,SAAS,EAAE,CAAA;IACxB,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,mBAAmB,CAAC,EAAE,MAAM,CAAA;CAC7B;AAED,qBAAa,YAAa,SAAQ,YAAa,YAAW,aAAa;IACrE,MAAM,CAAC,GAAG,SAAS;IAEZ,IAAI,CAAC,EAAE,YAAY,CAAC,YAAY,CAAA;IAEvC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAQ;IACjC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAQ;IACnC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAQ;IAC7B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAQ;IAC/B,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAa;IAC5C,OAAO,CAAC,cAAc,CAAqB;IAC3C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAgB;gBAE5B,OAAO,EAAE,mBAAmB;IA6BzC,SAAS;IAIT;;;;OAIG;IACG,KAAK;IAgBX,YAAY,CAAE,KAAK,EAAE,YAAY,CAAC,WAAW;IAQ7C,eAAe,CAAE,KAAK,EAAE,YAAY,CAAC,cAAc;IAYnD,OAAO,CAAE,QAAQ,EAAE,QAAQ;IAI3B;;;;OAIG;IACG,IAAI;CA2BX"}
|