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

[WIP] Add secio & move to pull-streams #67

Merged
merged 9 commits into from
Sep 7, 2016
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,13 @@
"libp2p-tcp": "^0.7.4",
"libp2p-webrtc-star": "^0.3.2",
"libp2p-websockets": "^0.7.1",
"pre-commit": "^1.1.2",
"pre-commit": "^1.1.3",
"pull-stream": "^3.4.3",
"stream-pair": "^1.0.3",
"webrtcsupport": "^2.2.0"
},
"dependencies": {
"babel-runtime": "^6.6.1",
"babel-runtime": "^6.9.0",
"bl": "^1.1.2",
"browserify-zlib": "github:ipfs/browserify-zlib",
"debug": "^2.2.0",
Expand All @@ -61,8 +62,9 @@
"ip-address": "^5.8.0",
"length-prefixed-stream": "^1.5.0",
"libp2p-identify": "^0.1.3",
"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 @@ -77,4 +79,4 @@
"Richard Littauer <richard.littauer@gmail.com>",
"dignifiedquire <dignifiedquire@gmail.com>"
]
}
}
17 changes: 12 additions & 5 deletions src/connection.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
'use strict'

const protocolMuxer = require('./protocol-muxer')
const identify = require('libp2p-identify')
const multistream = require('multistream-select')
const debug = require('debug')
const log = debug('libp2p:swarm:connection')

const protocolMuxer = require('./protocol-muxer')

