mirror of
https://gh.catmak.name/https://github.com/mihomo-party-org/mihomo-party
synced 2025-12-27 05:00:30 +08:00
fix: 修复DNS配置和性能优化,解决运行时配置显示问题 (#1094)
- 修复DNS配置相关问题 - 性能优化改进 - 添加mihomoConfigs() API用于获取实时配置 - 修复config-viewer显示log-level总是info的问题 - 优化核心启动流程,使用API轮询替代日志解析 - 重构配置管理,提升启动稳定性 🤖 Generated with [Claude Code](https://claude.ai/code) Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
parent
d51d6ed0d7
commit
68bbde0d16
@ -44,11 +44,6 @@ export async function generateProfile(): Promise<void> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const profile = deepMerge(currentProfile, controledMihomoConfig)
|
const profile = deepMerge(currentProfile, controledMihomoConfig)
|
||||||
// 确保可以拿到基础日志信息
|
|
||||||
// 使用 debug 可以调试内核相关问题 `debug/pprof`
|
|
||||||
if (['info', 'debug'].includes(profile['log-level']) === false) {
|
|
||||||
profile['log-level'] = 'info'
|
|
||||||
}
|
|
||||||
runtimeConfig = profile
|
runtimeConfig = profile
|
||||||
|
|
||||||
// 先正常生成 YAML 字符串
|
// 先正常生成 YAML 字符串
|
||||||
|
|||||||
@ -7,7 +7,8 @@ import {
|
|||||||
mihomoProfileWorkDir,
|
mihomoProfileWorkDir,
|
||||||
mihomoTestDir,
|
mihomoTestDir,
|
||||||
mihomoWorkConfigPath,
|
mihomoWorkConfigPath,
|
||||||
mihomoWorkDir
|
mihomoWorkDir,
|
||||||
|
mihomoIpcPath
|
||||||
} from '../utils/dirs'
|
} from '../utils/dirs'
|
||||||
import { generateProfile } from './factory'
|
import { generateProfile } from './factory'
|
||||||
import {
|
import {
|
||||||
@ -28,16 +29,14 @@ import {
|
|||||||
stopMihomoTraffic,
|
stopMihomoTraffic,
|
||||||
stopMihomoLogs,
|
stopMihomoLogs,
|
||||||
stopMihomoMemory,
|
stopMihomoMemory,
|
||||||
patchMihomoConfig
|
mihomoVersion
|
||||||
} from './mihomoApi'
|
} from './mihomoApi'
|
||||||
import chokidar from 'chokidar'
|
import chokidar from 'chokidar'
|
||||||
import { readFile, rm, writeFile } from 'fs/promises'
|
import { readFile, rm, writeFile } from 'fs/promises'
|
||||||
import { promisify } from 'util'
|
import { promisify } from 'util'
|
||||||
import { mainWindow } from '..'
|
|
||||||
import path from 'path'
|
import path from 'path'
|
||||||
import os from 'os'
|
import os from 'os'
|
||||||
import { createWriteStream, existsSync } from 'fs'
|
import { createWriteStream, existsSync } from 'fs'
|
||||||
import { uploadRuntimeConfig } from '../resolve/gistApi'
|
|
||||||
import { startMonitor } from '../resolve/trafficMonitor'
|
import { startMonitor } from '../resolve/trafficMonitor'
|
||||||
import { safeShowErrorBox } from '../utils/init'
|
import { safeShowErrorBox } from '../utils/init'
|
||||||
import i18next from '../../shared/i18n'
|
import i18next from '../../shared/i18n'
|
||||||
@ -52,8 +51,6 @@ chokidar.watch(path.join(mihomoCoreDir(), 'meta-update'), {}).on('unlinkDir', as
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
export const mihomoIpcPath =
|
|
||||||
process.platform === 'win32' ? '\\\\.\\pipe\\MihomoParty\\mihomo' : '/tmp/mihomo-party.sock'
|
|
||||||
const ctlParam = process.platform === 'win32' ? '-ext-ctl-pipe' : '-ext-ctl-unix'
|
const ctlParam = process.platform === 'win32' ? '-ext-ctl-pipe' : '-ext-ctl-unix'
|
||||||
|
|
||||||
let setPublicDNSTimer: NodeJS.Timeout | null = null
|
let setPublicDNSTimer: NodeJS.Timeout | null = null
|
||||||
@ -72,7 +69,6 @@ export async function startCore(detached = false): Promise<Promise<void>[]> {
|
|||||||
disableSystemCA = false,
|
disableSystemCA = false,
|
||||||
skipSafePathCheck = false
|
skipSafePathCheck = false
|
||||||
} = await getAppConfig()
|
} = await getAppConfig()
|
||||||
const { 'log-level': logLevel } = await getControledMihomoConfig()
|
|
||||||
if (existsSync(path.join(dataDir(), 'core.pid'))) {
|
if (existsSync(path.join(dataDir(), 'core.pid'))) {
|
||||||
const pid = parseInt(await readFile(path.join(dataDir(), 'core.pid'), 'utf-8'))
|
const pid = parseInt(await readFile(path.join(dataDir(), 'core.pid'), 'utf-8'))
|
||||||
try {
|
try {
|
||||||
@ -139,50 +135,42 @@ export async function startCore(detached = false): Promise<Promise<void>[]> {
|
|||||||
})
|
})
|
||||||
child.stdout?.pipe(stdout)
|
child.stdout?.pipe(stdout)
|
||||||
child.stderr?.pipe(stderr)
|
child.stderr?.pipe(stderr)
|
||||||
|
try {
|
||||||
|
await waitForCoreReady()
|
||||||
|
await managerLogger.info('Core API is ready, starting background services.')
|
||||||
|
await startMihomoTraffic()
|
||||||
|
await startMihomoConnections()
|
||||||
|
await startMihomoLogs()
|
||||||
|
await startMihomoMemory()
|
||||||
|
retry = 10
|
||||||
|
return [Promise.resolve()]
|
||||||
|
} catch (error) {
|
||||||
|
await managerLogger.error('Core failed to start or API not responding.', error)
|
||||||
|
await stopCore() // Stop the failed core process
|
||||||
|
throw error // Re-throw the error to be caught by the caller
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function waitForCoreReady(timeoutMs = 15000): Promise<void> {
|
||||||
|
const startTime = Date.now()
|
||||||
|
const pollInterval = 1000 // ms
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
child.stdout?.on('data', async (data) => {
|
const poll = setInterval(async () => {
|
||||||
const str = data.toString()
|
if (Date.now() - startTime > timeoutMs) {
|
||||||
if (str.includes('configure tun interface: operation not permitted')) {
|
clearInterval(poll)
|
||||||
patchControledMihomoConfig({ tun: { enable: false } })
|
reject(new Error(`Core API did not respond within ${timeoutMs / 1000}s.`))
|
||||||
mainWindow?.webContents.send('controledMihomoConfigUpdated')
|
return
|
||||||
ipcMain.emit('updateTrayMenu')
|
|
||||||
reject(i18next.t('tun.error.tunPermissionDenied'))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((process.platform !== 'win32' && str.includes('External controller unix listen error')) ||
|
try {
|
||||||
(process.platform === 'win32' && str.includes('External controller pipe listen error'))
|
await mihomoVersion()
|
||||||
) {
|
clearInterval(poll)
|
||||||
reject(i18next.t('mihomo.error.externalControllerListenError'))
|
resolve()
|
||||||
|
} catch (error) {
|
||||||
|
// Ignore connection errors and keep polling
|
||||||
}
|
}
|
||||||
|
}, pollInterval)
|
||||||
if (
|
|
||||||
(process.platform !== 'win32' && str.includes('RESTful API unix listening at')) ||
|
|
||||||
(process.platform === 'win32' && str.includes('RESTful API pipe listening at'))
|
|
||||||
) {
|
|
||||||
resolve([
|
|
||||||
new Promise((resolve) => {
|
|
||||||
child.stdout?.on('data', async (data) => {
|
|
||||||
if (data.toString().toLowerCase().includes('start initial compatible provider default')) {
|
|
||||||
try {
|
|
||||||
mainWindow?.webContents.send('groupsUpdated')
|
|
||||||
mainWindow?.webContents.send('rulesUpdated')
|
|
||||||
await uploadRuntimeConfig()
|
|
||||||
} catch {
|
|
||||||
// ignore
|
|
||||||
}
|
|
||||||
await patchMihomoConfig({ 'log-level': logLevel })
|
|
||||||
resolve()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
])
|
|
||||||
await startMihomoTraffic()
|
|
||||||
await startMihomoConnections()
|
|
||||||
await startMihomoLogs()
|
|
||||||
await startMihomoMemory()
|
|
||||||
retry = 10
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -6,7 +6,7 @@ import { tray } from '../resolve/tray'
|
|||||||
import { calcTraffic } from '../utils/calc'
|
import { calcTraffic } from '../utils/calc'
|
||||||
import { getRuntimeConfig } from './factory'
|
import { getRuntimeConfig } from './factory'
|
||||||
import { floatingWindow } from '../resolve/floatingWindow'
|
import { floatingWindow } from '../resolve/floatingWindow'
|
||||||
import { mihomoIpcPath } from './manager'
|
import { mihomoIpcPath } from '../utils/dirs'
|
||||||
|
|
||||||
let axiosIns: AxiosInstance = null!
|
let axiosIns: AxiosInstance = null!
|
||||||
let mihomoTrafficWs: WebSocket | null = null
|
let mihomoTrafficWs: WebSocket | null = null
|
||||||
|
|||||||
@ -158,3 +158,6 @@ export function coreLogPath(): string {
|
|||||||
const name = `core-${year}-${month}-${day}`
|
const name = `core-${year}-${month}-${day}`
|
||||||
return path.join(logDir(), `${name}.log`)
|
return path.join(logDir(), `${name}.log`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const mihomoIpcPath =
|
||||||
|
process.platform === 'win32' ? '\\\\.\\pipe\\MihomoParty\\mihomo' : '/tmp/mihomo-party.sock'
|
||||||
|
|||||||
@ -324,9 +324,6 @@ async function migration(): Promise<void> {
|
|||||||
'external-controller-pipe': undefined
|
'external-controller-pipe': undefined
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
if (externalController === undefined) {
|
|
||||||
await patchControledMihomoConfig({ 'external-controller': '' })
|
|
||||||
}
|
|
||||||
if (!showFloatingWindow && disableTray) {
|
if (!showFloatingWindow && disableTray) {
|
||||||
await patchAppConfig({ disableTray: false })
|
await patchAppConfig({ disableTray: false })
|
||||||
}
|
}
|
||||||
|
|||||||
@ -59,8 +59,8 @@ export const defaultControledMihomoConfig: Partial<IMihomoConfig> = {
|
|||||||
'tproxy-port': 0,
|
'tproxy-port': 0,
|
||||||
'allow-lan': false,
|
'allow-lan': false,
|
||||||
'unified-delay': true,
|
'unified-delay': true,
|
||||||
'tcp-concurrent': false,
|
'tcp-concurrent': true,
|
||||||
'log-level': 'info',
|
'log-level': 'warning',
|
||||||
'find-process-mode': 'strict',
|
'find-process-mode': 'strict',
|
||||||
'bind-address': '*',
|
'bind-address': '*',
|
||||||
'lan-allowed-ips': ['0.0.0.0/0', '::/0'],
|
'lan-allowed-ips': ['0.0.0.0/0', '::/0'],
|
||||||
@ -80,16 +80,17 @@ export const defaultControledMihomoConfig: Partial<IMihomoConfig> = {
|
|||||||
},
|
},
|
||||||
dns: {
|
dns: {
|
||||||
enable: true,
|
enable: true,
|
||||||
ipv6: false,
|
ipv6: true,
|
||||||
'enhanced-mode': 'fake-ip',
|
'enhanced-mode': 'fake-ip',
|
||||||
'fake-ip-range': '198.18.0.1/16',
|
'fake-ip-range': '198.18.0.1/16',
|
||||||
'fake-ip-filter': ['*', '+.lan', '+.local', 'time.*.com', 'ntp.*.com', '+.market.xiaomi.com'],
|
'fake-ip-filter': ['+.lan', '+.local', '+.arpa', 'time.*.com', 'ntp.*.com', '+.market.xiaomi.com', 'localhost.ptlogin2.qq.com', '+.msftncsi.com', 'www.msftconnecttest.com'],
|
||||||
|
'fake-ip-filter-mode': 'blacklist',
|
||||||
'use-hosts': false,
|
'use-hosts': false,
|
||||||
'use-system-hosts': false,
|
'use-system-hosts': false,
|
||||||
'respect-rules': false,
|
'respect-rules': false,
|
||||||
'default-nameserver': ['tls://223.5.5.5'],
|
'default-nameserver': ['system', '223.6.6.6', '8.8.8.8', '2400:3200::1', '2001:4860:4860::8888'],
|
||||||
nameserver: ['https://doh.pub/dns-query', 'https://dns.alidns.com/dns-query'],
|
nameserver: ['8.8.8.8', 'https://doh.pub/dns-query', 'https://dns.alidns.com/dns-query'],
|
||||||
'proxy-server-nameserver': ['https://doh.pub/dns-query', 'https://dns.alidns.com/dns-query'],
|
'proxy-server-nameserver': ['https://doh.pub/dns-query', 'https://dns.alidns.com/dns-query', 'tls://223.5.5.5'],
|
||||||
'direct-nameserver': [],
|
'direct-nameserver': [],
|
||||||
fallback: [],
|
fallback: [],
|
||||||
'fallback-filter': {
|
'fallback-filter': {
|
||||||
@ -137,10 +138,10 @@ export const defaultControledMihomoConfig: Partial<IMihomoConfig> = {
|
|||||||
'geo-update-interval': 24,
|
'geo-update-interval': 24,
|
||||||
'geodata-mode': false,
|
'geodata-mode': false,
|
||||||
'geox-url': {
|
'geox-url': {
|
||||||
geoip: 'https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geoip-lite.dat',
|
geoip: 'https://cdn.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@release/geoip-lite.dat',
|
||||||
geosite: 'https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geosite.dat',
|
geosite: 'https://cdn.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@release/geosite.dat',
|
||||||
mmdb: 'https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geoip.metadb',
|
mmdb: 'https://cdn.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@release/geoip.metadb',
|
||||||
asn: 'https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/GeoLite2-ASN.mmdb'
|
asn: 'https://cdn.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@release/GeoLite2-ASN.mmdb'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -17,25 +17,30 @@ const DNS: React.FC = () => {
|
|||||||
const { dns, hosts } = controledMihomoConfig || {}
|
const { dns, hosts } = controledMihomoConfig || {}
|
||||||
const {
|
const {
|
||||||
enable = true,
|
enable = true,
|
||||||
ipv6 = false,
|
ipv6 = true,
|
||||||
'fake-ip-range': fakeIPRange = '198.18.0.1/16',
|
'fake-ip-range': fakeIPRange = '198.18.0.1/16',
|
||||||
'fake-ip-filter': fakeIPFilter = [
|
'fake-ip-filter': fakeIPFilter = [
|
||||||
'*',
|
|
||||||
'+.lan',
|
'+.lan',
|
||||||
'+.local',
|
'+.local',
|
||||||
|
'+.arpa',
|
||||||
'time.*.com',
|
'time.*.com',
|
||||||
'ntp.*.com',
|
'ntp.*.com',
|
||||||
'+.market.xiaomi.com'
|
'+.market.xiaomi.com',
|
||||||
|
'localhost.ptlogin2.qq.com',
|
||||||
|
'+.msftncsi.com',
|
||||||
|
'www.msftconnecttest.com'
|
||||||
],
|
],
|
||||||
|
'fake-ip-filter-mode': fakeIPFilterMode = 'blacklist',
|
||||||
'enhanced-mode': enhancedMode = 'fake-ip',
|
'enhanced-mode': enhancedMode = 'fake-ip',
|
||||||
'use-hosts': useHosts = false,
|
'use-hosts': useHosts = false,
|
||||||
'use-system-hosts': useSystemHosts = false,
|
'use-system-hosts': useSystemHosts = false,
|
||||||
'respect-rules': respectRules = false,
|
'respect-rules': respectRules = false,
|
||||||
'default-nameserver': defaultNameserver = ['tls://223.5.5.5'],
|
'default-nameserver': defaultNameserver = ['system', '223.6.6.6', '8.8.8.8', '2400:3200::1', '2001:4860:4860::8888'],
|
||||||
nameserver = ['https://doh.pub/dns-query', 'https://dns.alidns.com/dns-query'],
|
nameserver = ['8.8.8.8', 'https://doh.pub/dns-query', 'https://dns.alidns.com/dns-query'],
|
||||||
'proxy-server-nameserver': proxyServerNameserver = [
|
'proxy-server-nameserver': proxyServerNameserver = [
|
||||||
'https://doh.pub/dns-query',
|
'https://doh.pub/dns-query',
|
||||||
'https://dns.alidns.com/dns-query'
|
'https://dns.alidns.com/dns-query',
|
||||||
|
'tls://223.5.5.5'
|
||||||
],
|
],
|
||||||
'direct-nameserver': directNameserver = [],
|
'direct-nameserver': directNameserver = [],
|
||||||
fallback = [],
|
fallback = [],
|
||||||
@ -54,6 +59,7 @@ const DNS: React.FC = () => {
|
|||||||
enhancedMode,
|
enhancedMode,
|
||||||
fakeIPRange,
|
fakeIPRange,
|
||||||
fakeIPFilter,
|
fakeIPFilter,
|
||||||
|
fakeIPFilterMode,
|
||||||
useSystemHosts,
|
useSystemHosts,
|
||||||
respectRules,
|
respectRules,
|
||||||
defaultNameserver,
|
defaultNameserver,
|
||||||
@ -61,10 +67,10 @@ const DNS: React.FC = () => {
|
|||||||
proxyServerNameserver,
|
proxyServerNameserver,
|
||||||
directNameserver,
|
directNameserver,
|
||||||
fallback,
|
fallback,
|
||||||
fallbackGeoip: fallbackFilter?.geoip || true,
|
fallbackGeoip: fallbackFilter.geoip,
|
||||||
fallbackGeoipCode: fallbackFilter?.['geoip-code'] || 'CN',
|
fallbackGeoipCode: fallbackFilter['geoip-code'],
|
||||||
fallbackIpcidr: fallbackFilter?.ipcidr || ['240.0.0.0/4', '0.0.0.0/32'],
|
fallbackIpcidr: fallbackFilter.ipcidr,
|
||||||
fallbackDomain: fallbackFilter?.domain || ['+.google.com', '+.facebook.com', '+.youtube.com'],
|
fallbackDomain: fallbackFilter.domain,
|
||||||
useNameserverPolicy,
|
useNameserverPolicy,
|
||||||
nameserverPolicy: Object.entries(nameserverPolicy || {}).map(([domain, value]) => ({
|
nameserverPolicy: Object.entries(nameserverPolicy || {}).map(([domain, value]) => ({
|
||||||
domain,
|
domain,
|
||||||
|
|||||||
@ -49,7 +49,7 @@ const Mihomo: React.FC = () => {
|
|||||||
secret,
|
secret,
|
||||||
authentication = [],
|
authentication = [],
|
||||||
'skip-auth-prefixes': skipAuthPrefixes = ['127.0.0.1/32', '::1/128'],
|
'skip-auth-prefixes': skipAuthPrefixes = ['127.0.0.1/32', '::1/128'],
|
||||||
'log-level': logLevel = 'info',
|
'log-level': logLevel = 'warning',
|
||||||
'find-process-mode': findProcessMode = 'strict',
|
'find-process-mode': findProcessMode = 'strict',
|
||||||
'allow-lan': allowLan,
|
'allow-lan': allowLan,
|
||||||
'lan-allowed-ips': lanAllowedIps = ['0.0.0.0/0', '::/0'],
|
'lan-allowed-ips': lanAllowedIps = ['0.0.0.0/0', '::/0'],
|
||||||
|
|||||||
7
src/shared/types.d.ts
vendored
7
src/shared/types.d.ts
vendored
@ -354,7 +354,12 @@ interface IMihomoDNSConfig {
|
|||||||
'default-nameserver'?: string[]
|
'default-nameserver'?: string[]
|
||||||
nameserver?: string[]
|
nameserver?: string[]
|
||||||
fallback?: string[]
|
fallback?: string[]
|
||||||
'fallback-filter'?: { [key: string]: boolean | string | string[] }
|
'fallback-filter'?: {
|
||||||
|
geoip?: boolean
|
||||||
|
'geoip-code'?: string
|
||||||
|
ipcidr?: string[]
|
||||||
|
domain?: string[]
|
||||||
|
}
|
||||||
'proxy-server-nameserver'?: string[]
|
'proxy-server-nameserver'?: string[]
|
||||||
'direct-nameserver'?: string[]
|
'direct-nameserver'?: string[]
|
||||||
'direct-nameserver-follow-policy'?: boolean
|
'direct-nameserver-follow-policy'?: boolean
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user