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

Commit

Permalink
start integrating secio
Browse files Browse the repository at this point in the history
  • Loading branch information
dignifiedquire committed May 27, 2016
1 parent 896fe7a commit bf1574d
Show file tree
Hide file tree
Showing 10 changed files with 240 additions and 29,571 deletions.
12 changes: 7 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
"node": "^4.3.0"
},
"devDependencies": {
"aegir": "^3.0.4",
"aegir": "^3.1.1",
"bl": "^1.1.2",
"buffer-loader": "0.0.1",
"chai": "^3.5.0",
Expand All @@ -48,17 +48,19 @@
"libp2p-tcp": "^0.6.0",
"libp2p-webrtc-star": "^0.2.0",
"libp2p-websockets": "^0.6.0",
"pre-commit": "^1.1.2",
"pre-commit": "^1.1.3",
"stream-pair": "^1.0.3",
"webrtcsupport": "^2.2.0"
},
"dependencies": {
"babel-runtime": "^6.6.1",
"babel-runtime": "^6.9.0",
"browserify-zlib": "github:ipfs/browserify-zlib",
"debug": "^2.2.0",
"duplex-passthrough": "github:diasdavid/duplex-passthrough",
"ip-address": "^5.8.0",
"libp2p-secio": "^0.3.0",
"lodash.contains": "^2.4.3",
"multiaddr": "^2.0.0",
"multiaddr": "^2.0.2",
"multistream-select": "^0.9.0",
"peer-id": "^0.7.0",
"peer-info": "^0.7.0",
Expand All @@ -73,4 +75,4 @@
"Richard Littauer <[email protected]>",
"dignifiedquire <[email protected]>"
]
}
}
14 changes: 13 additions & 1 deletion src/default-handler.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,32 @@
'use strict'

const multistream = require('multistream-select')
const debug = require('debug')

const log = debug('libp2p:swarm:handler')
log.error = debug('libp2p:swarm:handler:error')

