var broadcast = require('broadcast-stream') var ref = require('ssb-ref') // local plugin // broadcasts the address:port:pubkey triple of the ssb server // on the LAN, using multicast UDP function isFunction (f) { return 'function' === typeof f } function isEmpty (o) { for(var k in o) return false return true } /* idea: instead of broadcasting constantly, broadcast at startup, or when ip address changes (change networks) or when you receive a boardcast. this should use network more efficiently. */ module.exports = { name: 'local', version: '2.0.0', init: function init (ssbServer, config) { if(config.gossip && config.gossip.local === false) return { init: function () { delete this.init init(ssbServer, config) } } var local = broadcast(config.port) var addrs = {} var lastSeen = {} // cleanup old local peers setInterval(function () { Object.keys(lastSeen).forEach((key) => { if (Date.now() - lastSeen[key] > 10e3) { ssbServer.gossip.remove(addrs[key]) delete lastSeen[key] } }) }, 5e3) // discover new local peers local.on('data', function (buf) { if (buf.loopback) return var data = buf.toString() var peer = ref.parseAddress(data) if (peer && peer.key !== ssbServer.id) { addrs[peer.key] = peer lastSeen[peer.key] = Date.now() //note: add the raw data, not the parsed data. //so we still have the whole address, including protocol (eg, websockets) ssbServer.gossip.add(data, 'local') } }) ssbServer.status.hook(function (fn) { var _status = fn() if(!isEmpty(addrs)) { _status.local = {} for(var k in addrs) _status.local[k] = {address: addrs[k], seen: lastSeen[k]} } return _status }) setImmediate(function () { // broadcast self var int = setInterval(function () { if(config.gossip && config.gossip.local === false) return // TODO: sign beacons, so that receipient can be confidant // that is really your id. // (which means they can update their peer table) // Oh if this includes your local address, // then it becomes unforgeable. var addr = ssbServer.getAddress('private') || ssbServer.getAddress('local') if(addr) local.write(addr) }, 1000) if(int.unref) int.unref() }) } }