]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
Add an API-specific lookup method to DNSBackend.
authorMiod Vallat <miod.vallat@powerdns.com>
Thu, 20 Mar 2025 13:35:00 +0000 (14:35 +0100)
committerMiod Vallat <miod.vallat@powerdns.com>
Mon, 14 Apr 2025 14:57:40 +0000 (16:57 +0200)
This method, APILookup(), behaves similarly to lookup() but allows
disabled records to be returned to the caller. Backends with no support
for disabled records (bind, geoip, ldap, lua2, pipe, tinydns) implement
it as a by-default wrapper over lookup(). Other backends override with
their own processing.

SQL-style backends use distinct queries, api-id-query and
api-any-id-query, so as not to penalize non-API workloads.

13 files changed:
docs/backends/remote.rst
modules/gmysqlbackend/gmysqlbackend.cc
modules/godbcbackend/godbcbackend.cc
modules/gpgsqlbackend/gpgsqlbackend.cc
modules/gsqlite3backend/gsqlite3backend.cc
modules/lmdbbackend/lmdbbackend.cc
modules/lmdbbackend/lmdbbackend.hh
modules/remotebackend/remotebackend.cc
modules/remotebackend/remotebackend.hh
pdns/backends/gsql/gsqlbackend.cc
pdns/backends/gsql/gsqlbackend.hh
pdns/dnsbackend.cc
pdns/dnsbackend.hh

index 2be4f4ebe8fae4809e5cd841dc6d18142c68ba7e..59748bca4e89f3e59d621bd2658fc6a8540391dc 100644 (file)
@@ -156,6 +156,7 @@ Methods required for different features
 :Secondary operation: ``getUnfreshSlaveInfos``, ``startTransaction``, ``commitTransaction``, ``abortTransaction``, ``feedRecord``, ``setFresh``
 :DNSSEC operation (live-signing): ``getDomainKeys``, ``getBeforeAndAfterNamesAbsolute``
 :Filling the Zone Cache: ``getAllDomains``
+:HTTP API specific: ``APILookup``
 
 ``initialize``
 ~~~~~~~~~~~~~~
@@ -163,7 +164,7 @@ Methods required for different features
 Called to initialize the backend. This is not called for HTTP connector.
 You should do your initializations here.
 
--  Mandatory: Yes (except HTTP connector)
+-  Mandatory: yes (except HTTP connector)
 -  Parameters: all parameters in connection string
 -  Reply: true on success / false on failure
 
@@ -190,7 +191,7 @@ Response:
 This method is used to do the basic query. You can omit auth, but if you
 are using DNSSEC this can lead into trouble.
 
--  Mandatory: Yes
+-  Mandatory: yes
 -  Parameters: qtype, qname, zone_id
 -  Optional parameters: remote, local, real-remote
 -  Reply: array of ``qtype,qname,content,ttl,domain_id,scopeMask,auth``
@@ -236,6 +237,20 @@ Response:
 
     {"result":[{"qtype":"A", "qname":"www.example.com", "content":"203.0.113.2", "ttl": 60}]}
 
+``APILookup``
+~~~~~~~~~~~~~
+
+This method is similar to :ref:`remote-lookup`, but also returns disabled
+records. It allows for an extra optional parameter, ``include_disabled`` which, 
+if present and set to false, will only return non-disabled records (in which
+case, the behaviour is equivalent to the ``lookup`` method.)
+
+-  Mandatory: no (required if the HTTP API is to be used)
+-  Parameters: qtype, qname, zone_id
+-  Optional parameters: remote, local, real-remote, include_disabled
+-  Reply: array of ``qtype,qname,content,ttl,domain_id,scopeMask,auth,disabled``
+-  Optional values: scopeMask and auth
+
 ``list``
 ~~~~~~~~
 
@@ -243,7 +258,7 @@ Lists all records for the zonename. If you are running DNSSEC, you
 should take care of setting auth to appropriate value, otherwise things
 can go wrong.
 
--  Mandatory: No (Gives AXFR support)
+-  Mandatory: no (gives AXFR support)
 -  Parameters: zonename, domain_id
 -  Optional parameters: domain_id
 -  Reply: array of ``qtype,qname,content,ttl,domain_id,scopeMask,auth``
@@ -385,7 +400,7 @@ one of NSEC3PARAM, PRESIGNED, SOA-EDIT. Can be others, too. You **must**
 always return something, if there are no values, you shall return an empty
 array.
 
--  Mandatory: No
+-  Mandatory: no
 -  Parameters: name, kind
 -  Reply: array of strings
 
@@ -429,7 +444,7 @@ Replaces the value(s) on domain name for variable kind to string(s) on
 array value. The old value is discarded. Value can be an empty array,
 which can be interpreted as deletion request.
 
--  Mandatory: No
+-  Mandatory: no
 -  Parameters: name, kind, value
 -  Reply: true on success, false on failure
 
@@ -543,7 +558,7 @@ Response:
 
 Adds key into local storage. See :ref:`remote-getdomainkeys` for more information.
 
--  Mandatory: No
+-  Mandatory: no
 -  Parameters: name, key=\ ``<flags,active,published,content>``, id
 -  Reply: true for success, false for failure
 
@@ -607,7 +622,7 @@ Response:
 
 Removes key id from domain name.
 
--  Mandatory: No
+-  Mandatory: no
 -  Parameters: name, id
 -  Reply: true for success, false for failure
 
@@ -649,7 +664,7 @@ Response:
 
 Activates key id for domain name.
 
--  Mandatory: No
+-  Mandatory: no
 -  Parameters: name, id
 -  Reply: true for success, false for failure
 
@@ -691,7 +706,7 @@ Response:
 
 Deactivates key id for domain name.
 
--  Mandatory: No
+-  Mandatory: no
 -  Parameters: name, id
 -  Reply: true for success, false for failure
 
@@ -733,7 +748,7 @@ Response:
 
 Publish key id for domain name.
 
--  Mandatory: No
+-  Mandatory: no
 -  Parameters: name, id
 -  Reply: true for success, false for failure
 
@@ -776,7 +791,7 @@ Response:
 
 Unpublish key id for domain name.
 
--  Mandatory: No
+-  Mandatory: no
 -  Parameters: name, id
 -  Reply: true for success, false for failure
 
@@ -819,7 +834,7 @@ Response:
 
 Retrieves the key needed to sign AXFR.
 
--  Mandatory: No
+-  Mandatory: no
 -  Parameters: name
 -  Reply: algorithm, content
 
@@ -865,7 +880,7 @@ Everything else will default to something. Default values: serial:0,
 kind:NATIVE, id:-1, notified_serial:-1, last_check:0, masters: [].
 Masters, if present, must be array of strings.
 
--  Mandatory: No
+-  Mandatory: no
 -  Parameters: name
 -  Reply: zone
 -  Optional values: serial, kind, id, notified_serial, last_check,
@@ -909,7 +924,7 @@ Response:
 
 Updates last notified serial for the domain id. Any errors are ignored.
 
--  Mandatory: No
+-  Mandatory: no
 -  Parameters: id, serial
 -  Reply: true for success, false for failure
 
@@ -955,7 +970,7 @@ Response:
 
 Determines whether given IP is primary for given domain name.
 
--  Mandatory: No
+-  Mandatory: no
 -  Parameters: name,ip
 -  Reply: true for success, false for failure.
 
@@ -999,7 +1014,7 @@ Creates new domain with given record(s) as primary servers. IP address is
 the address where notify is received from. nsset is array of NS resource
 records.
 
--  Mandatory: No
+-  Mandatory: no
 -  Parameters: ip,domain,nsset,account
 -  Reply: true for success, false for failure. can also return
    account=>name of account< and nameserver.
@@ -1061,7 +1076,7 @@ Alternative response
 Creates new domain. This method is called when NOTIFY is received and
 you are superslaving.
 
- - Mandatory: No
+ - Mandatory: no
  - Parameters: ip, domain
  - Optional parameters: nameserver, account
  - Reply: true for success, false for failure
@@ -1107,7 +1122,7 @@ Response:
 This method replaces a given resource record with new set. The new qtype
 can be different from the old.
 
--  Mandatory: No
+-  Mandatory: no
 -  Parameters: domain_id, qname, qtype, rrset
 -  Reply: true for success, false for failure
 
@@ -1154,7 +1169,7 @@ Response:
 Asks to feed new record into system. If startTransaction was called,
 trxId identifies a transaction. It is not always called by PowerDNS.
 
--  Mandatory: No
+-  Mandatory: no
 -  Parameters: rr, trxid
 -  Reply: true for success, false for failure
 
@@ -1206,7 +1221,7 @@ _sip._upd.example.com, but no _udp.example.com. PowerDNS requires
 that there exists a non-terminal in between, and this instructs you to
 add one. If startTransaction is called, trxid identifies a transaction.
 
--  Mandatory: No
+-  Mandatory: no
 -  Parameters: nonterm, trxid
 -  Reply: true for success, false for failure
 
@@ -1253,7 +1268,7 @@ Response:
 Same as :ref:`remote-feedents`, but provides NSEC3 hashing
 parameters. Note that salt is BYTE value, and can be non-readable text.
 
--  Mandatory: No
+-  Mandatory: no
 -  Parameters: trxid, domain_id, domain, times, salt, narrow, nonterm
 -  Reply: true for success, false for failure
 
@@ -1300,7 +1315,7 @@ Response:
 Starts a new transaction. Transaction ID is chosen for you. Used to
 identify f.ex. AXFR transfer.
 
--  Mandatory: No
+-  Mandatory: no
 -  Parameters: domain_id, domain, trxid
 -  Reply: true for success, false for failure
 
@@ -1347,7 +1362,7 @@ Response:
 Signals successful transfer and asks to commit data into permanent
 storage.
 
--  Mandatory: No
+-  Mandatory: no
 -  Parameters: trxid
 -  Reply: true for success, false for failure
 
@@ -1391,7 +1406,7 @@ Response:
 
 Signals failed transaction, and that you should rollback any changes.
 
--  Mandatory: No
+-  Mandatory: no
 -  Parameters: trxid
 -  Reply: true for success, false for failure
 
@@ -1436,7 +1451,7 @@ Response:
 Asks you to calculate a new serial based on the given data and update
 the serial.
 
--  Mandatory: No
+-  Mandatory: no
 -  Parameters: domain,sd
 -  Reply: true for success, false for failure
 
@@ -1700,7 +1715,7 @@ Response:
 Called when a primary freshness check succeeded. This does not indicate the
 zone was updated on the primary.
 
--  Mandatory: No
+-  Mandatory: no
 -  Parameters: id
 -  Reply: true for success, false for failure
 
index 77c2fcd1b80a16ce74e3560c78455d0e5740f171..1b1f161eaf0c220193e40f12e968c963c7f50801 100644 (file)
@@ -94,6 +94,9 @@ public:
     declare(suffix, "any-query", "Any query", record_query + " disabled=0 and name=?");
     declare(suffix, "any-id-query", "Any with ID query", record_query + " disabled=0 and name=? and domain_id=?");
 
+    declare(suffix, "api-id-query", "API basic with ID query", record_query + " (disabled=0 or ?) and type=? and name=? and domain_id=?");
+    declare(suffix, "api-any-id-query", "API any with ID query", record_query + " (disabled=0 or ?) and name=? and domain_id=?");
+
     declare(suffix, "list-query", "AXFR query", "SELECT content,ttl,prio,type,domain_id,disabled,name,auth,ordername FROM records WHERE (disabled=0 OR ?) and domain_id=? order by name, type");
     declare(suffix, "list-subzone-query", "Subzone listing", record_query + " disabled=0 and (name=? OR name like ?) and domain_id=?");
 
index 00d30bc4bbf072107b9e6d2e42012570507b159d..f2c4b0fcaa5816a06862e0fc7c31f63fd2fde1d3 100644 (file)
@@ -75,6 +75,9 @@ public:
     declare(suffix, "any-query", "Any query", record_query + " disabled=0 and name=?");
     declare(suffix, "any-id-query", "Any with ID query", record_query + " disabled=0 and name=? and domain_id=?");
 
+    declare(suffix, "api-id-query", "API basic with ID query", record_query + " (disabled=0 or disabled=?) and type=? and name=? and domain_id=?");
+    declare(suffix, "api-any-id-query", "API any with ID query", record_query + " (disabled=0 or disabled=?) and name=? and domain_id=?");
+
     declare(suffix, "list-query", "AXFR query", "SELECT content,ttl,prio,type,domain_id,disabled,name,auth,CONVERT(varchar(255), ordername, 0) FROM records WHERE (disabled=0 OR disabled=?) and domain_id=? order by name, type");
     declare(suffix, "list-subzone-query", "Subzone listing", record_query + " disabled=0 and (name=? OR name like ?) and domain_id=?");
 
index 10f4b9ad9f3f9389953d8a6d608e60b99f1f80c8..895c865511aafa6de3141c84c262c7135b2c3954 100644 (file)
@@ -102,6 +102,9 @@ public:
     declare(suffix, "any-query", "Any query", record_query + " disabled=false and name=$1");
     declare(suffix, "any-id-query", "Any with ID query", record_query + " disabled=false and name=$1 and domain_id=$2");
 
+    declare(suffix, "api-id-query", "API basic with ID query", record_query + " (disabled=false or $1) and type=$2 and name=$3 and domain_id=$4");
+    declare(suffix, "api-any-id-query", "API any with ID query", record_query + " (disabled=false or $1) and name=$2 and domain_id=$3");
+
     declare(suffix, "list-query", "AXFR query", "SELECT content,ttl,prio,type,domain_id,disabled::int,name,auth::int,ordername FROM records WHERE (disabled=false OR $1) and domain_id=$2 order by name, type");
     declare(suffix, "list-subzone-query", "Subzone listing", record_query + " disabled=false and (name=$1 OR name like $2) and domain_id=$3");
 
index 4b45c5c6ee4b81e26440088205a2467488f82796..ae0cd6d698e39cfa5736130b1068fef66e1b36c6 100644 (file)
@@ -88,6 +88,9 @@ public:
     declare(suffix, "any-query", "Any query", record_query + " disabled=0 and name=:qname");
     declare(suffix, "any-id-query", "Any with ID query", record_query + " disabled=0 and name=:qname and domain_id=:domain_id");
 
+    declare(suffix, "api-id-query", "API basic with ID query", record_query + " (disabled=0 or :include_disabled) and type=:qtype and name=:qname and domain_id=:domain_id");
+    declare(suffix, "api-any-id-query", "API any with ID query", record_query + " (disabled=0 or :include_disabled) and name=:qname and domain_id=:domain_id");
+
     declare(suffix, "list-query", "AXFR query", "SELECT content,ttl,prio,type,domain_id,disabled,name,auth,ordername FROM records WHERE (disabled=0 OR :include_disabled) and domain_id=:domain_id order by name, type");
     declare(suffix, "list-subzone-query", "Subzone listing", record_query + " disabled=0 and (name=:zone OR name like :wildzone) and domain_id=:domain_id");
 
index 267816bbcd55db772476825be1e70cf7328a2263..737e2c6bc538ebcfb1c17adbff0344ef6ccbdf06 100644 (file)
@@ -1481,14 +1481,14 @@ bool LMDBBackend::list(const ZoneName& target, int /* id */, bool include_disabl
   return true;
 }
 
-void LMDBBackend::lookup(const QType& type, const DNSName& qdomain, int zoneId, DNSPacket* /* p */)
+void LMDBBackend::lookupInternal(const QType& type, const DNSName& qdomain, int zoneId, DNSPacket* /* p */, bool include_disabled)
 {
   if (d_dolog) {
     g_log << Logger::Warning << "Got lookup for " << qdomain << "|" << type.toString() << " in zone " << zoneId << endl;
     d_dtime.set();
   }
 
-  d_includedisabled = false;
+  d_includedisabled = include_disabled;
 
   DNSName hunt(qdomain);
   DomainInfo di;
index 65fa274644711ba6369b85afcaba6d1c0eb220b2..bf0f816ee5a3a90f7dda2628876332f938f00f69 100644 (file)
@@ -78,7 +78,8 @@ public:
   bool replaceComments(uint32_t domain_id, const DNSName& qname, const QType& qt, const vector<Comment>& comments) override;
 
   void getAllDomains(vector<DomainInfo>* domains, bool doSerial, bool include_disabled) override;
-  void lookup(const QType& type, const DNSName& qdomain, int zoneId, DNSPacket* p = nullptr) override;
+  void lookup(const QType& type, const DNSName& qdomain, int zoneId, DNSPacket* p = nullptr) override { lookupInternal(type, qdomain, zoneId, p, false); }
+  void APILookup(const QType& type, const DNSName& qdomain, int zoneId, DNSPacket* p = nullptr, bool include_disabled = false) override { lookupInternal(type, qdomain, zoneId, p, include_disabled); }
   bool get(DNSResourceRecord& rr) override;
   bool get(DNSZoneRecord& dzr) override;
 
@@ -311,6 +312,7 @@ private:
 
   void getAllDomainsFiltered(vector<DomainInfo>* domains, const std::function<bool(DomainInfo&)>& allow);
 
+  void lookupInternal(const QType& type, const DNSName& qdomain, int zoneId, DNSPacket* p, bool include_disabled);
   bool getSerial(DomainInfo& di);
 
   bool upgradeToSchemav3();
index 61f16330284990fdc88769feee59b8bdd46fa93f..daa5bbec713972506d5a9347dd8a29a15dd1e707 100644 (file)
@@ -225,6 +225,39 @@ void RemoteBackend::lookup(const QType& qtype, const DNSName& qdomain, int zoneI
   d_index = 0;
 }
 
+// Similar to lookup above, but passes an extra include_disabled parameter.
+void RemoteBackend::APILookup(const QType& qtype, const DNSName& qdomain, int zoneId, DNSPacket* pkt_p, bool include_disabled)
+{
+  if (d_index != -1) {
+    throw PDNSException("Attempt to lookup while one running");
+  }
+
+  string localIP = "0.0.0.0";
+  string remoteIP = "0.0.0.0";
+  string realRemote = "0.0.0.0/0";
+
+  if (pkt_p != nullptr) {
+    localIP = pkt_p->getLocal().toString();
+    realRemote = pkt_p->getRealRemote().toString();
+    remoteIP = pkt_p->getInnerRemote().toString();
+  }
+
+  Json query = Json::object{
+    {"method", "APILookup"},
+    {"parameters", Json::object{{"qtype", qtype.toString()}, {"qname", qdomain.toString()}, {"remote", remoteIP}, {"local", localIP}, {"real-remote", realRemote}, {"zone-id", zoneId}, {"include-disabled", include_disabled}}}};
+
+  if (!this->send(query) || !this->recv(d_result)) {
+    return;
+  }
+
+  // OK. we have result parameters in result. do not process empty result.
+  if (!d_result["result"].is_array() || d_result["result"].array_items().empty()) {
+    return;
+  }
+
+  d_index = 0;
+}
+
 bool RemoteBackend::list(const ZoneName& target, int domain_id, bool include_disabled)
 {
   if (d_index != -1) {
index b91f373eea4c6e06e8e8320da621b3a001affc40..e6d7062392f01d22aceeeae85baa0e004f33b4ca 100644 (file)
@@ -169,6 +169,7 @@ public:
 
   unsigned int getCapabilities() override;
   void lookup(const QType& qtype, const DNSName& qdomain, int zoneId = -1, DNSPacket* pkt_p = nullptr) override;
+  void APILookup(const QType& qtype, const DNSName& qdomain, int zoneId = -1, DNSPacket* pkt_p = nullptr, bool include_disabled = false) override;
   bool get(DNSResourceRecord& rr) override;
   bool list(const ZoneName& target, int domain_id, bool include_disabled = false) override;
 
index 42f6b525cd4df172a4cce18914ad02f4fae13ead..2b7fe5847d59e677b5d72b2aafcfce0e5c78bad0 100644 (file)
@@ -63,6 +63,9 @@ GSQLBackend::GSQLBackend(const string &mode, const string &suffix)
   d_ANYNoIdQuery=getArg("any-query");
   d_ANYIdQuery=getArg("any-id-query");
 
+  d_APIIdQuery=getArg("api-id-query");
+  d_APIANYIdQuery=getArg("api-any-id-query");
+
   d_listQuery=getArg("list-query");
   d_listSubZoneQuery=getArg("list-subzone-query");
 
@@ -140,6 +143,8 @@ GSQLBackend::GSQLBackend(const string &mode, const string &suffix)
   d_IdQuery_stmt = nullptr;
   d_ANYNoIdQuery_stmt = nullptr;
   d_ANYIdQuery_stmt = nullptr;
+  d_APIIdQuery_stmt = nullptr;
+  d_APIANYIdQuery_stmt = nullptr;
   d_listQuery_stmt = nullptr;
   d_listSubZoneQuery_stmt = nullptr;
   d_InfoOfDomainsZoneQuery_stmt = nullptr;
@@ -1456,6 +1461,44 @@ void GSQLBackend::lookup(const QType& qtype, const DNSName& qname, int domain_id
   d_qname=qname;
 }
 
+void GSQLBackend::APILookup(const QType& qtype, const DNSName& qname, int domain_id, DNSPacket* /* pkt_p */, bool include_disabled)
+{
+  try {
+    reconnectIfNeeded();
+
+    if(qtype.getCode()!=QType::ANY) {
+      d_query_name = "api-id-query";
+      d_query_stmt = &d_APIIdQuery_stmt;
+      // clang-format off
+      (*d_query_stmt)->
+        bind("include_disabled", (int)include_disabled)->
+        bind("qtype", qtype.toString())->
+        bind("qname", qname)->
+        bind("domain_id", domain_id);
+      // clang-format on
+    } else {
+      // qtype==ANY
+      d_query_name = "api-any-id-query";
+      d_query_stmt = &d_APIANYIdQuery_stmt;
+      // clang-format off
+      (*d_query_stmt)->
+        bind("include_disabled", (int)include_disabled)->
+        bind("qname", qname)->
+        bind("domain_id", domain_id);
+      // clang-format on
+    }
+
+    (*d_query_stmt)->
+      execute();
+  }
+  catch(SSqlException &e) {
+    throw PDNSException("GSQLBackend unable to APILookup '" + qname.toLogString() + "(" + std::to_string(domain_id) + ")|" + qtype.toString() + "':"+e.txtReason());
+  }
+
+  d_list=false;
+  d_qname=qname;
+}
+
 bool GSQLBackend::list(const ZoneName &target, int domain_id, bool include_disabled)
 {
   DLOG(g_log<<"GSQLBackend constructing handle for list of domain id '"<<domain_id<<"'"<<endl);
index 5a9e51baf49125de40918e50241f931fa3ff2fec..6b1b6205d849b12d242c5afed0c5f2ab9e3aab9a 100644 (file)
@@ -59,6 +59,8 @@ protected:
       d_IdQuery_stmt = d_db->prepare(d_IdQuery, 3);
       d_ANYNoIdQuery_stmt = d_db->prepare(d_ANYNoIdQuery, 1);
       d_ANYIdQuery_stmt = d_db->prepare(d_ANYIdQuery, 2);
+      d_APIIdQuery_stmt = d_db->prepare(d_APIIdQuery, 4);
+      d_APIANYIdQuery_stmt = d_db->prepare(d_APIANYIdQuery, 3);
       d_listQuery_stmt = d_db->prepare(d_listQuery, 2);
       d_listSubZoneQuery_stmt = d_db->prepare(d_listSubZoneQuery, 3);
       d_PrimaryOfDomainsZoneQuery_stmt = d_db->prepare(d_PrimaryOfDomainsZoneQuery, 1);
@@ -129,6 +131,8 @@ protected:
     d_IdQuery_stmt.reset();
     d_ANYNoIdQuery_stmt.reset();
     d_ANYIdQuery_stmt.reset();
+    d_APIIdQuery_stmt.reset();
+    d_APIANYIdQuery_stmt.reset();
     d_listQuery_stmt.reset();
     d_listSubZoneQuery_stmt.reset();
     d_PrimaryOfDomainsZoneQuery_stmt.reset();
@@ -196,6 +200,7 @@ protected:
 public:
   unsigned int getCapabilities() override;
   void lookup(const QType &, const DNSName &qdomain, int zoneId, DNSPacket *p=nullptr) override;
+  void APILookup(const QType &qtype, const DNSName &qname, int domain_id, DNSPacket *p=nullptr, bool include_disabled = false) override;
   bool list(const ZoneName &target, int domain_id, bool include_disabled=false) override;
   bool get(DNSResourceRecord &r) override;
   void getAllDomains(vector<DomainInfo>* domains, bool getSerial, bool include_disabled) override;
@@ -294,6 +299,9 @@ private:
   string d_ANYNoIdQuery;
   string d_ANYIdQuery;
 
+  string d_APIIdQuery;
+  string d_APIANYIdQuery;
+
   string d_listQuery;
   string d_listSubZoneQuery;
   string d_logprefix;
@@ -375,6 +383,8 @@ private:
   unique_ptr<SSqlStatement> d_IdQuery_stmt;
   unique_ptr<SSqlStatement> d_ANYNoIdQuery_stmt;
   unique_ptr<SSqlStatement> d_ANYIdQuery_stmt;
+  unique_ptr<SSqlStatement> d_APIIdQuery_stmt;
+  unique_ptr<SSqlStatement> d_APIANYIdQuery_stmt;
   unique_ptr<SSqlStatement> d_listQuery_stmt;
   unique_ptr<SSqlStatement> d_listSubZoneQuery_stmt;
   unique_ptr<SSqlStatement> d_PrimaryOfDomainsZoneQuery_stmt;
index fe33b449408e00729ce48c084054e52ebcc2a68d..a3e529846d6f6e315f4c8b0a7fd2fa32c98332a9 100644 (file)
@@ -67,6 +67,12 @@ int DNSBackend::getArgAsNum(const string& key)
   return arg().asNum(d_prefix + "-" + key);
 }
 
+// Default API lookup has no support for disabled records and simply wraps lookup()
+void DNSBackend::APILookup(const QType& qtype, const DNSName& qdomain, int zoneId, DNSPacket* pkt_p, bool /* include_disabled */)
+{
+  lookup(qtype, qdomain, zoneId, pkt_p);
+}
+
 void BackendFactory::declare(const string& suffix, const string& param, const string& explanation, const string& value)
 {
   string fullname = d_name + suffix + "-" + param;
index 5b670f439a61905d8f92e1abb83b4e86fe9dd136..6059b1077eb6d87327cd0ef57368e4b986b6dd47 100644 (file)
@@ -169,6 +169,7 @@ public:
 
   //! lookup() initiates a lookup. A lookup without results should not throw!
   virtual void lookup(const QType& qtype, const DNSName& qdomain, int zoneId = -1, DNSPacket* pkt_p = nullptr) = 0;
+  virtual void APILookup(const QType& qtype, const DNSName& qdomain, int zoneId = -1, DNSPacket* pkt_p = nullptr, bool include_disabled = false);
   virtual bool get(DNSResourceRecord&) = 0; //!< retrieves one DNSResource record, returns false if no more were available
   virtual bool get(DNSZoneRecord& zoneRecord);