feedback7 G-TOOLS: listen on :: by default so one socket serves IPv6 and IPv4 (PR #291 by @LimitlessHPPK)
Ported only the dual-stack listen from PR #291 (the change accepted as #188). With HOST unset the server binds :: and, if that fails with EAFNOSUPPORT, EADDRNOTAVAIL or EINVAL, retries 0.0.0.0. An explicit HOST, including 0.0.0.0 and 127.0.0.1, is tried once. The boot banner and doctor list shareable IPv6 addresses in brackets, skip fe80::, and keep one URL per /64. An explicit IPv6 literal in the local URL is bracketed. The Windows service listing no longer drops those bracketed lines. Not ported: /dev/grant, the settings-default migration, and the firewall scripts. The Docker image stays on 0.0.0.0; the alpine fallback was not booted. Tests: node --test test/ipv6-bind.test.js test/doctor.test.js test/ci.test.js — 20 pass, 0 fail (8 bind, 4 doctor, 8 ci).
This commit is contained in:
1 parent
c36320fe4a
commit
51c53de189
11 files changed
+374
-54
No files matched your search
+29
-4
@@ -14,18 +14,43 @@ import fs from 'node:fs';
|
||||
import os from 'node:os';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import { APP_VERSION, DEV_BUILD } from '../../shared/constants.js';
|
||||
import { limitKeyOf } from '../net.js';
|
||||
import { applyPendingUpdate } from '../update.js';
|
||||
import { ROOT } from './config.js';
|
||||
|
||||
/** Non-internal IPv4 addresses as http URLs. @param {number} port */
|
||||
/**
|
||||
* Non-internal addresses as http URLs — IPv4 first, then IPv6 (an IPv6 literal needs brackets: `http://[240e:…]:3000`).
|
||||
* Link-local (`fe80::`) is left out: a URL cannot carry the zone id. Several privacy addresses in one /64 collapse
|
||||
* to one URL (`limitKeyOf`).
|
||||
* @param {number} port
|
||||
*/
|
||||
export function lanUrls(port) {
|
||||
const out = [];
|
||||
const v4 = [];
|
||||
const v6 = [];
|
||||
const v6Seen = new Set();
|
||||
for (const addrs of Object.values(os.networkInterfaces())) {
|
||||
for (const a of addrs || []) {
|
||||
if ((a.family === 'IPv4' || a.family === 4) && !a.internal) out.push(`http://${a.address}:${port}`);
|
||||
if (a.internal) continue;
|
||||
if (a.family === 'IPv4' || a.family === 4) { v4.push(`http://${a.address}:${port}`); continue; }
|
||||
if (a.family !== 'IPv6' && a.family !== 6) continue;
|
||||
if (/^fe80:/i.test(a.address)) continue;
|
||||
const prefix = limitKeyOf(a.address);
|
||||
if (v6Seen.has(prefix)) continue;
|
||||
v6Seen.add(prefix);
|
||||
v6.push(`http://[${a.address}]:${port}`);
|
||||
}
|
||||
}
|
||||
return out;
|
||||
return [...v4, ...v6];
|
||||
}
|
||||
|
||||
/**
|
||||
* The host as it appears in the local URL. A wildcard bind (`0.0.0.0` or `::`) reads `localhost`. An IPv6 literal
|
||||
* is bracketed (`http://[2001:db8::1]:3000`); an IPv4 address or a name is kept.
|
||||
* @param {string} host
|
||||
*/
|
||||
export function displayHost(host) {
|
||||
if (host === '0.0.0.0' || host === '::') return 'localhost';
|
||||
return host.includes(':') ? `[${host}]` : host;
|
||||
}
|
||||
|
||||
/** Is the module whose `import.meta.url` is `metaUrl` the file node was started with? */
|
||||
|
||||
Reference in new issue
Block a user