Skip to content
This repository was archived by the owner on Aug 23, 2019. It is now read-only.

Commit 514d480

Browse files
dignifiedquiredryajov
authored andcommitted
feat(dial): exposing connection handle flow
1 parent 5274e87 commit 514d480

File tree

5 files changed

+170
-138
lines changed

5 files changed

+170
-138
lines changed

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -87,4 +87,4 @@
8787
"greenkeeper[bot] <greenkeeper[bot]@users.noreply.github.com>",
8888
"ᴠɪᴄᴛᴏʀ ʙᴊᴇʟᴋʜᴏʟᴍ <[email protected]>"
8989
]
90-
}
90+
}

src/dial.js

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

3-
const multistream = require('multistream-select')
43
const Connection = require('interface-connection').Connection
54
const debug = require('debug')
65
const log = debug('libp2p:swarm:dial')
7-
const setImmediate = require('async/setImmediate')
8-
9-
const protocolMuxer = require('./protocol-muxer')
106

117
module.exports = function dial (swarm) {
128
return (pi, protocol, callback) => {
@@ -18,6 +14,7 @@ module.exports = function dial (swarm) {
1814
callback = callback || function noop () {}
1915

2016
const proxyConn = new Connection()
17+
const connHandler = swarm.connHandler(pi, protocol, proxyConn)
2118

2219
const b58Id = pi.id.toB58String()
2320
log('dialing %s', b58Id)
@@ -28,54 +25,22 @@ module.exports = function dial (swarm) {
2825
if (err) {
2926
return callback(err)
3027
}
31-
gotWarmedUpConn(conn)
28+
connHandler.handleNew(conn, callback)
3229
})
3330
} else {
3431
const conn = swarm.conns[b58Id]
3532
swarm.conns[b58Id] = undefined
36-
gotWarmedUpConn(conn)
33+
connHandler.handleWarmedUp(conn, callback)
3734
}
3835
} else {
3936
if (!protocol) {
4037
return callback()
4138
}
42-
gotMuxer(swarm.muxedConns[b58Id].muxer)
39+
connHandler.gotMuxer(swarm.muxedConns[b58Id].muxer, callback)
4340
}
4441

4542
return proxyConn
4643

