mirror of
https://github.com/moonlight-stream/Internet-Hosting-Tool.git
synced 2026-06-18 22:51:12 +00:00
Always run the loopback server test
It appears that in rare cases NAT reflection can work where real WAN traffic fails
This commit is contained in:
+69
-82
@@ -1283,101 +1283,88 @@ int main(int argc, char* argv[])
|
|||||||
// Go directly to the relay check if we have only IPv6 connectivity
|
// Go directly to the relay check if we have only IPv6 connectivity
|
||||||
igdDisconnected = false;
|
igdDisconnected = false;
|
||||||
locallyReportedWanAddr = {};
|
locallyReportedWanAddr = {};
|
||||||
goto RelayCheck;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to connect via WAN IPv4 address
|
struct addrinfo hint = {};
|
||||||
fprintf(LOG_OUT, "Testing GameStream ports via STUN-reported WAN address\n");
|
struct addrinfo* result;
|
||||||
if (!TestAllPorts(&ss, portMsgBuf, sizeof(portMsgBuf), false, true)) {
|
|
||||||
RelayCheck:
|
|
||||||
struct addrinfo hint = {};
|
|
||||||
struct addrinfo* result;
|
|
||||||
|
|
||||||
// We can get here if the router doesn't support NAT reflection.
|
hint.ai_family = AF_UNSPEC;
|
||||||
// We'll need to call out to our loopback server to get a second opinion.
|
hint.ai_flags = AI_ADDRCONFIG;
|
||||||
|
err = getaddrinfo("loopback.moonlight-stream.org", NULL, &hint, &result);
|
||||||
|
if (err != 0 || result == NULL) {
|
||||||
|
fprintf(LOG_OUT, "getaddrinfo() failed: %d\n", err);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
bool allPortsFailedOnV4 = true;
|
||||||
|
|
||||||
hint.ai_family = AF_UNSPEC;
|
// First try the relay server over IPv4. If this passes, it's considered a full success
|
||||||
hint.ai_flags = AI_ADDRCONFIG;
|
fprintf(LOG_OUT, "Testing GameStream ports via IPv4 loopback server\n");
|
||||||
err = getaddrinfo("loopback.moonlight-stream.org", NULL, &hint, &result);
|
for (struct addrinfo* current = result; current != NULL; current = current->ai_next) {
|
||||||
if (err != 0 || result == NULL) {
|
if (current->ai_family == AF_INET) {
|
||||||
fprintf(LOG_OUT, "getaddrinfo() failed: %d\n", err);
|
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, true, &allPortsFailedOnV4)) {
|
||||||
|
freeaddrinfo(result);
|
||||||
|
snprintf(msgBuf, sizeof(msgBuf), "This PC is ready to host over the Internet!\n\n"
|
||||||
|
"For the easiest setup, you should pair Moonlight to your gaming PC from your home network before trying to stream over the Internet.\n\n"
|
||||||
|
"If you can't, you can type the following address into Moonlight's Add PC dialog: %s", wanAddrStr);
|
||||||
|
DisplayMessage(msgBuf, nullptr, MpInfo);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
bool allPortsFailedOnV4 = true;
|
|
||||||
|
|
||||||
// First try the relay server over IPv4. If this passes, it's considered a full success
|
// If that fails, try the relay server over IPv6. If this passes, it will be a partial success
|
||||||
fprintf(LOG_OUT, "Testing GameStream ports via IPv4 loopback server\n");
|
fprintf(LOG_OUT, "Testing GameStream ports via IPv6 loopback server\n");
|
||||||
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_INET6) {
|
||||||
fprintf(CONSOLE_OUT, "Testing GameStream connectivity over the Internet using a 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, portMsgBuf, sizeof(portMsgBuf), true, true, &allPortsFailedOnV4)) {
|
// Pass the portMsgBuf only if we've detected an IPv6-only setup. Otherwise, we want to preserve
|
||||||
|
// the failing ports from the IPv4 to display in the error dialog.
|
||||||
|
if (TestAllPorts((PSOCKADDR_STORAGE)current->ai_addr,
|
||||||
|
ss.ss_family == AF_INET6 ? portMsgBuf : NULL,
|
||||||
|
ss.ss_family == AF_INET6 ? sizeof(portMsgBuf) : 0, true, true)) {
|
||||||
|
// 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
|
||||||
|
// 2) IPv6-only - indicates the connection is fundamentally limited to IPv6 for all connectivity
|
||||||
|
// 3) All ports failed the test with our IPv4 relay - This is one final heuristic to weed out IPv4 misconfigurations. If we have some ports open,
|
||||||
|
// it clearly indicates IPv4 support is possible, just currently misconfigured.
|
||||||
|
//
|
||||||
|
// Our last (implicit) heuristic is that we actually managed to establish an IPv6 connection. This means that there was either
|
||||||
|
// no IPv6 firewall (hopefully not) or that we were able to talk to a PCP/IGDv6 gateway to allow us through. Hopefully if we have
|
||||||
|
// a gateway that is unresponsive to UPnP/NAT-PMP, we wouldn't even be able to establish this connection so we would inherently fall
|
||||||
|
// to the checks below for IPv4 issues.
|
||||||
|
if (IsDoubleNAT(&locallyReportedWanAddr) || igdDisconnected || IsPossibleCGN(&locallyReportedWanAddr) || ss.ss_family == AF_INET6 || allPortsFailedOnV4) {
|
||||||
|
snprintf(msgBuf, sizeof(msgBuf), "This PC has limited connectivity for Internet hosting. It will work only for clients on certain networks.\n\n"
|
||||||
|
"If you want to try streaming with this configuration, you must pair Moonlight to your gaming PC from your home network before trying to stream over the Internet.\n\n"
|
||||||
|
"To get full connectivity, please contact your ISP and ask for a \"public IP address\" which they may offer for free upon request. For more information and workarounds, click the Help button.");
|
||||||
|
DisplayMessage(msgBuf, "https://github.com/moonlight-stream/moonlight-docs/wiki/Internet-Streaming-Errors#limited-connectivity-for-hosting-error", MpWarn);
|
||||||
freeaddrinfo(result);
|
freeaddrinfo(result);
|
||||||
goto AllTestsPassed;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If that fails, try the relay server over IPv6. If this passes, it will be a partial success
|
|
||||||
fprintf(LOG_OUT, "Testing GameStream ports via IPv6 loopback server\n");
|
|
||||||
for (struct addrinfo* current = result; current != NULL; current = current->ai_next) {
|
|
||||||
if (current->ai_family == AF_INET6) {
|
|
||||||
fprintf(CONSOLE_OUT, "Testing GameStream connectivity over the Internet using an IPv6 relay server...\n");
|
|
||||||
// Pass the portMsgBuf only if we've detected an IPv6-only setup. Otherwise, we want to preserve
|
|
||||||
// the failing ports from the IPv4 to display in the error dialog.
|
|
||||||
if (TestAllPorts((PSOCKADDR_STORAGE)current->ai_addr,
|
|
||||||
ss.ss_family == AF_INET6 ? portMsgBuf : NULL,
|
|
||||||
ss.ss_family == AF_INET6 ? sizeof(portMsgBuf) : 0, true, true)) {
|
|
||||||
// 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
|
|
||||||
// 2) IPv6-only - indicates the connection is fundamentally limited to IPv6 for all connectivity
|
|
||||||
// 3) All ports failed the test with our IPv4 relay - This is one final heuristic to weed out IPv4 misconfigurations. If we have some ports open,
|
|
||||||
// it clearly indicates IPv4 support is possible, just currently misconfigured.
|
|
||||||
//
|
|
||||||
// Our last (implicit) heuristic is that we actually managed to establish an IPv6 connection. This means that there was either
|
|
||||||
// no IPv6 firewall (hopefully not) or that we were able to talk to a PCP/IGDv6 gateway to allow us through. Hopefully if we have
|
|
||||||
// a gateway that is unresponsive to UPnP/NAT-PMP, we wouldn't even be able to establish this connection so we would inherently fall
|
|
||||||
// to the checks below for IPv4 issues.
|
|
||||||
if (IsDoubleNAT(&locallyReportedWanAddr) || igdDisconnected || IsPossibleCGN(&locallyReportedWanAddr) || ss.ss_family == AF_INET6 || allPortsFailedOnV4) {
|
|
||||||
snprintf(msgBuf, sizeof(msgBuf), "This PC has limited connectivity for Internet hosting. It will work only for clients on certain networks.\n\n"
|
|
||||||
"If you want to try streaming with this configuration, you must pair Moonlight to your gaming PC from your home network before trying to stream over the Internet.\n\n"
|
|
||||||
"To get full connectivity, please contact your ISP and ask for a \"public IP address\" which they may offer for free upon request. For more information and workarounds, click the Help button.");
|
|
||||||
DisplayMessage(msgBuf, "https://github.com/moonlight-stream/moonlight-docs/wiki/Internet-Streaming-Errors#limited-connectivity-for-hosting-error", MpWarn);
|
|
||||||
freeaddrinfo(result);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
freeaddrinfo(result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Many UPnP devices report IGD disconnected when double-NATed. If it was really offline,
|
freeaddrinfo(result);
|
||||||
// we probably would not have even gotten past STUN.
|
|
||||||
if (IsDoubleNAT(&locallyReportedWanAddr) || igdDisconnected) {
|
|
||||||
snprintf(msgBuf, sizeof(msgBuf), "Your router appears be connected to the Internet through another router. Click the Help button for guidance on fixing this issue.");
|
|
||||||
DisplayMessage(msgBuf, "https://github.com/moonlight-stream/moonlight-docs/wiki/Internet-Streaming-Errors#connected-through-another-router-error");
|
|
||||||
}
|
|
||||||
else if (IsPossibleCGN(&locallyReportedWanAddr)) {
|
|
||||||
snprintf(msgBuf, sizeof(msgBuf), "Your ISP is running a Carrier-Grade NAT that is preventing you from hosting services like Moonlight on the Internet.\n\n"
|
|
||||||
"Ask your ISP for a \"public IP address\" which they may offer for free upon request. For more information and workarounds, click the Help button.");
|
|
||||||
DisplayMessage(msgBuf, "https://github.com/moonlight-stream/moonlight-docs/wiki/Internet-Streaming-Errors#carrier-grade-nat-error");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
snprintf(msgBuf, sizeof(msgBuf), "Internet GameStream connectivity check failed.\n\n"
|
|
||||||
"First, try restarting your router. If that fails, check that UPnP is enabled in your router settings. For more information and workarounds, click the Help button.\n\n"
|
|
||||||
"The following ports were not forwarded properly:\n%s", portMsgBuf);
|
|
||||||
DisplayMessage(msgBuf, "https://github.com/moonlight-stream/moonlight-docs/wiki/Internet-Streaming-Errors#internet-gamestream-connectivity-check-error");
|
|
||||||
}
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AllTestsPassed:
|
// Many UPnP devices report IGD disconnected when double-NATed. If it was really offline,
|
||||||
snprintf(msgBuf, sizeof(msgBuf), "This PC is ready to host over the Internet!\n\n"
|
// we probably would not have even gotten past STUN.
|
||||||
"For the easiest setup, you should pair Moonlight to your gaming PC from your home network before trying to stream over the Internet.\n\n"
|
if (IsDoubleNAT(&locallyReportedWanAddr) || igdDisconnected) {
|
||||||
"If you can't, you can type the following address into Moonlight's Add PC dialog: %s", wanAddrStr);
|
snprintf(msgBuf, sizeof(msgBuf), "Your router appears be connected to the Internet through another router. Click the Help button for guidance on fixing this issue.");
|
||||||
DisplayMessage(msgBuf, nullptr, MpInfo);
|
DisplayMessage(msgBuf, "https://github.com/moonlight-stream/moonlight-docs/wiki/Internet-Streaming-Errors#connected-through-another-router-error");
|
||||||
|
}
|
||||||
|
else if (IsPossibleCGN(&locallyReportedWanAddr)) {
|
||||||
|
snprintf(msgBuf, sizeof(msgBuf), "Your ISP is running a Carrier-Grade NAT that is preventing you from hosting services like Moonlight on the Internet.\n\n"
|
||||||
|
"Ask your ISP for a \"public IP address\" which they may offer for free upon request. For more information and workarounds, click the Help button.");
|
||||||
|
DisplayMessage(msgBuf, "https://github.com/moonlight-stream/moonlight-docs/wiki/Internet-Streaming-Errors#carrier-grade-nat-error");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
snprintf(msgBuf, sizeof(msgBuf), "Internet GameStream connectivity check failed.\n\n"
|
||||||
|
"First, try restarting your router. If that fails, check that UPnP is enabled in your router settings. For more information and workarounds, click the Help button.\n\n"
|
||||||
|
"The following ports were not forwarded properly:\n%s", portMsgBuf);
|
||||||
|
DisplayMessage(msgBuf, "https://github.com/moonlight-stream/moonlight-docs/wiki/Internet-Streaming-Errors#internet-gamestream-connectivity-check-error");
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return -1;
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user