Skip to content

Commit e4925f3

Browse files
authored
fix: filter out duplicate dns results MONGOSH-2027 (#209)
1 parent 12992e7 commit e4925f3

File tree

2 files changed

+79
-8
lines changed

2 files changed

+79
-8
lines changed

src/rfc-8252-http-server.spec.ts

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { RFC8252HTTPServer } from './rfc-8252-http-server';
1+
import { getAllInterfaces, RFC8252HTTPServer } from './rfc-8252-http-server';
22
import { expect } from 'chai';
33
import type { Server as HTTPServer } from 'http';
44
import { createServer as createHTTPServer } from 'http';
@@ -485,4 +485,58 @@ describe('RFC8252HTTPServer', function () {
485485
});
486486
});
487487
});
488+
489+
context('getAllInterfaces', function () {
490+
let dnsLookupStub: sinon.SinonStub;
491+
this.beforeEach(function () {
492+
dnsLookupStub = sinon.stub();
493+
});
494+
495+
it('filters out exact duplicates', async function () {
496+
dnsLookupStub.resolves([
497+
{ address: '127.0.0.1', family: 4 },
498+
{ address: '127.0.0.1', family: 4 },
499+
{ address: '[::1]', family: 6 },
500+
{ address: '[::1]', family: 6 },
501+
]);
502+
503+
const interfaces = await getAllInterfaces('localhost', dnsLookupStub);
504+
505+
expect(interfaces).to.have.lengthOf(2);
506+
expect(interfaces[0].address).to.equal('127.0.0.1');
507+
expect(interfaces[1].address).to.equal('[::1]');
508+
expect(interfaces[0].family).to.equal(4);
509+
expect(interfaces[1].family).to.equal(6);
510+
});
511+
512+
it('keeps same addresses, different family', async function () {
513+
dnsLookupStub.resolves([
514+
{ address: '127.0.0.1', family: 4 },
515+
{ address: '127.0.0.1', family: 6 },
516+
]);
517+
518+
const interfaces = await getAllInterfaces('localhost', dnsLookupStub);
519+
520+
expect(interfaces).to.have.lengthOf(2);
521+
expect(interfaces[0].address).to.equal('127.0.0.1');
522+
expect(interfaces[1].address).to.equal('127.0.0.1');
523+
expect(interfaces[0].family).to.equal(4);
524+
expect(interfaces[1].family).to.equal(6);
525+
});
526+
527+
it('keeps same familes, different address', async function () {
528+
dnsLookupStub.resolves([
529+
{ address: '127.0.0.1', family: 4 },
530+
{ address: '192.168.1.15', family: 4 },
531+
]);
532+
533+
const interfaces = await getAllInterfaces('localhost', dnsLookupStub);
534+
535+
expect(interfaces).to.have.lengthOf(2);
536+
expect(interfaces[0].address).to.equal('127.0.0.1');
537+
expect(interfaces[1].address).to.equal('192.168.1.15');
538+
expect(interfaces[0].family).to.equal(4);
539+
expect(interfaces[1].family).to.equal(4);
540+
});
541+
});
488542
});

src/rfc-8252-http-server.ts

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,26 @@ export interface RFC8252HTTPServerOptions {
2929
redirectServerRequestHandler?: RedirectServerRequestHandler;
3030
}
3131

32+
export async function getAllInterfaces(
33+
hostname: string,
34+
lookup: typeof dns.lookup = dns.lookup
35+
): Promise<{ address: string; family: number }[]> {
36+
const dnsResults = await lookup(hostname, {
37+
all: true,
38+
hints: ADDRCONFIG,
39+
});
40+
41+
return dnsResults
42+
.filter(
43+
(dns, index, arr) =>
44+
arr.findIndex(
45+
(otherDns) =>
46+
dns.address === otherDns.address && dns.family === otherDns.family
47+
) === index
48+
)
49+
.map(({ address, family }) => ({ address, family }));
50+
}
51+
3252
/** @internal */
3353
export class RFC8252HTTPServer {
3454
private readonly redirectUrl: URL;
@@ -368,14 +388,11 @@ export class RFC8252HTTPServer {
368388
// to do what Node.js does by default when only a host is provided,
369389
// namely listening on all interfaces.
370390
let hostname = this.redirectUrl.hostname;
371-
if (hostname.startsWith('[') && hostname.endsWith(']'))
391+
if (hostname.startsWith('[') && hostname.endsWith(']')) {
372392
hostname = hostname.slice(1, -1);
373-
const dnsResults = (
374-
await dns.lookup(hostname, {
375-
all: true,
376-
hints: ADDRCONFIG,
377-
})
378-
).map(({ address, family }) => ({ address, family }));
393+
}
394+
395+
const dnsResults = await getAllInterfaces(hostname);
379396

380397
this.logger.emit('mongodb-oidc-plugin:local-listen-resolved-hostname', {
381398
url: this.redirectUrl.toString(),

0 commit comments

Comments
 (0)