|
26 | 26 | #include "Common/Serialize/Serializer.h"
|
27 | 27 | #include "Common/Serialize/SerializeFuncs.h"
|
28 | 28 | #include "Common/Serialize/SerializeMap.h"
|
| 29 | +#include "Common/System/OSD.h" |
29 | 30 | #include "Common/Data/Format/JSONReader.h"
|
30 | 31 | #include "Core/HLE/HLE.h"
|
31 | 32 | #include "Core/HLE/FunctionWrappers.h"
|
@@ -208,8 +209,9 @@ bool LoadDNSForGameID(std::string_view gameID, InfraDNSConfig *dns) {
|
208 | 209 | }
|
209 | 210 |
|
210 | 211 | std::string name = game.getStringOr("name", "");
|
| 212 | + std::string dyn_dns = game.getStringOr("dyn_dns", dns->dns.c_str()); |
211 | 213 | dns->dns = game.getStringOr("dns", dns->dns.c_str());
|
212 |
| - |
| 214 | + dns->dyn_dns = game.getStringOr("dyn_dns", ""); |
213 | 215 | if (game.hasChild("domains", JSON_OBJECT)) {
|
214 | 216 | const JsonGet domains = game.getDict("domains");
|
215 | 217 | for (auto iter : domains.value_) {
|
@@ -712,9 +714,45 @@ static int sceNetInit(u32 poolSize, u32 calloutPri, u32 calloutStack, u32 netini
|
712 | 714 | memset(&adhocSockets, 0, sizeof(adhocSockets));
|
713 | 715 |
|
714 | 716 | if (g_Config.bInfrastructureAutoDNS) {
|
715 |
| - // Load the automatic DNS config. |
| 717 | + // Load the automatic DNS config for this game - or the defaults. |
716 | 718 | std::string discID = g_paramSFO.GetDiscID();
|
717 | 719 | LoadDNSForGameID(discID, &g_infraDNSConfig);
|
| 720 | + |
| 721 | + // If dyn_dns is non-empty, try to use it to replace the specified DNS. |
| 722 | + // If fails, we just use the dns. TODO: Do this in the background somehow... |
| 723 | + const auto &dns = g_infraDNSConfig.dns; |
| 724 | + const auto &dyn_dns = g_infraDNSConfig.dyn_dns; |
| 725 | + if (!dyn_dns.empty()) { |
| 726 | + // Try to look it up in system DNS |
| 727 | + INFO_LOG(Log::sceNet, "DynDNS requested, trying to resolve '%s'...", dyn_dns.c_str()); |
| 728 | + addrinfo *resolved = nullptr; |
| 729 | + std::string err; |
| 730 | + if (!net::DNSResolve(dyn_dns, "", &resolved, err)) { |
| 731 | + ERROR_LOG(Log::sceNet, "Error resolving, falling back to '%s'", dns.c_str()); |
| 732 | + } else if (resolved) { |
| 733 | + bool found = false; |
| 734 | + for (auto ptr = resolved; ptr && !found; ptr = ptr->ai_next) { |
| 735 | + switch (ptr->ai_family) { |
| 736 | + case AF_INET: |
| 737 | + { |
| 738 | + char ipstr[256]; |
| 739 | + if (inet_ntop(ptr->ai_family, &(((struct sockaddr_in*)ptr->ai_addr)->sin_addr), ipstr, sizeof(ipstr)) != 0) { |
| 740 | + INFO_LOG(Log::sceNet, "Successfully resolved '%s' to '%s', overriding DNS.", dyn_dns.c_str(), ipstr); |
| 741 | + if (g_infraDNSConfig.dns != ipstr) { |
| 742 | + WARN_LOG(Log::sceNet, "Replacing specified DNS IP %s with dyndns %s!", g_infraDNSConfig.dns.c_str(), ipstr); |
| 743 | + g_infraDNSConfig.dns = ipstr; |
| 744 | + } else { |
| 745 | + INFO_LOG(Log::sceNet, "DynDNS: %s already up to date", g_infraDNSConfig.dns.c_str()); |
| 746 | + } |
| 747 | + found = true; |
| 748 | + } |
| 749 | + break; |
| 750 | + } |
| 751 | + } |
| 752 | + } |
| 753 | + net::DNSResolveFree(resolved); |
| 754 | + } |
| 755 | + } |
718 | 756 | }
|
719 | 757 |
|
720 | 758 | netInited = true;
|
|
0 commit comments