diff --git a/README.md b/README.md index 224edfa4..48bf4d65 100644 --- a/README.md +++ b/README.md @@ -51,7 +51,7 @@ CrossDesk 支持 Windows、macOS、Linux 之间的远程访问,也可从浏览 | 实时画面与声音 | H.264 / AV1、30 / 60 fps 设置、硬件编解码选项、远端声音播放;实际能力取决于设备与构建配置 | | 多设备与多显示器 | 近期连接、设备别名、会话标签与远端显示器切换 | | 输入与协作 | 键鼠输入、远端光标同步、组合键、文本剪贴板同步、文件传输 | -| 网络与部署 | P2P 直连、TURN 中继、SRTP 加密选项、自托管信令与中继服务 | +| 网络与部署 | P2P 直连与默认增强打洞、TURN 中继、默认 SRTP、自托管信令与中继服务 | | Windows 锁屏控制 | 通过 CrossDesk Service 支持锁屏、登录界面及安全桌面的输入转发 | 各客户端的入口和能力有所不同;桌面会话操作见下文,iOS 的具体功能见 [开发说明](apps/ios/README.md)。 @@ -93,7 +93,7 @@ sudo apt install "./crossdesk-linux-amd64-.deb" ### 从浏览器连接 -1. 保持被控电脑上的 CrossDesk 运行,并确认已连接服务器;在被控端“设置”中保持 **启用 SRTP** 开启。 +1. 保持被控电脑上的 CrossDesk 运行,并确认已连接服务器;新版本默认请求 SRTP,无需在设置中开启。 2. 打开 [Web 客户端](https://web.crossdesk.cn/),输入 **远程设备 ID** 和 **密码**,点击“连接”。 3. 连接后使用页面提供的显示器、鼠标模式和键盘控件操作远端;手机和平板也可通过浏览器访问。 @@ -125,16 +125,19 @@ sudo apt install "./crossdesk-linux-amd64-.deb" 点击主窗口右上角 **☰ → 设置**,修改后点击“确认”保存。建议在建立连接前调整;会话进行中部分选项不可修改。设置列表可向下滚动,查看自托管、启动方式与文件保存路径。

- 当前设置界面:画质、帧率、画面偏好、编解码、中继与 SRTP + 设置界面参考:画质、帧率、画面偏好、编解码与中继;旧图中的 SRTP 开关已移除

+SRTP 已默认开启,参考图中的旧 SRTP 开关不再提供。原生桌面默认使用 pool-wide 增强打洞;只有双方支持且认证、映射条件满足时才启动。无 DTLS 指纹旧端仍可兼容连接,但可能回退到未加密 RTP,此类连接不启用增强打洞。 + + | 设置 | 说明 | | --- | --- | | 画面质量 / 帧率 | 选择低、中、高画质与 30 / 60 fps;实际帧率取决于网络和设备 | | 画面偏好 | 在帧率优先、画质优先、平衡之间选择 | | 视频编码格式 | H.264 / AV1;硬件编解码是否可用取决于平台、硬件与构建选项 | | 启用中继服务 | 允许借助 TURN 中继建立连接;P2P 连接失败时先检查此项 | -| 启用 SRTP | 媒体传输加密选项,两端配置需兼容 | +| SRTP | 默认请求媒体加密,无本地关闭开关;无指纹旧端保留兼容回退 | | 自托管配置 | 设置服务器地址、信令端口与中继端口,并勾选启用 | | 开机自启 / 启用守护进程 | 调整启动与进程守护行为,按界面提示重启后生效 | | 文件保存路径 | 选择接收文件的目录 | diff --git a/README_EN.md b/README_EN.md index 4c772f94..9759d36b 100644 --- a/README_EN.md +++ b/README_EN.md @@ -51,7 +51,7 @@ See the [screenshot notes](docs/images/README.md) for image sources and refresh | Live video and audio | H.264 / AV1, 30 / 60 fps settings, hardware codec options, and remote audio; availability depends on hardware and build configuration | | Devices and displays | Recent connections, device aliases, session tabs, and remote display switching | | Input and sharing | Keyboard/mouse input, remote cursor synchronization, shortcuts, text clipboard synchronization, and file transfer | -| Networking and deployment | Direct P2P connections, TURN relay, an SRTP encryption option, and self-hosted signaling/relay services | +| Networking and deployment | Direct P2P with hole punching enabled by default, TURN relay, SRTP by default, and self-hosted signaling/relay services | | Windows protected desktops | CrossDesk Service forwards input on lock screens, sign-in screens, and secure desktops | Controls and capabilities vary by client. Desktop controls are described below; see the [iOS guide](apps/ios/README.md) for native mobile features. @@ -93,7 +93,7 @@ The eye button shows or hides the local password; the pencil button changes it. ### Connect from a browser -1. Keep CrossDesk running and connected to the server on the host computer, with **Enable SRTP** enabled in its Settings. +1. Keep CrossDesk running and connected to the server on the host computer; current versions request SRTP by default, with no Settings switch. 2. Open the [Web Client](https://web.crossdesk.cn/), enter the **Remote Device ID** and **Password**, and click **Connect**. 3. Use the page's display, mouse-mode, and keyboard controls during the session. Phone and tablet browsers can also connect. @@ -125,16 +125,19 @@ Desktop clients synchronize text clipboard contents. Configure the receiving dir Open **☰ → Settings** in the top-right corner and click **OK** to save. Configure the session before connecting; some settings are disabled during an active session. Scroll down for self-hosting, startup behavior, and the file save path.