47-
function gotWarmedUpConn (conn) {
48-
conn.setPeerInfo(pi)
49-
attemptMuxerUpgrade(conn, (err, muxer) => {
50-
if (!protocol) {
51-
if (err) {
52-
swarm.conns[b58Id] = conn
53-
}
54-
return callback()
55-
}
56-
57-
if (err) {
58-
// couldn't upgrade to Muxer, it is ok
59-
protocolHandshake(conn, protocol, callback)
60-
} else {
61-
gotMuxer(muxer)
62-
}
63-
})
64-
}
65-
66-
function gotMuxer (muxer) {
67-
if (swarm.identify) {
68-
// TODO: Consider:
69-
// 1. overload getPeerInfo
70-
// 2. exec identify (through getPeerInfo)
71-
// 3. update the peerInfo that is already stored in the conn
72-
}
73-
74-
openConnInMuxedConn(muxer, (conn) => {
75-
protocolHandshake(conn, protocol, callback)
76-
})
77-
}
78-
7944
function attemptDial (pi, cb) {
8045
const tKeys = swarm.availableTransports(pi)
8146

@@ -94,106 +59,9 @@ module.exports = function dial (swarm) {
9459
return nextTransport(tKeys.shift())
9560
}
9661

97-
cryptoDial()
98-
99-
function cryptoDial () {
100-
const ms = new multistream.Dialer()
101-
ms.handle(conn, (err) => {
102-
if (err) {
103-
return cb(err)
104-
}
105-
106-
const id = swarm._peerInfo.id
107-
log('selecting crypto: %s', swarm.crypto.tag)
108-
ms.select(swarm.crypto.tag, (err, conn) => {
109-
if (err) {
110-
return cb(err)
111-
}
112-
113-
const wrapped = swarm.crypto.encrypt(id, id.privKey, conn)
114-
cb(null, wrapped)
115-
})
116-
})
117-
}
62+
cb(null, conn)
11863
})
11964
}
12065
}
121-
122-
function attemptMuxerUpgrade (conn, cb) {
123-
const muxers = Object.keys(swarm.muxers)
124-
if (muxers.length === 0) {
125-
return cb(new Error('no muxers available'))
126-
}
127-
128-
// 1. try to handshake in one of the muxers available
129-
// 2. if succeeds
130-
// - add the muxedConn to the list of muxedConns
131-
// - add incomming new streams to connHandler
132-
133-
const ms = new multistream.Dialer()
134-
ms.handle(conn, (err) => {
135-
if (err) {
136-
return callback(new Error('multistream not supported'))
137-
}
138-
139-
nextMuxer(muxers.shift())
140-
})
141-
142-
function nextMuxer (key) {
143-
log('selecting %s', key)
144-
ms.select(key, (err, conn) => {
145-
if (err) {
146-
if (muxers.length === 0) {
147-
cb(new Error('could not upgrade to stream muxing'))
148-
} else {
149-
nextMuxer(muxers.shift())
150-
}
151-
return
152-
}
153-
154-
const muxedConn = swarm.muxers[key].dialer(conn)
155-
swarm.muxedConns[b58Id] = {}
156-
swarm.muxedConns[b58Id].muxer = muxedConn
157-
// should not be needed anymore - swarm.muxedConns[b58Id].conn = conn
158-
159-
muxedConn.once('close', () => {
160-
const b58Str = pi.id.toB58String()
161-
delete swarm.muxedConns[b58Str]
162-
pi.disconnect()
163-
swarm._peerBook.get(b58Str).disconnect()
164-
setImmediate(() => swarm.emit('peer-mux-closed', pi))
165-
})
166-
167-
// For incoming streams, in case identify is on
168-
muxedConn.on('stream', (conn) => {
169-
protocolMuxer(swarm.protocols, conn)
170-
})
171-
172-
setImmediate(() => swarm.emit('peer-mux-established', pi))
173-
174-
cb(null, muxedConn)
175-
})
176-
}
177-
}
178-
179-
function openConnInMuxedConn (muxer, cb) {
180-
cb(muxer.newStream())
181-
}
182-
183-
function protocolHandshake (conn, protocol, cb) {
184-
const ms = new multistream.Dialer()
185-
ms.handle(conn, (err) => {
186-
if (err) {
187-
return callback(err)
188-
}
189-
ms.select(protocol, (err, conn) => {
190-
if (err) {
191-
return callback(err)
192-
}
193-
proxyConn.setInnerConn(conn)
194-
callback(null, proxyConn)
195-
})
196-
})
197-
}
19866
}
19967
}

src/handler.js

