Resolve fallback dns addrs during build
This commit is contained in:
parent
f5787ba1bc
commit
e3dbcc1e0f
10 changed files with 151 additions and 34 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -3,6 +3,7 @@ node_modules_bkp
|
|||
.sass-cache
|
||||
coverage/*
|
||||
build/curve25519_compiled.js
|
||||
build/dns-fallback.json
|
||||
stylesheets/*.css.map
|
||||
/dist
|
||||
.DS_Store
|
||||
|
|
33
app/dns-fallback.ts
Normal file
33
app/dns-fallback.ts
Normal file
|
@ -0,0 +1,33 @@
|
|||
// Copyright 2024 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import { join } from 'path';
|
||||
import { readFile } from 'fs/promises';
|
||||
import { DNSFallbackSchema } from '../ts/types/DNSFallback';
|
||||
import type { DNSFallbackType } from '../ts/types/DNSFallback';
|
||||
|
||||
let cached: DNSFallbackType | undefined;
|
||||
|
||||
export async function getDNSFallback(): Promise<DNSFallbackType> {
|
||||
if (cached != null) {
|
||||
return cached;
|
||||
}
|
||||
|
||||
const configPath = join(__dirname, '..', 'build', 'dns-fallback.json');
|
||||
let str: string;
|
||||
try {
|
||||
str = await readFile(configPath, 'utf8');
|
||||
} catch (error) {
|
||||
console.error(
|
||||
'Warning: build/dns-fallback.json not build, run `yarn generate`'
|
||||
);
|
||||
cached = [];
|
||||
return cached;
|
||||
}
|
||||
|
||||
const json = JSON.parse(str);
|
||||
|
||||
const result = DNSFallbackSchema.parse(json);
|
||||
cached = result;
|
||||
return result;
|
||||
}
|
13
app/main.ts
13
app/main.ts
|
@ -36,6 +36,7 @@ import packageJson from '../package.json';
|
|||
import * as GlobalErrors from './global_errors';
|
||||
import { setup as setupCrashReports } from './crashReports';
|
||||
import { setup as setupSpellChecker } from './spell_check';
|
||||
import { getDNSFallback } from './dns-fallback';
|
||||
import { redactAll, addSensitivePath } from '../ts/util/privacy';
|
||||
import { createSupportUrl } from '../ts/util/createSupportUrl';
|
||||
import { missingCaseError } from '../ts/util/missingCaseError';
|
||||
|
@ -52,7 +53,6 @@ import { explodePromise } from '../ts/util/explodePromise';
|
|||
|
||||
import './startup_config';
|
||||
|
||||
import type { ConfigType } from './config';
|
||||
import type { RendererConfigType } from '../ts/types/RendererConfig';
|
||||
import {
|
||||
directoryConfigSchema,
|
||||
|
@ -112,6 +112,7 @@ import { HourCyclePreference } from '../ts/types/I18N';
|
|||
import { DBVersionFromFutureError } from '../ts/sql/migrations';
|
||||
import type { ParsedSignalRoute } from '../ts/util/signalRoutes';
|
||||
import { parseSignalRoute } from '../ts/util/signalRoutes';
|
||||
import * as dns from '../ts/util/dns';
|
||||
import { ZoomFactorService } from '../ts/services/ZoomFactorService';
|
||||
|
||||
const STICKER_CREATOR_PARTITION = 'sticker-creator';
|
||||
|
@ -1734,6 +1735,8 @@ if (DISABLE_GPU) {
|
|||
// Some APIs can only be used after this event occurs.
|
||||
let ready = false;
|
||||
app.on('ready', async () => {
|
||||
dns.setFallback(await getDNSFallback());
|
||||
|
||||
const [userDataPath, crashDumpsPath, installPath] = await Promise.all([
|
||||
realpath(app.getPath('userData')),
|
||||
realpath(app.getPath('crashDumps')),
|
||||
|
@ -2449,15 +2452,17 @@ ipc.on('get-config', async event => {
|
|||
updatesUrl: config.get<string>('updatesUrl'),
|
||||
resourcesUrl: config.get<string>('resourcesUrl'),
|
||||
artCreatorUrl: config.get<string>('artCreatorUrl'),
|
||||
cdnUrl0: config.get<ConfigType>('cdn').get<string>('0'),
|
||||
cdnUrl2: config.get<ConfigType>('cdn').get<string>('2'),
|
||||
cdnUrl3: config.get<ConfigType>('cdn').get<string>('3'),
|
||||
cdnUrl0: config.get<string>('cdn.0'),
|
||||
cdnUrl2: config.get<string>('cdn.2'),
|
||||
cdnUrl3: config.get<string>('cdn.3'),
|
||||
certificateAuthority: config.get<string>('certificateAuthority'),
|
||||
environment:
|
||||
!isTestEnvironment(getEnvironment()) && ciMode
|
||||
? Environment.Production
|
||||
: getEnvironment(),
|
||||
ciMode,
|
||||
// Should be already computed and cached at this point
|
||||
dnsFallback: await getDNSFallback(),
|
||||
nodeVersion: process.versions.node,
|
||||
hostname: os.hostname(),
|
||||
osRelease: os.release(),
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
"postinstall": "yarn build:acknowledgments && patch-package && yarn electron:install-app-deps",
|
||||
"postuninstall": "yarn build:acknowledgments",
|
||||
"start": "electron .",
|
||||
"generate": "npm-run-all build-protobuf build:esbuild sass get-expire-time copy-components",
|
||||
"generate": "npm-run-all build-protobuf build:esbuild build:dns-fallback sass get-expire-time copy-components",
|
||||
"build-release": "yarn run build",
|
||||
"sign-release": "node ts/updater/generateSignature.js",
|
||||
"notarize": "echo 'No longer necessary'",
|
||||
|
@ -75,6 +75,7 @@
|
|||
"build": "run-s --print-label generate build:esbuild:prod build:release",
|
||||
"build-linux": "yarn generate && yarn build:esbuild:prod && yarn build:release -- --publish=never",
|
||||
"build:acknowledgments": "node scripts/generate-acknowledgments.js",
|
||||
"build:dns-fallback": "node ts/scripts/generate-dns-fallback.js",
|
||||
"build:dev": "run-s --print-label generate build:esbuild:prod",
|
||||
"build:esbuild": "node scripts/esbuild.js",
|
||||
"build:esbuild:prod": "node scripts/esbuild.js --prod",
|
||||
|
@ -501,6 +502,7 @@
|
|||
"build/available-locales.json",
|
||||
"build/locale-display-names.json",
|
||||
"build/country-display-names.json",
|
||||
"build/dns-fallback.json",
|
||||
"node_modules/**",
|
||||
"!node_modules/underscore/**",
|
||||
"!node_modules/emoji-datasource/emoji_pretty.json",
|
||||
|
|
71
ts/scripts/generate-dns-fallback.ts
Normal file
71
ts/scripts/generate-dns-fallback.ts
Normal file
|
@ -0,0 +1,71 @@
|
|||
// Copyright 2024 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import { join } from 'path';
|
||||
import { lookup as lookupCb } from 'dns';
|
||||
import { writeFile } from 'fs/promises';
|
||||
import { promisify } from 'util';
|
||||
import type { ResolvedEndpoint } from 'electron';
|
||||
|
||||
import { isNotNil } from '../util/isNotNil';
|
||||
|
||||
const lookup = promisify(lookupCb);
|
||||
|
||||
const FALLBACK_DOMAINS = [
|
||||
'chat.signal.org',
|
||||
'storage.signal.org',
|
||||
'cdsi.signal.org',
|
||||
'cdn.signal.org',
|
||||
'cdn2.signal.org',
|
||||
'cdn3.signal.org',
|
||||
'updates2.signal.org',
|
||||
'sfu.voip.signal.org',
|
||||
'create.signal.art',
|
||||
];
|
||||
|
||||
async function main() {
|
||||
const config = await Promise.all(
|
||||
FALLBACK_DOMAINS.sort().map(async domain => {
|
||||
const addresses = await lookup(domain, { all: true });
|
||||
|
||||
const endpoints = addresses
|
||||
.map(({ address, family }): ResolvedEndpoint | null => {
|
||||
if (family === 4) {
|
||||
return { family: 'ipv4', address };
|
||||
}
|
||||
if (family === 6) {
|
||||
return { family: 'ipv6', address };
|
||||
}
|
||||
return null;
|
||||
})
|
||||
.filter(isNotNil)
|
||||
.sort((a, b) => {
|
||||
if (a.family < b.family) {
|
||||
return -1;
|
||||
}
|
||||
if (a.family > b.family) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (a.address < b.address) {
|
||||
return -1;
|
||||
}
|
||||
if (a.address > b.address) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
|
||||
return { domain, endpoints };
|
||||
})
|
||||
);
|
||||
|
||||
const outPath = join(__dirname, '../../build/dns-fallback.json');
|
||||
|
||||
await writeFile(outPath, `${JSON.stringify(config, null, 2)}\n`);
|
||||
}
|
||||
|
||||
main().catch(error => {
|
||||
console.error(error);
|
||||
process.exit(1);
|
||||
});
|
18
ts/types/DNSFallback.ts
Normal file
18
ts/types/DNSFallback.ts
Normal file
|
@ -0,0 +1,18 @@
|
|||
// Copyright 2024 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import z from 'zod';
|
||||
|
||||
export const DNSFallbackSchema = z.array(
|
||||
z.object({
|
||||
domain: z.string(),
|
||||
endpoints: z.array(
|
||||
z.object({
|
||||
family: z.enum(['ipv4', 'ipv6']),
|
||||
address: z.string(),
|
||||
})
|
||||
),
|
||||
})
|
||||
);
|
||||
|
||||
export type DNSFallbackType = z.infer<typeof DNSFallbackSchema>;
|
|
@ -6,6 +6,7 @@ import { z } from 'zod';
|
|||
import { Environment } from '../environment';
|
||||
import { themeSettingSchema } from './StorageUIKeys';
|
||||
import { HourCyclePreferenceSchema } from './I18N';
|
||||
import { DNSFallbackSchema } from './DNSFallback';
|
||||
|
||||
const environmentSchema = z.nativeEnum(Environment);
|
||||
|
||||
|
@ -40,6 +41,7 @@ export const rendererConfigSchema = z.object({
|
|||
contentProxyUrl: configRequiredStringSchema,
|
||||
crashDumpsPath: configRequiredStringSchema,
|
||||
ciMode: z.enum(['full', 'benchmark']).or(z.literal(false)),
|
||||
dnsFallback: DNSFallbackSchema,
|
||||
environment: environmentSchema,
|
||||
homePath: configRequiredStringSchema,
|
||||
hostname: configRequiredStringSchema,
|
||||
|
|
|
@ -40,6 +40,7 @@ const HOST_LOG_ALLOWLIST = new Set([
|
|||
'cdsi.signal.org',
|
||||
'cdn.signal.org',
|
||||
'cdn2.signal.org',
|
||||
'cdn3.signal.org',
|
||||
'create.signal.art',
|
||||
|
||||
// Staging
|
||||
|
|
|
@ -12,35 +12,16 @@ import type { ResolvedHost, ResolvedEndpoint } from 'electron';
|
|||
|
||||
import { strictAssert } from './assert';
|
||||
import { drop } from './drop';
|
||||
import type { DNSFallbackType } from '../types/DNSFallback';
|
||||
|
||||
const FALLBACK_ADDRS: ReadonlyMap<
|
||||
string,
|
||||
ReadonlyArray<ResolvedEndpoint>
|
||||
> = new Map([
|
||||
[
|
||||
'cdsi.signal.org',
|
||||
[
|
||||
{ family: 'ipv4', address: '40.122.45.194' },
|
||||
{ family: 'ipv6', address: '2603:1030:7::1' },
|
||||
],
|
||||
],
|
||||
[
|
||||
'chat.signal.org',
|
||||
[
|
||||
{ family: 'ipv4', address: '13.248.212.111' },
|
||||
{ family: 'ipv4', address: '76.223.92.165' },
|
||||
{ family: 'ipv6', address: '2600:9000:a507:ab6d:4ce3:2f58:25d7:9cbf' },
|
||||
{ family: 'ipv6', address: '2600:9000:a61f:527c:d5eb:a431:5239:3232' },
|
||||
],
|
||||
],
|
||||
[
|
||||
'sfu.voip.signal.org',
|
||||
[
|
||||
{ family: 'ipv4', address: '34.49.5.136' },
|
||||
{ family: 'ipv6', address: '2600:1901:0:9c39::' },
|
||||
],
|
||||
],
|
||||
]);
|
||||
const fallbackAddrs = new Map<string, ReadonlyArray<ResolvedEndpoint>>();
|
||||
|
||||
export function setFallback(dnsFallback: DNSFallbackType): void {
|
||||
fallbackAddrs.clear();
|
||||
for (const { domain, endpoints } of dnsFallback) {
|
||||
fallbackAddrs.set(domain, endpoints);
|
||||
}
|
||||
}
|
||||
|
||||
function lookupAll(
|
||||
hostname: string,
|
||||
|
@ -80,7 +61,7 @@ function lookupAll(
|
|||
);
|
||||
}
|
||||
} catch (error) {
|
||||
const fallback = FALLBACK_ADDRS.get(hostname);
|
||||
const fallback = fallbackAddrs.get(hostname);
|
||||
if (fallback) {
|
||||
result = { endpoints: fallback.slice() };
|
||||
} else {
|
||||
|
|
|
@ -12,6 +12,7 @@ import { textsecure } from '../../textsecure';
|
|||
import * as Attachments from '../attachments';
|
||||
import { setup } from '../../signal';
|
||||
import { addSensitivePath } from '../../util/privacy';
|
||||
import * as dns from '../../util/dns';
|
||||
import * as log from '../../logging/log';
|
||||
import { SignalContext } from '../context';
|
||||
|
||||
|
@ -72,6 +73,8 @@ if (config.crashDumpsPath) {
|
|||
addSensitivePath(config.crashDumpsPath);
|
||||
}
|
||||
|
||||
dns.setFallback(SignalContext.config.dnsFallback);
|
||||
|
||||
window.Signal = setup({
|
||||
Attachments,
|
||||
getRegionCode: () => window.storage.get('regionCode'),
|
||||
|
|
Loading…
Add table
Reference in a new issue