Merge branch 'layers' of git.daplie.com:Daplie/Goldilocks.js into layers
This commit is contained in:
commit
3c5bc9103e
|
@ -61,6 +61,9 @@ function readConfigAndRun(args) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!config.dns) {
|
||||||
|
config.dns = { proxy: { port: 3053 } };
|
||||||
|
}
|
||||||
if (!config.tcp) {
|
if (!config.tcp) {
|
||||||
config.tcp = {};
|
config.tcp = {};
|
||||||
}
|
}
|
||||||
|
@ -116,24 +119,63 @@ function readConfigAndRun(args) {
|
||||||
config.addresses = addresses;
|
config.addresses = addresses;
|
||||||
config.device = { hostname: 'daplien-pod' };
|
config.device = { hostname: 'daplien-pod' };
|
||||||
|
|
||||||
|
var PromiseA = require('bluebird');
|
||||||
|
var tcpProm, dnsProm;
|
||||||
|
|
||||||
if (config.tcp.ports) {
|
if (config.tcp.ports) {
|
||||||
run(config);
|
tcpProm = PromiseA.resolve();
|
||||||
return;
|
} else {
|
||||||
|
tcpProm = new PromiseA(function (resolve, reject) {
|
||||||
|
require('../lib/check-ports').checkTcpPorts(function (failed, bound) {
|
||||||
|
config.tcp.ports = Object.keys(bound);
|
||||||
|
if (config.tcp.ports.length) {
|
||||||
|
resolve();
|
||||||
|
} else {
|
||||||
|
reject(failed);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
require('../lib/check-ports.js').checkPorts(config, function (failed, bound) {
|
if (config.dns.bind) {
|
||||||
config.tcp.ports = Object.keys(bound);
|
dnsProm = PromiseA.resolve();
|
||||||
|
} else {
|
||||||
|
dnsProm = new PromiseA(function (resolve) {
|
||||||
|
require('../lib/check-ports').checkUdpPorts(function (failed, bound) {
|
||||||
|
var ports = Object.keys(bound);
|
||||||
|
|
||||||
if (!config.tcp.ports.length) {
|
if (ports.length === 0) {
|
||||||
|
// I don't think we want to prevent the rest of the app from running in
|
||||||
|
// this case like we do for TCP, do don't call reject.
|
||||||
|
console.warn('could not bind to the desired ports for DNS');
|
||||||
|
Object.keys(failed).forEach(function (key) {
|
||||||
|
console.log('[error bind]', key, failed[key].code);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else if (ports.length === 1) {
|
||||||
|
config.dns.bind = parseInt(ports[0], 10);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
config.dns.bind = ports.map(function (numStr) {
|
||||||
|
return parseInt(numStr, 10);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
PromiseA.all([tcpProm, dnsProm])
|
||||||
|
.then(function () {
|
||||||
|
run(config);
|
||||||
|
})
|
||||||
|
.catch(function (failed) {
|
||||||
console.warn("could not bind to the desired ports");
|
console.warn("could not bind to the desired ports");
|
||||||
Object.keys(failed).forEach(function (key) {
|
Object.keys(failed).forEach(function (key) {
|
||||||
console.log('[error bind]', key, failed[key].code);
|
console.log('[error bind]', key, failed[key].code);
|
||||||
});
|
});
|
||||||
return;
|
});
|
||||||
}
|
|
||||||
|
|
||||||
run(config);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function readEnv(args) {
|
function readEnv(args) {
|
||||||
|
@ -166,7 +208,7 @@ else if (process.argv.length > 2) {
|
||||||
var program = require('commander');
|
var program = require('commander');
|
||||||
|
|
||||||
program
|
program
|
||||||
.version(require('package.json').version)
|
.version(require('../package.json').version)
|
||||||
.option('--agree-tos [url1,url2]', "agree to all Terms of Service for Daplie, Let's Encrypt, etc (or specific URLs only)")
|
.option('--agree-tos [url1,url2]', "agree to all Terms of Service for Daplie, Let's Encrypt, etc (or specific URLs only)")
|
||||||
.option('--config', 'Path to config file (Goldilocks.json or Goldilocks.yml) example: --config /etc/goldilocks/Goldilocks.json')
|
.option('--config', 'Path to config file (Goldilocks.json or Goldilocks.yml) example: --config /etc/goldilocks/Goldilocks.json')
|
||||||
.option('--tunnel [token]', 'Turn tunnel on. This will enter interactive mode for login if no token is specified.')
|
.option('--tunnel [token]', 'Turn tunnel on. This will enter interactive mode for login if no token is specified.')
|
||||||
|
|
|
@ -11,7 +11,18 @@ function bindTcpAndRelease(port, cb) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkPorts(config, cb) {
|
function bindUdpAndRelease(port, cb) {
|
||||||
|
var socket = require('dgram').createSocket('udp4');
|
||||||
|
socket.on('error', function (e) {
|
||||||
|
cb(e);
|
||||||
|
});
|
||||||
|
socket.bind(port, function () {
|
||||||
|
socket.close();
|
||||||
|
cb();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkTcpPorts(cb) {
|
||||||
var bound = {};
|
var bound = {};
|
||||||
var failed = {};
|
var failed = {};
|
||||||
|
|
||||||
|
@ -32,7 +43,6 @@ function checkPorts(config, cb) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bound['80'] && bound['443']) {
|
if (bound['80'] && bound['443']) {
|
||||||
//config.tcp.ports = [ 80, 443 ];
|
|
||||||
cb(null, bound);
|
cb(null, bound);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -52,4 +62,34 @@ function checkPorts(config, cb) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports.checkPorts = checkPorts;
|
function checkUdpPorts(cb) {
|
||||||
|
var bound = {};
|
||||||
|
var failed = {};
|
||||||
|
|
||||||
|
bindUdpAndRelease(53, function (e) {
|
||||||
|
if (e) {
|
||||||
|
failed[53] = e;
|
||||||
|
} else {
|
||||||
|
bound[53] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bound[53]) {
|
||||||
|
cb(null, bound);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.warn("default DNS port 53 not available, trying 8053");
|
||||||
|
bindUdpAndRelease(8053, function (e) {
|
||||||
|
if (e) {
|
||||||
|
failed[8053] = e;
|
||||||
|
} else {
|
||||||
|
bound[8053] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
cb(null, bound);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports.checkTcpPorts = checkTcpPorts;
|
||||||
|
module.exports.checkUdpPorts = checkUdpPorts;
|
||||||
|
|
|
@ -236,6 +236,12 @@ module.exports.create = function (deps, config) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function dnsListener(msg) {
|
||||||
|
var dgram = require('dgram');
|
||||||
|
var socket = dgram.createSocket('udp4');
|
||||||
|
socket.send(msg, config.dns.proxy.port, config.dns.proxy.address || '127.0.0.1');
|
||||||
|
}
|
||||||
|
|
||||||
function approveDomains(opts, certs, cb) {
|
function approveDomains(opts, certs, cb) {
|
||||||
// This is where you check your database and associated
|
// This is where you check your database and associated
|
||||||
// email addresses with domains and agreements and such
|
// email addresses with domains and agreements and such
|
||||||
|
@ -448,7 +454,19 @@ module.exports.create = function (deps, config) {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
PromiseA.all(config.tcp.ports.map(function (port) {
|
var listenPromises = config.tcp.ports.map(function (port) {
|
||||||
return listeners.tcp.add(port, netHandler);
|
return listeners.tcp.add(port, netHandler);
|
||||||
}));
|
});
|
||||||
|
|
||||||
|
if (config.dns.bind) {
|
||||||
|
if (Array.isArray(config.dns.bind)) {
|
||||||
|
listenPromises = listenPromises.concat(config.dns.bind.map(function (port) {
|
||||||
|
return listeners.udp.add(port, dnsListener);
|
||||||
|
}));
|
||||||
|
} else {
|
||||||
|
listenPromises.push(listeners.udp.add(config.dns.bind, dnsListener));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return PromiseA.all(listenPromises);
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var serversMap = module.exports._serversMap = {};
|
var serversMap = module.exports._serversMap = {};
|
||||||
|
var dgramMap = module.exports._dgramMap = {};
|
||||||
|
var PromiseA = require('bluebird');
|
||||||
|
|
||||||
module.exports.addTcpListener = function (port, handler) {
|
module.exports.addTcpListener = function (port, handler) {
|
||||||
var PromiseA = require('bluebird');
|
|
||||||
|
|
||||||
return new PromiseA(function (resolve, reject) {
|
return new PromiseA(function (resolve, reject) {
|
||||||
var stat = serversMap[port] || serversMap[port];
|
var stat = serversMap[port];
|
||||||
|
|
||||||
if (stat) {
|
if (stat) {
|
||||||
if (stat._closing) {
|
if (stat._closing) {
|
||||||
|
@ -34,9 +34,13 @@ module.exports.addTcpListener = function (port, handler) {
|
||||||
stat = serversMap[port] = {
|
stat = serversMap[port] = {
|
||||||
server: server
|
server: server
|
||||||
, handler: handler
|
, handler: handler
|
||||||
, _closing: false
|
, _closing: null
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Add .destroy so we can close all open connections. Better if added before listen
|
||||||
|
// to eliminate any possibility of it missing an early connection in it's records.
|
||||||
|
enableDestroy(server);
|
||||||
|
|
||||||
server.on('connection', function (conn) {
|
server.on('connection', function (conn) {
|
||||||
conn.__port = port;
|
conn.__port = port;
|
||||||
conn.__proto = 'tcp';
|
conn.__proto = 'tcp';
|
||||||
|
@ -62,16 +66,13 @@ module.exports.addTcpListener = function (port, handler) {
|
||||||
resolved = true;
|
resolved = true;
|
||||||
resolve();
|
resolve();
|
||||||
});
|
});
|
||||||
|
|
||||||
enableDestroy(server); // adds .destroy
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
module.exports.closeTcpListener = function (port) {
|
module.exports.closeTcpListener = function (port) {
|
||||||
var PromiseA = require('bluebird');
|
|
||||||
|
|
||||||
return new PromiseA(function (resolve) {
|
return new PromiseA(function (resolve) {
|
||||||
var stat = serversMap[port];
|
var stat = serversMap[port];
|
||||||
if (!stat) {
|
if (!stat) {
|
||||||
|
resolve();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
stat.server.on('close', function () {
|
stat.server.on('close', function () {
|
||||||
|
@ -98,10 +99,79 @@ module.exports.destroyTcpListener = function (port) {
|
||||||
stat = null;
|
stat = null;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
module.exports.addUdpListener = function (port, handler) {
|
||||||
|
return new PromiseA(function (resolve, reject) {
|
||||||
|
var stat = dgramMap[port];
|
||||||
|
|
||||||
|
if (stat) {
|
||||||
|
// we'll replace the current listener
|
||||||
|
stat.handler = handler;
|
||||||
|
resolve();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var dgram = require('dgram');
|
||||||
|
var server = dgram.createSocket('udp4');
|
||||||
|
var resolved = false;
|
||||||
|
|
||||||
|
stat = dgramMap[port] = {
|
||||||
|
server: server
|
||||||
|
, handler: handler
|
||||||
|
};
|
||||||
|
|
||||||
|
server.on('message', function (msg, rinfo) {
|
||||||
|
msg._size = rinfo.size;
|
||||||
|
msg._remoteFamily = rinfo.family;
|
||||||
|
msg._remoteAddress = rinfo.address;
|
||||||
|
msg._remotePort = rinfo.port;
|
||||||
|
msg._port = port;
|
||||||
|
stat.handler(msg);
|
||||||
|
});
|
||||||
|
|
||||||
|
server.on('error', function (err) {
|
||||||
|
if (!resolved) {
|
||||||
|
delete dgramMap[port];
|
||||||
|
reject(err);
|
||||||
|
}
|
||||||
|
else if (stat.handler.onError) {
|
||||||
|
stat.handler.onError(err);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
server.on('close', function () {
|
||||||
|
delete dgramMap[port];
|
||||||
|
});
|
||||||
|
|
||||||
|
server.bind(port, function () {
|
||||||
|
resolved = true;
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
module.exports.closeUdpListener = function (port) {
|
||||||
|
var stat = dgramMap[port];
|
||||||
|
if (!stat) {
|
||||||
|
return PromiseA.resolve();
|
||||||
|
}
|
||||||
|
|
||||||
|
return new PromiseA(function (resolve) {
|
||||||
|
stat.server.once('close', resolve);
|
||||||
|
stat.server.close();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
module.exports.listeners = {
|
module.exports.listeners = {
|
||||||
tcp: {
|
tcp: {
|
||||||
add: module.exports.addTcpListener
|
add: module.exports.addTcpListener
|
||||||
, close: module.exports.closeTcpListener
|
, close: module.exports.closeTcpListener
|
||||||
, destroy: module.exports.destroyTcpListener
|
, destroy: module.exports.destroyTcpListener
|
||||||
}
|
}
|
||||||
|
, udp: {
|
||||||
|
add: module.exports.addUdpListener
|
||||||
|
, close: module.exports.closeUdpListener
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -18,5 +18,5 @@ popd
|
||||||
|
|
||||||
mkdir -p well-known
|
mkdir -p well-known
|
||||||
pushd well-known
|
pushd well-known
|
||||||
ln -sf ../org.oauth3/well-known/oauth3 ./oauth3
|
ln -snf ../org.oauth3/well-known/oauth3 ./oauth3
|
||||||
popd
|
popd
|
||||||
|
|
Loading…
Reference in New Issue