Skip to content

Commit 24d6293

Browse files
authored
NODEJS-646: Reset frozen list to something mutable when adding newly resolved addresses
1 parent bed8ff1 commit 24d6293

File tree

2 files changed

+59
-1
lines changed

2 files changed

+59
-1
lines changed

lib/control-connection.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,13 @@ class ControlConnection extends events.EventEmitter {
131131
const standardEndpoint = !isIPv6 ? endpoint : `[${address}]:${portNumber}`;
132132

133133
let resolvedAddressedByName = this._resolvedContactPoints.get(name);
134-
if (resolvedAddressedByName === undefined) {
134+
135+
// NODEJS-646
136+
//
137+
// We might have a frozen empty array if DNS resolution wasn't working when this name was
138+
// initially added, and if that's the case we can't add anything. Detect that case and
139+
// reset to a mutable array.
140+
if (resolvedAddressedByName === undefined || resolvedAddressedByName === utils.emptyArray) {
135141
resolvedAddressedByName = [];
136142
this._resolvedContactPoints.set(name, resolvedAddressedByName);
137143
}

test/unit/control-connection-tests.js

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,58 @@ describe('ControlConnection', function () {
282282
cc.shutdown();
283283
cc.hosts.values().forEach(h => h.shutdown());
284284
});
285+
286+
it('should add an address if previous resolution failed', async () => {
287+
let dnsWorks = false;
288+
const hostname = 'my-host-name';
289+
const resolvedAddresses = ['1','2'];
290+
291+
const ControlConnectionMock = proxyquire('../../lib/control-connection', { dns: {
292+
resolve4: function (name, cb) {
293+
if (dnsWorks) {
294+
cb(null, resolvedAddresses);
295+
}
296+
else {
297+
cb(null, []);
298+
}
299+
},
300+
resolve6: function (name, cb) {
301+
throw new Error('IPv6 resolution errors should be ignored');
302+
},
303+
lookup: function () {
304+
throw new Error('dns.lookup() should not be used');
305+
}
306+
}});
307+
const cc = new ControlConnectionMock(
308+
clientOptions.extend({ contactPoints: [hostname] }),
309+
null,
310+
getContext());
311+
312+
let err = null;
313+
314+
try {
315+
await cc.init();
316+
} catch (e) {
317+
err = e;
318+
}
319+
assert.instanceOf(err, errors.NoHostAvailableError);
320+
assert.deepStrictEqual(cc.getResolvedContactPoints().get(hostname), utils.emptyArray);
321+
322+
// Make DNS resolution magically work and re-run initialization
323+
err = null;
324+
dnsWorks = true;
325+
326+
try {
327+
await cc.init();
328+
} catch (e) {
329+
err = e;
330+
}
331+
332+
assert.isNull(err);
333+
assert.deepStrictEqual(
334+
cc.getResolvedContactPoints().get(hostname),
335+
resolvedAddresses.map(a => a + ":9042"));
336+
});
285337
});
286338

287339
describe('#getAddressForPeerHost()', function() {

0 commit comments

Comments
 (0)