- Current settings for quality, frame rate, video preference, codecs, relay, and SRTP + Settings reference for quality, frame rate, video preference, codecs, and relay; the old SRTP switch has been removed

+SRTP is enabled by default; the SRTP switch in this reference image is no longer available. Native desktop builds use pool-wide punching when both peers support it and authentication and mapping conditions are met. Legacy peers without DTLS fingerprints remain compatible through a possible unencrypted RTP fallback, which cannot use enhanced punching. + + | Setting | Purpose | | --- | --- | | Video Quality / Video Capture Frame Rate | Low, medium, or high quality and 30 / 60 fps; actual performance depends on the connection and device | | Video Preference | Choose frame-rate priority, quality priority, or balanced adaptation | | Video Encode Format | H.264 / AV1; hardware codec availability depends on the platform, device, and build options | | Enable TURN Service | Allow relay-assisted connections; check this setting if P2P fails | -| SRTP | Media encryption option; configurations on both ends must be compatible | +| SRTP | Requests media encryption by default, with no local off switch; retains fallback for legacy peers without fingerprints | | Self-Hosted Config | Set the host, signaling port, and TURN port, then enable the checkbox | | Auto Start / Enable Daemon | Configure startup and process supervision; restart as indicated by the UI | | File Save Path | Choose where received files are saved | diff --git a/apps/desktop/src/config_center/config_center.cpp b/apps/desktop/src/config_center/config_center.cpp index 5df11de5..86225b93 100644 --- a/apps/desktop/src/config_center/config_center.cpp +++ b/apps/desktop/src/config_center/config_center.cpp @@ -103,7 +103,12 @@ int ConfigCenter::Load() { ini_.SetLongValue(section_, "turn_mode", static_cast(turn_mode_)); persist_config_migration = true; } - enable_srtp_ = ini_.GetBoolValue(section_, "enable_srtp", enable_srtp_); + // Migrate the former user switch. Keep true in the file for older builds, + // while the current application always requests encrypted native media. + if (!ini_.GetBoolValue(section_, "enable_srtp", false)) { + ini_.SetBoolValue(section_, "enable_srtp", true); + persist_config_migration = true; + } enable_self_hosted_ = ini_.GetBoolValue(section_, "enable_self_hosted", enable_self_hosted_); @@ -165,7 +170,7 @@ int ConfigCenter::Save() { ini_.SetLongValue(section_, "turn_mode", static_cast(turn_mode_)); ini_.SetBoolValue(section_, "enable_turn", turn_mode_ != TURN_MODE::DISABLED); - ini_.SetBoolValue(section_, "enable_srtp", enable_srtp_); + ini_.SetBoolValue(section_, "enable_srtp", true); ini_.SetBoolValue(section_, "enable_self_hosted", enable_self_hosted_); // only save when self hosted @@ -301,16 +306,6 @@ int ConfigCenter::SetTurn(bool enable_turn) { return SetTurnMode(turn_mode_); } -int ConfigCenter::SetSrtp(bool enable_srtp) { - enable_srtp_ = enable_srtp; - ini_.SetBoolValue(section_, "enable_srtp", enable_srtp_); - SI_Error rc = ini_.SaveFile(config_path_.c_str()); - if (rc < 0) { - return -1; - } - return 0; -} - int ConfigCenter::SetServerHost(const std::string& signal_server_host) { signal_server_host_ = signal_server_host; ini_.SetValue(section_, "signal_server_host", signal_server_host_.c_str()); @@ -472,7 +467,7 @@ bool ConfigCenter::IsEnableTurn() const { return turn_mode_ != TURN_MODE::DISABLED; } -bool ConfigCenter::IsEnableSrtp() const { return enable_srtp_; } +bool ConfigCenter::IsEnableSrtp() const { return true; } std::string ConfigCenter::GetSignalServerHost() const { return signal_server_host_; diff --git a/apps/desktop/src/config_center/config_center.h b/apps/desktop/src/config_center/config_center.h index 7e6fe61e..9047eb00 100644 --- a/apps/desktop/src/config_center/config_center.h +++ b/apps/desktop/src/config_center/config_center.h @@ -47,7 +47,6 @@ class ConfigCenter { int SetHardwareVideoCodec(bool hardware_video_codec); int SetTurnMode(TURN_MODE turn_mode); int SetTurn(bool enable_turn); - int SetSrtp(bool enable_srtp); int SetServerHost(const std::string& signal_server_host); int SetServerPort(int signal_server_port); int SetSelfHosted(bool enable_self_hosted); @@ -99,7 +98,6 @@ class ConfigCenter { VIDEO_ENCODE_FORMAT video_encode_format_ = VIDEO_ENCODE_FORMAT::H264; bool hardware_video_codec_ = false; TURN_MODE turn_mode_ = TURN_MODE::AUTO_UDP_TCP; - bool enable_srtp_ = false; std::string signal_server_host_ = ""; std::string signal_server_host_default_ = "api.crossdesk.cn"; int signal_server_port_ = 0; diff --git a/apps/desktop/src/gui/application/gui_application.cpp b/apps/desktop/src/gui/application/gui_application.cpp index 5b518230..6dc25667 100644 --- a/apps/desktop/src/gui/application/gui_application.cpp +++ b/apps/desktop/src/gui/application/gui_application.cpp @@ -1230,7 +1230,6 @@ void GuiApplication::ResetSettingsUi() { ui_->main->set_hardware_codec_enabled(hardware_codec_available && enable_hardware_video_codec_); ui_->main->set_turn_enabled(enable_turn_); - ui_->main->set_srtp_enabled(enable_srtp_); ui_->main->set_self_hosted_enabled(enable_self_hosted_); ui_->main->set_autostart_enabled(enable_autostart_); ui_->main->set_daemon_enabled(enable_daemon_); @@ -2419,7 +2418,6 @@ void GuiApplication::SyncStreamWindow() { return; } (*ui_->stream)->set_window_maximized((*ui_->stream)->window().is_maximized()); - (*ui_->stream)->set_srtp_enabled(enable_srtp_); #if defined(__APPLE__) if (ui_->stream_live_resize_configuration_attempts > 0) { if (ConfigureStreamWindowLiveResize( @@ -2987,7 +2985,6 @@ void GuiApplication::SaveSettingsFromUi() { enable_hardware_video_codec_ = ConfigCenter::IsHardwareVideoCodecAvailable() && main->get_hardware_codec_enabled(); enable_turn_ = main->get_turn_enabled(); - enable_srtp_ = main->get_srtp_enabled(); enable_self_hosted_ = main->get_self_hosted_enabled(); enable_autostart_ = main->get_autostart_enabled(); enable_daemon_ = main->get_daemon_enabled(); @@ -3010,7 +3007,6 @@ void GuiApplication::SaveSettingsFromUi() { video_encode_format_button_value_)); config_center_->SetHardwareVideoCodec(enable_hardware_video_codec_); config_center_->SetTurn(enable_turn_); - config_center_->SetSrtp(enable_srtp_); config_center_->SetSelfHosted(enable_self_hosted_); config_center_->SetAutostart(enable_autostart_); config_center_->SetDaemon(enable_daemon_); @@ -3056,7 +3052,6 @@ void GuiApplication::SaveSettingsFromUi() { video_encode_format_button_value_last_ = video_encode_format_button_value_; enable_hardware_video_codec_last_ = enable_hardware_video_codec_; enable_turn_last_ = enable_turn_; - enable_srtp_last_ = enable_srtp_; enable_self_hosted_last_ = enable_self_hosted_; enable_autostart_last_ = enable_autostart_; enable_daemon_last_ = enable_daemon_; diff --git a/apps/desktop/src/gui/assets/layouts/layout.h b/apps/desktop/src/gui/assets/layouts/layout.h index d5b83742..27748a76 100644 --- a/apps/desktop/src/gui/assets/layouts/layout.h +++ b/apps/desktop/src/gui/assets/layouts/layout.h @@ -53,8 +53,6 @@ #define ENABLE_HARDWARE_VIDEO_CODEC_CHECKBOX_PADDING_EN 218 * dpi_scale_ #define ENABLE_TURN_CHECKBOX_PADDING_CN 171 * dpi_scale_ #define ENABLE_TURN_CHECKBOX_PADDING_EN 218 * dpi_scale_ -#define ENABLE_SRTP_CHECKBOX_PADDING_CN 171 * dpi_scale_ -#define ENABLE_SRTP_CHECKBOX_PADDING_EN 218 * dpi_scale_ #define ENABLE_SELF_HOSTED_SERVER_CHECKBOX_PADDING_CN 171 * dpi_scale_ #define ENABLE_SELF_HOSTED_SERVER_CHECKBOX_PADDING_EN 218 * dpi_scale_ #define ENABLE_AUTOSTART_PADDING_CN 171 * dpi_scale_ diff --git a/apps/desktop/src/gui/assets/layouts/layout_relative.h b/apps/desktop/src/gui/assets/layouts/layout_relative.h index e58a0e44..687627dd 100644 --- a/apps/desktop/src/gui/assets/layouts/layout_relative.h +++ b/apps/desktop/src/gui/assets/layouts/layout_relative.h @@ -57,8 +57,6 @@ #define ENABLE_HARDWARE_VIDEO_CODEC_CHECKBOX_PADDING_EN 218 #define ENABLE_TURN_CHECKBOX_PADDING_CN 171 #define ENABLE_TURN_CHECKBOX_PADDING_EN 218 -#define ENABLE_SRTP_CHECKBOX_PADDING_CN 171 -#define ENABLE_SRTP_CHECKBOX_PADDING_EN 218 #define ENABLE_SELF_HOSTED_SERVER_CHECKBOX_PADDING_CN 171 #define ENABLE_SELF_HOSTED_SERVER_CHECKBOX_PADDING_EN 218 #define ENABLE_AUTOSTART_PADDING_CN 171 diff --git a/apps/desktop/src/gui/assets/localization/localization_data.h b/apps/desktop/src/gui/assets/localization/localization_data.h index 82e9dc2d..a269ca59 100644 --- a/apps/desktop/src/gui/assets/localization/localization_data.h +++ b/apps/desktop/src/gui/assets/localization/localization_data.h @@ -149,7 +149,6 @@ struct TranslationRow { "Enable Hardware Video Codec:", u8"Использовать аппаратный кодек:") \ X(enable_turn, u8"启用中继服务:", \ "Enable TURN Service:", u8"Включить TURN-сервис:") \ - X(enable_srtp, u8"启用SRTP:", "Enable SRTP:", u8"Включить SRTP:") \ X(self_hosted_server_config, u8"自托管配置", "Self-Hosted Config", \ u8"Конфигурация self-hosted") \ X(self_hosted_server_settings, u8"自托管设置", "Self-Hosted Settings", \ diff --git a/apps/desktop/src/gui/features/settings/settings_manager.cpp b/apps/desktop/src/gui/features/settings/settings_manager.cpp index 89abcdea..87585851 100644 --- a/apps/desktop/src/gui/features/settings/settings_manager.cpp +++ b/apps/desktop/src/gui/features/settings/settings_manager.cpp @@ -308,7 +308,6 @@ int SettingsManager::Load() { owner_.enable_hardware_video_codec_ = owner_.config_center_->IsHardwareVideoCodec(); owner_.enable_turn_ = owner_.config_center_->IsEnableTurn(); - owner_.enable_srtp_ = owner_.config_center_->IsEnableSrtp(); owner_.enable_self_hosted_ = owner_.config_center_->IsSelfHosted(); owner_.enable_autostart_ = owner_.config_center_->IsEnableAutostart(); owner_.enable_daemon_ = owner_.config_center_->IsEnableDaemon(); @@ -335,7 +334,6 @@ int SettingsManager::Load() { owner_.enable_hardware_video_codec_last_ = owner_.enable_hardware_video_codec_; owner_.enable_turn_last_ = owner_.enable_turn_; - owner_.enable_srtp_last_ = owner_.enable_srtp_; owner_.enable_self_hosted_last_ = owner_.enable_self_hosted_; owner_.enable_autostart_last_ = owner_.enable_autostart_; diff --git a/apps/desktop/src/gui/runtime/runtime_state.h b/apps/desktop/src/gui/runtime/runtime_state.h index 464df2b1..e50a85cb 100644 --- a/apps/desktop/src/gui/runtime/runtime_state.h +++ b/apps/desktop/src/gui/runtime/runtime_state.h @@ -136,7 +136,6 @@ struct UserSettingsState { int video_encode_format_button_value_ = 0; bool enable_hardware_video_codec_ = true; bool enable_turn_ = true; - bool enable_srtp_ = false; char signal_server_ip_[256] = "api.crossdesk.cn"; char signal_server_port_[6] = "9099"; bool enable_self_hosted_ = false; @@ -147,7 +146,6 @@ struct UserSettingsState { int video_encode_format_button_value_last_ = 0; bool enable_hardware_video_codec_last_ = false; bool enable_turn_last_ = true; - bool enable_srtp_last_ = false; bool enable_self_hosted_last_ = false; bool enable_autostart_ = false; bool enable_autostart_last_ = false; diff --git a/apps/desktop/src/gui/ui/main_window.slint b/apps/desktop/src/gui/ui/main_window.slint index 7d9255f1..aeb2fafa 100644 --- a/apps/desktop/src/gui/ui/main_window.slint +++ b/apps/desktop/src/gui/ui/main_window.slint @@ -48,7 +48,6 @@ export global UiStrings { in-out property codec: "Video codec"; in-out property hardware-codec: "Hardware video codec"; in-out property turn-relay: "TURN relay"; - in-out property srtp: "SRTP encryption"; in-out property self-hosted: "Self-hosted server"; in-out property autostart: "Start with system"; in-out property daemon: "Run in background"; @@ -247,7 +246,6 @@ export component MainWindow inherits Window { in-out property codec-index: 0; in-out property hardware-codec-enabled: true; in-out property turn-enabled: true; - in-out property srtp-enabled: false; in-out property self-hosted-enabled: false; in-out property autostart-enabled: false; in-out property daemon-enabled: false; @@ -1488,11 +1486,6 @@ export component MainWindow inherits Window { Text { x: 8px; y: 3px; width: root.compact-language ? 145px : 212px; height: 24px; text: UiStrings.turn-relay; font-size: ImGuiFontStyle.body; overflow: elide; vertical-alignment: center; } ImGuiCheckBox { x: root.compact-language ? 157px : 224px; y: 3px; checked <=> root.turn-enabled; enabled: !root.settings-session-active; } } - Rectangle { - height: 30px; - Text { x: 8px; y: 3px; width: root.compact-language ? 145px : 212px; height: 24px; text: UiStrings.srtp; font-size: ImGuiFontStyle.body; overflow: elide; vertical-alignment: center; } - ImGuiCheckBox { x: root.compact-language ? 157px : 224px; y: 3px; checked <=> root.srtp-enabled; enabled: !root.settings-session-active; } - } Rectangle { height: 30px; Text { x: 8px; y: 3px; width: root.compact-language ? 145px : 212px; height: 24px; text: UiStrings.privacy-on-connect; color: root.privacy-setting-available ? #202124 : #8b8f95; font-size: ImGuiFontStyle.body; overflow: elide; vertical-alignment: center; } diff --git a/apps/desktop/src/gui/ui/stream_window.slint b/apps/desktop/src/gui/ui/stream_window.slint index 1e419c68..7fd408fc 100644 --- a/apps/desktop/src/gui/ui/stream_window.slint +++ b/apps/desktop/src/gui/ui/stream_window.slint @@ -160,7 +160,6 @@ export component StreamWindow inherits Window { in property remote-cursor-active: false; in property remote-cursor-shape: 0; in property audio-enabled: true; - in property srtp-enabled: false; in property fullscreen-enabled: false; in property stats-visible: false; in property <[NetworkStatsRow]> stats-rows; @@ -506,20 +505,8 @@ export component StreamWindow inherits Window { width: parent.width - 27px; height: parent.height; background: transparent; - if root.srtp-enabled: Text { - x: 0px; - width: 12px; - height: parent.height; - text: FontAwesomeIcons.shield-halved; - color: #30343b; - font-family: "Font Awesome 6 Free"; - font-weight: 900; - font-size: ImGuiFontStyle.base; - horizontal-alignment: center; - vertical-alignment: center; - } Text { - x: root.srtp-enabled ? 16px : 0px; + x: 0px; width: parent.width - self.x; height: parent.height; text: tab.title; diff --git a/apps/desktop/src/gui/ui/ui_localization.h b/apps/desktop/src/gui/ui/ui_localization.h index c848def4..1ee4a127 100644 --- a/apps/desktop/src/gui/ui/ui_localization.h +++ b/apps/desktop/src/gui/ui/ui_localization.h @@ -69,7 +69,6 @@ inline int ApplyMainWindowStrings( strings.set_hardware_codec( Text(localization::enable_hardware_video_codec[language])); strings.set_turn_relay(Text(localization::enable_turn[language])); - strings.set_srtp(Text(localization::enable_srtp[language])); strings.set_self_hosted( Text(localization::self_hosted_server_config[language])); strings.set_autostart(Text(localization::enable_autostart[language])); diff --git a/apps/desktop/src/gui/views/windows/main_settings_window.cpp b/apps/desktop/src/gui/views/windows/main_settings_window.cpp index c304493c..d2f85dde 100644 --- a/apps/desktop/src/gui/views/windows/main_settings_window.cpp +++ b/apps/desktop/src/gui/views/windows/main_settings_window.cpp @@ -268,25 +268,6 @@ int GuiApplication::SettingWindow() { ImGui::Separator(); - { - settings_items_offset += settings_items_padding; - ImGui::SetCursorPosY(settings_items_offset); - ImGui::AlignTextToFramePadding(); - ImGui::Text( - "%s", - localization::enable_srtp[localization_language_index_].c_str()); - ImGui::SameLine(); - if (ConfigCenter::LANGUAGE::CHINESE == localization_language_) { - ImGui::SetCursorPosX(title_bar_button_width_ * 4.275f); - } else { - ImGui::SetCursorPosX(title_bar_button_width_ * 5.955f); - } - - ImGui::Checkbox("##enable_srtp", &enable_srtp_); - } - - ImGui::Separator(); - { settings_items_offset += settings_items_padding; ImGui::SetCursorPosY(settings_items_offset + 1); @@ -569,14 +550,6 @@ int GuiApplication::SettingWindow() { } enable_turn_last_ = enable_turn_; - // SRTP - if (enable_srtp_) { - config_center_->SetSrtp(true); - } else { - config_center_->SetSrtp(false); - } - enable_srtp_last_ = enable_srtp_; - if (enable_self_hosted_) { config_center_->SetSelfHosted(true); } else { diff --git a/apps/desktop/src/gui/views/windows/stream_window.cpp b/apps/desktop/src/gui/views/windows/stream_window.cpp index fa6450b0..7b54eb47 100644 --- a/apps/desktop/src/gui/views/windows/stream_window.cpp +++ b/apps/desktop/src/gui/views/windows/stream_window.cpp @@ -136,10 +136,7 @@ int GuiApplication::StreamWindow() { continue; } - std::string tab_label = - enable_srtp_ - ? std::string(ICON_FA_SHIELD_HALVED) + " " + props->remote_id_ - : props->remote_id_; + const std::string& tab_label = props->remote_id_; if (ImGui::BeginTabItem(tab_label.c_str(), &props->tab_opened_)) { props->tab_selected_ = true; ImGui::SetWindowFontScale(0.6f); @@ -308,4 +305,4 @@ int GuiApplication::StreamWindow() { return 0; } -} // namespace crossdesk \ No newline at end of file +} // namespace crossdesk diff --git a/apps/desktop/tests/config_center_srtp_test.cpp b/apps/desktop/tests/config_center_srtp_test.cpp new file mode 100644 index 00000000..ed45ca00 --- /dev/null +++ b/apps/desktop/tests/config_center_srtp_test.cpp @@ -0,0 +1,50 @@ +#include "config_center.h" + +#include +#include +#include +#include + +using crossdesk::ConfigCenter; + +static void Check(bool result, const char* message) { + if (!result) throw std::runtime_error(message); +} + +int main(int argc, char** argv) { + try { + Check(argc == 2, "provide a new isolated output directory"); + const std::filesystem::path root(argv[1]); + Check(std::filesystem::create_directory(root), "output directory must be new"); + unsigned cases = 0; + for (const auto* setting : {"new", "missing", "false", "true", "invalid"}) { + const auto path = root / (std::string(setting) + ".ini"); + if (std::string(setting) != "new") { + std::ofstream file(path); + file << "[Settings]\nlanguage=2\nturn_mode=2\nfile_transfer_save_path=/saved-path\n"; + if (std::string(setting) != "missing") file << "enable_srtp=" << setting << '\n'; + } + ConfigCenter config(path.string()); + Check(config.IsEnableSrtp(), "fresh and legacy settings must request SRTP"); + if (std::string(setting) != "new") { + Check(config.GetLanguage() == ConfigCenter::LANGUAGE::RUSSIAN && + config.GetTurnMode() == ConfigCenter::TURN_MODE::FORCE_UDP && + config.GetFileTransferSavePath() == "/saved-path", + "SRTP migration preserves unrelated preferences"); + } + CSimpleIniA saved; + Check(saved.LoadFile(path.string().c_str()) >= 0 && + saved.GetBoolValue("Settings", "enable_srtp", false), + "SRTP migration persists before any later settings save"); + Check(config.Save() == 0 && config.Load() == 0 && config.IsEnableSrtp(), + "settings save/reload cannot disable SRTP"); + ConfigCenter reopened(path.string()); + Check(reopened.IsEnableSrtp(), "SRTP survives restart"); + ++cases; + } + std::cout << "PASS SRTP configuration migration cases=" << cases << '\n'; + } catch (const std::exception& error) { + std::cerr << "FAIL: " << error.what() << '\n'; + return 1; + } +} diff --git a/apps/desktop/xmake/targets.lua b/apps/desktop/xmake/targets.lua index 0c5d1f91..4b5fbd0d 100644 --- a/apps/desktop/xmake/targets.lua +++ b/apps/desktop/xmake/targets.lua @@ -339,6 +339,12 @@ function setup_targets() add_includedirs("apps/desktop/src", "apps/desktop/src/config_center", {public = true}) + target("config_center_srtp_test") + set_kind("binary") + set_default(false) + add_deps("config_center") + add_files("apps/desktop/tests/config_center_srtp_test.cpp") + target("assets") set_kind("headeronly") add_includedirs("apps/desktop/src/gui/assets/localization", diff --git a/deps/submodules/minirtc b/deps/submodules/minirtc index 5e1b4381..ce3c41c0 160000 --- a/deps/submodules/minirtc +++ b/deps/submodules/minirtc @@ -1 +1 @@ -Subproject commit 5e1b4381fbd243893289ec434a8fe4030be2f79e +Subproject commit ce3c41c05c62a622ddf4ebb30866d7c487d1392e diff --git a/docs/p2p-punching-implementation-plan.md b/docs/p2p-punching-implementation-plan.md index cee83d53..62530e45 100644 --- a/docs/p2p-punching-implementation-plan.md +++ b/docs/p2p-punching-implementation-plan.md @@ -1,6 +1,6 @@ # CrossDesk 双端 UDP 打洞增强实现方案 -状态:P0 门槛已通过;P1–P4 默认关闭原型、受控运行与跨平台构建已实现;真实异网 C 组已有两次增强直连通过双端日志及抓包核验,正式 P5 对照仍待执行。按用户要求,画面、声音、控制和切换质量不纳入本次验收。日期:2026-09-14。第 15 节保留 P0 历史记录,最新进展与边界见第 16 节。 +状态:P0 门槛已通过,P1–P4 原型、受控运行与跨平台构建已实现。按用户最新要求,原生桌面默认且仅提供 pool-wide,CrossDesk 本机 SRTP 固定开启;无指纹旧端保留原有兼容回退。真实异网已有增强直连证据,默认调整不代表正式收益验收通过。按用户要求,画面、声音、控制和切换质量不纳入本次验收。日期:2026-09-14。第 15 节保留 P0 历史记录,最新进展与边界见第 16 节。 源码基线:CrossDesk `73e3bf709d7c054df7bd75cfafceda0721c6cda1`;MiniRTC 子模块 `f169a696cb4e6cb59037ec02e85532e30d3c1262`;libnice `0.1.24` 加仓库已有补丁。 @@ -54,7 +54,7 @@ Mac 先前发往 :11968 的短包没有出现在 Windows 捕获中;成功开 3. **新 socket 由 libnice 管理。** 不在 GUI、业务数据通道或独立线程中建立脱离 ICE 生命周期的临时 socket 池。 4. **探索和 ICE 检查分开调度。** 数百个目的端口属于有限的探索集合;只有少量命中端点进入普通检查表。 5. **保留普通 ICE 与已有 30 秒升级窗口。** 增强操作不能重置该窗口、重启 DTLS,或延迟正常的中继可用状态。 -6. **默认关闭。** 编译扩展存在、运行配置开启、双方声明支持、网络和连接状态满足条件时才启动。 +6. **默认 pool-wide。** 原生桌面包含扩展、无公开模式选择;双方声明支持、加密认证、网络和连接状态满足条件时才启动。未满足条件仍使用原 ICE/中继。iOS/WebRTC 不启用。 这会使第一版主要改善“已通过中继连接,但希望随后升为 P2P”的场景。将来需要在没有中继时运行同类算法,应另行设计可验证的信令协调通道。 @@ -232,7 +232,7 @@ HELLO 的重发额度耗尽只停止主动发送,在原升级截止内继续 控制包与新增 PROBE/ACK 单独计数;提升后的普通 STUN 检查遵循 libnice 原节拍,但需要记录它们带来的额外事务和重传。媒体包不计入探测预算。 -首次实现用内部配置和明确命名的实验环境变量加载配置,仅读取一次,不增加公开 `Params` 布局或 GUI 开关;例如 `MINIRTC_UDP_PUNCH=off|wide-only|pool-wide`。无效值禁用增强并打印原因。端口池大小等调参入口统一由同一校验函数处理。 +当前原生桌面配置仅读取一次,固定使用 pool-wide,不增加公开 `Params` 布局或 GUI 模式开关。原 `MINIRTC_UDP_PUNCH` 模式变量不再读取,公开编译开关已移除。端口池大小等诊断调参入口仍由同一校验函数处理;无效预算禁用增强并打印原因,不绕过资源上限。 `wide-only` 保留同样的协议、角色和锚点选择,但 pool 侧只用一个端点;`pool-wide` 使用配置的端点池。基线 `off` 仍保留已有附近端口预测。不能让实验分组顺带改变其他 ICE、TURN 或重试配置。 @@ -423,7 +423,7 @@ P0 工具只能使用实验提供的明确对端地址,不含广范围探测 不再将这些项目列为阻塞项,也不将免验记为测试通过。仍需证明同一命中 socket 完成标准 ICE 提名并持续承载应用数据,保留 DTLS、兼容性及资源生命周期检查。 -在真实网络证明净收益且兼容/退出检查通过之前,保持默认关闭;通过后再单独形成默认启用及参数调整变更。 +原计划将收益验收作为默认启用门槛;用户现明确要求默认且仅用 pool-wide,因此调整默认策略。网络适用范围、认证、原截止和资源预算不变;历史 A/B 记录保留,新程序不再提供 A/B 模式,详见 16.5。 ## 11. 测试设计 @@ -487,7 +487,7 @@ P0 工具只能使用实验提供的明确对端地址,不含广范围探测 如果 P0 证明某个后端接口或 selected-pair 路径不可按本文实现,应先根据实际 libnice 代码修订这一处设计并给出替代路径,再继续后续阶段;不要把未完成的直接验证改成强制选路或延长超时。 -本方案当前的执行目标是一个默认关闭、可复现实验、完整管理 socket 生命周期的原型。通过 P5 后,才讨论默认启用、扩大网络适用范围,以及首次连接阶段的增强。 +本方案原始执行目标是默认关闭的实验原型;当前默认策略按用户要求改为 pool-wide,见 16.5。扩大网络适用范围及首次连接阶段增强不属于这次默认调整。 ## 14. 技术依据 @@ -777,3 +777,25 @@ socket。命中、ACK、发送失败、同进程会话争用、原窗口剩余 TURN → 标准 ICE → 同一命中 socket 上持续 SRTP。默认开关、128/1024/128 PPS 实验参数、30 秒升级截止及 DTLS 生命周期不变。结果和 Windows 操作见 [修复验证记录](../deps/submodules/minirtc/tests/ice/lab/punch-runtime-validation-2026-09-14.md#hello-启动错位与映射地址碰撞修复2026-09-14)。 + + +### 16.5 默认 pool-wide 与本机 SRTP 固定开启(2026-09-14) + +按用户要求,原生桌面不再提供 off/wide-only/pool-wide 三选一入口,也移除公开 +构建开关。读取进程配置时直接选择 pool-wide;遗留模式环境变量不再生效,诊断 +TRACE 与有界预算调参仍保留。内部 Off 是不支持平台/无效参数状态,WideOnly +仅保留 v1 协议及 P0/单端点夹具用途,不是产品选项。 + +CrossDesk 移除 Slint 和旧 ImGui 设置中的 SRTP 控件、对应 setter 与可变 UI 状态。 +INI 中旧 false/缺失/无效 SRTP 值迁移为 true,其他配置保留;新建连接始终请求 +SRTP。用户对旧版兼容提出疑问,因此保留无 DTLS 指纹旧端的原明文回退:这是 +默认请求加密,不是拒绝所有明文旧端。该回退不能启动增强打洞。原来只根据本地 +设置显示的加密盾牌被移除,避免在旧端回退时误报已加密。 + +没有改变候选/认证门槛、128 个端点、1024 个目标、128 PPS、30 秒总窗口, +没有强制选路或重启 DTLS。旧端没有增强能力时继续普通 ICE/中继;iOS 和 WebRTC +不启用此增强。默认启用是用户选择,不能从中推导所有 NAT 都能直连。 + +实验工具新计划只生成 C/pool-wide,拒绝启动旧 A/B 条目;历史结果仍可读取汇总。 +同机自动入口、旧端能力与无指纹兼容、SRTP 配置迁移及真实 TURN/DTLS/SRTP +验证详见 [本次记录](../deps/submodules/minirtc/tests/ice/lab/punch-runtime-validation-2026-09-14.md#默认-pool-wide-与本机-srtp-固定开启2026-09-14)。 diff --git a/docs/p2p-uu-comparison-test-plan.md b/docs/p2p-uu-comparison-test-plan.md index 8d21a020..eff4694f 100644 --- a/docs/p2p-uu-comparison-test-plan.md +++ b/docs/p2p-uu-comparison-test-plan.md @@ -19,7 +19,7 @@ - 每批只测试一种软件,另一种软件退出;暂停其他远控、下载。Windows 需由本地 人员操作,不能依赖即将退出的 UU 会话完成进程重启。这是原始隔离条件;若依赖 UU 管理通道操作对端,按第 9 节执行,不要求终止该通道,不声称满足完全隔离。 -- CrossDesk 双端打开 SRTP,运行 `pool-wide`、`TRACE=1`;每批固定实验参数。 +- CrossDesk 双端默认请求 SRTP,运行默认 `pool-wide` 并设置 `TRACE=1`;每批固定实验参数。 原 U01/X01 批次为 64 个端点、512 个随机顺序目标、100 PPS;后续按第 10 节 使用 128 个端点、1024 个离散递增目标、128 PPS,两批均为 10 秒探索与 3 秒 检查收尾。记录实际协商参数,禁止把不同版本与预算混成同一批结果。 @@ -155,12 +155,11 @@ CrossDesk 两端启动命令(X01/X02): ```sh cd /Users/dijunkun/crossdesk -MINIRTC_UDP_PUNCH=pool-wide MINIRTC_UDP_PUNCH_TRACE=1 xmake r crossdesk +MINIRTC_UDP_PUNCH_TRACE=1 xmake r crossdesk ``` ```powershell Set-Location E:\SourceCode\crossdesk -$env:MINIRTC_UDP_PUNCH = 'pool-wide' $env:MINIRTC_UDP_PUNCH_TRACE = '1' .\build\windows\x64\debug\crossdesk.exe ```