Fallback to dns.resolve4/6 on getaddrinfo failure
This commit is contained in:
parent
e4623e2ad5
commit
7e05893e1a
4 changed files with 68 additions and 0 deletions
62
ts/util/dns.ts
Normal file
62
ts/util/dns.ts
Normal file
|
@ -0,0 +1,62 @@
|
|||
// Copyright 2023 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import { lookup as nativeLookup, resolve4, resolve6 } from 'dns';
|
||||
import type { LookupOneOptions } from 'dns';
|
||||
|
||||
import * as log from '../logging/log';
|
||||
import * as Errors from '../types/errors';
|
||||
import { strictAssert } from './assert';
|
||||
|
||||
export function lookupWithFallback(
|
||||
hostname: string,
|
||||
opts: LookupOneOptions,
|
||||
callback: (
|
||||
err: NodeJS.ErrnoException | null,
|
||||
address: string,
|
||||
family: number
|
||||
) => void
|
||||
): void {
|
||||
// Node.js support various signatures, but we only support one.
|
||||
strictAssert(typeof opts === 'object', 'missing options');
|
||||
strictAssert(Boolean(opts.all) !== true, 'options.all is not supported');
|
||||
strictAssert(typeof callback === 'function', 'missing callback');
|
||||
|
||||
nativeLookup(hostname, opts, (err, ...nativeArgs) => {
|
||||
if (!err) {
|
||||
return callback(err, ...nativeArgs);
|
||||
}
|
||||
|
||||
const family = opts.family === 6 ? 6 : 4;
|
||||
|
||||
log.error(
|
||||
`lookup: failed for ${hostname}, error: ${Errors.toLogFormat(err)}. ` +
|
||||
`Retrying with c-ares (IPv${family})`
|
||||
);
|
||||
const onRecords = (
|
||||
fallbackErr: NodeJS.ErrnoException | null,
|
||||
records: Array<string>
|
||||
): void => {
|
||||
if (fallbackErr) {
|
||||
return callback(fallbackErr, '', 0);
|
||||
}
|
||||
|
||||
if (!Array.isArray(records) || records.length === 0) {
|
||||
return callback(
|
||||
new Error(`No DNS records returned for: ${hostname}`),
|
||||
'',
|
||||
0
|
||||
);
|
||||
}
|
||||
|
||||
const index = Math.floor(Math.random() * records.length);
|
||||
callback(null, records[index], family);
|
||||
};
|
||||
|
||||
if (family === 4) {
|
||||
resolve4(hostname, onRecords);
|
||||
} else {
|
||||
resolve6(hostname, onRecords);
|
||||
}
|
||||
});
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue