fix(web): disconnect only the disabled client instead of all sessions (#5138)

This commit is contained in:
neatnoise
2026-05-19 00:53:57 +02:00
committed by GitHub
parent 6d7740ceea
commit 3a196379c7
7 changed files with 46 additions and 1 deletions
+4 -1
View File
@@ -882,7 +882,10 @@ namespace confighttp {
output_tree["status"] = nvhttp::set_client_enabled(uuid, enabled);
if (!enabled && output_tree["status"]) {
rtsp_stream::terminate_sessions();
auto cert = nvhttp::get_cert_by_uuid(uuid);
if (!cert.empty()) {
rtsp_stream::terminate_sessions_by_cert(cert);
}
if (rtsp_stream::session_count() == 0 && proc::proc.running() > 0) {
proc::proc.terminate();
+14
View File
@@ -144,6 +144,9 @@ namespace nvhttp {
client_t client_root;
std::atomic<uint32_t> session_id_counter;
// Set by TLS verify callback, read by launch/resume handler (single-threaded HTTPS server)
std::string last_verified_client_cert; // NOSONAR(cpp:S5421) - intentionally mutable global
using args_t = SimpleWeb::CaseInsensitiveMultimap;
using resp_https_t = std::shared_ptr<typename SimpleWeb::ServerBase<SunshineHTTPS>::Response>;
using req_https_t = std::shared_ptr<typename SimpleWeb::ServerBase<SunshineHTTPS>::Request>;
@@ -326,6 +329,7 @@ namespace nvhttp {
launch_session->rtsp_iv_counter = 0;
}
launch_session->rtsp_url_scheme = launch_session->rtsp_cipher ? "rtspenc://"s : "rtsp://"s;
launch_session->client_cert = last_verified_client_cert;
// Generate the unique identifiers for this connection that we will send later during RTSP handshake
unsigned char raw_payload[8];
@@ -1141,6 +1145,7 @@ namespace nvhttp {
return verified;
}
last_verified_client_cert = pem;
verified = 1;
return verified;
@@ -1255,6 +1260,15 @@ namespace nvhttp {
return false;
}
std::string get_cert_by_uuid(const std::string_view uuid) {
for (const auto &named_cert : client_root.named_devices) {
if (named_cert.uuid == uuid) {
return named_cert.cert;
}
}
return {};
}
bool is_client_enabled(const std::string_view cert_pem) {
const client_t &client = client_root;
for (const auto &named_cert : client.named_devices) {
+1
View File
@@ -191,6 +191,7 @@ namespace nvhttp {
* @return true if the client was found and updated.
*/
bool set_client_enabled(std::string_view uuid, bool enabled);
std::string get_cert_by_uuid(std::string_view uuid);
/**
* @brief Get all paired clients.
+18
View File
@@ -569,6 +569,20 @@ namespace rtsp_stream {
}
}
void clear_by_cert(std::string_view cert) {
auto lg = _session_slots.lock();
for (auto i = _session_slots->begin(); i != _session_slots->end();) {
auto &slot = *(*i);
if (stream::session::client_cert(slot) == cert) {
stream::session::stop(slot);
stream::session::join(slot);
i = _session_slots->erase(i);
} else {
i++;
}
}
}
/**
* @brief Removes the provided session from the set of sessions.
* @param session The session to remove.
@@ -643,6 +657,10 @@ namespace rtsp_stream {
server.clear(true);
}
void terminate_sessions_by_cert(std::string_view cert) {
server.clear_by_cert(cert);
}
int send(tcp::socket &sock, const std::string_view &sv) {
std::size_t bytes_send = 0;
+2
View File
@@ -39,6 +39,7 @@ namespace rtsp_stream {
std::optional<crypto::cipher::gcm_t> rtsp_cipher;
std::string rtsp_url_scheme;
uint32_t rtsp_iv_counter;
std::string client_cert;
};
void launch_session_raise(std::shared_ptr<launch_session_t> launch_session);
@@ -59,6 +60,7 @@ namespace rtsp_stream {
* @brief Terminates all running streaming sessions.
*/
void terminate_sessions();
void terminate_sessions_by_cert(std::string_view cert);
/**
* @brief Runs the RTSP server loop.
+6
View File
@@ -405,6 +405,7 @@ namespace stream {
} control;
std::uint32_t launch_session_id;
std::string client_cert;
safe::mail_raw_t::event_t<bool> shutdown_event;
safe::signal_t controlEnd;
@@ -1902,6 +1903,10 @@ namespace stream {
return session.state.load(std::memory_order_relaxed);
}
const std::string &client_cert(session_t &session) {
return session.client_cert;
}
void stop(session_t &session) {
while_starting_do_nothing(session.state);
auto expected = state_e::RUNNING;
@@ -2009,6 +2014,7 @@ namespace stream {
session->shutdown_event = mail->event<bool>(mail::shutdown);
session->launch_session_id = launch_session.id;
session->client_cert = launch_session.client_cert;
session->config = config;
+1
View File
@@ -51,5 +51,6 @@ namespace stream {
void stop(session_t &session);
void join(session_t &session);
state_e state(session_t &session);
const std::string &client_cert(session_t &session);
} // namespace session
} // namespace stream