2015-11-06 11:05:32 +00:00
|
|
|
'use strict';
|
|
|
|
|
|
|
|
var cluster = require('cluster');
|
|
|
|
var PromiseA = require('bluebird');
|
|
|
|
var memstore;
|
2015-11-12 11:14:59 +00:00
|
|
|
var sqlstore;
|
2015-11-28 05:06:19 +00:00
|
|
|
var config;
|
2015-11-06 11:05:32 +00:00
|
|
|
// TODO
|
|
|
|
// var rootMasterKey;
|
|
|
|
|
|
|
|
function updateIps() {
|
|
|
|
console.log('[UPDATE IP]');
|
2015-11-28 05:06:19 +00:00
|
|
|
var allMap = {};
|
|
|
|
var hostnames = config.redirects.reduce(function (all, redirect) {
|
|
|
|
if (redirect.ip && !allMap[redirect.id]) {
|
|
|
|
allMap[redirect.id] = true;
|
|
|
|
all.push(redirect.id);
|
|
|
|
}
|
|
|
|
|
|
|
|
return all;
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
require('./ddns-updater').update(
|
|
|
|
config.ddns.services
|
|
|
|
, hostnames
|
|
|
|
, config.ddns.token
|
|
|
|
).then(function (results) {
|
2015-11-06 11:05:32 +00:00
|
|
|
results.forEach(function (result) {
|
|
|
|
if (result.error) {
|
|
|
|
console.error(result);
|
|
|
|
} else {
|
|
|
|
console.log('[SUCCESS]', result.service.hostname);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}).error(function (err) {
|
|
|
|
console.error('[UPDATE IP] ERROR');
|
|
|
|
console.error(err);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
function init(conf/*, state*/) {
|
2015-11-28 05:06:19 +00:00
|
|
|
config = conf;
|
2015-11-06 11:05:32 +00:00
|
|
|
if (!conf.ipcKey) {
|
|
|
|
conf.ipcKey = require('crypto').randomBytes(16).toString('base64');
|
|
|
|
}
|
2015-11-12 11:14:59 +00:00
|
|
|
if (!conf.sqlite3Sock) {
|
|
|
|
conf.sqlite3Sock = '/tmp/sqlite3.' + require('crypto').randomBytes(4).toString('hex') + '.sock';
|
|
|
|
}
|
|
|
|
if (!conf.memstoreSock) {
|
|
|
|
conf.memstoreSock = '/tmp/memstore.' + require('crypto').randomBytes(4).toString('hex') + '.sock';
|
|
|
|
}
|
2015-11-06 11:05:32 +00:00
|
|
|
|
|
|
|
try {
|
2015-11-12 11:14:59 +00:00
|
|
|
require('fs').unlinkSync(conf.memstoreSock);
|
|
|
|
} catch(e) {
|
|
|
|
if ('ENOENT' !== e.code) {
|
|
|
|
console.error(e.stack);
|
|
|
|
console.error(JSON.stringify(e));
|
|
|
|
}
|
|
|
|
// ignore
|
|
|
|
}
|
|
|
|
try {
|
|
|
|
require('fs').unlinkSync(conf.sqlite3Sock);
|
2015-11-06 11:05:32 +00:00
|
|
|
} catch(e) {
|
|
|
|
if ('ENOENT' !== e.code) {
|
|
|
|
console.error(e.stack);
|
|
|
|
console.error(JSON.stringify(e));
|
|
|
|
}
|
|
|
|
// ignore
|
|
|
|
}
|
|
|
|
|
|
|
|
var cstore = require('cluster-store');
|
2015-11-12 11:14:59 +00:00
|
|
|
var sqlite3 = require('sqlite3-cluster/server');
|
|
|
|
var promise = PromiseA.all([
|
|
|
|
cstore.create({
|
|
|
|
sock: conf.memstoreSock
|
|
|
|
, serve: cluster.isMaster && conf.memstoreSock
|
|
|
|
, store: cluster.isMaster && null //new require('express-session/session/memory')()
|
|
|
|
// TODO implement
|
|
|
|
, key: conf.ipcKey
|
|
|
|
}).then(function (_memstore) {
|
|
|
|
memstore = _memstore;
|
|
|
|
return memstore;
|
|
|
|
})
|
|
|
|
, sqlite3.createServer({
|
|
|
|
verbose: null
|
2015-11-28 05:06:19 +00:00
|
|
|
, sock: conf.sqlite3Sock
|
2015-11-12 11:14:59 +00:00
|
|
|
, ipcKey: conf.ipcKey
|
|
|
|
}).then(function (_sqlstore) {
|
|
|
|
sqlstore = _sqlstore;
|
|
|
|
return sqlstore;
|
|
|
|
})
|
|
|
|
]).then(function (/*args*/) {
|
|
|
|
return conf;
|
|
|
|
/*
|
|
|
|
{
|
|
|
|
conf: conf
|
|
|
|
, memstore: memstore // args[0]
|
|
|
|
, sqlstore: sqlstore // args[1]
|
|
|
|
};
|
|
|
|
*/
|
2015-11-06 11:05:32 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
// TODO check the IP every 5 minutes and update it every hour
|
|
|
|
setInterval(updateIps, 60 * 60 * 1000);
|
|
|
|
// we don't want this to load right away (extra procesing time)
|
|
|
|
setTimeout(updateIps, 1);
|
|
|
|
|
2015-11-12 11:14:59 +00:00
|
|
|
return promise;
|
2015-11-06 11:05:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function touch(conf, state) {
|
|
|
|
if (!state.initialize) {
|
|
|
|
state.initialize = init(conf, state);
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO if no xyz worker, start on xyz worker (unlock, for example)
|
|
|
|
return state.initialize.then(function () {
|
|
|
|
// TODO conf.locked = true|false;
|
|
|
|
conf.initialized = true;
|
|
|
|
return conf;
|
|
|
|
});
|
|
|
|
|
|
|
|
/*
|
|
|
|
setInterval(function () {
|
|
|
|
console.log('SIGUSR1 to caddy');
|
|
|
|
return caddy.update(caddyConf);
|
|
|
|
}, 10 * 60 * 1000);
|
|
|
|
*/
|
|
|
|
}
|
|
|
|
|
|
|
|
//var config = require('./device.json');
|
|
|
|
|
|
|
|
// require('ssl-root-cas').inject();
|
2015-11-12 11:14:59 +00:00
|
|
|
// TODO try SNI loopback.example.com as result of api.ipify.com with loopback token
|
2015-11-06 11:05:32 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
function phoneHome() {
|
|
|
|
var holepunch = require('./holepunch/beacon');
|
|
|
|
var ports;
|
|
|
|
|
|
|
|
ports = [
|
|
|
|
{ private: 65022
|
|
|
|
, public: 65022
|
|
|
|
, protocol: 'tcp'
|
|
|
|
, ttl: 0
|
|
|
|
, test: { service: 'ssh' }
|
|
|
|
, testable: false
|
|
|
|
}
|
|
|
|
, { private: 650443
|
|
|
|
, public: 650443
|
|
|
|
, protocol: 'tcp'
|
|
|
|
, ttl: 0
|
|
|
|
, test: { service: 'https' }
|
|
|
|
}
|
|
|
|
, { private: 65080
|
|
|
|
, public: 65080
|
|
|
|
, protocol: 'tcp'
|
|
|
|
, ttl: 0
|
|
|
|
, test: { service: 'http' }
|
|
|
|
}
|
|
|
|
];
|
|
|
|
|
|
|
|
// TODO return a middleware
|
|
|
|
holepunch.run(require('./redirects.json').reduce(function (all, redirect) {
|
|
|
|
if (!all[redirect.from.hostname]) {
|
|
|
|
all[redirect.from.hostname] = true;
|
|
|
|
all.push(redirect.from.hostname);
|
|
|
|
}
|
|
|
|
if (!all[redirect.to.hostname]) {
|
|
|
|
all[redirect.to.hostname] = true;
|
|
|
|
all.push(redirect.to.hostname);
|
|
|
|
}
|
|
|
|
|
|
|
|
return all;
|
|
|
|
}, []), ports).catch(function () {
|
|
|
|
console.error("Couldn't phone home. Oh well");
|
|
|
|
});
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
|
|
|
|
module.exports.init = init;
|
|
|
|
module.exports.touch = touch;
|