forked from coolaj86/goldilocks.js
		
	implemented setting DNS records after tunnel connect
currently done automatically by API we get the tunnel token from, but in the near-ish future that will be changed
This commit is contained in:
		
							parent
							
								
									82f0b45c56
								
							
						
					
					
						commit
						00de23ded7
					
				@ -98,12 +98,20 @@ module.exports.create = function (deps, conf) {
 | 
			
		||||
      return domains.indexOf(record.host) !== -1;
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    var oldDomains = ourDns.filter(function (record) {
 | 
			
		||||
    // Of all the DNS records referring to our device and the current list of domains determine
 | 
			
		||||
    // which domains have records with outdated address, and which ones we can just leave be
 | 
			
		||||
    // without updating them.
 | 
			
		||||
    var badAddrDomains = ourDns.filter(function (record) {
 | 
			
		||||
      return record.value !== addr;
 | 
			
		||||
    }).map(function (record) {
 | 
			
		||||
      return record.host;
 | 
			
		||||
    }).map(record => record.host);
 | 
			
		||||
    var goodAddrDomains = ourDns.filter(function (record) {
 | 
			
		||||
      return record.value === addr && badAddrDomains.indexOf(record.host) < 0;
 | 
			
		||||
    }).map(record => record.host);
 | 
			
		||||
    var requiredUpdates = domains.filter(function (domain) {
 | 
			
		||||
      return goodAddrDomains.indexOf(domain) !== -1;
 | 
			
		||||
    });
 | 
			
		||||
    var oldDns = await splitDomains(directives.api, oldDomains);
 | 
			
		||||
 | 
			
		||||
    var oldDns = await splitDomains(directives.api, badAddrDomains);
 | 
			
		||||
    var common = {
 | 
			
		||||
      api: 'devices.detach'
 | 
			
		||||
    , session: session
 | 
			
		||||
@ -113,7 +121,7 @@ module.exports.create = function (deps, conf) {
 | 
			
		||||
      return deps.OAUTH3.api(directives.api, Object.assign({}, common, record));
 | 
			
		||||
    }));
 | 
			
		||||
 | 
			
		||||
    var newDns = await splitDomains(directives.api, domains);
 | 
			
		||||
    var newDns = await splitDomains(directives.api, requiredUpdates);
 | 
			
		||||
    common = {
 | 
			
		||||
      api: 'devices.attach'
 | 
			
		||||
    , session: session
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,7 @@
 | 
			
		||||
'use strict';
 | 
			
		||||
 | 
			
		||||
module.exports.create = function (deps, conf) {
 | 
			
		||||
  var dns = deps.PromiseA.promisifyAll(require('dns'));
 | 
			
		||||
  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);
 | 
			
		||||
@ -40,7 +41,31 @@ module.exports.create = function (deps, conf) {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  var tunnelActive = false;
 | 
			
		||||
  async function connectTunnel() {
 | 
			
		||||
  async function startTunnel(tunnelSession, mod, domainList) {
 | 
			
		||||
    try {
 | 
			
		||||
      var dnsSession = await getSession(mod.tokenId);
 | 
			
		||||
      var tunnelDomain = await deps.tunnelClients.start(tunnelSession || dnsSession, domainList);
 | 
			
		||||
 | 
			
		||||
      var addrList;
 | 
			
		||||
      try {
 | 
			
		||||
        addrList = await dns.resolve4Async(tunnelDomain);
 | 
			
		||||
      } catch (e) {}
 | 
			
		||||
      if (!addrList || !addrList.length) {
 | 
			
		||||
        try {
 | 
			
		||||
          addrList = await dns.resolve6Async(tunnelDomain);
 | 
			
		||||
        } catch (e) {}
 | 
			
		||||
      }
 | 
			
		||||
      if (!addrList || !addrList.length || !addrList[0]) {
 | 
			
		||||
        throw new Error('failed to lookup IP for tunnel domain "' + tunnelDomain + '"');
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      await dnsCtrl.setDeviceAddress(dnsSession, addrList[0], domainList);
 | 
			
		||||
    } catch (err) {
 | 
			
		||||
      console.log('error starting tunnel for', domainList.join(', '));
 | 
			
		||||
      console.log(err);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  async function connectAllTunnels() {
 | 
			
		||||
    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
 | 
			
		||||
@ -48,20 +73,15 @@ module.exports.create = function (deps, conf) {
 | 
			
		||||
      tunnelSession = await deps.storage.tokens.get(conf.ddns.tunnel.tokenId);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    await iterateAllModules(function startTunnel(mod, domainList) {
 | 
			
		||||
    await iterateAllModules(function (mod, domainList) {
 | 
			
		||||
      if (mod.type !== 'dns@oauth3.org') { return null; }
 | 
			
		||||
 | 
			
		||||
      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);
 | 
			
		||||
      });
 | 
			
		||||
      return startTunnel(tunnelSession, mod, domainList);
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    tunnelActive = true;
 | 
			
		||||
  }
 | 
			
		||||
  async function disconnectTunnel() {
 | 
			
		||||
  async function disconnectTunnels() {
 | 
			
		||||
    deps.tunnelClients.disconnect();
 | 
			
		||||
    tunnelActive = false;
 | 
			
		||||
    await Promise.resolve();
 | 
			
		||||
@ -94,13 +114,8 @@ module.exports.create = function (deps, conf) {
 | 
			
		||||
      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);
 | 
			
		||||
      });
 | 
			
		||||
    await Promise.all(newTokens.map(function ({mod, domainList}) {
 | 
			
		||||
      return startTunnel(tunnelSession, mod, domainList);
 | 
			
		||||
    }));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -131,11 +146,11 @@ module.exports.create = function (deps, conf) {
 | 
			
		||||
    // address. Otherwise we need to use the tunnel to accept traffic.
 | 
			
		||||
    if (!notLooped.length) {
 | 
			
		||||
      if (tunnelActive) {
 | 
			
		||||
        await disconnectTunnel();
 | 
			
		||||
        await disconnectTunnels();
 | 
			
		||||
      }
 | 
			
		||||
    } else {
 | 
			
		||||
      if (!tunnelActive) {
 | 
			
		||||
        await connectTunnel();
 | 
			
		||||
        await connectAllTunnels();
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
@ -285,7 +300,7 @@ module.exports.create = function (deps, conf) {
 | 
			
		||||
      if (equal(curConf.ddns.tunnel, conf.ddns.tunnel)) {
 | 
			
		||||
        return checkTunnelTokens();
 | 
			
		||||
      } else {
 | 
			
		||||
        return disconnectTunnel().then(connectTunnel);
 | 
			
		||||
        return disconnectTunnels().then(connectAllTunnels);
 | 
			
		||||
      }
 | 
			
		||||
    }).catch(function (err) {
 | 
			
		||||
      console.error('error transitioning DNS between configurations');
 | 
			
		||||
 | 
			
		||||
@ -92,6 +92,10 @@ module.exports.create = function (deps, config) {
 | 
			
		||||
    // to keep record of what domains we are handling and what tunnel server
 | 
			
		||||
    // those domains should go to.
 | 
			
		||||
    activeDomains[data.domains] = data;
 | 
			
		||||
 | 
			
		||||
    // This is mostly for the start, but return the host for the tunnel server
 | 
			
		||||
    // we've connected to (after stripping the protocol and path away).
 | 
			
		||||
    return data.tunnelUrl.replace(/^[a-z]*:\/\//i, '').replace(/\/.*/, '');
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  async function acquireToken(session, domains) {
 | 
			
		||||
@ -118,7 +122,7 @@ module.exports.create = function (deps, config) {
 | 
			
		||||
 | 
			
		||||
    var directives = await OAUTH3.discover(session.token.aud);
 | 
			
		||||
    var tokenData = await OAUTH3.api(directives.api, opts);
 | 
			
		||||
    await addToken(tokenData);
 | 
			
		||||
    return addToken(tokenData);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function disconnectAll() {
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user