diff --git a/sunshine/nvhttp.cpp b/sunshine/nvhttp.cpp index 0733056c..d0912c37 100644 --- a/sunshine/nvhttp.cpp +++ b/sunshine/nvhttp.cpp @@ -472,22 +472,21 @@ void launch(std::shared_ptr::Response> respons auto appid = util::from_view(args.at("appid")) -2; - stream::app_name.clear(); + stream::launch_session_t launch_session; if(appid >= 0) { auto pos = std::begin(proc::proc.get_apps()); std::advance(pos, appid); - stream::app_name = pos->first; + launch_session.app_name = pos->first; } auto clientID = args.at("uniqueid"s); - auto aesKey = *util::from_hex(args.at("rikey"s), true); + launch_session.gcm_key = *util::from_hex(args.at("rikey"s), true); uint32_t prepend_iv = util::endian::big(util::from_view(args.at("rikeyid"s))); auto prepend_iv_p = (uint8_t*)&prepend_iv; - std::copy(std::begin(aesKey), std::end(aesKey), std::begin(stream::gcm_key)); - auto next = std::copy(prepend_iv_p, prepend_iv_p + sizeof(prepend_iv), std::begin(stream::iv)); - std::fill(next, std::end(stream::iv), 0); + auto next = std::copy(prepend_iv_p, prepend_iv_p + sizeof(prepend_iv), std::begin(launch_session.iv)); + std::fill(next, std::end(launch_session.iv), 0); pt::ptree tree; @@ -498,6 +497,8 @@ void launch(std::shared_ptr::Response> respons response->write(data.str()); }); + stream::launch_event.raise(std::move(launch_session)); + /* bool sops = args.at("sops"s) == "1"; std::optional gcmap { std::nullopt }; diff --git a/sunshine/stream.cpp b/sunshine/stream.cpp index 08594862..e97e5c80 100644 --- a/sunshine/stream.cpp +++ b/sunshine/stream.cpp @@ -89,10 +89,7 @@ struct audio_packet_raw_t { #pragma pack(pop) -//TODO: Bundle in thread safe container -crypto::aes_t gcm_key; -crypto::aes_t iv; -std::string app_name; +safe::event_t launch_event; struct config_t { audio::config_t audio; @@ -847,12 +844,13 @@ void cmd_announce(host_t &host, peer_t peer, msg_t &&req) { auto seqn_str = std::to_string(req->sequenceNumber); option.content = const_cast(seqn_str.c_str()); - if(session.video_packets) { - // already streaming + if(session.video_packets || !launch_event.peek()) { + //Either already streaming or /launch has not been used respond(host, peer, &option, 503, "Service Unavailable", req->sequenceNumber, {}); return; } + auto launch_session { std::move(*launch_event.pop()) }; std::string_view payload { req->payload, (size_t)req->payloadLength }; @@ -917,6 +915,10 @@ void cmd_announce(host_t &host, peer_t peer, msg_t &&req) { return; } + auto &app_name = launch_session.app_name; + auto &gcm_key = launch_session.gcm_key; + auto &iv = launch_session.iv; + if(!app_name.empty() && session.app_name != app_name ) { if(auto err_code = proc::proc.execute(app_name)) { if(err_code == 404) { diff --git a/sunshine/stream.h b/sunshine/stream.h index d5824483..31546947 100644 --- a/sunshine/stream.h +++ b/sunshine/stream.h @@ -6,14 +6,16 @@ #define SUNSHINE_STREAM_H #include "crypto.h" - +#include "thread_safe.h" namespace stream { -//FIXME: Make thread safe -extern crypto::aes_t gcm_key; -extern crypto::aes_t iv; -extern std::string app_name; +struct launch_session_t { + crypto::aes_t gcm_key; + crypto::aes_t iv; + std::string app_name; +}; +extern safe::event_t launch_event; void rtpThread(); }