From b30311be657731865ce55292c5d6a5b57d3e4ac3 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Sun, 31 Jan 2021 08:27:56 -0800 Subject: [PATCH] dns.mitm: support wildcards in hosts --- .../dns_mitm/dnsmitm_host_redirection.cpp | 49 +++++++++++++++++-- 1 file changed, 46 insertions(+), 3 deletions(-) diff --git a/stratosphere/ams_mitm/source/dns_mitm/dnsmitm_host_redirection.cpp b/stratosphere/ams_mitm/source/dns_mitm/dnsmitm_host_redirection.cpp index a9ed4c95a..998c3aeca 100644 --- a/stratosphere/ams_mitm/source/dns_mitm/dnsmitm_host_redirection.cpp +++ b/stratosphere/ams_mitm/source/dns_mitm/dnsmitm_host_redirection.cpp @@ -23,10 +23,53 @@ namespace ams::mitm::socket::resolver { namespace { + /* https://github.com/clibs/wildcardcmp */ + constexpr int wildcardcmp(const char *pattern, const char *string) { + const char *w = nullptr; /* last `*` */ + const char *s = nullptr; /* last checked char */ + + /* malformed */ + if (!pattern || !string) return 0; + + /* loop 1 char at a time */ + while (1) { + if (!*string) { + if (!*pattern) return 1; + if ('*' == *pattern) return 1; + if (!*s) return 0; + string = s++; + pattern = w; + continue; + } else { + if (*pattern != *string) { + if ('*' == *pattern) { + w = ++pattern; + s = string; + /* "*" -> "foobar" */ + if (*pattern) continue; + return 1; + } else if (w) { + string++; + /* "*ooba*" -> "foobar" */ + continue; + } + return 0; + } + } + + string++; + pattern++; + } + + return 1; + } + constexpr const char DefaultHostsFile[] = "# Nintendo telemetry servers\n" - "127.0.0.1 receive-lp1.dg.srv.nintendo.net\n" - "127.0.0.1 receive-lp1.er.srv.nintendo.net\n"; + "127.0.0.1 receive-*.*.srv.nintendo.net\n"; + + static_assert(wildcardcmp("receive-*.*.srv.nintendo.net", "receive-lp1.dg.srv.nintendo.net") == 1); + static_assert(wildcardcmp("receive-*.*.srv.nintendo.net", "receive-lp1.er.srv.nintendo.net") == 1); constinit os::SdkMutex g_redirection_lock; std::unordered_map g_redirection_map; @@ -305,7 +348,7 @@ namespace ams::mitm::socket::resolver { std::scoped_lock lk(g_redirection_lock); for (const auto &[host, address] : g_redirection_map) { - if (std::strcmp(host.c_str(), hostname) == 0) { + if (wildcardcmp(host.c_str(), hostname) == 0) { *out = address; return true; }