Skip to content

Commit 2b7cc55

Browse files
jacobheundaviddias
authored andcommitted
feat: add check for protector and enforced pnet
fix: update protector config and tests docs: add private network info to the readme test: fix an issue with config
1 parent 40739e9 commit 2b7cc55

File tree

5 files changed

+113
-0
lines changed

5 files changed

+113
-0
lines changed

README.md

+12
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ const SECIO = require('libp2p-secio')
115115
const MulticastDNS = require('libp2p-mdns')
116116
const DHT = require('libp2p-kad-dht')
117117
const defaultsDeep = require('@nodeutils/defaults-deep')
118+
const Protector = require('libp2p-pnet')
118119

119120
class Node extends libp2p {
120121
constructor (_peerInfo, _peerBook, _options) {
@@ -135,6 +136,7 @@ class Node extends libp2p {
135136
connEncryption: [
136137
SECIO
137138
],
139+
connProtector: new Protector(/*protector specific opts*/),
138140
peerDiscovery: [
139141
MulticastDNS
140142
],
@@ -431,6 +433,16 @@ Each one of these values is [an exponential moving-average instance](https://git
431433

432434
Stats are not updated in real-time. Instead, measurements are buffered and stats are updated at an interval. The maximum interval can be defined through the `Switch` constructor option `stats.computeThrottleTimeout`, defined in miliseconds.
433435

436+
### Private Networks
437+
438+
#### Enforcement
439+
440+
Libp2p provides support for connection protection, such as for private networks. You can enforce network protection by setting the environment variable `LIBP2P_FORCE_PNET=1`. When this variable is on, if no protector is set via `options.connProtector`, Libp2p will throw an error upon creation.
441+
442+
#### Protectors
443+
444+
Some available network protectors:
445+
* [libp2p-pnet](https://github.com/libp2p/js-libp2p-pnet)
434446

435447
## Development
436448

src/config.js

+3
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ const OptionsSchema = Joi.object({
1313
transport: Joi.array().items(ModuleSchema).min(1).required(),
1414
streamMuxer: Joi.array().items(ModuleSchema).allow(null),
1515
connEncryption: Joi.array().items(ModuleSchema).allow(null),
16+
connProtector: Joi.object().keys({
17+
protect: Joi.func().required()
18+
}).unknown(),
1619
peerDiscovery: Joi.array().items(ModuleSchema).allow(null),
1720
dht: ModuleSchema.allow(null)
1821
}).required(),

src/index.js

+7
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,13 @@ class Node extends EventEmitter {
7575
})
7676
}
7777

78+
// Attach private network protector
79+
if (this._modules.connProtector) {
80+
this._switch.protector = this._modules.connProtector
81+
} else if (process.env.LIBP2P_FORCE_PNET) {
82+
throw new Error('Private network is enforced, but no protector was provided')
83+
}
84+
7885
// dht provided components (peerRouting, contentRouting, dht)
7986
if (this._config.EXPERIMENTAL.dht) {
8087
const DHT = this._modules.dht

test/node.js

+1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
'use strict'
22

3+
require('./pnet.node')
34
require('./transports.node')
45
require('./stream-muxing.node')
56
require('./peer-discovery.node')

test/pnet.node.js

+90
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
/* eslint-env mocha */
2+
'use strict'
3+
4+
const chai = require('chai')
5+
chai.use(require('dirty-chai'))
6+
const expect = chai.expect
7+
const PeerInfo = require('peer-info')
8+
const PeerId = require('peer-id')
9+
const waterfall = require('async/waterfall')
10+
const WS = require('libp2p-websockets')
11+
const defaultsDeep = require('@nodeutils/defaults-deep')
12+
13+
const Libp2p = require('../src')
14+
15+
describe('private network', () => {
16+
let config
17+
18+
before((done) => {
19+
waterfall([
20+
(cb) => PeerId.create({ bits: 512 }, cb),
21+
(peerId, cb) => PeerInfo.create(peerId, cb),
22+
(peerInfo, cb) => {
23+
config = {
24+
peerInfo,
25+
modules: {
26+
transport: [ WS ]
27+
}
28+
}
29+
cb()
30+
}
31+
], () => done())
32+
})
33+
34+
describe('enforced network protection', () => {
35+
before(() => {
36+
process.env.LIBP2P_FORCE_PNET = 1
37+
})
38+
39+
after(() => {
40+
delete process.env.LIBP2P_FORCE_PNET
41+
})
42+
43+
it('should throw an error without a provided protector', () => {
44+
expect(() => {
45+
return new Libp2p(config)
46+
}).to.throw('Private network is enforced, but no protector was provided')
47+
})
48+
49+
it('should create a libp2p node with a provided protector', () => {
50+
let node
51+
let protector = {
52+
psk: '123',
53+
tag: '/psk/1.0.0',
54+
protect: () => { }
55+
}
56+
57+
expect(() => {
58+
let options = defaultsDeep(config, {
59+
modules: {
60+
connProtector: protector
61+
}
62+
})
63+
64+
node = new Libp2p(options)
65+
return node
66+
}).to.not.throw()
67+
expect(node._switch.protector).to.deep.equal(protector)
68+
})
69+
70+
it('should throw an error if the protector does not have a protect method', () => {
71+
expect(() => {
72+
let options = defaultsDeep(config, {
73+
modules: {
74+
connProtector: { }
75+
}
76+
})
77+
78+
return new Libp2p(options)
79+
}).to.throw()
80+
})
81+
})
82+
83+
describe('network protection not enforced', () => {
84+
it('should not throw an error with no provided protector', () => {
85+
expect(() => {
86+
return new Libp2p(config)
87+
}).to.not.throw()
88+
})
89+
})
90+
})

0 commit comments

Comments
 (0)