• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

PowerDNS / pdns / 12631365029

06 Jan 2025 11:05AM UTC coverage: 64.817% (+8.2%) from 56.642%
12631365029

Pull #14985

github

web-flow
Merge d5a9bdb7f into 788f396a7
Pull Request #14985: rec: store authority recs and signatures as shared pointers to const data

37736 of 89006 branches covered (42.4%)

Branch coverage included in aggregate %.

131 of 136 new or added lines in 9 files covered. (96.32%)

9097 existing lines in 174 files now uncovered.

126127 of 163803 relevant lines covered (77.0%)

4589994.28 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

50.66
/pdns/lua-auth4.cc
1
#include "config.h"
2
#include "ext/luawrapper/include/LuaContext.hpp"
3
#include "lua-auth4.hh"
4
#include "stubresolver.hh"
5
#include <fstream>
6
#include "logger.hh"
7
#include "dnsparser.hh"
8
#include "namespaces.hh"
9
#include "ednssubnet.hh"
10
#include <unordered_set>
11
#include "sstuff.hh"
12
#include <thread>
13

14
#include "ueberbackend.hh"
15

16
LuaContext* AuthLua4::getLua()
UNCOV
17
{
×
UNCOV
18
  return d_lw.get();
×
19
}
×
20

21
void AuthLua4::postPrepareContext() {
44✔
22
  d_lw->writeFunction("resolve", [](const std::string& qname, uint16_t qtype) {
44✔
UNCOV
23
      std::vector<DNSZoneRecord> ret;
×
UNCOV
24
      std::unordered_map<int, DNSResourceRecord> luaResult;
×
25
      stubDoResolve(DNSName(qname), qtype, ret);
×
26
      int i = 0;
×
27
      for(const auto &row: ret) {
×
28
        luaResult[++i] = DNSResourceRecord::fromWire(row.dr);
×
29
        luaResult[i].auth = row.auth;
×
30
      }
×
31
      return luaResult;
×
32
  });
×
33

34
/* DNSPacket */
35
  d_lw->writeFunction("newDNSPacket", [](bool isQuery) { return std::make_shared<DNSPacket>(isQuery); });
44✔
36
  d_lw->writeFunction("dupDNSPacket", [](const std::shared_ptr<DNSPacket> &orig) { return std::make_shared<DNSPacket>(*orig); });
44✔
37
  d_lw->registerFunction<DNSPacket, int(const char *, size_t)>("noparse", [](DNSPacket &p, const char *mesg, size_t len){ return p.noparse(mesg, len); });
44✔
38
  d_lw->registerFunction<DNSPacket, int(const char *, size_t)>("parse", [](DNSPacket &p, const char *mesg, size_t len){ return p.parse(mesg, len); });
44✔
39
  d_lw->registerFunction<DNSPacket, const std::string()>("getString", [](DNSPacket &p) { return p.getString(); });
44✔
40
  d_lw->registerFunction<DNSPacket, void(const ComboAddress&)>("setRemote", [](DNSPacket &p, const ComboAddress &ca) { p.setRemote(&ca); });
44✔
41
  d_lw->registerFunction<DNSPacket, ComboAddress()>("getRemote", [](DNSPacket &p) { return p.getInnerRemote(); });
44✔
42
  d_lw->registerFunction<DNSPacket, Netmask()>("getRealRemote", [](DNSPacket &p) { return p.getRealRemote(); });
44✔
43
  d_lw->registerFunction<DNSPacket, ComboAddress()>("getLocal", [](DNSPacket &p) { return p.getLocal(); });
44✔
44
  d_lw->registerFunction<DNSPacket, unsigned int()>("getRemotePort", [](DNSPacket &p) { return p.getInnerRemote().getPort(); });
44✔
45
  d_lw->registerFunction<DNSPacket, std::tuple<const std::string, unsigned int>()>("getQuestion", [](DNSPacket &p) { return std::tuple(p.qdomain.toString(), static_cast<unsigned int>(p.qtype.getCode())); });
44✔
46
  d_lw->registerFunction<DNSPacket, void(bool)>("setA", [](DNSPacket &p, bool a) { return p.setA(a); });
44✔
47
  d_lw->registerFunction<DNSPacket, void(unsigned int)>("setID", [](DNSPacket &p, unsigned int id) { return p.setID(static_cast<uint16_t>(id)); });
44✔
48
  d_lw->registerFunction<DNSPacket, void(bool)>("setRA", [](DNSPacket &p, bool ra) { return p.setRA(ra); });
44✔
49
  d_lw->registerFunction<DNSPacket, void(bool)>("setRD", [](DNSPacket &p, bool rd) { return p.setRD(rd); });
44✔
50
  d_lw->registerFunction<DNSPacket, void(bool)>("setAnswer", [](DNSPacket &p, bool answer) { return p.setAnswer(answer); });
44✔
51
  d_lw->registerFunction<DNSPacket, void(unsigned int)>("setOpCode", [](DNSPacket &p, unsigned int opcode) { return p.setOpcode(static_cast<uint16_t>(opcode)); });
44✔
52
  d_lw->registerFunction<DNSPacket, void(int)>("setRcode", [](DNSPacket &p, int rcode) { return p.setRcode(rcode); });
44✔
53
  d_lw->registerFunction<DNSPacket, void()>("clearRecords",[](DNSPacket &p){p.clearRecords();});
44✔
54
  d_lw->registerFunction<DNSPacket, void(DNSRecord&, bool)>("addRecord", [](DNSPacket &p, DNSRecord &dr, bool auth) { DNSZoneRecord dzr; dzr.dr = dr; dzr.auth = auth; p.addRecord(std::move(dzr)); });
44✔
55
  d_lw->registerFunction<DNSPacket, void(const vector<pair<unsigned int, DNSRecord> >&)>("addRecords", [](DNSPacket &p, const vector<pair<unsigned int, DNSRecord> >& records){ for(const auto &dr: records){ DNSZoneRecord dzr; dzr.dr = std::get<1>(dr); dzr.auth = true; p.addRecord(std::move(dzr)); }});
44!
56
  d_lw->registerFunction<DNSPacket, void(unsigned int, const DNSName&, const std::string&)>("setQuestion", [](DNSPacket &p, unsigned int opcode, const DNSName &name, const string &type){ QType qtype; qtype = type; p.setQuestion(static_cast<int>(opcode), name, static_cast<int>(qtype.getCode())); });
44✔
57
  d_lw->registerFunction<DNSPacket, bool()>("isEmpty", [](DNSPacket &p){return p.isEmpty();});
44✔
58
  d_lw->registerFunction<DNSPacket, std::shared_ptr<DNSPacket>()>("replyPacket",[](DNSPacket& p){ return p.replyPacket();});
44✔
59
  d_lw->registerFunction<DNSPacket, bool()>("hasEDNSSubnet", [](DNSPacket &p){return p.hasEDNSSubnet();});
44✔
60
  d_lw->registerFunction<DNSPacket, bool()>("hasEDNS",[](DNSPacket &p){return p.hasEDNS();});
44✔
61
  d_lw->registerFunction<DNSPacket, unsigned int()>("getEDNSVersion",[](DNSPacket &p){return p.getEDNSVersion();});
44✔
62
  d_lw->registerFunction<DNSPacket, void(unsigned int)>("setEDNSRcode",[](DNSPacket &p, unsigned int extRCode){p.setEDNSRcode(static_cast<uint16_t>(extRCode));});
44✔
63
  d_lw->registerFunction<DNSPacket, unsigned int()>("getEDNSRcode",[](DNSPacket &p){return p.getEDNSRCode();});
44✔
64
  d_lw->registerFunction<DNSPacket, DNSName()>("getTSIGKeyname",[](DNSPacket &p){ return p.getTSIGKeyname();});
44✔
65
  d_lw->registerFunction<DNSPacket, std::unordered_map<unsigned int, DNSRecord>()>("getRRS", [](DNSPacket &p){ std::unordered_map<unsigned int, DNSRecord> ret; unsigned int i = 0; for(const auto &rec: p.getRRS()) { ret.insert({i++, rec.dr}); } return ret;});
44!
66
  d_lw->registerMember<DNSPacket, DNSName>("qdomain", [](const DNSPacket &p) -> DNSName { return p.qdomain; }, [](DNSPacket &p, const DNSName& name) { p.qdomain = name; });
44✔
67
  d_lw->registerMember<DNSPacket, DNSName>("qdomainwild", [](const DNSPacket &p) -> DNSName { return p.qdomainwild; }, [](DNSPacket &p, const DNSName& name) { p.qdomainwild = name; });
44✔
68
  d_lw->registerMember<DNSPacket, DNSName>("qdomainzone", [](const DNSPacket &p) -> DNSName { return p.qdomainzone; }, [](DNSPacket &p, const DNSName& name) { p.qdomainzone = name; });
44✔
69

70
  d_lw->registerMember<DNSPacket, std::string>("d_peer_principal", [](const DNSPacket &p) -> std::string { return p.d_peer_principal; }, [](DNSPacket &p, const std::string &princ) { p.d_peer_principal = princ; });
44✔
71
  d_lw->registerMember<DNSPacket, const std::string>("qtype", [](const DNSPacket &p) ->  const std::string { return p.qtype.toString(); }, [](DNSPacket &p, const std::string &type) { p.qtype = type; });
44✔
72
/* End of DNSPacket */
73

74

75
/* update policy */
76
  d_lw->registerFunction<DNSName(UpdatePolicyQuery::*)()>("getQName", [](UpdatePolicyQuery& upq) { return upq.qname; });
44✔
77
  d_lw->registerFunction<DNSName(UpdatePolicyQuery::*)()>("getZoneName", [](UpdatePolicyQuery& upq) { return upq.zonename; });
44✔
78
  d_lw->registerFunction<uint16_t(UpdatePolicyQuery::*)()>("getQType", [](UpdatePolicyQuery& upq) { return upq.qtype; });
44✔
79
  d_lw->registerFunction<ComboAddress(UpdatePolicyQuery::*)()>("getLocal", [](UpdatePolicyQuery& upq) { return upq.local; });
44✔
80
  d_lw->registerFunction<ComboAddress(UpdatePolicyQuery::*)()>("getRemote", [](UpdatePolicyQuery& upq) { return upq.remote; });
44✔
81
  d_lw->registerFunction<Netmask(UpdatePolicyQuery::*)()>("getRealRemote", [](UpdatePolicyQuery& upq) { return upq.realRemote; });
44✔
82
  d_lw->registerFunction<DNSName(UpdatePolicyQuery::*)()>("getTsigName", [](UpdatePolicyQuery& upq) { return upq.tsigName; });
44✔
83
  d_lw->registerFunction<std::string(UpdatePolicyQuery::*)()>("getPeerPrincipal", [](UpdatePolicyQuery& upq) { return upq.peerPrincipal; });
45✔
84
/* end of update policy */
85
  if (!d_include_path.empty()) {
44!
UNCOV
86
    includePath(d_include_path);
×
UNCOV
87
  }
×
88
}
44✔
89

90
void AuthLua4::postLoad() {
2✔
91
  d_update_policy = d_lw->readVariable<boost::optional<luacall_update_policy_t>>("updatepolicy").get_value_or(nullptr);
2✔
92
  d_axfr_filter = d_lw->readVariable<boost::optional<luacall_axfr_filter_t>>("axfrfilter").get_value_or(nullptr);
2✔
93
  d_prequery = d_lw->readVariable<boost::optional<luacall_prequery_t>>("prequery").get_value_or(nullptr);
2✔
94
}
2✔
95

96
bool AuthLua4::axfrfilter(const ComboAddress& remote, const DNSName& zone, const DNSResourceRecord& in, vector<DNSResourceRecord>& out) {
×
97
  if (!d_axfr_filter) {
×
98
    return false;
×
UNCOV
99
  }
×
100

101
  const auto& [rcode, rows] = d_axfr_filter(remote, zone, in);
×
UNCOV
102
  if (rcode < 0) {
×
103
    // no modification, handle normally
104
    return false;
×
105
  }
×
UNCOV
106
  else if (rcode == 0) {
×
107
    // replace the matching record by the filtered record(s)
108
  }
×
UNCOV
109
  else if (rcode == 1) {
×
110
    // append the filtered record(s) after the matching record
111
    out.push_back(in);
×
112
  }
×
113
  else
×
UNCOV
114
    throw PDNSException("Cannot understand return code "+std::to_string(rcode)+" in axfr filter response");
×
115

116
  try {
×
117
    for(const auto& row: rows) {
×
UNCOV
118
      DNSResourceRecord rec;
×
119

120
      const auto& map = row.second;
×
121
      rec.qtype = QType(boost::get<unsigned int>(map.at("qtype")));
×
122
      rec.qname = DNSName(boost::get<std::string>(map.at("qname")));
×
123
      rec.qname.makeUsLowerCase();
×
124
      if (map.count("ttl")) {
×
125
        rec.ttl = boost::get<unsigned int>(map.at("ttl"));
×
126
      }
×
UNCOV
127
      rec.setContent(boost::get<std::string>(map.at("content")));
×
128

129
      out.push_back(rec);
×
130
    }
×
131
  }
×
132
  catch (const std::exception& e) {
×
133
    throw PDNSException("Cannot understand axfr filter response: " + std::string(e.what()));
×
134
  }
×
135
  catch (const PDNSException& e) {
×
136
    throw PDNSException("Cannot understand axfr filter response: " + e.reason);
×
UNCOV
137
  }
×
138

139
  return true;
×
UNCOV
140
}
×
141

142

143
bool AuthLua4::updatePolicy(const DNSName &qname, const QType& qtype, const DNSName &zonename, const DNSPacket& packet) {
3✔
144
  // default decision is all goes
145
  if (d_update_policy == nullptr) return true;
3!
146

147
  UpdatePolicyQuery upq;
3✔
148
  upq.qname = qname;
3✔
149
  upq.qtype = qtype.getCode();
3✔
150
  upq.zonename = zonename;
3✔
151
  upq.local = packet.getLocal();
3✔
152
  upq.remote = packet.getInnerRemote();
3✔
153
  upq.realRemote = packet.getRealRemote();
3✔
154
  upq.tsigName = packet.getTSIGKeyname();
3✔
155
  upq.peerPrincipal = packet.d_peer_principal;
3✔
156

157
  return d_update_policy(upq);
3✔
158
}
3✔
159

160
std::unique_ptr<DNSPacket> AuthLua4::prequery(const DNSPacket& q) {
1✔
161
  if (d_prequery == nullptr) return nullptr;
1!
162

163
  auto r = q.replyPacket();
1✔
164
  if (d_prequery(r.get()))
1!
165
    return r;
1✔
166

UNCOV
167
  return nullptr;
×
168
}
1✔
169

170
AuthLua4::~AuthLua4() = default;
19✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc