LuaAction(LuaAction::func_t func) : d_func(func)
{}
- Action operator()(const ComboAddress& remote, const DNSName& qname, uint16_t qtype, dnsheader* dh, int len, string* ruleresult) const
+ Action operator()(const ComboAddress& remote, const DNSName& qname, uint16_t qtype, dnsheader* dh, uint16_t& len, string* ruleresult) const override
{
auto ret = d_func(remote, qname, qtype, dh, len);
if(ruleresult)
{"Pool", (int)DNSAction::Action::Pool},
{"None",(int)DNSAction::Action::Pool}}
);
-
g_lua.writeFunction("newServer",
[client](boost::variant<string,newserver_t> pvars, boost::optional<int> qps)
return std::shared_ptr<DNSAction>(new NoRecurseAction);
});
+ g_lua.writeFunction("SpoofAction", [](const string& a, boost::optional<string> b) {
+ if(b)
+ return std::shared_ptr<DNSAction>(new SpoofAction(ComboAddress(a), ComboAddress(*b)));
+ else
+ return std::shared_ptr<DNSAction>(new SpoofAction(ComboAddress(a)));
+ });
+
+ g_lua.writeFunction("addDomainSpoof", [](const std::string& domain, const std::string& ip, boost::optional<string> ip6) {
+ SuffixMatchNode smn;
+ ComboAddress a, b;
+ b.sin6.sin6_family=0;
+ try
+ {
+ smn.add(DNSName(domain));
+ a=ComboAddress(ip);
+ if(ip6)
+ b=ComboAddress(*ip6);
+ }
+ catch(std::exception& e) {
+ g_outputBuffer="Error parsing parameters: "+string(e.what());
+ return;
+ }
+ g_rulactions.modify([&smn,&a,&b](decltype(g_rulactions)::value_type& rulactions) {
+ rulactions.push_back({
+ std::make_shared<SuffixMatchNodeRule>(smn),
+ std::make_shared<SpoofAction>(a, b) });
+ });
+
+ });
+
+
g_lua.writeFunction("DropAction", []() {
return std::shared_ptr<DNSAction>(new DropAction);
});
class DropAction : public DNSAction
{
public:
- DNSAction::Action operator()(const ComboAddress& remote, const DNSName& qname, uint16_t qtype, dnsheader* dh, int len, string* ruleresult) const override
+ DNSAction::Action operator()(const ComboAddress& remote, const DNSName& qname, uint16_t qtype, dnsheader* dh, uint16_t& len, string* ruleresult) const override
{
return Action::Drop;
}
public:
QPSAction(int limit) : d_qps(limit, limit)
{}
- DNSAction::Action operator()(const ComboAddress& remote, const DNSName& qname, uint16_t qtype, dnsheader* dh, int len, string* ruleresult) const override
+ DNSAction::Action operator()(const ComboAddress& remote, const DNSName& qname, uint16_t qtype, dnsheader* dh, uint16_t& len, string* ruleresult) const override
{
if(d_qps.check())
return Action::Allow;
public:
DelayAction(int msec) : d_msec(msec)
{}
- DNSAction::Action operator()(const ComboAddress& remote, const DNSName& qname, uint16_t qtype, dnsheader* dh, int len, string* ruleresult) const override
+ DNSAction::Action operator()(const ComboAddress& remote, const DNSName& qname, uint16_t qtype, dnsheader* dh, uint16_t& len, string* ruleresult) const override
{
*ruleresult=std::to_string(d_msec);
return Action::Delay;
{
public:
PoolAction(const std::string& pool) : d_pool(pool) {}
- DNSAction::Action operator()(const ComboAddress& remote, const DNSName& qname, uint16_t qtype, dnsheader* dh, int len, string* ruleresult) const override
+ DNSAction::Action operator()(const ComboAddress& remote, const DNSName& qname, uint16_t qtype, dnsheader* dh, uint16_t& len, string* ruleresult) const override
{
*ruleresult=d_pool;
return Action::Pool;
{
public:
QPSPoolAction(unsigned int limit, const std::string& pool) : d_qps(limit, limit), d_pool(pool) {}
- DNSAction::Action operator()(const ComboAddress& remote, const DNSName& qname, uint16_t qtype, dnsheader* dh, int len, string* ruleresult) const override
+ DNSAction::Action operator()(const ComboAddress& remote, const DNSName& qname, uint16_t qtype, dnsheader* dh, uint16_t& len, string* ruleresult) const override
{
if(d_qps.check()) {
*ruleresult=d_pool;
{
public:
RCodeAction(int rcode) : d_rcode(rcode) {}
- DNSAction::Action operator()(const ComboAddress& remote, const DNSName& qname, uint16_t qtype, dnsheader* dh, int len, string* ruleresult) const override
+ DNSAction::Action operator()(const ComboAddress& remote, const DNSName& qname, uint16_t qtype, dnsheader* dh, uint16_t& len, string* ruleresult) const override
{
dh->rcode = d_rcode;
dh->qr = true; // for good measure
class TCAction : public DNSAction
{
public:
- DNSAction::Action operator()(const ComboAddress& remote, const DNSName& qname, uint16_t qtype, dnsheader* dh, int len, string* ruleresult) const override
+ DNSAction::Action operator()(const ComboAddress& remote, const DNSName& qname, uint16_t qtype, dnsheader* dh, uint16_t& len, string* ruleresult) const override
{
dh->tc = true;
dh->qr = true; // for good measure
}
};
+class SpoofAction : public DNSAction
+{
+public:
+ SpoofAction(const ComboAddress& a) : d_a(a) { d_aaaa.sin4.sin_family = 0;}
+ SpoofAction(const ComboAddress& a, const ComboAddress& aaaa) : d_a(a), d_aaaa(aaaa) {}
+ DNSAction::Action operator()(const ComboAddress& remote, const DNSName& qname, uint16_t qtype, dnsheader* dh, uint16_t& len, string* ruleresult) const override
+ {
+ if((qtype == QType::A && d_a.sin4.sin_family == 0) ||
+ (qtype == QType::AAAA && d_aaaa.sin4.sin_family == 0) || (qtype != QType::A && qtype != QType::AAAA))
+ return Action::None;
+
+ dh->qr = true; // for good measure
+ dh->ra = dh->rd; // for good measure
+ dh->ad = false;
+ dh->ancount = htons(1);
+ dh->arcount = 0; // for now, forget about your EDNS, we're marching over it
+ unsigned int consumed=0;
+
+ DNSName ignore((char*)dh, len, sizeof(dnsheader), false, 0, 0, &consumed);
+
+ char* dest = ((char*)dh) +sizeof(dnsheader) + consumed + 4;
+ uint8_t addrlen = qtype == QType::A ? 4 : 16;
+
+ const unsigned char recordstart[]={0xc0, 0x0c, // compressed name
+ 0, (unsigned char) qtype,
+ 0, 1, // IN
+ 0, 0, 0, 60, // TTL
+ 0, addrlen};
+ memcpy(dest, recordstart, sizeof(recordstart));
+ if(qtype==QType::A)
+ memcpy(dest+sizeof(recordstart), &d_a.sin4.sin_addr.s_addr, 4);
+ else
+ memcpy(dest+sizeof(recordstart), &d_aaaa.sin6.sin6_addr.s6_addr, 16);
+ len = (dest + sizeof(recordstart) + addrlen) - (char*)dh;
+ return Action::HeaderModify;
+ }
+ string toString() const override
+ {
+ string ret;
+ if(d_a.sin4.sin_family)
+ ret="spoof in "+d_a.toString();
+ if(d_aaaa.sin6.sin6_family) {
+ if(!ret.empty()) ret += ", ";
+ ret+="spoof in "+d_aaaa.toString();
+ }
+ return ret;
+ }
+private:
+ ComboAddress d_a;
+ ComboAddress d_aaaa;
+};
+
+
class NoRecurseAction : public DNSAction
{
public:
- DNSAction::Action operator()(const ComboAddress& remote, const DNSName& qname, uint16_t qtype, dnsheader* dh, int len, string* ruleresult) const override
+ DNSAction::Action operator()(const ComboAddress& remote, const DNSName& qname, uint16_t qtype, dnsheader* dh, uint16_t& len, string* ruleresult) const override
{
dh->rd = false;
return Action::HeaderModify;
class DisableValidationAction : public DNSAction
{
public:
- DNSAction::Action operator()(const ComboAddress& remote, const DNSName& qname, uint16_t qtype, dnsheader* dh, int len, string* ruleresult) const override
+ DNSAction::Action operator()(const ComboAddress& remote, const DNSName& qname, uint16_t qtype, dnsheader* dh, uint16_t& len, string* ruleresult) const override
{
dh->cd = true;
return Action::HeaderModify;