#include "rec-lua-conf.hh"
#include "ednsoptions.hh"
#include "gettime.hh"
+#include "pubsuffix.hh"
#ifdef NOD_ENABLED
#include "nod.hh"
#endif /* NOD_ENABLED */
}
parseACLs();
- sortPublicSuffixList();
+ initPublicSuffixList(::arg()["public-suffix-list-file"]);
if(!::arg()["dont-query"].empty()) {
vector<string> ips;
::arg().set("udp-source-port-max", "Maximum UDP port to bind on")="65535";
::arg().set("udp-source-port-avoid", "List of comma separated UDP port number to avoid")="11211";
::arg().set("rng", "Specify random number generator to use. Valid values are auto,sodium,openssl,getrandom,arc4random,urandom.")="auto";
+ ::arg().set("public-suffix-list-file", "Path to the Public Suffix List file, if any")="";
#ifdef NOD_ENABLED
::arg().set("new-domain-tracking", "Track newly observed domains (i.e. never seen before).")="no";
::arg().set("new-domain-log", "Log newly observed domains.")="yes";
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-#ifndef PDNS_PUBSUFFIX_HH
-extern const char* g_pubsuffix[];
-#endif
+#pragma once
+
+#include <string>
+#include <vector>
+
+extern std::vector<std::vector<std::string>> g_pubs;
+
+/* initialize the g_pubs variable with the public suffix list,
+ using the file passed in parameter if any, or the built-in
+ list otherwise.
+*/
+void initPublicSuffixList(const std::string& file);
std::map<std::string, std::string> getAllStatsMap();
extern pthread_mutex_t g_carbon_config_lock;
-void sortPublicSuffixList();
std::vector<std::pair<DNSName, uint16_t> >* pleaseGetQueryRing();
std::vector<std::pair<DNSName, uint16_t> >* pleaseGetServfailQueryRing();
std::vector<std::pair<DNSName, uint16_t> >* pleaseGetBogusQueryRing();
return ret.str();
}
-namespace {
- typedef vector<vector<string> > pubs_t;
- pubs_t g_pubs;
-}
-
-void sortPublicSuffixList()
-{
- for(const char** p=g_pubsuffix; *p; ++p) {
- string low=toLower(*p);
-
- vector<string> parts;
- stringtok(parts, low, ".");
- reverse(parts.begin(), parts.end());
- g_pubs.push_back(parts);
- }
- sort(g_pubs.begin(), g_pubs.end());
-}
-
// XXX DNSName Pain - this function should benefit from native DNSName methods
DNSName getRegisteredName(const DNSName& dom)
{
pollmplexer.cc \
protobuf.cc protobuf.hh \
pubsuffix.hh pubsuffix.cc \
+ pubsuffixloader.cc \
qtype.hh qtype.cc \
rcpgenerator.cc rcpgenerator.hh \
rec-carbon.cc \
setting.
Improves performance on Linux.
+.. _settting-public-suffix-list-file:
+
+``public-suffix-list-file``
+---------------------------
+.. versionadded:: 4.2.0
+
+- Path
+- Default: unset
+
+Path to the Public Suffix List file, if any. If set, PowerDNS will try to load the Public Suffix List from this file instead of using the built-in list. The PSL is used to group the queries by relevant domain names when displaying the top queries.
+
.. _setting-query-local-address:
``query-local-address``
--- /dev/null
+/*
+ * This file is part of PowerDNS or dnsdist.
+ * Copyright -- PowerDNS.COM B.V. and its contributors
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * In addition, for the avoidance of any doubt, permission is granted to
+ * link this program with OpenSSL and to (re)distribute the binaries
+ * produced as the result of such linking.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <fstream>
+#include <stdexcept>
+
+#include "dnsname.hh"
+#include "logger.hh"
+#include "misc.hh"
+#include "pubsuffix.hh"
+
+extern const char* g_pubsuffix[];
+std::vector<std::vector<std::string>> g_pubs;
+
+void initPublicSuffixList(const std::string& file)
+{
+ std::vector<std::vector<std::string>> pbList;
+
+ bool loaded = false;
+ if (!file.empty()) {
+ try {
+ std::ifstream suffixFile(file);
+ if (!suffixFile.is_open()) {
+ throw std::runtime_error("Error opening the public suffix list file");
+ }
+
+ std::string line;
+ while (std::getline(suffixFile, line)) {
+ if (line.empty() || (line.rfind("//", 0) == 0)) {
+ /* skip empty and commented lines */
+ continue;
+ }
+ try {
+ DNSName name(toLower(line));
+ pbList.push_back(name.labelReverse().getRawLabels());
+ }
+ catch(...) {
+ /* not a DNS name, ignoring */
+ }
+ }
+
+ g_log<<Logger::Info<<"Loaded the Public Suffix List from '"<<file<<"'"<<endl;
+ loaded = true;
+ }
+ catch (const std::exception& e) {
+ g_log<<Logger::Warning<<"Error while loading the Public Suffix List from '"<<file<<"', falling back to the built-in list: "<<e.what()<<endl;
+ }
+ }
+
+ if (!loaded) {
+ pbList.clear();
+
+ for(const char** p = g_pubsuffix; *p; ++p) {
+ string low=toLower(*p);
+
+ vector<string> parts;
+ stringtok(parts, low, ".");
+ reverse(parts.begin(), parts.end());
+ pbList.push_back(parts);
+ }
+ }
+
+ sort(pbList.begin(), pbList.end());
+ g_pubs = std::move(pbList);
+}