fix:public DNS not set in macos, tun+fake-ip

This commit is contained in:
huzibaca 2024-10-26 08:55:00 +08:00
parent 652a20c523
commit 76d04805a4
No known key found for this signature in database
GPG Key ID: D4364EE4851DC302
5 changed files with 199 additions and 5 deletions

View File

@ -279,27 +279,50 @@ async function resolveSidecar(binInfo) {
}
}
const resolveSetDnsScript = () =>
resolveResource({
file: "set_dns.sh",
localPath: path.join(cwd, "scripts/set_dns.sh"),
});
const resolveUnSetDnsScript = () =>
resolveResource({
file: "unset_dns.sh",
localPath: path.join(cwd, "scripts/unset_dns.sh"),
});
/**
* download the file to the resources dir
*/
async function resolveResource(binInfo) {
const { file, downloadURL } = binInfo;
const { file, downloadURL, localPath } = binInfo;
const resDir = path.join(cwd, "src-tauri/resources");
const targetPath = path.join(resDir, file);
if (!FORCE && fs.existsSync(targetPath)) return;
if (downloadURL) {
await fsp.mkdir(resDir, { recursive: true });
await downloadFile(downloadURL, targetPath);
}
if (localPath) {
await fs.copyFile(localPath, targetPath, (err) => {
if (err) {
console.error("Error copying file:", err);
} else {
console.log("File was copied successfully");
}
});
log_debug(`copy file finished: "${localPath}"`);
}
log_success(`${file} finished`);
}
/**
* download file and save to `path`
*/
async function downloadFile(url, path) {
*/ async function downloadFile(url, path) {
const options = {};
const httpProxy =
@ -474,6 +497,18 @@ const tasks = [
retry: 5,
winOnly: true,
},
{
name: "set_dns_script",
func: resolveSetDnsScript,
retry: 5,
macosOnly: true,
},
{
name: "unset_dns_script",
func: resolveUnSetDnsScript,
retry: 5,
macosOnly: true,
},
];
async function runTask() {
@ -482,6 +517,7 @@ async function runTask() {
if (task.winOnly && platform !== "win32") return runTask();
if (task.linuxOnly && platform !== "linux") return runTask();
if (task.unixOnly && platform === "win32") return runTask();
if (task.macosOnly && platform !== "darwin") return runTask();
for (let i = 0; i < task.retry; i++) {
try {

58
scripts/set_dns.sh Normal file
View File

@ -0,0 +1,58 @@
#!/bin/bash
function is_valid_ip() {
local ip=$1
local IFS='.'
local -a octets
if [[ ! $ip =~ ^([0-9]+\.){3}[0-9]+$ ]]; then
return 1
fi
read -r -a octets <<<"$ip"
if [ "${#octets[@]}" -ne 4 ]; then
return 1
fi
for octet in "${octets[@]}"; do
if ! [[ "$octet" =~ ^[0-9]+$ ]] || ((octet < 0 || octet > 255)); then
return 1
fi
done
return 0
}
if [ $# -lt 1 ]; then
echo "Usage: $0 <hardware_port>"
exit 1
fi
if ! is_valid_ip "$1"; then
echo "$1 is not a valid IP address."
exit 1
fi
nic=$(route -n get default | grep "interface" | awk '{print $2}')
hardware_port=$(networksetup -listallhardwareports | awk -v dev="$nic" '
/Hardware Port:/{
port=$0; gsub("Hardware Port: ", "", port)
}
/Device: /{
if ($2 == dev) {
print port;
exit
}
}
')
original_dns=$(networksetup -getdnsservers "$hardware_port")
if [ ${#original_dns} -gt 15 ]; then
echo "Empty" >original_dns.txt
else
echo $original_dns >original_dns.txt
fi
networksetup -setdnsservers "$hardware_port" "$1"

22
scripts/unset_dns.sh Normal file
View File

@ -0,0 +1,22 @@
#!/bin/bash
nic=$(route -n get default | grep "interface" | awk '{print $2}')
hardware_port=$(networksetup -listallhardwareports | awk -v dev="$nic" '
/Hardware Port:/{
port=$0; gsub("Hardware Port: ", "", port)
}
/Device: /{
if ($2 == dev) {
print port;
exit
}
}
')
if [ -f original_dns.txt ]; then
original_dns=$(cat original_dns.txt)
else
original_dns=$(networksetup -getdnsservers "$hardware_port")
fi
networksetup -setdnsservers "$hardware_port" $original_dns

View File

@ -35,8 +35,12 @@ pub async fn use_tun(mut config: Mapping, enable: bool) -> Mapping {
revise!(dns_val, "ip-v6", true);
revise!(dns_val, "enhanced-mode", "fake-ip");
revise!(dns_val, "fake-ip-range", "10.96.0.0/16");
#[cfg(target_os = "macos")]
set_public_dns("10.96.0.2".to_string()).await;
} else {
revise!(dns_val, "enhanced-mode", "redir-host");
#[cfg(target_os = "macos")]
restore_public_dns().await;
}
revise!(tun_val, "enable", enable);
@ -44,3 +48,76 @@ pub async fn use_tun(mut config: Mapping, enable: bool) -> Mapping {
revise!(config, "dns", dns_val);
config
}
#[cfg(target_os = "macos")]
async fn set_public_dns(dns_server: String) {
use crate::core::handle;
use crate::utils::dirs;
use tauri_plugin_shell::ShellExt;
let app_handle = handle::Handle::global().app_handle().unwrap();
log::info!(target: "app", "try to set system dns");
let resource_dir = dirs::app_resources_dir().unwrap();
let script = resource_dir.join("set_dns.sh");
if !script.exists() {
log::error!(target: "app", "set_dns.sh not found");
return;
}
let script = script.to_string_lossy().into_owned();
match app_handle
.shell()
.command("bash")
.args([script, dns_server])
.current_dir(resource_dir)
.status()
.await
{
Ok(status) => {
if status.success() {
log::info!(target: "app", "set system dns successfully");
} else {
let code = status.code().unwrap_or(-1);
log::error!(target: "app", "set system dns failed: {code}");
}
}
Err(err) => {
log::error!(target: "app", "set system dns failed: {err}");
}
}
}
#[cfg(target_os = "macos")]
async fn restore_public_dns() {
use crate::core::handle;
use crate::utils::dirs;
use tauri_plugin_shell::ShellExt;
let app_handle = handle::Handle::global().app_handle().unwrap();
log::info!(target: "app", "try to unset system dns");
let resource_dir = dirs::app_resources_dir().unwrap();
let script = resource_dir.join("unset_dns.sh");
if !script.exists() {
log::error!(target: "app", "unset_dns.sh not found");
return;
}
let script = script.to_string_lossy().into_owned();
match app_handle
.shell()
.command("bash")
.args([script])
.current_dir(resource_dir)
.status()
.await
{
Ok(status) => {
if status.success() {
log::info!(target: "app", "unset system dns successfully");
} else {
let code = status.code().unwrap_or(-1);
log::error!(target: "app", "unset system dns failed: {code}");
}
}
Err(err) => {
log::error!(target: "app", "unset system dns failed: {err}");
}
}
}

View File

@ -3,6 +3,7 @@
"identifier": "io.github.clash-verge-rev.clash-verge-rev",
"bundle": {
"targets": ["app", "dmg"],
"resources": ["resources/set_dns.sh", "resources/unset_dns.sh"],
"macOS": {
"frameworks": [],
"minimumSystemVersion": "10.15",