Don't proceed after WSAEADDRINUSE for the loopback relay to avoid false positives

This commit is contained in:
Cameron Gutman
2019-07-30 21:47:29 -07:00
parent 5a2edb9a36
commit efdcaed4c1
+12 -11
View File
@@ -216,7 +216,7 @@ enum PortTestStatus {
PortTestError, PortTestError,
PortTestUnknown PortTestUnknown
}; };
PortTestStatus TestPort(PSOCKADDR_STORAGE addr, int proto, int port, bool withServer) PortTestStatus TestPort(PSOCKADDR_STORAGE addr, int proto, int port, bool withServer, bool isLoopbackRelay)
{ {
SOCKET clientSock = INVALID_SOCKET, serverSock = INVALID_SOCKET; SOCKET clientSock = INVALID_SOCKET, serverSock = INVALID_SOCKET;
int err; int err;
@@ -244,8 +244,9 @@ PortTestStatus TestPort(PSOCKADDR_STORAGE addr, int proto, int port, bool withSe
if (err == SOCKET_ERROR) { if (err == SOCKET_ERROR) {
if (WSAGetLastError() == WSAEADDRINUSE) { if (WSAGetLastError() == WSAEADDRINUSE) {
// If someone is already listening (perhaps GFE is currently streaming), // If someone is already listening (perhaps GFE is currently streaming),
// we can proceed if it's a TCP connection. // we can proceed if it's a TCP connection unless it's a loopback relay
if (proto == IPPROTO_TCP) { // which would give us a false positive result.
if (proto == IPPROTO_TCP && !isLoopbackRelay) {
closesocket(serverSock); closesocket(serverSock);
serverSock = INVALID_SOCKET; serverSock = INVALID_SOCKET;
} }
@@ -442,7 +443,7 @@ PortTestStatus TestHttpPort(PSOCKADDR_STORAGE addr, int port)
return PortTestOk; return PortTestOk;
} }
bool TestAllPorts(PSOCKADDR_STORAGE addr, char* portMsg, int portMsgLen, bool consolePrint, bool* allPortsFailed = nullptr) bool TestAllPorts(PSOCKADDR_STORAGE addr, char* portMsg, int portMsgLen, bool isLoopbackRelay, bool consolePrint, bool* allPortsFailed = nullptr)
{ {
bool ret = true; bool ret = true;
@@ -461,7 +462,7 @@ bool TestAllPorts(PSOCKADDR_STORAGE addr, char* portMsg, int portMsgLen, bool co
k_Ports[i].port); k_Ports[i].port);
} }
PortTestStatus status = TestPort(addr, k_Ports[i].proto, k_Ports[i].port, k_Ports[i].withServer); PortTestStatus status = TestPort(addr, k_Ports[i].proto, k_Ports[i].port, k_Ports[i].withServer, isLoopbackRelay);
if (status != PortTestError && !k_Ports[i].withServer) { if (status != PortTestError && !k_Ports[i].withServer) {
// Test using a real HTTP client if the port wasn't totally dead. // Test using a real HTTP client if the port wasn't totally dead.
@@ -837,7 +838,7 @@ int main(int argc, char* argv[])
sin.sin_family = AF_INET; sin.sin_family = AF_INET;
sin.sin_addr = in4addr_loopback; sin.sin_addr = in4addr_loopback;
fprintf(LOG_OUT, "Testing GameStream ports via loopback\n"); fprintf(LOG_OUT, "Testing GameStream ports via loopback\n");
if (!TestAllPorts(&ss, portMsgBuf, sizeof(portMsgBuf), true)) { if (!TestAllPorts(&ss, portMsgBuf, sizeof(portMsgBuf), false, true)) {
snprintf(msgBuf, sizeof(msgBuf), snprintf(msgBuf, sizeof(msgBuf),
"Local GameStream connectivity check failed.\n\nFirst, try reinstalling GeForce Experience. If that doesn't resolve the problem, try temporarily disabling your antivirus and firewall."); "Local GameStream connectivity check failed.\n\nFirst, try reinstalling GeForce Experience. If that doesn't resolve the problem, try temporarily disabling your antivirus and firewall.");
DisplayMessage(msgBuf, "https://github.com/moonlight-stream/moonlight-docs/wiki/Troubleshooting"); DisplayMessage(msgBuf, "https://github.com/moonlight-stream/moonlight-docs/wiki/Troubleshooting");
@@ -853,7 +854,7 @@ int main(int argc, char* argv[])
// Try to connect via LAN address // Try to connect via LAN address
fprintf(LOG_OUT, "Testing GameStream ports via local network\n"); fprintf(LOG_OUT, "Testing GameStream ports via local network\n");
if (!TestAllPorts(&ss, portMsgBuf, sizeof(portMsgBuf), true)) { if (!TestAllPorts(&ss, portMsgBuf, sizeof(portMsgBuf), false, true)) {
snprintf(msgBuf, sizeof(msgBuf), snprintf(msgBuf, sizeof(msgBuf),
"Local network GameStream connectivity check failed. This is almost always caused by a firewall on your computer blocking the connection.\n\nTry temporarily disabling your antivirus and firewall."); "Local network GameStream connectivity check failed. This is almost always caused by a firewall on your computer blocking the connection.\n\nTry temporarily disabling your antivirus and firewall.");
DisplayMessage(msgBuf, "https://github.com/moonlight-stream/moonlight-docs/wiki/Troubleshooting"); DisplayMessage(msgBuf, "https://github.com/moonlight-stream/moonlight-docs/wiki/Troubleshooting");
@@ -882,7 +883,7 @@ int main(int argc, char* argv[])
// We don't actually care about the outcome here but it's nice to have in logs // We don't actually care about the outcome here but it's nice to have in logs
// to determine whether solving the double NAT will actually make Moonlight work. // to determine whether solving the double NAT will actually make Moonlight work.
TestAllPorts((PSOCKADDR_STORAGE)&locallyReportedWanAddr, portMsgBuf, sizeof(portMsgBuf), false); TestAllPorts((PSOCKADDR_STORAGE)&locallyReportedWanAddr, portMsgBuf, sizeof(portMsgBuf), false, false);
fprintf(LOG_OUT, "Detected inconsistency between UPnP/NAT-PMP and STUN reported WAN addresses!\n"); fprintf(LOG_OUT, "Detected inconsistency between UPnP/NAT-PMP and STUN reported WAN addresses!\n");
} }
@@ -898,7 +899,7 @@ int main(int argc, char* argv[])
// Try to connect via WAN IPv4 address // Try to connect via WAN IPv4 address
fprintf(LOG_OUT, "Testing GameStream ports via STUN-reported WAN address\n"); fprintf(LOG_OUT, "Testing GameStream ports via STUN-reported WAN address\n");
if (!TestAllPorts(&ss, portMsgBuf, sizeof(portMsgBuf), true)) { if (!TestAllPorts(&ss, portMsgBuf, sizeof(portMsgBuf), false, true)) {
RelayCheck: RelayCheck:
struct addrinfo hint = {}; struct addrinfo hint = {};
struct addrinfo* result; struct addrinfo* result;
@@ -920,7 +921,7 @@ int main(int argc, char* argv[])
for (struct addrinfo* current = result; current != NULL; current = current->ai_next) { for (struct addrinfo* current = result; current != NULL; current = current->ai_next) {
if (current->ai_family == AF_INET) { if (current->ai_family == AF_INET) {
fprintf(CONSOLE_OUT, "Testing GameStream connectivity over the Internet using a relay server...\n"); fprintf(CONSOLE_OUT, "Testing GameStream connectivity over the Internet using a relay server...\n");
if (TestAllPorts((PSOCKADDR_STORAGE)current->ai_addr, portMsgBuf, sizeof(portMsgBuf), true, &allPortsFailedOnV4)) { if (TestAllPorts((PSOCKADDR_STORAGE)current->ai_addr, portMsgBuf, sizeof(portMsgBuf), true, true, &allPortsFailedOnV4)) {
freeaddrinfo(result); freeaddrinfo(result);
goto AllTestsPassed; goto AllTestsPassed;
} }
@@ -932,7 +933,7 @@ int main(int argc, char* argv[])
for (struct addrinfo* current = result; current != NULL; current = current->ai_next) { for (struct addrinfo* current = result; current != NULL; current = current->ai_next) {
if (current->ai_family == AF_INET6) { if (current->ai_family == AF_INET6) {
fprintf(CONSOLE_OUT, "Testing GameStream connectivity over the Internet using an IPv6 relay server...\n"); fprintf(CONSOLE_OUT, "Testing GameStream connectivity over the Internet using an IPv6 relay server...\n");
if (TestAllPorts((PSOCKADDR_STORAGE)current->ai_addr, NULL, 0, true)) { if (TestAllPorts((PSOCKADDR_STORAGE)current->ai_addr, NULL, 0, true, true)) {
// We will terminate the test at the IPv6 limited connectivity warning in the following cases: // We will terminate the test at the IPv6 limited connectivity warning in the following cases:
// 1) Double-NAT/CGN - indicates the connection is fundamentally limited to IPv6 for end-to-end connectivity // 1) Double-NAT/CGN - indicates the connection is fundamentally limited to IPv6 for end-to-end connectivity
// 2) IPv6-only - indicates the connection is fundamentally limited to IPv6 for all connectivity // 2) IPv6-only - indicates the connection is fundamentally limited to IPv6 for all connectivity