changed loopback endpoint to check all ports

This commit is contained in:
tigerbot 2017-06-26 18:12:00 -06:00
parent 000d36e76a
commit f37730c97d
4 changed files with 89 additions and 50 deletions

View File

@ -186,11 +186,11 @@ module.exports.create = function (deps, config) {
return;
}
if (Array.isArray(bindList)) {
bindList.forEach(function (port) {
bindList.filter(Number).forEach(function (port) {
tcpPortMap[port] = true;
});
}
else {
else if (Number(bindList)) {
tcpPortMap[bindList] = true;
}
}

View File

@ -5,23 +5,37 @@ module.exports.create = function () {
var request = PromiseA.promisify(require('request'));
var pending = {};
function loopback(session, opts) {
function checkPublicAddr(host) {
return request({
method: 'GET'
, url: 'https://'+host+'/api/org.oauth3.tunnel/checkip'
, json: true
}).then(function (result) {
if (!result.body) {
return PromiseA.reject(new Error('No response body in request for public address'));
}
if (result.body.error) {
var err = new Error(result.body.error.message);
return PromiseA.reject(Object.assign(err, result.body.error));
}
console.log(result.body, result.body.address);
return result.body.address;
});
}
function checkSinglePort(host, address, port) {
var crypto = require('crypto');
var token = crypto.randomBytes(8).toString('hex');
var keyAuth = crypto.randomBytes(32).toString('hex');
pending[token] = keyAuth;
var host;
if (!opts) {
opts = session;
host = 'api.oauth3.org';
} else {
host = 'api.' + ((session.token || {}).aud || 'oauth3.org');
}
opts.token = token;
opts.keyAuthorization = keyAuth;
opts.iat = Date.now();
var opts = {
address: address
, port: port
, token: token
, keyAuthorization: keyAuth
, iat: Date.now()
};
return request({
method: 'POST'
@ -29,11 +43,44 @@ module.exports.create = function () {
, json: opts
})
.then(function (result) {
if (result.body.error) {
var err = new Error(result.body.error.message);
return PromiseA.reject(Object.assign(err, result.body.error));
delete pending[token];
if (!result.body) {
return PromiseA.reject(new Error('No response body in loopback request for port '+port));
}
return result.body.success;
// If the loopback requests don't go to us then there are all kinds of ways it could
// error, but none of them really provide much extra information so we don't do
// anything that will break the PromiseA.all out and mask the other results.
if (result.body.error) {
console.log('error on remote side of port '+port+' loopback', result.body.error);
}
return !!result.body.success;
}, function (err) {
delete pending[token];
throw err;
});
}
function loopback(session) {
var host;
if (!session) {
host = 'api.oauth3.org';
} else {
host = 'api.' + ((session.token || {}).aud || 'oauth3.org');
}
return checkPublicAddr(host).then(function (address) {
console.log('checking to see if', address, 'gets back to us');
var ports = require('./servers').listeners.tcp.list();
return PromiseA.all(ports.map(function (port) {
return checkSinglePort(host, address, port);
}))
.then(function (values) {
var result = {error: null, address: address};
ports.forEach(function (port, ind) {
result[port] = values[ind];
});
return result;
});
});
}

View File

@ -46,20 +46,18 @@ module.exports.addTcpListener = function (port, handler) {
conn.__proto = 'tcp';
stat.handler(conn);
});
server.on('error', function (e) {
server.on('close', function () {
console.log('TCP server on port %d closed', port);
delete serversMap[port];
});
server.on('error', function (e) {
if (!resolved) {
reject(e);
return;
}
if (handler.onError) {
} else if (handler.onError) {
handler.onError(e);
return;
} else {
throw e;
}
throw e;
});
server.listen(port, function () {
@ -75,29 +73,20 @@ module.exports.closeTcpListener = function (port) {
resolve();
return;
}
stat.server.on('close', function () {
// once the clients close too
delete serversMap[port];
if (stat._closing) {
stat._closing(); // resolve
stat._closing = null;
}
stat = null;
});
stat._closing = resolve;
stat.server.once('close', resolve);
stat.server.close();
});
};
module.exports.destroyTcpListener = function (port) {
var stat = serversMap[port];
delete serversMap[port];
stat.server.destroy();
if (stat._closing) {
stat._closing();
stat._closing = null;
if (stat) {
stat.server.destroy();
}
stat = null;
};
module.exports.listTcpListeners = function () {
return Object.keys(serversMap).map(Number).filter(Boolean);
};
module.exports.addUdpListener = function (port, handler) {
return new PromiseA(function (resolve, reject) {
@ -162,6 +151,9 @@ module.exports.closeUdpListener = function (port) {
stat.server.close();
});
};
module.exports.listUdpListeners = function () {
return Object.keys(dgramMap).map(Number).filter(Boolean);
};
module.exports.listeners = {
@ -169,9 +161,11 @@ module.exports.listeners = {
add: module.exports.addTcpListener
, close: module.exports.closeTcpListener
, destroy: module.exports.destroyTcpListener
, list: module.exports.listTcpListeners
}
, udp: {
add: module.exports.addUdpListener
, close: module.exports.closeUdpListener
, list: module.exports.listUdpListeners
}
};

View File

@ -309,20 +309,18 @@ module.exports.create = function (deps, conf) {
});
}
, loopback: function (req, res) {
if (handleCors(req, res, 'POST')) {
if (handleCors(req, res, 'GET')) {
return;
}
isAuthorized(req, res, function () {
jsonParser(req, res, function () {
res.setHeader('Content-Type', 'application/json');
deps.loopback(req.body)
.then(function (success) {
res.end(JSON.stringify({error: null, success: success}));
deps.loopback()
.then(function (result) {
res.end(JSON.stringify(result));
}, function (err) {
res.end(JSON.stringify({error: {message: err.message, code: err.code}}))
res.end(JSON.stringify({error: {message: err.message, code: err.code}}));
});
});
});
}
, paywall_check: function (req, res) {
if (handleCors(req, res, 'GET')) {