This repository has been archived on 2023-11-14. You can view files and clone it, but cannot push or open issues/pull-requests.
valnet/lib/node.js

111 lines
2.8 KiB
JavaScript

const EventEmitter = require('events')
const stp = require('./STP');
const upnp = require('./upnp');
const md5 = require('md5');
const pkg = require('./../package.json');
const { config, write } = require('./config.js');
const log = require('signale').scope('NODE');
const bonjour = require('bonjour')();
const Gateway = require('./Gateway');
class Node extends EventEmitter {
clients = [];
hash = null;
name = null;
readyPromise = null;
port = null;
identity;
multicastAd = null;
multicastBrowser = null;
connected = false;
constructor(identity) {
super();
this.identity = identity;
this.hash = md5(identity.publicKey);
this.name = `valnet-node-${identity.name}`;
this.readyPromise = this.negotiatePort()
.then(this.startServer.bind(this))
.catch(this.serverStartupFailed.bind(this))
.then(this.connectNetwork.bind(this))
}
async connectNetwork() {
const gateway = new Gateway(this.identity, config.endpoints);
}
async serverStartupFailed(error) {
log.warn('Failed to set up Valet server on node.')
}
async startServer() {
log.info('creating Valnet Node on port ' + this.port + '...');
stp.createServer({
identity: this.identity,
port: this.port
}, (connection) => {
log.info('incomming connection from ' + connection.remoteAddress);
});
log.info('advertising node on multicast...')
this.multicastAd = bonjour.publish({
name: this.name,
type: 'STP',
port: this.port
});
this.multicastBrowser = bonjour.find({});
this.multicastBrowser.on('up', this.serviceUp.bind(this));
this.multicastBrowser.on('down', this.serviceDown.bind(this));
// log.success('Node successfully registered!');
}
async serviceUp({name, address, port, protocol}) {
// log.debug(`Found ${name} @ ${address}:${port} using ${protocol}`);
}
async serviceDown(service) {
log.debug('down', service);
}
async negotiatePort() {
const mappings = await upnp.mappings();
const matchingMappings = mappings.filter(mapping => {
return mapping.description === this.name
});
const alreadyMapped = matchingMappings.length > 0;
const takenPorts = mappings.map(mapping => mapping.public.port);
if(alreadyMapped) {
this.port = matchingMappings[0].public.port;
log.success(`upnp port ${this.port} already registered!`);
return;
}
for(let port = config.ports.relay; port <= config.ports.relayEnd; port ++) {
if(takenPorts.indexOf(port) === -1) {
await upnp.mapIndefinite(port, this.name);
this.port = port;
log.success(`registered upnp port ${this.port}`);
return;
}
}
// console.log(mappings, this.hash);
}
static get Node() {
return Node;
}
get ready() {
return this.readyPromise;
}
}
module.exports = Node;