module.exports = function connection (swarm) {
return {
Expand All @@ -14,7 +17,7 @@ module.exports = function connection (swarm) {

// for listening
swarm.handle(muxer.multicodec, (conn) => {
const muxedConn = muxer(conn, true)
const muxedConn = muxer.listen(conn)

muxedConn.on('stream', (conn) => {
protocolMuxer(swarm.protocols, conn)
Expand All @@ -35,7 +38,7 @@ module.exports = function connection (swarm) {
ms.select(identify.multicodec, (err, conn) => {
if (err) { return cb(err) }

identify.exec(conn, (err, peerInfo, observedAddrs) => {
identify.listen(conn, (err, peerInfo, observedAddrs) => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note: This will change to 'dialer', once identify CR is applied

if (err) { return cb(err) }

observedAddrs.forEach((oa) => {
Expand All @@ -50,7 +53,7 @@ module.exports = function connection (swarm) {

conn.getPeerInfo((err, peerInfo) => {
if (err) {
return console.log('Identify not successful')
return log('Identify not successful')
}
swarm.muxedConns[peerInfo.id.toB58String()] = {
muxer: muxedConn
Expand All @@ -63,12 +66,16 @@ module.exports = function connection (swarm) {
})
})
}

return conn
})
},

reuse () {
swarm.identify = true
swarm.handle(identify.multicodec, identify.handler(swarm._peerInfo))
swarm.handle(identify.multicodec, (conn) => {
identify.dial(conn, swarm._peerInfo)
})
}
}
}
24 changes: 20 additions & 4 deletions src/dial.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,12 @@

const multistream = require('multistream-select')
const Connection = require('interface-connection').Connection
const debug = require('debug')
const log = debug('libp2p:swarm:dial')

const protocolMuxer = require('./protocol-muxer')
const secio = require('./secio')
const tags = require('./tags')

module.exports = function dial (swarm) {
return (pi, protocol, callback) => {
Expand All @@ -19,6 +23,7 @@ module.exports = function dial (swarm) {
const proxyConn = new Connection()

const b58Id = pi.id.toB58String()
log('dialing %s', b58Id)

if (!swarm.muxedConns[b58Id]) {
if (!swarm.conns[b58Id]) {
Expand All @@ -44,7 +49,6 @@ module.exports = function dial (swarm) {

function gotWarmedUpConn (conn) {
conn.setPeerInfo(pi)

attemptMuxerUpgrade(conn, (err, muxer) => {
if (!protocol) {
if (err) {
Expand Down Expand Up @@ -97,13 +101,24 @@ module.exports = function dial (swarm) {
cryptoDial()

function cryptoDial () {
// currently, no crypto channel is implemented
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) {
return ms.select(tags.plaintex, cb)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this typo is what was causing my issue in libp2p-ipfs

}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be a Swarm option. In the same fashion that we do .connection.reuse(), we should do .connection.crypto(secio) and then check if it has the ingredients necessary.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and also, .connection.plaintext(false) to disable plaintext mode

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why should this be a method? It's just a matter of setting swarm.encrypt = true right now to control this.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so that later we can use the method to pick different crypto channels


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

cb(null, secio.create(id, conn))
})
})
}
})
Expand All @@ -129,6 +144,7 @@ module.exports = function dial (swarm) {
if (err) {
return callback(new Error('multistream not supported'))
}
log('selecting %s', key)
ms.select(key, (err, conn) => {
if (err) {
if (muxers.length === 0) {
Expand All @@ -139,7 +155,7 @@ module.exports = function dial (swarm) {
return
}

const muxedConn = swarm.muxers[key](conn, false)
const muxedConn = swarm.muxers[key].dial(conn)
swarm.muxedConns[b58Id] = {}
swarm.muxedConns[b58Id].muxer = muxedConn
// should not be needed anymore - swarm.muxedConns[b58Id].conn = conn
Expand Down
33 changes: 23 additions & 10 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ const transport = require('./transport')
const connection = require('./connection')
const dial = require('./dial')
const protocolMuxer = require('./protocol-muxer')
const secio = require('./secio')
const tags = require('./tags')

exports = module.exports = Swarm

Expand Down Expand Up @@ -50,6 +52,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 @@ -90,9 +95,18 @@ function Swarm (peerInfo) {
this.protocols[protocol] = handler
}

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

this.handle(cryptoTag, (conn) => {
if (this.encrypt === false) {
return protocolMuxer(this.protocols, conn)
}

const secure = secio.create(this._peerInfo.id, conn)
protocolMuxer(this.protocols, secure)
})

this.unhandle = (protocol, handler) => {
Expand Down Expand Up @@ -122,14 +136,13 @@ function Swarm (peerInfo) {

const transports = this.transports

parallel(Object.keys(transports).map((key) => {
return (cb) => {
parallel(
Object.keys(transports).map((key) => (cb) => {
parallel(transports[key].listeners.map((listener) => {
return (cb) => {
listener.close(cb)
}
return (cb) => listener.close(cb)
}), cb)
}
}), callback)
}),
callback
)
}
}
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.secure
}
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'
}
47 changes: 8 additions & 39 deletions src/transport.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
const Connection = require('interface-connection').Connection
const parallel = require('run-parallel')
const debug = require('debug')
const log = debug('libp2p:swarm')
const log = debug('libp2p:swarm:transport')

const protocolMuxer = require('./protocol-muxer')

Expand All @@ -16,7 +16,7 @@ module.exports = function (swarm) {
}

if (!callback) { callback = noop }

log('adding %s', key)
if (swarm.transports[key]) {
throw new Error('There is already a transport with this key')
}
Expand All @@ -34,26 +34,16 @@ module.exports = function (swarm) {
if (!Array.isArray(multiaddrs)) {
multiaddrs = [multiaddrs]
}

log('dialing %s', key, multiaddrs.map((m) => m.toString()))
// a) filter the multiaddrs that are actually valid for this transport (use a func from the transport itself) (maybe even make the transport do that)
multiaddrs = dialables(t, multiaddrs)

// b) if multiaddrs.length = 1, return the conn from the
// transport, otherwise, create a passthrough
if (multiaddrs.length === 1) {
const conn = t.dial(multiaddrs.shift())

conn.once('error', connectError)

conn.once('connect', () => {
conn.removeListener('error', connectError)
callback(null, conn)
})

return conn
}
function connectError () {
callback(new Error('failed to connect to every multiaddr'))
callback(null, new Connection(conn))
return
}

// c) multiaddrs should already be a filtered list
Expand All @@ -62,23 +52,9 @@ module.exports = function (swarm) {

next(multiaddrs.shift())

return proxyConn

// TODO improve in the future to make all the dials in paralell
function next (multiaddr) {
const conn = t.dial(multiaddr)

conn.once('error', connectError)

function connectError () {
if (multiaddrs.length === 0) {
return callback(new Error('failed to connect to every multiaddr'))
}
next(multiaddrs.shift())
}

conn.once('connect', () => {
conn.removeListener('error', connectError)
const conn = t.dial(multiaddr, () => {
proxyConn.setInnerConn(conn)
callback(null, proxyConn)
})
Expand All @@ -105,7 +81,6 @@ module.exports = function (swarm) {
return (cb) => {
const listener = transport.createListener(handler)
listener.listen(ma, () => {
log('Listener started on:', ma.toString())
listener.getAddrs((err, addrs) => {
if (err) {
return cb(err)
Expand Down Expand Up @@ -142,13 +117,7 @@ module.exports = function (swarm) {
}

function dialables (tp, multiaddrs) {
return tp.filter(multiaddrs.map((addr) => {
// webrtc-star needs the /ipfs/QmHash
if (addr.toString().indexOf('webrtc-star') > 0) {
return addr
}

return addr
}))
return tp.filter(multiaddrs)
}

function noop () {}
Loading