diff --git a/sunshine/nvhttp.cpp b/sunshine/nvhttp.cpp index 994b9daf..66efae76 100644 --- a/sunshine/nvhttp.cpp +++ b/sunshine/nvhttp.cpp @@ -721,7 +721,7 @@ void resume(bool &host_audio, resp_https_t response, req_https_t request) { stream::launch_session_raise(make_launch_session(host_audio, args)); tree.put("root..status_code", 200); - tree.put("root.sessionUrl0", "rtspru://"s + request->local_endpoint_address() + ':' + std::to_string(map_port(stream::RTSP_SETUP_PORT))); + tree.put("root.sessionUrl0", "rtsp://"s + request->local_endpoint_address() + ':' + std::to_string(map_port(stream::RTSP_SETUP_PORT))); tree.put("root.resume", 1); } diff --git a/sunshine/rtsp.cpp b/sunshine/rtsp.cpp index ab86a1db..b67d8f2e 100644 --- a/sunshine/rtsp.cpp +++ b/sunshine/rtsp.cpp @@ -9,6 +9,7 @@ extern "C" { } #include +#include #include #include @@ -42,6 +43,7 @@ using cmd_func_t = std::function { public: @@ -77,11 +79,17 @@ public: socket->sock.close(); }); - msg_t req { new msg_t::element_type }; + msg_t req { new msg_t::element_type {} }; auto &incomplete = socket->incomplete; + if(incomplete.empty()) { - parseRtspMessage(req.get(), socket->msg_buf.data(), bytes); + if(auto status = parseRtspMessage(req.get(), socket->msg_buf.data(), bytes)) { + BOOST_LOG(error) << "Malformed RTSP message: ["sv << status << ']'; + + respond(socket->sock, nullptr, 400, "BAD REQUEST", req->sequenceNumber, {}); + return; + } for(auto option = req->options; option != nullptr; option = option->next) { if("Content-length"sv == option->option) { @@ -89,8 +97,11 @@ public: // If content_length > bytes read, then we need to store current data read, // to be appended by the next read. - auto content_length = util::from_view(option->content); - if(content_length <= bytes) { + std::string_view content { option->content }; + auto begin = std::find_if(std::begin(content), std::end(content), [](auto ch) { return (bool)std::isdigit(ch); }); + + socket->content_length = util::from_chars(begin, std::end(content)); + if(socket->content_length <= bytes + incomplete.size()) { break; } @@ -112,7 +123,17 @@ public: std::copy_n(socket->msg_buf.data(), bytes, std::begin(incomplete) + incomplete_size); - parseRtspMessage(req.get(), incomplete.data(), incomplete.size()); + if(incomplete.size() < socket->content_length) { + fg.disable(); + return; + } + + if(auto status = parseRtspMessage(req.get(), incomplete.data(), incomplete.size())) { + BOOST_LOG(error) << "Malformed RTSP message: ["sv << status << ']'; + + respond(socket->sock, nullptr, 400, "BAD REQUEST", req->sequenceNumber, {}); + return; + } } print_msg(req.get()); @@ -128,8 +149,10 @@ public: tcp::socket sock; + std::vector incomplete; + std::size_t content_length = std::numeric_limits::max(); std::array msg_buf; }; @@ -152,6 +175,8 @@ public: return -1; } + acceptor.set_option(boost::asio::socket_base::reuse_address { true }); + acceptor.bind(tcp::endpoint(tcp::v4(), port), ec); if(ec) { return -1; @@ -532,10 +557,10 @@ void cmd_announce(rtsp_server_t *server, tcp::socket &sock, msg_t &&req) { config.audio.flags[audio::config_t::HIGH_QUALITY] = util::from_view(args.at("x-nv-audio.surround.AudioQuality"sv)); - config.controlProtocolType = util::from_view(args.at("x-nv-general.useReliableUdp"sv)); - config.packetsize = util::from_view(args.at("x-nv-video[0].packetSize"sv)); - config.minRequiredFecPackets = util::from_view(args.at("x-nv-vqos[0].fec.minRequiredFecPackets"sv)); - config.featureFlags = util::from_view(args.at("x-nv-general.featureFlags"sv)); + config.controlProtocolType = util::from_view(args.at("x-nv-general.useReliableUdp"sv)); + config.packetsize = util::from_view(args.at("x-nv-video[0].packetSize"sv)); + config.minRequiredFecPackets = util::from_view(args.at("x-nv-vqos[0].fec.minRequiredFecPackets"sv)); + config.featureFlags = util::from_view(args.at("x-nv-general.featureFlags"sv)); config.monitor.height = util::from_view(args.at("x-nv-video[0].clientViewportHt"sv)); config.monitor.width = util::from_view(args.at("x-nv-video[0].clientViewportWd"sv)); diff --git a/sunshine/upnp.cpp b/sunshine/upnp.cpp index ad17e880..a8fc6f4b 100644 --- a/sunshine/upnp.cpp +++ b/sunshine/upnp.cpp @@ -139,7 +139,7 @@ std::unique_ptr start() { auto wm_http = std::to_string(map_port(confighttp::PORT_HTTPS)); std::vector mappings { - { rtsp, rtsp, "RTSP setup port"s, false }, + { rtsp, rtsp, "RTSP setup port"s, true }, { video, video, "Video stream port"s, false }, { audio, audio, "Control stream port"s, false }, { control, control, "Audio stream port"s, false },