js-libp2p/src/identify.js

160 lines
4.3 KiB
JavaScript
Raw Normal View History

2015-07-15 21:19:46 -07:00
/*
* Identify is one of the protocols swarms speaks in order to broadcast and learn
* about the ip:port pairs a specific peer is available through
*/
var Interactive = require('multistream-select').Interactive
var protobufs = require('protocol-buffers-stream')
var fs = require('fs')
var path = require('path')
var schema = fs.readFileSync(path.join(__dirname, '/identify.proto'))
2015-11-01 19:50:11 +01:00
var Address6 = require('ip-address').Address6
2015-09-23 19:14:29 +01:00
var Id = require('peer-id')
var multiaddr = require('multiaddr')
2015-07-15 21:19:46 -07:00
2015-09-23 19:14:29 +01:00
exports = module.exports = identify
2015-07-15 21:19:46 -07:00
2015-09-23 19:14:29 +01:00
var protoId = '/ipfs/identify/1.0.0'
2015-07-15 21:19:46 -07:00
2015-09-23 19:14:29 +01:00
exports.protoId = protoId
var createProtoStream = protobufs(schema)
2015-07-15 21:19:46 -07:00
2015-09-23 19:14:29 +01:00
function identify (muxedConns, peerInfoSelf, socket, conn, muxer) {
var msi = new Interactive()
msi.handle(conn, function () {
msi.select(protoId, function (err, ds) {
if (err) {
return console.log(err) // TODO Treat error
}
2015-07-15 21:19:46 -07:00
2015-09-23 19:14:29 +01:00
var ps = createProtoStream()
2015-07-15 21:19:46 -07:00
2015-09-23 19:14:29 +01:00
ps.on('identify', function (msg) {
var peerId = Id.createFromPubKey(msg.publicKey)
updateSelf(peerInfoSelf, msg.observedAddr)
muxedConns[peerId.toB58String()] = {
muxer: muxer,
socket: socket
}
2015-09-23 20:34:31 +01:00
// TODO: Pass the new discovered info about the peer that contacted us
// to something like the Kademlia Router, so the peerInfo for this peer
// is fresh
// - before this was exectued through a event emitter
// self.emit('peer-update', {
// peerId: peerId,
// listenAddrs: msg.listenAddrs.map(function (mhb) {return multiaddr(mhb)})
// })
2015-09-23 19:14:29 +01:00
})
2015-07-15 21:19:46 -07:00
var mh = getMultiaddr(socket)
2015-09-23 19:14:29 +01:00
ps.identify({
protocolVersion: 'na',
agentVersion: 'na',
2015-09-23 19:14:29 +01:00
publicKey: peerInfoSelf.id.pubKey,
listenAddrs: peerInfoSelf.multiaddrs.map(function (mh) {
return mh.buffer
}),
observedAddr: mh.buffer
})
2015-09-23 19:14:29 +01:00
ps.pipe(ds).pipe(ps)
ps.finalize()
})
2015-07-15 21:19:46 -07:00
})
2015-09-23 19:14:29 +01:00
}
exports.getHandlerFunction = function (peerInfoSelf, muxedConns) {
return function (conn) {
// wait for the other peer to identify itself
// update our multiaddr with observed addr list
// then get the socket from our list of muxedConns and send the reply back
var ps = createProtoStream()
ps.on('identify', function (msg) {
updateSelf(peerInfoSelf, msg.observedAddr)
2015-07-15 21:19:46 -07:00
2015-09-23 19:14:29 +01:00
var peerId = Id.createFromPubKey(msg.publicKey)
var socket = muxedConns[peerId.toB58String()].socket
var mh = getMultiaddr(socket)
ps.identify({
protocolVersion: 'na',
agentVersion: 'na',
publicKey: peerInfoSelf.id.pubKey,
listenAddrs: peerInfoSelf.multiaddrs.map(function (mh) {
return mh.buffer
}),
observedAddr: mh.buffer
2015-07-15 21:19:46 -07:00
})
2015-09-23 19:14:29 +01:00
// TODO: Pass the new discovered info about the peer that contacted us
// to something like the Kademlia Router, so the peerInfo for this peer
// is fresh
// - before this was exectued through a event emitter
// self.emit('peer-update', {
// peerId: peerId,
// listenAddrs: msg.listenAddrs.map(function (mhb) {
// return multiaddr(mhb)
// })
// })
ps.finalize()
2015-07-15 21:19:46 -07:00
})
2015-09-23 19:14:29 +01:00
ps.pipe(conn).pipe(ps)
}
2015-07-15 21:19:46 -07:00
}
function getMultiaddr (socket) {
var mh
2015-11-01 19:50:11 +01:00
if (socket.remoteFamily === 'IPv6') {
var addr = new Address6(socket.remoteAddress)
if (addr.v4) {
2015-11-01 19:50:11 +01:00
var ip4 = addr.to4().correctForm()
mh = multiaddr('/ip4/' + ip4 + '/tcp/' + socket.remotePort)
} else {
mh = multiaddr('/ip6/' + socket.remoteAddress + '/tcp/' + socket.remotePort)
}
} else {
mh = multiaddr('/ip4/' + socket.remoteAddress + '/tcp/' + socket.remotePort)
}
return mh
}
function updateSelf (peerSelf, observedAddr) {
var omh = multiaddr(observedAddr)
2015-07-20 14:42:47 -07:00
if (!peerSelf.previousObservedAddrs) {
peerSelf.previousObservedAddrs = []
}
for (var i = 0; i < peerSelf.previousObservedAddrs.length; i++) {
if (peerSelf.previousObservedAddrs[i].toString() === omh.toString()) {
peerSelf.previousObservedAddrs.splice(i, 1)
2015-07-20 14:42:47 -07:00
addToSelf()
return
}
2015-07-20 14:42:47 -07:00
}
peerSelf.previousObservedAddrs.push(omh)
2015-07-20 14:42:47 -07:00
function addToSelf () {
var isIn = false
peerSelf.multiaddrs.forEach(function (mh) {
if (mh.toString() === omh.toString()) {
isIn = true
}
})
if (!isIn) {
peerSelf.multiaddrs.push(omh)
}
}
}