Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/cmap/auth/gssapi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ export async function performGSSAPICanonicalizeHostName(

try {
// Perform a reverse ptr lookup on the ip address.
const results = await dns.promises.resolvePtr(address);
const results = await dns.promises.resolve(address, 'PTR');
// If the ptr did not error but had no results, return the host.
return results.length > 0 ? results[0] : host;
} catch {
Expand All @@ -185,7 +185,7 @@ export async function performGSSAPICanonicalizeHostName(
export async function resolveCname(host: string): Promise<string> {
// Attempt to resolve the host name
try {
const results = await dns.promises.resolveCname(host);
const results = await dns.promises.resolve(host, 'CNAME');
// Get the first resolved host id
return results.length > 0 ? results[0] : host;
} catch {
Expand Down
14 changes: 7 additions & 7 deletions src/connection_string.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,26 +41,26 @@ const LB_REPLICA_SET_ERROR = 'loadBalanced option not supported with a replicaSe
const LB_DIRECT_CONNECTION_ERROR =
'loadBalanced option not supported when directConnection is provided';

function retryDNSTimeoutFor(api: 'resolveSrv'): (a: string) => Promise<dns.SrvRecord[]>;
function retryDNSTimeoutFor(api: 'resolveTxt'): (a: string) => Promise<string[][]>;
function retryDNSTimeoutFor(api: 'SRV'): (a: string) => Promise<dns.SrvRecord[]>;
function retryDNSTimeoutFor(api: 'TXT'): (a: string) => Promise<string[][]>;
function retryDNSTimeoutFor(
api: 'resolveSrv' | 'resolveTxt'
api: 'SRV' | 'TXT'
): (a: string) => Promise<dns.SrvRecord[] | string[][]> {
return async function dnsReqRetryTimeout(lookupAddress: string) {
try {
return await dns.promises[api](lookupAddress);
return (await dns.promises.resolve(lookupAddress, api)) as dns.SrvRecord[] | string[][];
} catch (firstDNSError) {
if (firstDNSError.code === dns.TIMEOUT) {
return await dns.promises[api](lookupAddress);
return (await dns.promises.resolve(lookupAddress, api)) as dns.SrvRecord[] | string[][];
} else {
throw firstDNSError;
}
}
};
}

const resolveSrv = retryDNSTimeoutFor('resolveSrv');
const resolveTxt = retryDNSTimeoutFor('resolveTxt');
const resolveSrv = retryDNSTimeoutFor('SRV');
const resolveTxt = retryDNSTimeoutFor('TXT');

/**
* Lookup a `mongodb+srv` connection string, combine the parts and reparse it as a normal
Expand Down
2 changes: 1 addition & 1 deletion src/sdam/srv_polling.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ export class SrvPoller extends TypedEventEmitter<SrvPollerEvents> {
let srvRecords;

try {
srvRecords = await dns.promises.resolveSrv(this.srvAddress);
srvRecords = await dns.promises.resolve(this.srvAddress, 'SRV');
} catch {
this.failure();
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,21 +31,19 @@ describe('DNS timeout errors', () => {
await client.close();
});

const restoreDNS =
api =>
async (...args) => {
sinon.restore();
return await dns.promises[api](...args);
};
const restoreDNS = api => async args => {
sinon.restore();
return await dns.promises.resolve(args, api);
};

describe('when SRV record look up times out', () => {
beforeEach(() => {
stub = sinon
.stub(dns.promises, 'resolveSrv')
.stub(dns.promises, 'resolve')
.onFirstCall()
.rejects(new DNSTimeoutError())
.onSecondCall()
.callsFake(restoreDNS('resolveSrv'));
.callsFake(restoreDNS('SRV'));
});

afterEach(async function () {
Expand All @@ -61,11 +59,11 @@ describe('DNS timeout errors', () => {
describe('when TXT record look up times out', () => {
beforeEach(() => {
stub = sinon
.stub(dns.promises, 'resolveTxt')
.stub(dns.promises, 'resolve')
.onFirstCall()
.rejects(new DNSTimeoutError())
.onSecondCall()
.callsFake(restoreDNS('resolveTxt'));
.callsFake(restoreDNS('TXT'));
});

afterEach(async function () {
Expand All @@ -81,7 +79,7 @@ describe('DNS timeout errors', () => {
describe('when SRV record look up times out twice', () => {
beforeEach(() => {
stub = sinon
.stub(dns.promises, 'resolveSrv')
.stub(dns.promises, 'resolve')
.onFirstCall()
.rejects(new DNSTimeoutError())
.onSecondCall()
Expand All @@ -102,7 +100,7 @@ describe('DNS timeout errors', () => {
describe('when TXT record look up times out twice', () => {
beforeEach(() => {
stub = sinon
.stub(dns.promises, 'resolveTxt')
.stub(dns.promises, 'resolve')
.onFirstCall()
.rejects(new DNSTimeoutError())
.onSecondCall()
Expand All @@ -123,11 +121,11 @@ describe('DNS timeout errors', () => {
describe('when SRV record look up throws a non-timeout error', () => {
beforeEach(() => {
stub = sinon
.stub(dns.promises, 'resolveSrv')
.stub(dns.promises, 'resolve')
.onFirstCall()
.rejects(new DNSSomethingError())
.onSecondCall()
.callsFake(restoreDNS('resolveSrv'));
.callsFake(restoreDNS('SRV'));
});

afterEach(async function () {
Expand All @@ -144,11 +142,11 @@ describe('DNS timeout errors', () => {
describe('when TXT record look up throws a non-timeout error', () => {
beforeEach(() => {
stub = sinon
.stub(dns.promises, 'resolveTxt')
.stub(dns.promises, 'resolve')
.onFirstCall()
.rejects(new DNSSomethingError())
.onSecondCall()
.callsFake(restoreDNS('resolveTxt'));
.callsFake(restoreDNS('TXT'));
});

afterEach(async function () {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ describe('Initial DNS Seedlist Discovery (Prose Tests)', () => {
beforeEach(async function () {
// this fn stubs DNS resolution to always pass - so we are only checking pre-DNS validation

sinon.stub(dns.promises, 'resolveSrv').callsFake(async () => {
const stub = sinon.stub(dns.promises, 'resolve');
stub.withArgs(sinon.match.any, 'SRV').callsFake(async () => {
return [
{
name: 'resolved.mongo.localhost',
Expand All @@ -34,7 +35,7 @@ describe('Initial DNS Seedlist Discovery (Prose Tests)', () => {
];
});

sinon.stub(dns.promises, 'resolveTxt').callsFake(async () => {
stub.withArgs(sinon.match.any, 'TXT').callsFake(async () => {
throw { code: 'ENODATA' };
});

Expand Down Expand Up @@ -84,9 +85,11 @@ describe('Initial DNS Seedlist Discovery (Prose Tests)', () => {
* - the SRV mongodb+srv://blogs.mongodb.com resolving to blogs.evil.com
* Remember, the domain of an SRV with one or two . separated parts is the SRVs entire hostname.
*/
let stub;

beforeEach(async function () {
sinon.stub(dns.promises, 'resolveTxt').callsFake(async () => {
stub = sinon.stub(dns.promises, 'resolve');
stub.withArgs(sinon.match.any, 'TXT').callsFake(async () => {
throw { code: 'ENODATA' };
});
});
Expand All @@ -96,7 +99,7 @@ describe('Initial DNS Seedlist Discovery (Prose Tests)', () => {
});

it('an SRV with one domain level causes a runtime error', async function () {
sinon.stub(dns.promises, 'resolveSrv').callsFake(async () => {
stub.withArgs(sinon.match.any, 'SRV').callsFake(async () => {
return [
{
name: 'localhost.mongodb',
Expand All @@ -115,7 +118,7 @@ describe('Initial DNS Seedlist Discovery (Prose Tests)', () => {
});

it('an SRV with two domain levels causes a runtime error', async function () {
sinon.stub(dns.promises, 'resolveSrv').callsFake(async () => {
stub.withArgs(sinon.match.any, 'SRV').callsFake(async () => {
return [
{
name: 'test_1.evil.local', // this string only ends with part of the domain, not all of it!
Expand All @@ -134,7 +137,7 @@ describe('Initial DNS Seedlist Discovery (Prose Tests)', () => {
});

it('an SRV with three or more domain levels causes a runtime error', async function () {
sinon.stub(dns.promises, 'resolveSrv').callsFake(async () => {
stub.withArgs(sinon.match.any, 'SRV').callsFake(async () => {
return [
{
name: 'blogs.evil.com',
Expand Down Expand Up @@ -166,8 +169,11 @@ describe('Initial DNS Seedlist Discovery (Prose Tests)', () => {
context(
'when given a host from DNS resolution that is identical to the original SRVs hostname',
function () {
let stub;

beforeEach(async function () {
sinon.stub(dns.promises, 'resolveTxt').callsFake(async () => {
stub = sinon.stub(dns.promises, 'resolve');
stub.withArgs(sinon.match.any, 'TXT').callsFake(async () => {
throw { code: 'ENODATA' };
});
});
Expand All @@ -177,7 +183,7 @@ describe('Initial DNS Seedlist Discovery (Prose Tests)', () => {
});

it('an SRV with one domain level causes a runtime error', async function () {
sinon.stub(dns.promises, 'resolveSrv').callsFake(async () => {
stub.withArgs(sinon.match.any, 'SRV').callsFake(async () => {
return [
{
name: 'localhost',
Expand All @@ -198,7 +204,7 @@ describe('Initial DNS Seedlist Discovery (Prose Tests)', () => {
});

it('an SRV with two domain levels causes a runtime error', async function () {
sinon.stub(dns.promises, 'resolveSrv').callsFake(async () => {
stub.withArgs(sinon.match.any, 'SRV').callsFake(async () => {
return [
{
name: 'mongo.local',
Expand Down Expand Up @@ -233,8 +239,11 @@ describe('Initial DNS Seedlist Discovery (Prose Tests)', () => {
context(
'when given a returned address that does NOT share the domain name of the SRV record because its missing a `.`',
function () {
let stub;

beforeEach(async function () {
sinon.stub(dns.promises, 'resolveTxt').callsFake(async () => {
stub = sinon.stub(dns.promises, 'resolve');
stub.withArgs(sinon.match.any, 'TXT').callsFake(async () => {
throw { code: 'ENODATA' };
});
});
Expand All @@ -244,7 +253,7 @@ describe('Initial DNS Seedlist Discovery (Prose Tests)', () => {
});

it('an SRV with one domain level causes a runtime error', async function () {
sinon.stub(dns.promises, 'resolveSrv').callsFake(async () => {
stub.withArgs(sinon.match.any, 'SRV').callsFake(async () => {
return [
{
name: 'test_1.cluster_1localhost',
Expand All @@ -263,7 +272,7 @@ describe('Initial DNS Seedlist Discovery (Prose Tests)', () => {
});

it('an SRV with two domain levels causes a runtime error', async function () {
sinon.stub(dns.promises, 'resolveSrv').callsFake(async () => {
stub.withArgs(sinon.match.any, 'SRV').callsFake(async () => {
return [
{
name: 'test_1.my_hostmongo.local',
Expand All @@ -282,7 +291,7 @@ describe('Initial DNS Seedlist Discovery (Prose Tests)', () => {
});

it('an SRV with three domain levels causes a runtime error', async function () {
sinon.stub(dns.promises, 'resolveSrv').callsFake(async () => {
stub.withArgs(sinon.match.any, 'SRV').callsFake(async () => {
return [
{
name: 'cluster.testmongodb.com',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@ describe('Polling Srv Records for Mongos Discovery', () => {
initialRecords ??= mockRecords;
// first call is for the driver initial connection
// second call will check the poller
resolveSrvStub = sinon.stub(dns.promises, 'resolveSrv').callsFake(async address => {
resolveSrvStub = sinon.stub(dns.promises, 'resolve').callsFake(async address => {
expect(address).to.equal(`_${srvServiceName}._tcp.test.mock.test.build.10gen.cc`);
if (initialDNSLookup) {
initialDNSLookup = false;
Expand Down
Loading