This is an automated email from the ASF dual-hosted git repository.
SiyaoIsHiding pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/cassandra-nodejs-driver.git
The following commit(s) were added to refs/heads/trunk by this push:
new 9a37061d CASSNODEJS-16: Use system resolver for contact points
9a37061d is described below
commit 9a37061d2d8a7f10dd2d2486fac745330ed5a0d6
Author: finalchild <[email protected]>
AuthorDate: Thu Oct 8 23:26:44 2026 +0900
CASSNODEJS-16: Use system resolver for contact points
patch by finalchild; reviewed by Jorge Bay and Jane He
---
lib/control-connection.js | 33 +++---------
test/unit/control-connection-tests.js | 99 ++++++++++++-----------------------
2 files changed, 41 insertions(+), 91 deletions(-)
diff --git a/lib/control-connection.js b/lib/control-connection.js
index fd707529..e970d355 100644
--- a/lib/control-connection.js
+++ b/lib/control-connection.js
@@ -895,40 +895,21 @@ class ControlConnection extends events.EventEmitter {
}
/**
- * Uses the DNS protocol to resolve a IPv4 and IPv6 addresses (A and AAAA
records) for the hostname.
+ * Uses the operating system resolver to resolve all IPv4 and IPv6 addresses
for the hostname.
* It returns an Array of addresses that can be empty and logs the error.
* @private
* @param name
*/
async _resolveAll(name) {
- const addresses = [];
- const resolve4 = util.promisify(dns.resolve4);
- const resolve6 = util.promisify(dns.resolve6);
const lookup = util.promisify(dns.lookup);
- // Ignore errors for resolve calls
- const ipv4Promise = resolve4(name).catch(() => {}).then(r => r ||
utils.emptyArray);
- const ipv6Promise = resolve6(name).catch(() => {}).then(r => r ||
utils.emptyArray);
-
- let arr;
- arr = await ipv4Promise;
- arr.forEach(address => addresses.push({address, isIPv6: false}));
-
- arr = await ipv6Promise;
- arr.forEach(address => addresses.push({address, isIPv6: true}));
-
- if (addresses.length === 0) {
- // In case dns.resolve*() methods don't yield a valid address for the
host name
- // Use system call getaddrinfo() that might resolve according to host
system definitions
- try {
- arr = await lookup(name, { all: true });
- arr.forEach(({address, family}) => addresses.push({address, isIPv6:
family === 6}));
- } catch (err) {
- this.log('error', `Host with name ${name} could not be resolved`, err);
- }
+ try {
+ const addresses = await lookup(name, { all: true });
+ return addresses.map(({address, family}) => ({address, isIPv6: family
=== 6}));
+ } catch (err) {
+ this.log('error', `Host with name ${name} could not be resolved`, err);
+ return utils.emptyArray;
}
-
- return addresses;
}
/**
diff --git a/test/unit/control-connection-tests.js
b/test/unit/control-connection-tests.js
index 8481d3d7..8bfc1e35 100644
--- a/test/unit/control-connection-tests.js
+++ b/test/unit/control-connection-tests.js
@@ -81,14 +81,12 @@ describe('ControlConnection', function () {
it('should resolve IPv4 and IPv6 addresses, default host (localhost) and
port', () => {
const ControlConnectionMock = proxyquire('../../lib/control-connection',
{ dns: {
- resolve4: function (name, cb) {
- cb(null, ifLocalhost(name, ['127.0.0.1']));
- },
- resolve6: function (name, cb) {
- cb(null, ifLocalhost(name, ['::1']));
- },
- lookup: function () {
- throw new Error('dns.lookup() should not be used');
+ lookup: function (name, options, cb) {
+ assert.deepStrictEqual(options, { all: true });
+ cb(null, ifLocalhost(name, [
+ { address: '127.0.0.1', family: 4 },
+ { address: '::1', family: 6 }
+ ]));
}
}});
@@ -99,14 +97,12 @@ describe('ControlConnection', function () {
it('should resolve IPv4 and IPv6 addresses with non default port', () => {
const ControlConnectionMock = proxyquire('../../lib/control-connection',
{ dns: {
- resolve4: function (name, cb) {
- cb(null, ifLocalhost(name, ['127.0.0.1']));
- },
- resolve6: function (name, cb) {
- cb(null, ifLocalhost(name, ['::1']));
- },
- lookup: function () {
- throw new Error('dns.lookup() should not be used');
+ lookup: function (name, options, cb) {
+ assert.deepStrictEqual(options, { all: true });
+ cb(null, ifLocalhost(name, [
+ { address: '127.0.0.1', family: 4 },
+ { address: '::1', family: 6 }
+ ]));
}
}});
@@ -116,16 +112,23 @@ describe('ControlConnection', function () {
'localhost:9999');
});
- it('should resolve all IPv4 and IPv6 addresses provided by dns.resolve()',
() => {
+ it('should resolve all IPv4 and IPv6 addresses using the operating system
resolver', () => {
const ControlConnectionMock = proxyquire('../../lib/control-connection',
{ dns: {
- resolve4: function (name, cb) {
- cb(null, ['1', '2']);
+ resolve4: function () {
+ throw new Error('dns.resolve4() should not be used');
},
- resolve6: function (name, cb) {
- cb(null, ['10', '20']);
+ resolve6: function () {
+ throw new Error('dns.resolve6() should not be used');
},
- lookup: function () {
- throw new Error('dns.lookup() should not be used');
+ lookup: function (name, options, cb) {
+ assert.strictEqual(name, 'localhost');
+ assert.deepStrictEqual(options, { all: true });
+ cb(null, [
+ { address: '1', family: 4 },
+ { address: '2', family: 4 },
+ { address: '10', family: 6 },
+ { address: '20', family: 6 }
+ ]);
}
}});
@@ -134,52 +137,24 @@ describe('ControlConnection', function () {
[ '1:9042', '2:9042', '[10]:9042', '[20]:9042' ]);
});
- it('should ignore IPv4 or IPv6 resolution errors', function () {
+ it('should handle system resolver errors', function () {
const ControlConnectionMock = proxyquire('../../lib/control-connection',
{ dns: {
- resolve4: function (name, cb) {
- cb(null, ['1', '2']);
- },
- resolve6: function (name, cb) {
+ lookup: function (name, options, cb) {
cb(new Error('Test error'));
- },
- lookup: function () {
- throw new Error('dns.lookup() should not be used');
}
}});
- return testResolution(ControlConnectionMock, [ '1:9042', '2:9042']);
+ return testResolution(ControlConnectionMock, [], utils.emptyArray);
});
- it('should use dns.lookup() as failover', () => {
+ it('should handle an empty system resolver result', () => {
const ControlConnectionMock = proxyquire('../../lib/control-connection',
{ dns: {
- resolve4: function (name, cb) {
- cb(new Error('Test error'));
- },
- resolve6: function (name, cb) {
- cb(new Error('Test error'));
- },
lookup: function (name, options, cb) {
- cb(null, [{ address: '123', family: 4 }]);
- }
- }});
-
- return testResolution(ControlConnectionMock, [ '123:9042' ]);
- });
-
- it('should use dns.lookup() when no address was resolved', () => {
- const ControlConnectionMock = proxyquire('../../lib/control-connection',
{ dns: {
- resolve4: function (name, cb) {
- cb(null);
- },
- resolve6: function (name, cb) {
cb(null, []);
- },
- lookup: function (name, options, cb) {
- cb(null, [{ address: '1234', family: 4 }]);
}
}});
- return testResolution(ControlConnectionMock, [ '1234:9042' ]);
+ return testResolution(ControlConnectionMock, [], utils.emptyArray);
});
it('should continue iterating through the hosts when borrowing a
connection fails',async () => {
@@ -284,19 +259,13 @@ describe('ControlConnection', function () {
const resolvedAddresses = ['1','2'];
const ControlConnectionMock = proxyquire('../../lib/control-connection',
{ dns: {
- resolve4: function (name, cb) {
+ lookup: function (name, options, cb) {
if (dnsWorks) {
- cb(null, resolvedAddresses);
+ cb(null, resolvedAddresses.map(address => ({ address, family: 4
})));
}
else {
cb(null, []);
}
- },
- resolve6: function (name, cb) {
- throw new Error('IPv6 resolution errors should be ignored');
- },
- lookup: function () {
- throw new Error('dns.lookup() should not be used');
}
}});
const cc = new ControlConnectionMock(
@@ -590,4 +559,4 @@ function getContext(options) {
return state.connection = getFakeConnection(endpoint,
options.queryResults);
}
};
-}
\ No newline at end of file
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]