+162
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
'use strict'
2+
3+
const multistream = require('multistream-select')
4+
const protocolMuxer = require('./protocol-muxer')
5+
6+
const debug = require('debug')
7+
const log = debug('libp2p:swarm:handle')
8+
9+
module.exports = function process (swarm) {
10+
return (pi, protocol, proxyConn) => {
11+
const b58Id = pi.id.toB58String()
12+
13+
function cryptoDial (conn, cb) {
14+
const ms = new multistream.Dialer()
15+
ms.handle(conn, (err) => {
16+
if (err) {
17+
return cb(err)
18+
}
19+
20+
const id = swarm._peerInfo.id
21+
log('selecting crypto: %s', swarm.crypto.tag)
22+
ms.select(swarm.crypto.tag, (err, conn) => {
23+
if (err) {
24+
return cb(err)
25+
}
26+
27+
const wrapped = swarm.crypto.encrypt(id, id.privKey, conn)
28+
cb(null, wrapped)
29+
})
30+
})
31+
}
32+
33+
function gotWarmedUpConn (conn, cb) {
34+
conn.setPeerInfo(pi)
35+
attemptMuxerUpgrade(conn, (err, muxer) => {
36+
if (!protocol) {
37+
if (err) {
38+
swarm.conns[b58Id] = conn
39+
}
40+
return cb()
41+
}
42+
43+
if (err) {
44+
// couldn't upgrade to Muxer, it is ok
45+
protocolHandshake(conn, protocol, cb)
46+
} else {
47+
gotMuxer(muxer, cb)
48+
}
49+
})
50+
}
51+
52+
function attemptMuxerUpgrade (conn, cb) {
53+
const muxers = Object.keys(swarm.muxers)
54+
if (muxers.length === 0) {
55+
return cb(new Error('no muxers available'))
56+
}
57+
58+
// 1. try to handshake in one of the muxers available
59+
// 2. if succeeds
60+
// - add the muxedConn to the list of muxedConns
61+
// - add incomming new streams to connHandler
62+
63+
const ms = new multistream.Dialer()
64+
ms.handle(conn, (err) => {
65+
if (err) {
66+
return cb(new Error('multistream not supported'))
67+
}
68+
69+
nextMuxer(muxers.shift())
70+
})
71+
72+
function nextMuxer (key) {
73+
log('selecting %s', key)
74+
ms.select(key, (err, conn) => {
75+
if (err) {
76+
if (muxers.length === 0) {
77+
cb(new Error('could not upgrade to stream muxing'))
78+
} else {
79+
nextMuxer(muxers.shift())
80+
}
81+
return
82+
}
83+
84+
const muxedConn = swarm.muxers[key].dialer(conn)
85+
swarm.muxedConns[b58Id] = {}
86+
swarm.muxedConns[b58Id].muxer = muxedConn
87+
// should not be needed anymore - swarm.muxedConns[b58Id].conn = conn
88+
89+
swarm.emit('peer-mux-established', pi)
90+
91+
muxedConn.once('close', () => {
92+
const b58Str = pi.id.toB58String()
93+
delete swarm.muxedConns[b58Str]
94+
pi.disconnect()
95+
swarm._peerBook.get(b58Str).disconnect()
96+
swarm.emit('peer-mux-closed', pi)
97+
})
98+
99+
// For incoming streams, in case identify is on
100+
muxedConn.on('stream', (conn) => {
101+
protocolMuxer(swarm.protocols, conn)
102+
})
103+
104+
cb(null, muxedConn)
105+
})
106+
}
107+
}
108+
109+
function openConnInMuxedConn (muxer, cb) {
110+
cb(muxer.newStream())
111+
}
112+
113+
function protocolHandshake (conn, protocol, cb) {
114+
const ms = new multistream.Dialer()
115+
ms.handle(conn, (err) => {
116+
if (err) {
117+
return cb(err)
118+
}
119+
ms.select(protocol, (err, conn) => {
120+
if (err) {
121+
return cb(err)
122+
}
123+
proxyConn.setInnerConn(conn)
124+
cb(null, proxyConn)
125+
})
126+
})
127+
}
128+
129+
function handleNew (conn, cb) {
130+
cryptoDial(conn, (err, conn) => {
131+
if (err) {
132+
log(err)
133+
return cb(err)
134+
}
135+
gotWarmedUpConn(conn, cb)
136+
})
137+
}
138+
139+
function handleWarmedUp (conn, cb) {
140+
gotWarmedUpConn(conn, cb)
141+
}
142+
143+
function gotMuxer (muxer, cb) {
144+
if (swarm.identify) {
145+
// TODO: Consider:
146+
// 1. overload getPeerInfo
147+
// 2. exec identify (through getPeerInfo)
148+
// 3. update the peerInfo that is already stored in the conn
149+
}
150+
151+
openConnInMuxedConn(muxer, (conn) => {
152+
protocolHandshake(conn, protocol, cb)
153+
})
154+
}
155+
156+
return {
157+
handleNew: handleNew,
158+
handleWarmedUp: handleWarmedUp,
159+
gotMuxer: gotMuxer
160+
}
161+
}
162+
}

src/index.js

+2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ const each = require('async/each')
66
const series = require('async/series')
77
const transport = require('./transport')
88
const connection = require('./connection')
9+
const handler = require('./handler')
910
const dial = require('./dial')
1011
const protocolMuxer = require('./protocol-muxer')
1112
const plaintext = require('./plaintext')
@@ -56,6 +57,7 @@ function Swarm (peerInfo, peerBook) {
5657

5758
this.transport = transport(this)
5859
this.connection = connection(this)
60+
this.connHandler = handler(this)
5961

6062
this.availableTransports = (pi) => {
6163
const myAddrs = pi.multiaddrs.toArray()

test/01-transport-tcp.node.js

Whitespace-only changes.

0 commit comments

Comments
 (0)