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覆写语法有所变动,请更新后参考文档进行修改
|
- 1.2.x YAML覆写语法有所变动,请更新后参考文档进行修改
|
||||||
|
|
||||||
|
### New Features
|
||||||
|
|
||||||
|
- MacOS 支持自动设置系统DNS
|
||||||
|
|
||||||
### Performance Improvements
|
### Performance Improvements
|
||||||
|
|
||||||
- 优化规则/代理页面性能
|
- 优化规则/代理页面性能
|
||||||
|
|
|
@ -7,7 +7,12 @@ import {
|
||||||
mihomoWorkDir
|
mihomoWorkDir
|
||||||
} from '../utils/dirs'
|
} from '../utils/dirs'
|
||||||
import { generateProfile } from './factory'
|
import { generateProfile } from './factory'
|
||||||
import { getAppConfig, patchAppConfig, patchControledMihomoConfig } from '../config'
|
import {
|
||||||
|
getAppConfig,
|
||||||
|
getControledMihomoConfig,
|
||||||
|
patchAppConfig,
|
||||||
|
patchControledMihomoConfig
|
||||||
|
} from '../config'
|
||||||
import { dialog, safeStorage } from 'electron'
|
import { dialog, safeStorage } from 'electron'
|
||||||
import { pauseWebsockets, startMihomoTraffic } from './mihomoApi'
|
import { pauseWebsockets, startMihomoTraffic } from './mihomoApi'
|
||||||
import { writeFile } from 'fs/promises'
|
import { writeFile } from 'fs/promises'
|
||||||
|
@ -18,12 +23,16 @@ let child: ChildProcess
|
||||||
let retry = 10
|
let retry = 10
|
||||||
|
|
||||||
export async function startCore(): Promise<void> {
|
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)
|
const corePath = mihomoCorePath(core)
|
||||||
await autoGrantCorePermition(corePath)
|
await autoGrantCorePermition(corePath)
|
||||||
await generateProfile()
|
await generateProfile()
|
||||||
await checkProfile()
|
await checkProfile()
|
||||||
stopCore()
|
await stopCore()
|
||||||
|
if (tun?.enable && autoSetDNS) {
|
||||||
|
await setPublicDNS()
|
||||||
|
}
|
||||||
child = spawn(corePath, ['-d', mihomoWorkDir()])
|
child = spawn(corePath, ['-d', mihomoWorkDir()])
|
||||||
child.on('close', async (code, signal) => {
|
child.on('close', async (code, signal) => {
|
||||||
await writeFile(logPath(), `[Manager]: Core closed, code: ${code}, signal: ${signal}\n`, {
|
await writeFile(logPath(), `[Manager]: Core closed, code: ${code}, signal: ${signal}\n`, {
|
||||||
|
@ -34,13 +43,13 @@ export async function startCore(): Promise<void> {
|
||||||
retry--
|
retry--
|
||||||
await restartCore()
|
await restartCore()
|
||||||
} else {
|
} else {
|
||||||
stopCore()
|
await stopCore()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
child.stdout?.on('data', async (data) => {
|
child.stdout?.on('data', async (data) => {
|
||||||
if (data.toString().includes('updater: finished')) {
|
if (data.toString().includes('updater: finished')) {
|
||||||
stopCore()
|
await stopCore()
|
||||||
await startCore()
|
await startCore()
|
||||||
}
|
}
|
||||||
if (data.toString().includes('configure tun interface: operation not permitted')) {
|
if (data.toString().includes('configure tun interface: operation not permitted')) {
|
||||||
|
@ -54,7 +63,7 @@ export async function startCore(): Promise<void> {
|
||||||
resolve(await startCore())
|
resolve(await startCore())
|
||||||
} else {
|
} else {
|
||||||
dialog.showErrorBox('内核连接失败', '请尝试更改外部控制端口后重启内核')
|
dialog.showErrorBox('内核连接失败', '请尝试更改外部控制端口后重启内核')
|
||||||
stopCore()
|
await stopCore()
|
||||||
reject('External controller listen error')
|
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) {
|
if (child) {
|
||||||
child.removeAllListeners()
|
child.removeAllListeners()
|
||||||
child.kill('SIGINT')
|
child.kill('SIGINT')
|
||||||
|
@ -149,3 +164,72 @@ export async function manualGrantCorePermition(password?: string): Promise<void>
|
||||||
export function isEncryptionAvailable(): boolean {
|
export function isEncryptionAvailable(): boolean {
|
||||||
return safeStorage.isEncryptionAvailable()
|
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()
|
pauseWebsockets()
|
||||||
stopCore()
|
await stopCore()
|
||||||
triggerSysProxy(false)
|
triggerSysProxy(false)
|
||||||
app.exit()
|
app.exit()
|
||||||
})
|
})
|
||||||
|
|
|
@ -7,9 +7,12 @@ import { manualGrantCorePermition, restartCore, setupFirewall } from '@renderer/
|
||||||
import { platform } from '@renderer/utils/init'
|
import { platform } from '@renderer/utils/init'
|
||||||
import React, { Key, useState } from 'react'
|
import React, { Key, useState } from 'react'
|
||||||
import BasePasswordModal from '@renderer/components/base/base-password-modal'
|
import BasePasswordModal from '@renderer/components/base/base-password-modal'
|
||||||
|
import { useAppConfig } from '@renderer/hooks/use-app-config'
|
||||||
|
|
||||||
const Tun: React.FC = () => {
|
const Tun: React.FC = () => {
|
||||||
const { controledMihomoConfig, patchControledMihomoConfig } = useControledMihomoConfig()
|
const { controledMihomoConfig, patchControledMihomoConfig } = useControledMihomoConfig()
|
||||||
|
const { appConfig, patchAppConfig } = useAppConfig()
|
||||||
|
const { autoSetDNS = true } = appConfig || {}
|
||||||
const { tun } = controledMihomoConfig || {}
|
const { tun } = controledMihomoConfig || {}
|
||||||
const [loading, setLoading] = useState(false)
|
const [loading, setLoading] = useState(false)
|
||||||
const [openPasswordModal, setOpenPasswordModal] = useState(false)
|
const [openPasswordModal, setOpenPasswordModal] = useState(false)
|
||||||
|
@ -137,6 +140,18 @@ const Tun: React.FC = () => {
|
||||||
</Button>
|
</Button>
|
||||||
</SettingItem>
|
</SettingItem>
|
||||||
)}
|
)}
|
||||||
|
{platform === 'darwin' && (
|
||||||
|
<SettingItem title="自动设置系统DNS" divider>
|
||||||
|
<Switch
|
||||||
|
size="sm"
|
||||||
|
isSelected={autoSetDNS}
|
||||||
|
onValueChange={async (v) => {
|
||||||
|
await patchAppConfig({ autoSetDNS: v })
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</SettingItem>
|
||||||
|
)}
|
||||||
|
|
||||||
<SettingItem title="Tun 模式堆栈" divider>
|
<SettingItem title="Tun 模式堆栈" divider>
|
||||||
<Tabs
|
<Tabs
|
||||||
size="sm"
|
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'
|
proxyDisplayOrder: 'default' | 'delay' | 'name'
|
||||||
envType?: 'bash' | 'cmd' | 'powershell'
|
envType?: 'bash' | 'cmd' | 'powershell'
|
||||||
proxyCols: 'auto' | '1' | '2' | '3' | '4'
|
proxyCols: 'auto' | '1' | '2' | '3' | '4'
|
||||||
|
autoSetDNS?: boolean
|
||||||
|
originDNS?: string
|
||||||
useWindowFrame: boolean
|
useWindowFrame: boolean
|
||||||
proxyInTray: boolean
|
proxyInTray: boolean
|
||||||
siderOrder: string[]
|
siderOrder: string[]
|
||||||
|
|
Loading…
Reference in New Issue
Block a user