-
Notifications
You must be signed in to change notification settings - Fork 3k
/
Copy pathddns_resolver.js
70 lines (62 loc) · 2.19 KB
/
ddns_resolver.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
const error = require('../error');
const logger = require('../../logger').ddns;
const utils = require('../utils');
const ddnsResolver = {
/** Pattern to match any valid domain/subdomain */
ddnsRegex: /^((?!-)[A-Za-z\d-]{1,63}(?<!-)\.)+[A-Za-z]{2,6}$/,
/**
* Resolves the given address to its IP
* @param {String} domainName domain name of the dynamic DNS record
* @param {boolean} forceUpdate option to force resolution instead of using the cached value
*/
resolveAddress: (domainName, forceUpdate=false) => {
if (!forceUpdate && ddnsResolver._cache.has(domainName)) {
// Check if it is still valid
const value = ddnsResolver._cache.get(domainName);
const ip = value[0];
const lastUpdated = value[1];
const nowSeconds = Date.now();
const delta = nowSeconds - lastUpdated;
if (delta < ddnsResolver._updateIntervalMs) {
return Promise.resolve(ip);
}
}
ddnsResolver._cache.delete(domainName);
// Reach here only if cache value doesn't exist or needs to be updated
let host = domainName.toLowerCase();
return ddnsResolver._queryHost(host)
.then((resolvedIP) => {
ddnsResolver._cache.set(domainName, [resolvedIP, Date.now()]);
return resolvedIP;
})
.catch((/*error*/) => {
// return input address in case of failure
logger.error(`Failed to resolve IP for ${host}`);
return domainName;
});
},
/** Cache mapping host to (ip address, last updated time) */
_cache: new Map(),
/**
* Uses execSafe to query the IP address of the given host
* @param {String} host host to query
* @returns {Promise} resolves to the IPV4 address of the host
*/
_queryHost: (host) => {
return utils.execSafe('getent', ['ahostsv4', host])
.then((result) => {
const ipv4Regex = /(\d{1,3}\.){3}\d{1,3}/;
const match = result.match(ipv4Regex);
if (!match) {
logger.error(`IPV4 lookup for ${host} returned invalid output: ${result}`);
throw error.ValidationError('Invalid output from getent hosts');
}
return match[0];
},
(error) => {
logger.error('Error looking up IP for ' + host + ': ', error);
throw error;
});
},
};
module.exports = ddnsResolver;