forked from floatdrop/dns-graceful-stack-switch
-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
80 lines (65 loc) · 2.2 KB
/
index.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
71
72
73
74
75
76
77
78
79
80
var dns = require('dns');
/** old dns.lookup function - used to restore original function **/
var lookup;
/**
* A module that monkeypatch dns.lookup for graceful
* falling to another IP stack version.
* @module dns-graceful-stack-switch
*/
/**
* Monkeypatch function
* @param {Number} defaultVersion - version of IP stack, that will be used first
* @param {Boolean} remove - if true, removes monkeypatch
*/
module.exports = function(defaultVersion, remove) {
if (remove && dns.lookup._wrapped) {
dns.lookup = lookup;
lookup = undefined;
return;
}
/* check, that we won't wrap already wrapped function */
if (dns.lookup._wrapped)
return;
/** default version of IP stack to lookup first */
defaultVersion = defaultVersion || process.env.NODE_DNS_GRACEFUL_STACK_SWITCH_DEFAULT || 4;
/** store original function, in case removing */
lookup = dns.lookup;
/**
* Patched function wrapper
* @param domain {String} - domain to lookup for
* @param family {Number} - version of IP stack to use first
* @param callback {Function} - callback function (signature: function(err, address, family))
*/
dns.lookup = function(domain, family, callback) {
if (arguments.length === 2) {
callback = family;
family = 0;
} else if (!family) {
family = 0;
} else {
family = +family;
if (family !== 4 && family !== 6) {
throw new Error('invalid argument: `family` must be 4 or 6');
}
}
var requestedFamily = family || defaultVersion;
lookup(domain, requestedFamily, function(err, address, family) {
if (!err) {
return callback(err, address, family);
}
/* store error for full output, in case next lookup fails */
var prevError = "IPv" + requestedFamily + " " + err + "; ";
/* choose other family, that was not used */
var otherFamily = requestedFamily === 4 ? 6 : 4;
lookup(domain, otherFamily, function(err, address, family) {
if (err) {
/* modify error to store previous lookup error */
err = prevError + "IPv" + otherFamily + " " + err;
}
callback(err, address, family);
});
});
};
/** _wrapped - boolean flag to recognize patched functions between different versions of modules **/
dns.lookup._wrapped = true;
};