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