return std::make_shared<RemoteLogger>(ComboAddress(remote), timeout ? *timeout : 2, maxQueuedEntries ? *maxQueuedEntries : 100, reconnectWaitTime ? *reconnectWaitTime : 1);
});
+ g_lua.writeFunction("TeeAction", [](const std::string& remote) {
+ return std::shared_ptr<DNSAction>(new TeeAction(ComboAddress(remote, 53)));
+ });
+
+ g_lua.registerFunction<void(DNSAction::*)()>("printStats", [](const DNSAction& ta) {
+ auto stats = ta.getStats();
+ for(const auto& s : stats) {
+ g_outputBuffer+=s.first+"\t"+std::to_string(s.second)+"\n";
+ }
+ });
}
enum class Action { Drop, Nxdomain, Spoof, Allow, HeaderModify, Pool, Delay, None};
virtual Action operator()(DNSQuestion*, string* ruleresult) const =0;
virtual string toString() const = 0;
+ virtual std::unordered_map<string, double> getStats() const
+ {
+ return {{}};
+ }
};
class DNSResponseAction
dnslabeltext.cc \
dnsname.cc dnsname.hh \
dnsparser.hh dnsparser.cc \
- dnsrulactions.hh \
+ dnsrulactions.cc dnsrulactions.hh \
dnswriter.cc dnswriter.hh \
dolog.hh \
ednsoptions.cc ednsoptions.hh \
--- /dev/null
+#include "dnsrulactions.hh"
+#include <iostream>
+
+using namespace std;
+
+TeeAction::TeeAction(const ComboAddress& ca) : d_remote(ca)
+{
+ cerr<<"Created!"<<endl;
+ d_fd=SSocket(d_remote.sin4.sin_family, SOCK_DGRAM, 0);
+ SConnect(d_fd, d_remote);
+ d_worker=std::thread(std::bind(&TeeAction::worker, this));
+
+}
+
+TeeAction::~TeeAction()
+{
+ cerr<<"Closding down!"<<endl;
+ d_pleaseQuit=true;
+ close(d_fd);
+ d_worker.join();
+}
+
+DNSAction::Action TeeAction::operator()(DNSQuestion* dq, string* ruleresult) const
+{
+ d_queries++;
+ send(d_fd, (char*)dq->dh, dq->len, 0);
+ return DNSAction::Action::None;
+}
+
+string TeeAction::toString() const
+{
+ return "tee to "+d_remote.toStringWithPort();
+}
+
+std::unordered_map<string,double> TeeAction::getStats() const
+{
+ return {{"queries", d_queries},
+ {"responses", d_responses},
+ {"socket-errors", d_errors}};
+}
+
+void TeeAction::worker()
+{
+ char packet[1500];
+ int res=0;
+ for(;;) {
+ res=recv(d_fd, packet, sizeof(packet), 0);
+ if(res < 0)
+ d_errors++;
+ else if(res > 0)
+ d_responses++;
+ if(d_pleaseQuit)
+ break;
+ }
+}
};
+class TeeAction : public DNSAction
+{
+public:
+ TeeAction(const ComboAddress& ca);
+ ~TeeAction();
+ DNSAction::Action operator()(DNSQuestion* dq, string* ruleresult) const override;
+ string toString() const override;
+ std::unordered_map<string, double> getStats() const override;
+private:
+ ComboAddress d_remote;
+ std::thread d_worker;
+ void worker();
+
+ int d_fd;
+ unsigned long d_errors{0};
+ mutable unsigned long d_queries{0};
+ unsigned long d_responses{0};
+ std::atomic<bool> d_pleaseQuit{false};
+};
+
+
+
class PoolAction : public DNSAction
{
public: