import os from 'os'; import * as nodeIp from 'ip'; export const SCRYPTED_INSECURE_PORT = parseInt(process.env.SCRYPTED_INSECURE_PORT) || 11080; export const SCRYPTED_SECURE_PORT = parseInt(process.env.SCRYPTED_SECURE_PORT) || 10443; export const SCRYPTED_DEBUG_PORT = parseInt(process.env.SCRYPTED_DEBUG_PORT) || 10081; export function getIpAddress(): string { return nodeIp.address(); } function normalizeFamilyNodeV18(family: string|number) { if (family === 'IPv4') return 4; if (family === 'IPv6') return 6; return family; } function nodeIpAddress(family: number): string[] { // https://chromium.googlesource.com/external/webrtc/+/master/rtc_base/network.cc#236 const costlyNetworks = ["ipsec", "tun", "utun", "tap"]; const ignoreNetworks = [ // seen these on macos 'llw', 'awdl', ...costlyNetworks, ]; const interfaces = os.networkInterfaces(); const all = Object.keys(interfaces) .map((nic) => { for (const costly of ignoreNetworks) { if (nic.startsWith(costly)) { return { nic, addresses: [], }; } } const addresses = interfaces[nic]!.filter( (details) => normalizeFamilyNodeV18(details.family) === family && !nodeIp.isLoopback(details.address) ); return { nic, addresses: addresses.map((address) => address.address), }; }) .filter((address) => !!address); // os.networkInterfaces doesn't actually return addresses in a good order. // have seen instances where en0 (ethernet) is after en1 (wlan), etc. // eth0 > eth1 all.sort((a, b) => a.nic.localeCompare(b.nic)); return Object.values(all) .map((entry) => entry.addresses) .flat(); } export function getHostAddresses(useIpv4: boolean, useIpv6: boolean) { const address: string[] = []; if (useIpv4) address.push(...nodeIpAddress(4)); if (useIpv6) address.push(...nodeIpAddress(6)); return address; }