|
|
@ -4,19 +4,9 @@ module.exports.create = function (deps, conf) { |
|
|
|
var network = deps.PromiseA.promisifyAll(deps.recase.camelCopy(require('network'))); |
|
|
|
var loopback = require('./loopback').create(deps, conf); |
|
|
|
var dnsCtrl = require('./dns-ctrl').create(deps, conf); |
|
|
|
var equal = require('deep-equal'); |
|
|
|
|
|
|
|
var loopbackDomain; |
|
|
|
function updateConf() { |
|
|
|
loopbackDomain = 'oauth3.org'; |
|
|
|
if (conf.ddns && conf.ddns.loopback) { |
|
|
|
if (conf.ddns.loopback.type === 'tunnel@oauth3.org' && conf.ddns.loopback.domain) { |
|
|
|
loopbackDomain = conf.ddns.loopback.domain; |
|
|
|
} else { |
|
|
|
console.error('invalid loopback configuration: bad type or missing domain'); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
updateConf(); |
|
|
|
|
|
|
|
function iterateAllModules(action) { |
|
|
|
var promises = conf.ddns.modules.map(function (mod) { |
|
|
@ -57,13 +47,13 @@ module.exports.create = function (deps, conf) { |
|
|
|
tunnelSession = await deps.storage.tokens.get(conf.ddns.tunnel.tokenId); |
|
|
|
} |
|
|
|
|
|
|
|
await iterateAllModules(function startTunnel(mod, domainsList) { |
|
|
|
await iterateAllModules(function startTunnel(mod, domainList) { |
|
|
|
if (mod.type !== 'dns@oauth3.org') { return null; } |
|
|
|
|
|
|
|
return getSession(mod.token_id).then(function (dnsSession) { |
|
|
|
return deps.tunnelClients.start(tunnelSession || dnsSession, domainsList); |
|
|
|
return getSession(mod.tokenId).then(function (dnsSession) { |
|
|
|
return deps.tunnelClients.start(tunnelSession || dnsSession, domainList); |
|
|
|
}).catch(function (err) { |
|
|
|
console.log('error starting tunnel for', domainsList.join(', ')); |
|
|
|
console.log('error starting tunnel for', domainList.join(', ')); |
|
|
|
console.log(err); |
|
|
|
}); |
|
|
|
}); |
|
|
@ -73,6 +63,44 @@ module.exports.create = function (deps, conf) { |
|
|
|
async function disconnectTunnel() { |
|
|
|
deps.tunnelClients.disconnect(); |
|
|
|
tunnelActive = false; |
|
|
|
await Promise.resolve(); |
|
|
|
} |
|
|
|
async function checkTunnelTokens() { |
|
|
|
var oldTokens = deps.tunnelClients.current(); |
|
|
|
|
|
|
|
var newTokens = await iterateAllModules(function checkTokens(mod, domainList) { |
|
|
|
if (mod.type !== 'dns@oauth3.org') { return null; } |
|
|
|
|
|
|
|
var domainStr = domainList.slice().sort().join(','); |
|
|
|
// If there is already a token handling exactly the domains this modules
|
|
|
|
// needs handled remove it from the list of tokens to be removed. Otherwise
|
|
|
|
// return the module and domain list so we can get new tokens.
|
|
|
|
if (oldTokens[domainStr]) { |
|
|
|
delete oldTokens[domainStr]; |
|
|
|
} else { |
|
|
|
return Promise.resolve({ mod, domainList }); |
|
|
|
} |
|
|
|
}); |
|
|
|
|
|
|
|
await Promise.all(Object.values(oldTokens).map(deps.tunnelClients.remove)); |
|
|
|
|
|
|
|
if (!newTokens.length) { return; } |
|
|
|
|
|
|
|
var tunnelSession; |
|
|
|
if (conf.ddns.tunnel) { |
|
|
|
// In the case of a non-existant token, I'm not sure if we want to throw here and prevent
|
|
|
|
// any tunnel connections, or if we want to ignore it and fall back to the DNS tokens
|
|
|
|
tunnelSession = await deps.storage.tokens.get(conf.ddns.tunnel.tokenId); |
|
|
|
} |
|
|
|
|
|
|
|
await Promise.all(newTokens.map(function startTunnel({mod, domainList}) { |
|
|
|
return getSession(mod.tokenId).then(function (dnsSession) { |
|
|
|
return deps.tunnelClients.start(tunnelSession || dnsSession, domainList); |
|
|
|
}).catch(function (err) { |
|
|
|
console.log('error starting tunnel for', domainList.join(', ')); |
|
|
|
console.log(err); |
|
|
|
}); |
|
|
|
})); |
|
|
|
} |
|
|
|
|
|
|
|
var localAddr, gateway; |
|
|
@ -128,13 +156,13 @@ module.exports.create = function (deps, conf) { |
|
|
|
} |
|
|
|
publicAddress = addr; |
|
|
|
|
|
|
|
await iterateAllModules(function setModuleDNS(mod, domainsList) { |
|
|
|
await iterateAllModules(function setModuleDNS(mod, domainList) { |
|
|
|
if (mod.type !== 'dns@oauth3.org' || mod.disabled) { return null; } |
|
|
|
|
|
|
|
return getSession(mod.token_id).then(function (session) { |
|
|
|
return dnsCtrl.setDeviceAddress(session, addr, domainsList); |
|
|
|
return getSession(mod.tokenId).then(function (session) { |
|
|
|
return dnsCtrl.setDeviceAddress(session, addr, domainList); |
|
|
|
}).catch(function (err) { |
|
|
|
console.log('error setting DNS records for', domainsList.join(', ')); |
|
|
|
console.log('error setting DNS records for', domainList.join(', ')); |
|
|
|
console.log(err); |
|
|
|
}); |
|
|
|
}); |
|
|
@ -143,6 +171,38 @@ module.exports.create = function (deps, conf) { |
|
|
|
recheckPubAddr(); |
|
|
|
setInterval(recheckPubAddr, 5*60*1000); |
|
|
|
|
|
|
|
var curConf; |
|
|
|
function updateConf() { |
|
|
|
if (curConf && equal(curConf.ddns, conf.ddns) && equal(curConf.domains, conf.domains)) { |
|
|
|
// We could update curConf, but since everything we care about is the same...
|
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
if (!curConf || !equal(curConf.ddns.loopback, conf.ddns.loopback)) { |
|
|
|
loopbackDomain = 'oauth3.org'; |
|
|
|
if (conf.ddns && conf.ddns.loopback) { |
|
|
|
if (conf.ddns.loopback.type === 'tunnel@oauth3.org' && conf.ddns.loopback.domain) { |
|
|
|
loopbackDomain = conf.ddns.loopback.domain; |
|
|
|
} else { |
|
|
|
console.error('invalid loopback configuration: bad type or missing domain'); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (tunnelActive) { |
|
|
|
if (!curConf || !equal(curConf.ddns.tunnel, conf.ddns.tunnel)) { |
|
|
|
disconnectTunnel().then(connectTunnel); |
|
|
|
} else { |
|
|
|
checkTunnelTokens(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// We need to make a deep copy of the config so we can use it next time to
|
|
|
|
// compare and see what setup/cleanup is needed to adapt to the changes.
|
|
|
|
curConf = JSON.parse(JSON.stringify(conf)); |
|
|
|
} |
|
|
|
updateConf(); |
|
|
|
|
|
|
|
return { |
|
|
|
loopbackServer: loopback.server |
|
|
|
, setDeviceAddress: dnsCtrl.setDeviceAddress |
|
|
|