diff --git a/src/identify/identify.proto b/src/identify/identify.proto new file mode 100644 index 00000000..280bc401 --- /dev/null +++ b/src/identify/identify.proto @@ -0,0 +1,25 @@ +message Identify { + + // protocolVersion determines compatibility between peers + optional string protocolVersion = 5; // e.g. ipfs/1.0.0 + + // agentVersion is like a UserAgent string in browsers, or client version in bittorrent + // includes the client name and client. + optional string agentVersion = 6; // e.g. go-ipfs/0.1.0 + + // publicKey is this node's public key (which also gives its node.ID) + // - may not need to be sent, as secure channel implies it has been sent. + // - then again, if we change / disable secure channel, may still want it. + optional bytes publicKey = 1; + + // listenAddrs are the multiaddrs the sender node listens for open connections on + repeated bytes listenAddrs = 2; + + // oservedAddr is the multiaddr of the remote endpoint that the sender node perceives + // this is useful information to convey to the other side, as it helps the remote endpoint + // determine whether its connection to the local peer goes through NAT. + // optional bytes observedAddr = 4; + + // (DEPRECATED) protocols are the services this node is running + // repeated string protocols = 3; +} diff --git a/src/identify/index.js b/src/identify/index.js new file mode 100644 index 00000000..606c2216 --- /dev/null +++ b/src/identify/index.js @@ -0,0 +1,81 @@ +/* + * 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 EventEmmiter = require('events').EventEmitter +var util = require('util') +var protobufs = require('protocol-buffers-stream') +var fs = require('fs') +var schema = fs.readFileSync(__dirname + '/identify.proto') + +exports = module.exports = Identify + +util.inherits(Identify, EventEmmiter) + +function Identify (swarm, peerSelf) { + var self = this + self.createProtoStream = protobufs(schema) + + swarm.registerHandler('/ipfs/identify/1.0.0', function (stream) { + var ps = self.createProtoStream() + + ps.on('identify', function (msg) { + console.log('RECEIVED PROTOBUF - ', msg) + // 1. wrap the msg + // 2. create a Peer obj using the publick key to derive the ID + // 3. populate it with observedAddr + // 4. maybe emit 2 peers update to update the other peer and also ourselfs? + self.emit('peer-update', {}) + }) + + ps.identify({ + protocolVersion: 'na', + agentVersion: 'na', + publicKey: peerSelf.id.pubKey, + listenAddrs: peerSelf.multiaddrs + // observedAddr: new Buffer() + }) + + ps.pipe(stream).pipe(ps) + + // TODO(daviddias) ps.end() based on https://github.com/mafintosh/protocol-buffers-stream/issues/1 + }) + + swarm.on('connection-unknown', function (conn) { + conn.dialStream(function (err, stream) { + if (err) { return console.log(err) } + var msi = new Interactive() + msi.handle(stream, function () { + msi.select('/ipfs/identify/1.0.0', function (err, ds) { + if (err) { return console.log(err) } + + var ps = self.createProtoStream() + + ps.on('identify', function (msg) { + console.log('RECEIVED PROTOBUF - ', msg) + // 1. wrap the msg + // 2. create a Peer obj using the publick key to derive the ID + // 3. populate it with observedAddr + // 4. maybe emit 2 peers update to update the other peer and also ourselfs? + // 5. add the conn to connections list -> swarm.connections[otherPeerId] = conn + self.emit('peer-update', {}) + }) + + ps.identify({ + protocolVersion: 'na', + agentVersion: 'na', + publicKey: peerSelf.id.pubKey, + listenAddrs: peerSelf.multiaddrs + // observedAddr: new Buffer() + }) + + ps.pipe(ds).pipe(ps) + + // TODO(daviddias) ps.end() based on https://github.com/mafintosh/protocol-buffers-stream/issues/1 + }) + }) + }) + }) +} diff --git a/src/identify/proto-test.js b/src/identify/proto-test.js new file mode 100644 index 00000000..2fd4d88a --- /dev/null +++ b/src/identify/proto-test.js @@ -0,0 +1,24 @@ +var protobufs = require('protocol-buffers-stream') +var fs = require('fs') +var schema = fs.readFileSync(__dirname + '/identify.proto') + +var createProtoStream = protobufs(schema) + +var ps = createProtoStream() + +ps.on('identify', function (msg) { + console.log('RECEIVED PROTOBUF - ', msg) +// self.emit('peer-update', {}) +}) + +ps.identify({ + protocolVersion: 'nop', + agentVersion: 'nop' +// publicKey: new Buffer(), +// listenAddrs: new Buffer([buf1, buf2]) +// observedAddr: new Buffer() +}) + +ps.pipe(ps) + +// ps.end()