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
|
@ -28,6 +28,7 @@ import { formatAcceptLanguageHeader } from '../util/userLanguages';
|
||||||
import { toWebSafeBase64, fromWebSafeBase64 } from '../util/webSafeBase64';
|
import { toWebSafeBase64, fromWebSafeBase64 } from '../util/webSafeBase64';
|
||||||
import { getBasicAuth } from '../util/getBasicAuth';
|
import { getBasicAuth } from '../util/getBasicAuth';
|
||||||
import { isPnpEnabled } from '../util/isPnpEnabled';
|
import { isPnpEnabled } from '../util/isPnpEnabled';
|
||||||
|
import { lookupWithFallback } from '../util/dns';
|
||||||
import type { SocketStatus } from '../types/SocketStatus';
|
import type { SocketStatus } from '../types/SocketStatus';
|
||||||
import { toLogFormat } from '../types/errors';
|
import { toLogFormat } from '../types/errors';
|
||||||
import { isPackIdValid, redactPackId } from '../types/Stickers';
|
import { isPackIdValid, redactPackId } from '../types/Stickers';
|
||||||
|
@ -243,6 +244,7 @@ async function _promiseAjax(
|
||||||
agent: proxyUrl
|
agent: proxyUrl
|
||||||
? new ProxyAgent(proxyUrl)
|
? new ProxyAgent(proxyUrl)
|
||||||
: new Agent({
|
: new Agent({
|
||||||
|
lookup: lookupWithFallback,
|
||||||
keepAlive: !options.disableSessionResumption,
|
keepAlive: !options.disableSessionResumption,
|
||||||
maxCachedSessions: options.disableSessionResumption ? 0 : undefined,
|
maxCachedSessions: options.disableSessionResumption ? 0 : undefined,
|
||||||
}),
|
}),
|
||||||
|
|
|
@ -10,6 +10,7 @@ import { strictAssert } from '../util/assert';
|
||||||
import { explodePromise } from '../util/explodePromise';
|
import { explodePromise } from '../util/explodePromise';
|
||||||
import { getUserAgent } from '../util/getUserAgent';
|
import { getUserAgent } from '../util/getUserAgent';
|
||||||
import * as durations from '../util/durations';
|
import * as durations from '../util/durations';
|
||||||
|
import { lookupWithFallback } from '../util/dns';
|
||||||
import * as log from '../logging/log';
|
import * as log from '../logging/log';
|
||||||
import * as Timers from '../Timers';
|
import * as Timers from '../Timers';
|
||||||
import { ConnectTimeoutError, HTTPError } from './Errors';
|
import { ConnectTimeoutError, HTTPError } from './Errors';
|
||||||
|
@ -55,6 +56,7 @@ export function connect<Resource extends IResource>({
|
||||||
tlsOptions: {
|
tlsOptions: {
|
||||||
ca: certificateAuthority,
|
ca: certificateAuthority,
|
||||||
agent: proxyAgent,
|
agent: proxyAgent,
|
||||||
|
lookup: lookupWithFallback,
|
||||||
},
|
},
|
||||||
maxReceivedFrameSize: 0x210000,
|
maxReceivedFrameSize: 0x210000,
|
||||||
});
|
});
|
||||||
|
|
|
@ -8,6 +8,7 @@ import ProxyAgent from 'proxy-agent';
|
||||||
import * as packageJson from '../../package.json';
|
import * as packageJson from '../../package.json';
|
||||||
import { getUserAgent } from '../util/getUserAgent';
|
import { getUserAgent } from '../util/getUserAgent';
|
||||||
import * as durations from '../util/durations';
|
import * as durations from '../util/durations';
|
||||||
|
import { lookupWithFallback } from '../util/dns';
|
||||||
|
|
||||||
export const GOT_CONNECT_TIMEOUT = durations.MINUTE;
|
export const GOT_CONNECT_TIMEOUT = durations.MINUTE;
|
||||||
export const GOT_LOOKUP_TIMEOUT = durations.MINUTE;
|
export const GOT_LOOKUP_TIMEOUT = durations.MINUTE;
|
||||||
|
@ -37,6 +38,7 @@ export function getGotOptions(): GotOptions {
|
||||||
https: {
|
https: {
|
||||||
certificateAuthority,
|
certificateAuthority,
|
||||||
},
|
},
|
||||||
|
lookup: lookupWithFallback as GotOptions['lookup'],
|
||||||
headers: {
|
headers: {
|
||||||
'Cache-Control': 'no-cache',
|
'Cache-Control': 'no-cache',
|
||||||
'User-Agent': getUserAgent(packageJson.version),
|
'User-Agent': getUserAgent(packageJson.version),
|
||||||
|
|
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