// incomming connection handler
module.exports = function connHandler (protocols, conn) {
const ms = new multistream.Listener()
Object.keys(protocols).forEach((protocol) => {
const keys = Object.keys(protocols)

log('handling', keys)
keys.forEach((protocol) => {
if (!protocol) {
return
}

ms.addHandler(protocol, protocols[protocol])
})

conn.on('error', (err) => {
log.error(err)
})

ms.handle(conn, (err) => {
if (err) {
log.error(err)
return // the multistream handshake failed
}
})
Expand Down
39 changes: 36 additions & 3 deletions src/dial.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,14 @@

const multistream = require('multistream-select')
const DuplexPassThrough = require('duplex-passthrough')
const debug = require('debug')

const connHandler = require('./default-handler')
const secio = require('./secio')
const tags = require('./tags')

const log = debug('libp2p:swarm:dial')
log.error = debug('libp2p:swarm:dial:error')

module.exports = function dial (swarm) {
return (pi, protocol, callback) => {
Expand All @@ -17,9 +23,9 @@ module.exports = function dial (swarm) {
}

const pt = new DuplexPassThrough()

const b58Id = pi.id.toB58String()

log('dialing from %s to %s', swarm._peerInfo.id.toB58String(), b58Id)
if (!swarm.muxedConns[b58Id]) {
if (!swarm.conns[b58Id]) {
attemptDial(pi, (err, conn) => {
Expand Down Expand Up @@ -88,13 +94,35 @@ module.exports = function dial (swarm) {
cryptoDial()

function cryptoDial () {
// currently, js-libp2p-swarm doesn't implement any crypto
const ms = new multistream.Dialer()
ms.handle(conn, (err) => {
if (err) {
return cb(err)
}
ms.select('/plaintext/1.0.0', cb)

const id = swarm._peerInfo.id
if (id.privKey == null || swarm.encrypt === false) {
log(
'dialer %s dialing INSECURELY %s!',
id.toB58String(),
pi.id.toB58String()
)

return ms.select(tags.plaintex, cb)
}

ms.select(tags.secio, (err, conn) => {
if (err) {
return cb(err)
}

log(
'dialer %s dialing secure to %s!',
id.toB58String(),
pi.id.toB58String()
)
cb(null, secio.create(id, conn))
})
})
}
})
Expand All @@ -104,6 +132,7 @@ module.exports = function dial (swarm) {
function attemptMuxerUpgrade (conn, cb) {
const muxers = Object.keys(swarm.muxers)
if (muxers.length === 0) {
log.error('no muxers available')
return cb(new Error('no muxers available'))
}

Expand All @@ -115,14 +144,18 @@ module.exports = function dial (swarm) {
nextMuxer(muxers.shift())

function nextMuxer (key) {
log('attempting muxer upgrade %s', key)
const ms = new multistream.Dialer()
ms.handle(conn, (err) => {
if (err) {
log.error(err)
log.error('multistream not supported')
return callback(new Error('multistream not supported'))
}
ms.select(key, (err, conn) => {
if (err) {
if (muxers.length === 0) {
log.error('could not upgrade to stream muxing')
cb(new Error('could not upgrade to stream muxing'))
} else {
nextMuxer(muxers.shift())
Expand Down
4 changes: 4 additions & 0 deletions src/identify.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ exports.exec = (rawConn, muxer, peerInfo, callback) => {
})

const obsMultiaddr = rawConn.getObservedAddrs()[0]
let publicKey = new Buffer(0)
if (peerInfo.id.pubKey) {
publicKey = peerInfo.id.pubKey.bytes
}

let publicKey = new Buffer(0)
if (peerInfo.id.pubKey) {
Expand Down
39 changes: 34 additions & 5 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,16 @@ const util = require('util')
const EE = require('events').EventEmitter
const parallel = require('run-parallel')
const contains = require('lodash.contains')
const debug = require('debug')

const transport = require('./transport')
const connection = require('./connection')
const dial = require('./dial')
const connHandler = require('./default-handler')
const tags = require('./tags')
const secio = require('./secio')

const log = debug('libp2p:swarm')

exports = module.exports = Swarm

Expand Down Expand Up @@ -52,6 +57,9 @@ function Swarm (peerInfo) {
// is the Identify protocol enabled?
this.identify = false

// is encryption enabled?
this.encrypt = true

this.transport = transport(this)
this.connection = connection(this)

Expand Down Expand Up @@ -82,34 +90,55 @@ function Swarm (peerInfo) {

// Start listening on all available transports
this.listen = (callback) => {
log('listen')
parallel(this.availableTransports(peerInfo).map((ts) => (cb) => {
// Listen on the given transport
this.transport.listen(ts, {}, null, cb)
}), callback)
}

this.handle = (protocol, handler) => {
log('handling %s', protocol)
this.protocols[protocol] = handler
}

// our crypto handshake :)
this.handle('/plaintext/1.0.0', (conn) => {
connHandler(this.protocols, conn)
let cryptoTag = tags.secio
if (this.encrypt === false) {
cryptoTag = tags.plaintext
}

this.handle(cryptoTag, (conn) => {
if (this.encrypt === false) {
log(
'listener %s listening INSECURELY!',
this._peerInfo.id.toB58String()
)
return connHandler(this.protocols, conn)
}

log('securing connection %s', this._peerInfo.id.toB58String())
const secure = secio.create(this._peerInfo.id, conn)
connHandler(this.protocols, secure)
})

this.unhandle = (protocol, handler) => {
log('unhandling %s', protocol)
if (this.protocols[protocol]) {
delete this.protocols[protocol]
}
}

this.close = (callback) => {
log('closing')
Object.keys(this.muxedConns).forEach((key) => {
this.muxedConns[key].muxer.end()
})

parallel(Object.keys(this.transports).map((key) => {
return (cb) => this.transports[key].close(cb)
}), callback)
return (cb) => this.transport.close(key, cb)
}), (err) => {
log('closed', err)
callback(err)
})
}
}
10 changes: 10 additions & 0 deletions src/secio.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
'use strict'

const SecureSession = require('libp2p-secio').SecureSession

exports = module.exports

exports.create = (local, insecure) => {
const session = new SecureSession(local, local.privKey, insecure)
return session.secureStream()
}
6 changes: 6 additions & 0 deletions src/tags.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
'use strict'

module.exports = {
secio: '/secio/1.0.0',
plaintext: '/plaintext/1.0.0'
}
7 changes: 7 additions & 0 deletions src/transport.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,16 @@

const contains = require('lodash.contains')
const DuplexPassThrough = require('duplex-passthrough')
const debug = require('debug')

const connHandler = require('./default-handler')

const log = debug('libp2p:swarm:transport')

module.exports = function (swarm) {
return {
add (key, transport, options, callback) {
log('add %s', key)
if (typeof options === 'function') {
callback = options
options = {}
Expand All @@ -22,6 +26,7 @@ module.exports = function (swarm) {
},

dial (key, multiaddrs, callback) {
log('dial %s', key)
const t = swarm.transports[key]

if (!Array.isArray(multiaddrs)) {
Expand Down Expand Up @@ -69,6 +74,7 @@ module.exports = function (swarm) {
},

listen (key, options, handler, callback) {
log('listen %s', key)
// if no callback is passed, we pass conns to connHandler
if (!handler) {
handler = connHandler.bind(null, swarm.protocols)
Expand All @@ -90,6 +96,7 @@ module.exports = function (swarm) {
},

close (key, callback) {
log('close %s', key)
const transport = swarm.transports[key]

if (!transport) {
Expand Down
Loading

0 comments on commit bf1574d

Please sign in to comment.