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

Commit

Permalink
refactor: update files and add jsdocs to improve readability
Browse files Browse the repository at this point in the history
refactor: initial refactor of dial.js
refactor: add more jsdocs to dial and clean up some code
refactor: make get-peer-info more readable
fix: jsdocs in dial
docs: update some jsdocs
refactor: make dial.js a bit easier to consume
fix: fix linting
  • Loading branch information
jacobheun committed Apr 25, 2018
1 parent 97bb973 commit 4c6af13
Show file tree
Hide file tree
Showing 8 changed files with 662 additions and 398 deletions.
236 changes: 135 additions & 101 deletions src/connection.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,121 +12,155 @@ const Circuit = require('libp2p-circuit')

const plaintext = require('./plaintext')

module.exports = function connection (swtch) {
return {
addUpgrade () {},

addStreamMuxer (muxer) {
// for dialing
swtch.muxers[muxer.multicodec] = muxer

// for listening
swtch.handle(muxer.multicodec, (protocol, conn) => {
const muxedConn = muxer.listener(conn)

muxedConn.on('stream', swtch.protocolMuxer(null))

// If identify is enabled
// 1. overload getPeerInfo
// 2. call getPeerInfo
// 3. add this conn to the pool
if (swtch.identify) {
// overload peerInfo to use Identify instead
conn.getPeerInfo = (cb) => {
const conn = muxedConn.newStream()
const ms = new multistream.Dialer()
cb = once(cb)

waterfall([
(cb) => ms.handle(conn, cb),
(cb) => ms.select(identify.multicodec, cb),
(conn, cb) => identify.dialer(conn, cb),
(peerInfo, observedAddrs, cb) => {
observedAddrs.forEach((oa) => {
swtch._peerInfo.multiaddrs.addSafe(oa)
})
cb(null, peerInfo)
}
], (err, pi) => {
if (pi) {
conn.setPeerInfo(pi)
}
cb(err, pi)
})
}
/**
* Contains methods for binding handlers to the Switch
* in order to better manage its connections.
*/
class ConnectionManager {
constructor (_switch) {
this.switch = _switch
}

conn.getPeerInfo((err, peerInfo) => {
if (err) {
return log('Identify not successful')
/**
* Adds a listener for the given `muxer` and creates a handler for it
* leveraging the Switch.protocolMuxer handler factory
*
* @param {Muxer} muxer
* @returns {void}
*/
addStreamMuxer (muxer) {
// for dialing
this.switch.muxers[muxer.multicodec] = muxer

// for listening
this.switch.handle(muxer.multicodec, (protocol, conn) => {
const muxedConn = muxer.listener(conn)

muxedConn.on('stream', this.switch.protocolMuxer(null))

// If identify is enabled
// 1. overload getPeerInfo
// 2. call getPeerInfo
// 3. add this conn to the pool
if (this.switch.identify) {
// overload peerInfo to use Identify instead
conn.getPeerInfo = (callback) => {
const conn = muxedConn.newStream()
const ms = new multistream.Dialer()
callback = once(callback)

waterfall([
(cb) => ms.handle(conn, cb),
(cb) => ms.select(identify.multicodec, cb),
(conn, cb) => identify.dialer(conn, cb),
(peerInfo, observedAddrs, cb) => {
observedAddrs.forEach((oa) => {
this.switch._peerInfo.multiaddrs.addSafe(oa)
})
cb(null, peerInfo)
}
const b58Str = peerInfo.id.toB58String()

swtch.muxedConns[b58Str] = { muxer: muxedConn }

if (peerInfo.multiaddrs.size > 0) {
// with incomming conn and through identify, going to pick one
// of the available multiaddrs from the other peer as the one
// I'm connected to as we really can't be sure at the moment
// TODO add this consideration to the connection abstraction!
peerInfo.connect(peerInfo.multiaddrs.toArray()[0])
} else {
// for the case of websockets in the browser, where peers have
// no addr, use just their IPFS id
peerInfo.connect(`/ipfs/${b58Str}`)
], (err, peerInfo) => {
if (peerInfo) {
conn.setPeerInfo(peerInfo)
}
peerInfo = swtch._peerBook.put(peerInfo)
callback(err, peerInfo)
})
}

muxedConn.on('close', () => {
delete swtch.muxedConns[b58Str]
peerInfo.disconnect()
peerInfo = swtch._peerBook.put(peerInfo)
setImmediate(() => swtch.emit('peer-mux-closed', peerInfo))
})
conn.getPeerInfo((err, peerInfo) => {
if (err) {
return log('Identify not successful')
}
const b58Str = peerInfo.id.toB58String()

this.switch.muxedConns[b58Str] = { muxer: muxedConn }

if (peerInfo.multiaddrs.size > 0) {
// with incomming conn and through identify, going to pick one
// of the available multiaddrs from the other peer as the one
// I'm connected to as we really can't be sure at the moment
// TODO add this consideration to the connection abstraction!
peerInfo.connect(peerInfo.multiaddrs.toArray()[0])
} else {
// for the case of websockets in the browser, where peers have
// no addr, use just their IPFS id
peerInfo.connect(`/ipfs/${b58Str}`)
}
peerInfo = this.switch._peerBook.put(peerInfo)

setImmediate(() => swtch.emit('peer-mux-established', peerInfo))
muxedConn.on('close', () => {
delete this.switch.muxedConns[b58Str]
peerInfo.disconnect()
peerInfo = this.switch._peerBook.put(peerInfo)
setImmediate(() => this.switch.emit('peer-mux-closed', peerInfo))
})
}

return conn
})
},
setImmediate(() => this.switch.emit('peer-mux-established', peerInfo))
})
}

reuse () {
swtch.identify = true
swtch.handle(identify.multicodec, (protocol, conn) => {
identify.listener(conn, swtch._peerInfo)
})
},
return conn
})
}

enableCircuitRelay (config) {
config = config || {}
/**
* Adds the `encrypt` handler for the given `tag` and also sets the
* Switch's crypto to past `encrypt` function
*
* @param {String} tag
* @param {function(PeerID, Connection, PeerId, Callback)} encrypt
* @returns {void}
*/
crypto (tag, encrypt) {
if (!tag && !encrypt) {
tag = plaintext.tag
encrypt = plaintext.encrypt
}

if (config.enabled) {
if (!config.hop) {
Object.assign(config, { hop: { enabled: false, active: false } })
}
this.switch.unhandle(this.switch.crypto.tag)
this.switch.handle(tag, (protocol, conn) => {
const myId = this.switch._peerInfo.id
const secure = encrypt(myId, conn, undefined, () => {
this.switch.protocolMuxer(null)(secure)
})
})

// TODO: (dryajov) should we enable circuit listener and
// dialer by default?
swtch.transport.add(Circuit.tag, new Circuit(swtch, config))
}
},
this.switch.crypto = {tag, encrypt}
}

crypto (tag, encrypt) {
if (!tag && !encrypt) {
tag = plaintext.tag
encrypt = plaintext.encrypt
/**
* If config.enabled is true, a Circuit relay will be added to the
* available Switch transports.
*
* @param {any} config
* @returns {void}
*/
enableCircuitRelay (config) {
config = config || {}

if (config.enabled) {
if (!config.hop) {
Object.assign(config, { hop: { enabled: false, active: false } })
}

swtch.unhandle(swtch.crypto.tag)
swtch.handle(tag, (protocol, conn) => {
const myId = swtch._peerInfo.id
const secure = encrypt(myId, conn, undefined, () => {
swtch.protocolMuxer(null)(secure)
})
})

swtch.crypto = {tag, encrypt}
// TODO: (dryajov) should we enable circuit listener and
// dialer by default?
this.switch.transport.add(Circuit.tag, new Circuit(this.switch, config))
}
}

/**
* Sets identify to true on the Switch and performs handshakes
* for libp2p-identify leveraging the Switch's muxer.
*
* @returns {void}
*/
reuse () {
this.switch.identify = true
this.switch.handle(identify.multicodec, (protocol, conn) => {
identify.listener(conn, this.switch._peerInfo)
})
}
}

module.exports = ConnectionManager
Loading

0 comments on commit 4c6af13

Please sign in to comment.