mirror of
https://github.com/pompurin404/mihomo-party.git
synced 2024-11-16 11:42:19 +08:00
try to set dns
This commit is contained in:
parent
bb60d9dcfb
commit
90f5db2b7c
|
@ -2,6 +2,10 @@
|
|||
|
||||
- 1.2.x YAML覆写语法有所变动,请更新后参考文档进行修改
|
||||
|
||||
### New Features
|
||||
|
||||
- MacOS 支持自动设置系统DNS
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
- 优化规则/代理页面性能
|
||||
|
|
|
@ -7,7 +7,12 @@ import {
|
|||
mihomoWorkDir
|
||||
} from '../utils/dirs'
|
||||
import { generateProfile } from './factory'
|
||||
import { getAppConfig, patchAppConfig, patchControledMihomoConfig } from '../config'
|
||||
import {
|
||||
getAppConfig,
|
||||
getControledMihomoConfig,
|
||||
patchAppConfig,
|
||||
patchControledMihomoConfig
|
||||
} from '../config'
|
||||
import { dialog, safeStorage } from 'electron'
|
||||
import { pauseWebsockets, startMihomoTraffic } from './mihomoApi'
|
||||
import { writeFile } from 'fs/promises'
|
||||
|
@ -18,12 +23,16 @@ let child: ChildProcess
|
|||
let retry = 10
|
||||
|
||||
export async function startCore(): Promise<void> {
|
||||
const { core = 'mihomo' } = await getAppConfig()
|
||||
const { core = 'mihomo', autoSetDNS = true } = await getAppConfig()
|
||||
const { tun } = await getControledMihomoConfig()
|
||||
const corePath = mihomoCorePath(core)
|
||||
await autoGrantCorePermition(corePath)
|
||||
await generateProfile()
|
||||
await checkProfile()
|
||||
stopCore()
|
||||
await stopCore()
|
||||
if (tun?.enable && autoSetDNS) {
|
||||
await setPublicDNS()
|
||||
}
|
||||
child = spawn(corePath, ['-d', mihomoWorkDir()])
|
||||
child.on('close', async (code, signal) => {
|
||||
await writeFile(logPath(), `[Manager]: Core closed, code: ${code}, signal: ${signal}\n`, {
|
||||
|
@ -34,13 +43,13 @@ export async function startCore(): Promise<void> {
|
|||
retry--
|
||||
await restartCore()
|
||||
} else {
|
||||
stopCore()
|
||||
await stopCore()
|
||||
}
|
||||
})
|
||||
return new Promise((resolve, reject) => {
|
||||
child.stdout?.on('data', async (data) => {
|
||||
if (data.toString().includes('updater: finished')) {
|
||||
stopCore()
|
||||
await stopCore()
|
||||
await startCore()
|
||||
}
|
||||
if (data.toString().includes('configure tun interface: operation not permitted')) {
|
||||
|
@ -54,7 +63,7 @@ export async function startCore(): Promise<void> {
|
|||
resolve(await startCore())
|
||||
} else {
|
||||
dialog.showErrorBox('内核连接失败', '请尝试更改外部控制端口后重启内核')
|
||||
stopCore()
|
||||
await stopCore()
|
||||
reject('External controller listen error')
|
||||
}
|
||||
}
|
||||
|
@ -69,7 +78,13 @@ export async function startCore(): Promise<void> {
|
|||
})
|
||||
}
|
||||
|
||||
export function stopCore(): void {
|
||||
export async function stopCore(): Promise<void> {
|
||||
try {
|
||||
await recoverDNS()
|
||||
} catch (error) {
|
||||
// todo
|
||||
}
|
||||
|
||||
if (child) {
|
||||
child.removeAllListeners()
|
||||
child.kill('SIGINT')
|
||||
|
@ -149,3 +164,72 @@ export async function manualGrantCorePermition(password?: string): Promise<void>
|
|||
export function isEncryptionAvailable(): boolean {
|
||||
return safeStorage.isEncryptionAvailable()
|
||||
}
|
||||
|
||||
async function getDefaultService(password?: string): Promise<string> {
|
||||
const execPromise = promisify(exec)
|
||||
let sudo = ''
|
||||
if (password) sudo = `echo "${password}" | sudo -S `
|
||||
const { stdout: deviceOut } = await execPromise(`${sudo}route -n get default`)
|
||||
let device = deviceOut.split('\n').find((s) => s.includes('interface:'))
|
||||
device = device?.trim().split(' ').slice(1).join(' ')
|
||||
if (!device) throw new Error('Get device failed')
|
||||
const { stdout: hardwareOut } = await execPromise(`${sudo}networksetup -listallhardwareports`)
|
||||
const hardware = hardwareOut
|
||||
.split('Ethernet Address:')
|
||||
.find((s) => s.includes(`Device: ${device}`))
|
||||
if (!hardware) throw new Error('Get hardware failed')
|
||||
for (const line of hardware.split('\n')) {
|
||||
if (line.startsWith('Hardware Port:')) {
|
||||
return line.trim().split(' ').slice(2).join(' ')
|
||||
}
|
||||
}
|
||||
throw new Error('Get service failed')
|
||||
}
|
||||
|
||||
async function getOriginDNS(password?: string): Promise<void> {
|
||||
const execPromise = promisify(exec)
|
||||
let sudo = ''
|
||||
if (password) sudo = `echo "${password}" | sudo -S `
|
||||
const service = await getDefaultService(password)
|
||||
const { stdout: dns } = await execPromise(`${sudo}networksetup -getdnsservers ${service}`)
|
||||
if (dns.startsWith("There aren't any DNS Servers set on")) {
|
||||
await patchAppConfig({ originDNS: 'Empty' })
|
||||
} else {
|
||||
await patchAppConfig({ originDNS: dns.trim().replace(/\n/g, ' ') })
|
||||
}
|
||||
}
|
||||
|
||||
async function setDNS(dns: string, password?: string): Promise<void> {
|
||||
const service = await getDefaultService(password)
|
||||
let sudo = ''
|
||||
if (password) sudo = `echo "${password}" | sudo -S `
|
||||
const execPromise = promisify(exec)
|
||||
await execPromise(`${sudo}networksetup -setdnsservers ${service} ${dns}`)
|
||||
// todo
|
||||
}
|
||||
|
||||
async function setPublicDNS(): Promise<void> {
|
||||
if (process.platform !== 'darwin') return
|
||||
const { originDNS, encryptedPassword } = await getAppConfig()
|
||||
if (!originDNS) {
|
||||
let password: string | undefined
|
||||
if (encryptedPassword && isEncryptionAvailable()) {
|
||||
password = safeStorage.decryptString(Buffer.from(encryptedPassword))
|
||||
}
|
||||
await getOriginDNS(password)
|
||||
await setDNS('223.5.5.5', password)
|
||||
}
|
||||
}
|
||||
|
||||
async function recoverDNS(): Promise<void> {
|
||||
if (process.platform !== 'darwin') return
|
||||
const { originDNS, encryptedPassword } = await getAppConfig()
|
||||
if (originDNS) {
|
||||
let password: string | undefined
|
||||
if (encryptedPassword && isEncryptionAvailable()) {
|
||||
password = safeStorage.decryptString(Buffer.from(encryptedPassword))
|
||||
}
|
||||
await setDNS(originDNS, password)
|
||||
await patchAppConfig({ originDNS: undefined })
|
||||
}
|
||||
}
|
||||
|
|
|
@ -68,9 +68,9 @@ app.on('window-all-closed', (e) => {
|
|||
// }
|
||||
})
|
||||
|
||||
app.on('before-quit', () => {
|
||||
app.on('before-quit', async () => {
|
||||
pauseWebsockets()
|
||||
stopCore()
|
||||
await stopCore()
|
||||
triggerSysProxy(false)
|
||||
app.exit()
|
||||
})
|
||||
|
|
|
@ -7,9 +7,12 @@ import { manualGrantCorePermition, restartCore, setupFirewall } from '@renderer/
|
|||
import { platform } from '@renderer/utils/init'
|
||||
import React, { Key, useState } from 'react'
|
||||
import BasePasswordModal from '@renderer/components/base/base-password-modal'
|
||||
import { useAppConfig } from '@renderer/hooks/use-app-config'
|
||||
|
||||
const Tun: React.FC = () => {
|
||||
const { controledMihomoConfig, patchControledMihomoConfig } = useControledMihomoConfig()
|
||||
const { appConfig, patchAppConfig } = useAppConfig()
|
||||
const { autoSetDNS = true } = appConfig || {}
|
||||
const { tun } = controledMihomoConfig || {}
|
||||
const [loading, setLoading] = useState(false)
|
||||
const [openPasswordModal, setOpenPasswordModal] = useState(false)
|
||||
|
@ -137,6 +140,18 @@ const Tun: React.FC = () => {
|
|||
</Button>
|
||||
</SettingItem>
|
||||
)}
|
||||
{platform === 'darwin' && (
|
||||
<SettingItem title="自动设置系统DNS" divider>
|
||||
<Switch
|
||||
size="sm"
|
||||
isSelected={autoSetDNS}
|
||||
onValueChange={async (v) => {
|
||||
await patchAppConfig({ autoSetDNS: v })
|
||||
}}
|
||||
/>
|
||||
</SettingItem>
|
||||
)}
|
||||
|
||||
<SettingItem title="Tun 模式堆栈" divider>
|
||||
<Tabs
|
||||
size="sm"
|
||||
|
|
2
src/shared/types.d.ts
vendored
2
src/shared/types.d.ts
vendored
|
@ -217,6 +217,8 @@ interface IAppConfig {
|
|||
proxyDisplayOrder: 'default' | 'delay' | 'name'
|
||||
envType?: 'bash' | 'cmd' | 'powershell'
|
||||
proxyCols: 'auto' | '1' | '2' | '3' | '4'
|
||||
autoSetDNS?: boolean
|
||||
originDNS?: string
|
||||
useWindowFrame: boolean
|
||||
proxyInTray: boolean
|
||||
siderOrder: string[]
|
||||
|
|
Loading…
Reference in New Issue
Block a user