mirror of
https://github.com/kunkundi/crossdesk.git
synced 2026-10-17 17:33:21 +08:00
[fix] reuse stale sessions and stored passwords when reconnecting
This commit is contained in:
@@ -477,7 +477,42 @@ int GuiRuntime::ConnectTo(const std::string& remote_id, const char* password,
|
||||
LOG_INFO("Connect to [{}]", remote_id);
|
||||
focused_remote_id_ = remote_id;
|
||||
|
||||
bool exists = FindRemoteSession(remote_id) != nullptr;
|
||||
auto stale = FindRemoteSession(remote_id);
|
||||
bool exists = stale != nullptr;
|
||||
if (stale) {
|
||||
// A failed CreatePeer or a completed close can leave a session record
|
||||
// without a reusable peer. Recreate it instead of leaving the UI in
|
||||
// Connecting forever while JoinConnection has nothing to call.
|
||||
if (stale->peer_ == nullptr) {
|
||||
std::unique_lock lock(remote_sessions_mutex_);
|
||||
auto it = remote_sessions_.find(remote_id);
|
||||
if (it != remote_sessions_.end() && it->second == stale) {
|
||||
remote_sessions_.erase(it);
|
||||
exists = false;
|
||||
LOG_INFO("[{}] Recreating stale remote session before connect",
|
||||
remote_id);
|
||||
}
|
||||
}
|
||||
if (exists && !stale->closing_.load() &&
|
||||
!stale->connection_established_) {
|
||||
const auto status = stale->connection_status_.load();
|
||||
if (status == ConnectionStatus::Disconnected ||
|
||||
status == ConnectionStatus::Failed ||
|
||||
status == ConnectionStatus::Closed) {
|
||||
// The recreated session starts with an empty password; callers that
|
||||
// pass none expect the one stored by the previous attempt to be reused.
|
||||
const bool keep_stored_password = !password || !*password;
|
||||
pending_reconnects_[remote_id] = {
|
||||
keep_stored_password ? std::string(stale->remote_password_)
|
||||
: std::string(password),
|
||||
remember_password};
|
||||
CloseRemoteSession(stale);
|
||||
LOG_INFO("[{}] Reconnecting after terminal peer status {}", remote_id,
|
||||
static_cast<int>(status));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!exists) {
|
||||
PeerPtr* peer_to_init = nullptr;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <regex>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
@@ -114,8 +115,14 @@ int main() {
|
||||
"connection_attempt_active_");
|
||||
ok &= ExpectNotContains("connection_runtime.cpp", connection_runtime_cpp,
|
||||
"kConnectionAttemptTimeout");
|
||||
ok &= ExpectNotContains("connection_runtime.cpp", connection_runtime_cpp,
|
||||
"ConnectionStatus::Failed");
|
||||
// Reading a terminal transport status to reconnect is valid. This guard
|
||||
// prohibits synthesizing a failure locally, not comparisons with Failed.
|
||||
const std::regex synthetic_failure(
|
||||
R"((connection_status_\s*(=\s*|\.\s*(store|exchange)\s*\(\s*)|OnConnectionStatus\s*\(\s*)ConnectionStatus::Failed\b)");
|
||||
if (std::regex_search(connection_runtime_cpp, synthetic_failure)) {
|
||||
std::cerr << "connection_runtime.cpp synthesizes a Failed status\n";
|
||||
ok = false;
|
||||
}
|
||||
ok &= ExpectContains("peer_event_handler.cpp", peer_event_handler_cpp,
|
||||
"props->connection_status_.store(status);");
|
||||
ok &= ExpectContains("peer_event_handler.cpp", peer_event_handler_cpp,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#include <algorithm>
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
@@ -27,7 +28,12 @@ std::string ReadFile(const std::filesystem::path &path) {
|
||||
|
||||
std::ostringstream stream;
|
||||
stream << file.rdbuf();
|
||||
return stream.str();
|
||||
std::string contents = stream.str();
|
||||
// Normalize CRLF checkouts so multi-line expectations match on Windows
|
||||
// hosts with core.autocrlf enabled.
|
||||
contents.erase(std::remove(contents.begin(), contents.end(), '\r'),
|
||||
contents.end());
|
||||
return contents;
|
||||
}
|
||||
|
||||
bool ExpectContains(const char *name, const std::string &value,
|
||||
@@ -86,7 +92,7 @@ int main() {
|
||||
ok &= ExpectContains("targets.lua", targets,
|
||||
"target(\"crossdesk_session_helper\")");
|
||||
ok &= ExpectContains("targets.lua", targets,
|
||||
"add_files(crossdesk_windows_resource)");
|
||||
"add_files(crossdesk_windows_resource,");
|
||||
ok &= ExpectContains("session_helper_main.cpp", session_helper,
|
||||
"EnablePerMonitorDpiAwareness");
|
||||
ok &= ExpectContains("session_helper_main.cpp", session_helper,
|
||||
@@ -170,7 +176,8 @@ int main() {
|
||||
"Local Windows service temporarily unavailable");
|
||||
ok &= ExpectContains(
|
||||
"screen_capturer_win.cpp", screen_capturer_cpp,
|
||||
"Windows capturer secure desktop service temporarily unavailable");
|
||||
"Windows capturer secure desktop service temporarily \"\n"
|
||||
" \"unavailable");
|
||||
ok &= ExpectContains(
|
||||
"screen_capturer_win.cpp", screen_capturer_cpp,
|
||||
"Windows capturer secure desktop transient frame query failed");
|
||||
|
||||
@@ -31,7 +31,9 @@ int main() {
|
||||
static_cast<int>(crossdesk::ControlType::service_status) == 5 &&
|
||||
static_cast<int>(crossdesk::ControlType::service_command) == 6 &&
|
||||
static_cast<int>(crossdesk::ControlType::keyboard_state) == 7 &&
|
||||
static_cast<int>(crossdesk::ControlType::cursor_state) == 8,
|
||||
static_cast<int>(crossdesk::ControlType::cursor_state) == 8 &&
|
||||
static_cast<int>(crossdesk::ControlType::privacy_command) == 9 &&
|
||||
static_cast<int>(crossdesk::ControlType::privacy_status) == 10,
|
||||
"ControlType wire values changed");
|
||||
ok &= Expect(static_cast<int>(crossdesk::RemoteCursorShape::default_cursor) ==
|
||||
0 &&
|
||||
|
||||
Reference in New Issue
Block a user