diff --git a/db/ConfigBuilder.cpp b/db/ConfigBuilder.cpp index fc173c5..70f90c1 100644 --- a/db/ConfigBuilder.cpp +++ b/db/ConfigBuilder.cpp @@ -785,6 +785,7 @@ namespace NekoRay { .replace("%PROCESS_NAME_RULE%", process_name_rule) .replace("%CIDR_RULE%", cidr_rule) .replace("%TUN_NAME%", tun_name) + .replace("%STRICT_ROUTE%", dataStore->vpn_strict_route ? "true" : "false") .replace("%PORT%", Int2String(dataStore->inbound_socks_port)); // write config QFile file; diff --git a/examples/sing-box-vpn.json b/examples/sing-box-vpn.json index 4c8e1fd..a787e6c 100644 --- a/examples/sing-box-vpn.json +++ b/examples/sing-box-vpn.json @@ -16,6 +16,7 @@ %IPV6_ADDRESS% "mtu": %MTU%, "auto_route": true, + "strict_route": %STRICT_ROUTE%, "stack": "%STACK%", "endpoint_independent_nat": true, "sniff": false diff --git a/fmt/Bean2CoreObj_box.cpp b/fmt/Bean2CoreObj_box.cpp index 39450cf..0f00a50 100644 --- a/fmt/Bean2CoreObj_box.cpp +++ b/fmt/Bean2CoreObj_box.cpp @@ -36,6 +36,12 @@ namespace NekoRay::fmt { if (!alpn.trimmed().isEmpty()) { tls["alpn"] = QList2QJsonArray(alpn.split(",")); } + if (!utls.isEmpty()) { + tls["utls"] = QJsonObject{ + {"enabled", true}, + {"fingerprint", utls}, + }; + } outbound->insert("tls", tls); } diff --git a/fmt/V2RayStreamSettings.hpp b/fmt/V2RayStreamSettings.hpp index 23e5e2c..cde72bc 100644 --- a/fmt/V2RayStreamSettings.hpp +++ b/fmt/V2RayStreamSettings.hpp @@ -17,6 +17,7 @@ namespace NekoRay::fmt { QString sni = ""; QString alpn = ""; QString certificate = ""; + QString utls = ""; bool allow_insecure = false; // ws early data QString ws_early_data_name = ""; @@ -35,6 +36,7 @@ namespace NekoRay::fmt { _add(new configItem("h_type", &header_type, itemType::string)); _add(new configItem("ed_name", &ws_early_data_name, itemType::string)); _add(new configItem("ed_len", &ws_early_data_length, itemType::integer)); + _add(new configItem("utls", &utls, itemType::string)); } QJsonObject BuildStreamSettingsV2Ray(); diff --git a/main/NekoRay.cpp b/main/NekoRay.cpp index ec783f5..aeb06b8 100644 --- a/main/NekoRay.cpp +++ b/main/NekoRay.cpp @@ -54,7 +54,8 @@ namespace NekoRay { _add(new configItem("vpn_impl", &vpn_implementation, itemType::integer)); _add(new configItem("vpn_mtu", &vpn_mtu, itemType::integer)); _add(new configItem("vpn_ipv6", &vpn_ipv6, itemType::boolean)); - _add(new configItem("vpn_hide_console", &vpn_hide_consloe, itemType::boolean)); + _add(new configItem("vpn_hide_console", &vpn_hide_console, itemType::boolean)); + _add(new configItem("vpn_strict_route", &vpn_strict_route, itemType::boolean)); _add(new configItem("vpn_bypass_process", &vpn_bypass_process, itemType::string)); _add(new configItem("vpn_bypass_cidr", &vpn_bypass_cidr, itemType::string)); _add(new configItem("check_include_pre", &check_include_pre, itemType::boolean)); diff --git a/main/NekoRay_DataStore.hpp b/main/NekoRay_DataStore.hpp index 8367be7..10c67e0 100644 --- a/main/NekoRay_DataStore.hpp +++ b/main/NekoRay_DataStore.hpp @@ -112,7 +112,8 @@ namespace NekoRay { int vpn_implementation = 0; int vpn_mtu = 9000; bool vpn_ipv6 = false; - bool vpn_hide_consloe = false; + bool vpn_hide_console = false; + bool vpn_strict_route = false; QString vpn_bypass_process = ""; QString vpn_bypass_cidr = ""; diff --git a/translations/zh_CN.ts b/translations/zh_CN.ts index e9860a8..f94873d 100644 --- a/translations/zh_CN.ts +++ b/translations/zh_CN.ts @@ -341,14 +341,6 @@ Already set 已设置 - - Path - 路径(Path) - - - Host - 主机(Host) - Packet Encoding 包编码 diff --git a/ui/dialog_basic_settings.ui b/ui/dialog_basic_settings.ui index ce92c62..4df4177 100644 --- a/ui/dialog_basic_settings.ui +++ b/ui/dialog_basic_settings.ui @@ -598,33 +598,6 @@
ui/widget/MyLineEdit.h
- - tabWidget - socks_ip - custom_inbound_edit - inbound_socks_port - inbound_http_port - http_enable - test_url - test_concurrent - log_level - mux_cool_enable - mux_cool - check_include_pre - theme - language - rfsh_r - connection_statistics - start_minimal - user_agent - sub_use_proxy - core_v2ray_asset - core_v2ray_asset_pick - extra_core_add - extra_core_del - insecure_hint - skip_cert - diff --git a/ui/dialog_vpn_settings.cpp b/ui/dialog_vpn_settings.cpp index 62697f9..9717578 100644 --- a/ui/dialog_vpn_settings.cpp +++ b/ui/dialog_vpn_settings.cpp @@ -14,10 +14,11 @@ DialogVPNSettings::DialogVPNSettings(QWidget *parent) : ui->vpn_implementation->setCurrentIndex(NekoRay::dataStore->vpn_implementation); ui->vpn_mtu->setCurrentText(Int2String(NekoRay::dataStore->vpn_mtu)); ui->vpn_ipv6->setChecked(NekoRay::dataStore->vpn_ipv6); - ui->hide_console->setChecked(NekoRay::dataStore->vpn_hide_consloe); + ui->hide_console->setChecked(NekoRay::dataStore->vpn_hide_console); #ifndef Q_OS_WIN ui->hide_console->setVisible(false); #endif + ui->strict_route->setChecked(NekoRay::dataStore->vpn_strict_route); // D_LOAD_STRING(vpn_bypass_cidr) D_LOAD_STRING(vpn_bypass_process) @@ -35,7 +36,8 @@ void DialogVPNSettings::accept() { NekoRay::dataStore->fake_dns = ui->fake_dns->isChecked(); NekoRay::dataStore->vpn_mtu = mtu; NekoRay::dataStore->vpn_ipv6 = ui->vpn_ipv6->isChecked(); - NekoRay::dataStore->vpn_hide_consloe = ui->hide_console->isChecked(); + NekoRay::dataStore->vpn_hide_console = ui->hide_console->isChecked(); + NekoRay::dataStore->vpn_strict_route = ui->strict_route->isChecked(); // D_SAVE_STRING_QTEXTEDIT(vpn_bypass_cidr) D_SAVE_STRING_QTEXTEDIT(vpn_bypass_process) diff --git a/ui/dialog_vpn_settings.ui b/ui/dialog_vpn_settings.ui index c657517..16a7b86 100644 --- a/ui/dialog_vpn_settings.ui +++ b/ui/dialog_vpn_settings.ui @@ -107,6 +107,13 @@ + + + + Strict Route + + + @@ -147,15 +154,6 @@ - - vpn_implementation - vpn_mtu - hide_console - vpn_ipv6 - fake_dns - vpn_bypass_cidr - vpn_bypass_process - diff --git a/ui/edit/dialog_edit_profile.cpp b/ui/edit/dialog_edit_profile.cpp index f77b807..88087d0 100644 --- a/ui/edit/dialog_edit_profile.cpp +++ b/ui/edit/dialog_edit_profile.cpp @@ -190,6 +190,7 @@ void DialogEditProfile::typeSelected(const QString &newType) { ui->host->setText(stream->host); ui->sni->setText(stream->sni); ui->alpn->setText(stream->alpn); + ui->utls->setCurrentText(stream->utls); ui->insecure->setChecked(stream->allow_insecure); ui->header_type->setCurrentText(stream->header_type); ui->ws_early_data_name->setText(stream->ws_early_data_name); @@ -309,6 +310,7 @@ void DialogEditProfile::accept() { stream->host = ui->host->text(); stream->sni = ui->sni->text(); stream->alpn = ui->alpn->text(); + stream->utls = ui->utls->currentText(); stream->allow_insecure = ui->insecure->isChecked(); stream->header_type = ui->header_type->currentText(); stream->ws_early_data_name = ui->ws_early_data_name->text(); diff --git a/ui/edit/dialog_edit_profile.ui b/ui/edit/dialog_edit_profile.ui index a8d681d..d0ed167 100644 --- a/ui/edit/dialog_edit_profile.ui +++ b/ui/edit/dialog_edit_profile.ui @@ -319,7 +319,7 @@ serviceName (gRPC) key (QUIC) - Path + Path @@ -333,7 +333,7 @@ key (QUIC) security (QUIC) - Host + Host @@ -346,10 +346,10 @@ security (QUIC) - 伪装头部 (tcp/quic) + 伪装头部类型 (tcp/quic) - headerType + header @@ -415,14 +415,104 @@ security (QUIC) - - - When enabled, V2Ray will not check the validity of the TLS certificate provided by the remote host (the security is equivalent to plaintext) - - - Allow insecure - - + + + + + + 0 + 0 + + + + When enabled, V2Ray will not check the validity of the TLS certificate provided by the remote host (the security is equivalent to plaintext) + + + Allow insecure + + + + + + + Qt::Vertical + + + + + + + + 0 + 0 + + + + Currently only supported in sing-box core. + + + uTLS + + + + + + + true + + + + + + + + + chrome + + + + + firefox + + + + + edge + + + + + safari + + + + + 360 + + + + + qq + + + + + ios + + + + + android + + + + + random + + + + + @@ -501,6 +591,7 @@ security (QUIC) ws_early_data_length ws_early_data_name insecure + utls sni alpn certificate_edit diff --git a/ui/mainwindow.cpp b/ui/mainwindow.cpp index b97ee60..2a24058 100644 --- a/ui/mainwindow.cpp +++ b/ui/mainwindow.cpp @@ -1469,7 +1469,7 @@ bool MainWindow::StartVPNProcess() { WinCommander::runProcessElevated(QApplication::applicationDirPath() + "/nekobox_core.exe", {"--disable-color", "run", "-c", configPath}, "", - NekoRay::dataStore->vpn_hide_consloe + NekoRay::dataStore->vpn_hide_console ); // blocking vpn_pid = 0; runOnUiThread([=] {