moved tunnel client manager into DDNS directory where it's used
This commit is contained in:
parent
a27252eb77
commit
eda766e48c
|
@ -5,6 +5,7 @@ module.exports.create = function (deps, conf) {
|
||||||
var network = deps.PromiseA.promisifyAll(deps.recase.camelCopy(require('network')));
|
var network = deps.PromiseA.promisifyAll(deps.recase.camelCopy(require('network')));
|
||||||
var loopback = require('./loopback').create(deps, conf);
|
var loopback = require('./loopback').create(deps, conf);
|
||||||
var dnsCtrl = require('./dns-ctrl').create(deps, conf);
|
var dnsCtrl = require('./dns-ctrl').create(deps, conf);
|
||||||
|
var tunnelClients = require('./tunnel-client-manager').create(deps, conf);
|
||||||
var equal = require('deep-equal');
|
var equal = require('deep-equal');
|
||||||
|
|
||||||
var loopbackDomain;
|
var loopbackDomain;
|
||||||
|
@ -44,7 +45,7 @@ module.exports.create = function (deps, conf) {
|
||||||
async function startTunnel(tunnelSession, mod, domainList) {
|
async function startTunnel(tunnelSession, mod, domainList) {
|
||||||
try {
|
try {
|
||||||
var dnsSession = await getSession(mod.tokenId);
|
var dnsSession = await getSession(mod.tokenId);
|
||||||
var tunnelDomain = await deps.tunnelClients.start(tunnelSession || dnsSession, domainList);
|
var tunnelDomain = await tunnelClients.start(tunnelSession || dnsSession, domainList);
|
||||||
|
|
||||||
var addrList;
|
var addrList;
|
||||||
try {
|
try {
|
||||||
|
@ -82,12 +83,12 @@ module.exports.create = function (deps, conf) {
|
||||||
tunnelActive = true;
|
tunnelActive = true;
|
||||||
}
|
}
|
||||||
async function disconnectTunnels() {
|
async function disconnectTunnels() {
|
||||||
deps.tunnelClients.disconnect();
|
tunnelClients.disconnect();
|
||||||
tunnelActive = false;
|
tunnelActive = false;
|
||||||
await Promise.resolve();
|
await Promise.resolve();
|
||||||
}
|
}
|
||||||
async function checkTunnelTokens() {
|
async function checkTunnelTokens() {
|
||||||
var oldTokens = deps.tunnelClients.current();
|
var oldTokens = tunnelClients.current();
|
||||||
|
|
||||||
var newTokens = await iterateAllModules(function checkTokens(mod, domainList) {
|
var newTokens = await iterateAllModules(function checkTokens(mod, domainList) {
|
||||||
if (mod.type !== 'dns@oauth3.org') { return null; }
|
if (mod.type !== 'dns@oauth3.org') { return null; }
|
||||||
|
@ -103,7 +104,7 @@ module.exports.create = function (deps, conf) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
await Promise.all(Object.values(oldTokens).map(deps.tunnelClients.remove));
|
await Promise.all(Object.values(oldTokens).map(tunnelClients.remove));
|
||||||
|
|
||||||
if (!newTokens.length) { return; }
|
if (!newTokens.length) { return; }
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,52 @@ module.exports.create = function (deps, config) {
|
||||||
var activeTunnels = {};
|
var activeTunnels = {};
|
||||||
var activeDomains = {};
|
var activeDomains = {};
|
||||||
|
|
||||||
|
var customNet = {
|
||||||
|
createConnection: function (opts, cb) {
|
||||||
|
console.log('[gl.tunnel] creating connection');
|
||||||
|
|
||||||
|
// here "reader" means the socket that looks like the connection being accepted
|
||||||
|
// here "writer" means the remote-looking part of the socket that driving the connection
|
||||||
|
var writer;
|
||||||
|
|
||||||
|
function usePair(err, reader) {
|
||||||
|
if (err) {
|
||||||
|
process.nextTick(function () {
|
||||||
|
writer.emit('error', err);
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var wrapOpts = Object.assign({localAddress: '127.0.0.2', localPort: 'tunnel-0'}, opts);
|
||||||
|
wrapOpts.firstChunk = opts.data;
|
||||||
|
wrapOpts.hyperPeek = !!opts.data;
|
||||||
|
|
||||||
|
// Also override the remote and local address info. We use `defineProperty` because
|
||||||
|
// otherwise we run into problems of setting properties with only getters defined.
|
||||||
|
Object.defineProperty(reader, 'remoteAddress', { value: wrapOpts.remoteAddress });
|
||||||
|
Object.defineProperty(reader, 'remotePort', { value: wrapOpts.remotePort });
|
||||||
|
Object.defineProperty(reader, 'remoteFamiliy', { value: wrapOpts.remoteFamiliy });
|
||||||
|
Object.defineProperty(reader, 'localAddress', { value: wrapOpts.localAddress });
|
||||||
|
Object.defineProperty(reader, 'localPort', { value: wrapOpts.localPort });
|
||||||
|
Object.defineProperty(reader, 'localFamiliy', { value: wrapOpts.localFamiliy });
|
||||||
|
|
||||||
|
deps.tcp.handler(reader, wrapOpts);
|
||||||
|
process.nextTick(function () {
|
||||||
|
// this cb will cause the stream to emit its (actually) first data event
|
||||||
|
// (even though it already gave a peek into that first data chunk)
|
||||||
|
console.log('[tunnel] callback, data should begin to flow');
|
||||||
|
cb();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// We used to use `stream-pair` for non-tls connections, but there are places
|
||||||
|
// that require properties/functions to be present on the socket that aren't
|
||||||
|
// present on a JSStream so it caused problems.
|
||||||
|
writer = require('socket-pair').create(usePair);
|
||||||
|
return writer;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
function fillData(data) {
|
function fillData(data) {
|
||||||
if (typeof data === 'string') {
|
if (typeof data === 'string') {
|
||||||
data = { jwt: data };
|
data = { jwt: data };
|
||||||
|
@ -70,7 +116,7 @@ module.exports.create = function (deps, config) {
|
||||||
// get the promise that should tell us more about if it worked or not.
|
// get the promise that should tell us more about if it worked or not.
|
||||||
activeTunnels[data.tunnelUrl] = stunnel.connect({
|
activeTunnels[data.tunnelUrl] = stunnel.connect({
|
||||||
stunneld: data.tunnelUrl
|
stunneld: data.tunnelUrl
|
||||||
, net: deps.tunnel.net
|
, net: customNet
|
||||||
// NOTE: the ports here aren't that important since we are providing a custom
|
// NOTE: the ports here aren't that important since we are providing a custom
|
||||||
// `net.createConnection` that doesn't actually use the port. What is important
|
// `net.createConnection` that doesn't actually use the port. What is important
|
||||||
// is that any services we are interested in are listed in this object and have
|
// is that any services we are interested in are listed in this object and have
|
|
@ -165,71 +165,6 @@ module.exports.create = function (deps, config) {
|
||||||
modules.tls = require('./tls').create(deps, config, modules);
|
modules.tls = require('./tls').create(deps, config, modules);
|
||||||
modules.http = require('./http').create(deps, config, modules);
|
modules.http = require('./http').create(deps, config, modules);
|
||||||
|
|
||||||
deps.tunnel = deps.tunnel || {};
|
|
||||||
deps.tunnel.net = {
|
|
||||||
createConnection: function (opts, cb) {
|
|
||||||
console.log('[gl.tunnel] creating connection');
|
|
||||||
|
|
||||||
// here "reader" means the socket that looks like the connection being accepted
|
|
||||||
// here "writer" means the remote-looking part of the socket that driving the connection
|
|
||||||
var writer;
|
|
||||||
var wrapOpts = {};
|
|
||||||
|
|
||||||
function usePair(err, reader) {
|
|
||||||
if (err) {
|
|
||||||
process.nextTick(function () {
|
|
||||||
writer.emit('error', err);
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// this has the normal net/tcp stuff plus our custom stuff
|
|
||||||
// opts = { address, port,
|
|
||||||
// hostname, servername, tls, encrypted, data, localAddress, localPort, remoteAddress, remotePort, remoteFamily }
|
|
||||||
Object.keys(opts).forEach(function (key) {
|
|
||||||
wrapOpts[key] = opts[key];
|
|
||||||
try {
|
|
||||||
reader[key] = opts[key];
|
|
||||||
} catch(e) {
|
|
||||||
// can't set real socket getters, like remoteAddr
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// A few more extra specialty options
|
|
||||||
wrapOpts.localAddress = wrapOpts.localAddress || '127.0.0.2'; // TODO use the tunnel's external address
|
|
||||||
wrapOpts.localPort = wrapOpts.localPort || 'tunnel-0';
|
|
||||||
try {
|
|
||||||
reader._remoteAddress = wrapOpts.remoteAddress;
|
|
||||||
reader._remotePort = wrapOpts.remotePort;
|
|
||||||
reader._remoteFamily = wrapOpts.remoteFamily;
|
|
||||||
reader._localAddress = wrapOpts.localAddress;
|
|
||||||
reader._localPort = wrapOpts.localPort;
|
|
||||||
reader._localFamily = wrapOpts.localFamily;
|
|
||||||
} catch(e) {
|
|
||||||
}
|
|
||||||
|
|
||||||
tcpHandler(reader, wrapOpts);
|
|
||||||
|
|
||||||
process.nextTick(function () {
|
|
||||||
// this cb will cause the stream to emit its (actually) first data event
|
|
||||||
// (even though it already gave a peek into that first data chunk)
|
|
||||||
console.log('[tunnel] callback, data should begin to flow');
|
|
||||||
cb();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
wrapOpts.firstChunk = opts.data;
|
|
||||||
wrapOpts.hyperPeek = !!opts.data;
|
|
||||||
|
|
||||||
// We used to use `stream-pair` for non-tls connections, but there are places
|
|
||||||
// that require properties/functions to be present on the socket that aren't
|
|
||||||
// present on a JSStream so it caused problems.
|
|
||||||
writer = require('socket-pair').create(usePair);
|
|
||||||
return writer;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
deps.tunnelClients = require('../tunnel-client-manager').create(deps, config);
|
|
||||||
|
|
||||||
function updateListeners() {
|
function updateListeners() {
|
||||||
var current = listeners.list();
|
var current = listeners.list();
|
||||||
var wanted = config.tcp.bind;
|
var wanted = config.tcp.bind;
|
||||||
|
@ -297,6 +232,7 @@ module.exports.create = function (deps, config) {
|
||||||
|
|
||||||
var result = {
|
var result = {
|
||||||
updateConf
|
updateConf
|
||||||
|
, handler: tcpHandler
|
||||||
};
|
};
|
||||||
Object.defineProperty(result, 'mainPort', {enumerable: true, get: () => mainPort});
|
Object.defineProperty(result, 'mainPort', {enumerable: true, get: () => mainPort});
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue