mirror of
https://github.com/LizardByte/Sunshine.git
synced 2026-08-07 10:20:46 +00:00
fix(web): disconnect only the disabled client instead of all sessions (#5138)
This commit is contained in:
+4
-1
@@ -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();
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user