Add support for dynamic HTTPS port

This commit is contained in:
Cameron Gutman 2021-07-03 00:00:27 -05:00
parent 043c55ae66
commit 48728efee0
6 changed files with 40 additions and 15 deletions

View file

@ -29,7 +29,7 @@ public:
private:
bool tryPollComputer(NvAddress address, bool& changed)
{
NvHTTP http(address, m_Computer->serverCert);
NvHTTP http(address, 0, m_Computer->serverCert);
QString serverInfo;
try {
@ -595,7 +595,7 @@ void ComputerManager::addNewHostManually(QString address)
QUrl url = QUrl::fromUserInput(address);
if (url.isValid() && !url.host().isEmpty()) {
// If there wasn't a port specified, use the default
addNewHost(NvAddress(url.host(), url.port(47989)), false);
addNewHost(NvAddress(url.host(), url.port(DEFAULT_HTTP_PORT)), false);
}
else {
emit computerAddCompleted(false, false);
@ -671,7 +671,7 @@ private:
void run()
{
NvHTTP http(m_Address, QSslCertificate());
NvHTTP http(m_Address, 0, QSslCertificate());
qInfo() << "Processing new PC at" << m_Address.toString() << "from" << (m_Mdns ? "mDNS" : "user") << "with IPv6 address" << m_MdnsIpv6Address.toString();
@ -701,6 +701,7 @@ private:
// Fetch serverinfo again over HTTPS with the pinned cert
if (existingComputer != nullptr) {
Q_ASSERT(http.httpsPort() != 0);
serverInfo = fetchServerInfo(http);
if (serverInfo.isEmpty()) {
return;

View file

@ -2,6 +2,9 @@
#include <QHostAddress>
#define DEFAULT_HTTP_PORT 47989
#define DEFAULT_HTTPS_PORT 47984
class NvAddress
{
public:

View file

@ -7,8 +7,6 @@
#include <QNetworkInterface>
#include <QNetworkProxy>
#define DEFAULT_HTTP_PORT 47989
#define SER_NAME "hostname"
#define SER_UUID "uuid"
#define SER_MAC "mac"
@ -62,6 +60,7 @@ NvComputer::NvComputer(QSettings& settings)
this->gpuModel = nullptr;
this->isSupportedServerVersion = true;
this->externalPort = this->remoteAddress.port();
this->activeHttpsPort = 0;
}
void NvComputer::setRemoteAddress(QHostAddress address)
@ -156,10 +155,15 @@ NvComputer::NvComputer(NvHTTP& http, QString serverInfo)
this->localAddress = NvAddress();
}
QString httpsPort = NvHTTP::getXmlString(serverInfo, "HttpsPort");
if (httpsPort.isEmpty() || (this->activeHttpsPort = httpsPort.toUShort()) == 0) {
this->activeHttpsPort = DEFAULT_HTTPS_PORT;
}
// This is an extension which is not present in GFE. It is present for Sunshine to be able
// to support dynamic HTTP WAN ports without requiring the user to manually enter the port.
QString remotePortStr = NvHTTP::getXmlString(serverInfo, "ExternalPort");
if (remotePortStr.isEmpty() || (this->externalPort = this->remoteAddress.port()) == 0) {
if (remotePortStr.isEmpty() || (this->externalPort = remotePortStr.toUShort()) == 0) {
this->externalPort = DEFAULT_HTTP_PORT;
}
@ -442,6 +446,8 @@ bool NvComputer::update(NvComputer& that)
ASSIGN_IF_CHANGED_AND_NONNULL(remoteAddress);
ASSIGN_IF_CHANGED_AND_NONNULL(ipv6Address);
ASSIGN_IF_CHANGED_AND_NONNULL(manualAddress);
ASSIGN_IF_CHANGED(activeHttpsPort);
ASSIGN_IF_CHANGED(externalPort);
ASSIGN_IF_CHANGED(pairState);
ASSIGN_IF_CHANGED(serverCodecModeSupport);
ASSIGN_IF_CHANGED(currentGameId);

View file

@ -62,6 +62,7 @@ public:
ComputerState state;
PairState pairState;
NvAddress activeAddress;
uint16_t activeHttpsPort;
int currentGameId;
QString gfeVersion;
QString appVersion;

View file

@ -18,16 +18,14 @@
#define RESUME_TIMEOUT_MS 30000
#define QUIT_TIMEOUT_MS 30000
NvHTTP::NvHTTP(NvAddress address, QSslCertificate serverCert) :
NvHTTP::NvHTTP(NvAddress address, uint16_t httpsPort, QSslCertificate serverCert) :
m_ServerCert(serverCert)
{
m_BaseUrlHttp.setScheme("http");
m_BaseUrlHttps.setScheme("https");
setAddress(address);
// TODO: Use HttpsPort
setHttpsPort(47984);
setHttpsPort(httpsPort);
// Never use a proxy server
QNetworkProxy noProxy(QNetworkProxy::NoProxy);
@ -37,7 +35,7 @@ NvHTTP::NvHTTP(NvAddress address, QSslCertificate serverCert) :
}
NvHTTP::NvHTTP(NvComputer* computer) :
NvHTTP(computer->activeAddress, computer->serverCert)
NvHTTP(computer->activeAddress, computer->activeHttpsPort, computer->serverCert)
{
}
@ -127,8 +125,8 @@ NvHTTP::getServerInfo(NvLogLevel logLevel, bool fastFail)
{
QString serverInfo;
// Check if we have a pinned cert for this host yet
if (!m_ServerCert.isNull())
// Check if we have a pinned cert and HTTPS port for this host yet
if (!m_ServerCert.isNull() && httpsPort() != 0)
{
try
{
@ -163,13 +161,26 @@ NvHTTP::getServerInfo(NvLogLevel logLevel, bool fastFail)
}
else
{
// Only use HTTP prior to pairing
// Only use HTTP prior to pairing or fetching HTTPS port
serverInfo = openConnectionToString(m_BaseUrlHttp,
"serverinfo",
nullptr,
fastFail ? FAST_FAIL_TIMEOUT_MS : REQUEST_TIMEOUT_MS,
logLevel);
verifyResponseStatus(serverInfo);
// Populate the HTTPS port
uint16_t httpsPort = getXmlString(serverInfo, "HttpsPort").toUShort();
if (httpsPort == 0) {
httpsPort = DEFAULT_HTTPS_PORT;
}
setHttpsPort(httpsPort);
// If we just needed to determine the HTTPS port, we'll try again over
// HTTPS now that we have the port number
if (!m_ServerCert.isNull()) {
return getServerInfo(logLevel, fastFail);
}
}
return serverInfo;
@ -477,6 +488,9 @@ NvHTTP::openConnection(QUrl baseUrl,
int timeoutMs,
NvLogLevel logLevel)
{
// Port must be set
Q_ASSERT(baseUrl.port(0) != 0);
// Build a URL for the request
QUrl url(baseUrl);
url.setPath("/" + command);

View file

@ -109,7 +109,7 @@ public:
NVLL_VERBOSE
};
explicit NvHTTP(NvAddress address, QSslCertificate serverCert);
explicit NvHTTP(NvAddress address, uint16_t httpsPort, QSslCertificate serverCert);
explicit NvHTTP(NvComputer* computer);