From 53a9f365ce0913178eb2f5e1506843610f3a7908 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Mon, 5 Jul 2021 16:42:59 -0500 Subject: [PATCH 1/2] Allow expired or not-yet-valid client certificates --- sunshine/crypto.cpp | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/sunshine/crypto.cpp b/sunshine/crypto.cpp index d109cc51..bbf15859 100644 --- a/sunshine/crypto.cpp +++ b/sunshine/crypto.cpp @@ -17,6 +17,26 @@ void cert_chain_t::add(x509_t &&cert) { _certs.emplace_back(std::make_pair(std::move(cert), std::move(x509_store))); } +static int openssl_verify_cb(int ok, X509_STORE_CTX *ctx) { + int err_code = X509_STORE_CTX_get_error(ctx); + + switch (err_code) { + //FIXME: Checking for X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY is a temporary workaround to get mmonlight-embedded to work on the raspberry pi + case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY: + return 1; + + // Expired or not-yet-valid certificates are fine. Sometimes Moonlight is running on embedded devices + // that don't have accurate clocks (or haven't yet synchronized by the time Moonlight first runs). + // This behavior also matches what GeForce Experience does. + case X509_V_ERR_CERT_NOT_YET_VALID: + case X509_V_ERR_CERT_HAS_EXPIRED: + return 1; + + default: + return ok; + } +} + /* * When certificates from two or more instances of Moonlight have been added to x509_store_t, * only one of them will be verified by X509_verify_cert, resulting in only a single instance of @@ -32,6 +52,7 @@ const char *cert_chain_t::verify(x509_t::element_type *cert) { }); X509_STORE_CTX_init(_cert_ctx.get(), x509_store.get(), nullptr, nullptr); + X509_STORE_CTX_set_verify_cb(_cert_ctx.get(), openssl_verify_cb); X509_STORE_CTX_set_cert(_cert_ctx.get(), cert); auto err = X509_verify_cert(_cert_ctx.get()); @@ -42,10 +63,6 @@ const char *cert_chain_t::verify(x509_t::element_type *cert) { err_code = X509_STORE_CTX_get_error(_cert_ctx.get()); - //FIXME: Checking for X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY is a temporary workaround to get mmonlight-embedded to work on the raspberry pi - if(err_code == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY) { - return nullptr; - } if(err_code != X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT && err_code != X509_V_ERR_INVALID_CA) { return X509_verify_cert_error_string(err_code); } From 667878d2ebeb636603c315101d96d621a3b6bece Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Mon, 5 Jul 2021 17:54:57 -0500 Subject: [PATCH 2/2] Fix IDR frame delays after packet loss or client request This can lead to spurious poor connection warnings in Moonlight. --- sunshine/video.cpp | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/sunshine/video.cpp b/sunshine/video.cpp index 1807edca..655c4775 100644 --- a/sunshine/video.cpp +++ b/sunshine/video.cpp @@ -1025,22 +1025,14 @@ void encode_run( return; } - auto end = event->second; - frame_nr = end; - key_frame_nr = end + config.framerate; - } - else if(frame_nr == key_frame_nr) { - auto frame = session->device->frame; - - frame->pict_type = AV_PICTURE_TYPE_I; - frame->key_frame = 1; + key_frame_nr = frame_nr; } std::this_thread::sleep_until(next_frame); next_frame += delay; // When Moonlight request an IDR frame, send frames even if there is no new captured frame - if(frame_nr > key_frame_nr || images->peek()) { + if(!frame->key_frame || images->peek()) { if(auto img = images->pop(delay)) { session->device->convert(*img); }