mirror of
https://github.com/anope/anope.git
synced 2026-07-08 07:23:14 +02:00
Move DNS handling to a module
This commit is contained in:
@@ -6,6 +6,9 @@
|
||||
*/
|
||||
|
||||
#include "module.h"
|
||||
#include "../extra/dns.h"
|
||||
|
||||
static ServiceReference<DNS::Manager> dnsmanager("DNS::Manager", "dns/manager");
|
||||
|
||||
class DNSServer;
|
||||
static std::vector<DNSServer *> dns_servers;
|
||||
@@ -44,8 +47,8 @@ class DNSServer : public Serializable
|
||||
void Pool(bool p)
|
||||
{
|
||||
pooled = p;
|
||||
if (DNS::Engine)
|
||||
DNS::Engine->UpdateSerial();
|
||||
if (dnsmanager)
|
||||
dnsmanager->UpdateSerial();
|
||||
}
|
||||
|
||||
|
||||
@@ -220,8 +223,8 @@ class CommandOSDNS : public Command
|
||||
source.Reply(_("Added IP %s to %s."), params[2].c_str(), s->GetName().c_str());
|
||||
Log(LOG_ADMIN, source, this) << "to add IP " << params[2] << " to " << s->GetName();
|
||||
|
||||
if (s->Pooled())
|
||||
DNS::Engine->UpdateSerial();
|
||||
if (s->Pooled() && dnsmanager)
|
||||
dnsmanager->UpdateSerial();
|
||||
}
|
||||
|
||||
void DelIP(CommandSource &source, const std::vector<Anope::string> ¶ms)
|
||||
@@ -247,8 +250,8 @@ class CommandOSDNS : public Command
|
||||
s->Pool(false);
|
||||
}
|
||||
|
||||
if (s->Pooled())
|
||||
DNS::Engine->UpdateSerial();
|
||||
if (s->Pooled() && dnsmanager)
|
||||
dnsmanager->UpdateSerial();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
*
|
||||
* (C) 2003-2012 Anope Team
|
||||
* Contact us at team@anope.org
|
||||
*
|
||||
* Please read COPYING and README for further details.
|
||||
*
|
||||
* Based on the original code of Epona by Lara.
|
||||
* Based on the original code of Services by Andy Church.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef DNS_H
|
||||
#define DNS_H
|
||||
|
||||
namespace DNS
|
||||
{
|
||||
/** Valid query types
|
||||
*/
|
||||
enum QueryType
|
||||
{
|
||||
/* Nothing */
|
||||
QUERY_NONE,
|
||||
/* A simple A lookup */
|
||||
QUERY_A = 1,
|
||||
/* An authoritative name server */
|
||||
QUERY_NS = 2,
|
||||
/* A CNAME lookup */
|
||||
QUERY_CNAME = 5,
|
||||
/* Start of a zone of authority */
|
||||
QUERY_SOA = 6,
|
||||
/* Reverse DNS lookup */
|
||||
QUERY_PTR = 12,
|
||||
/* IPv6 AAAA lookup */
|
||||
QUERY_AAAA = 28,
|
||||
/* Zone transfer */
|
||||
QUERY_AXFR = 252
|
||||
};
|
||||
|
||||
/** Flags that can be AND'd into DNSPacket::flags to receive certain values
|
||||
*/
|
||||
enum
|
||||
{
|
||||
QUERYFLAGS_QR = 0x8000,
|
||||
QUERYFLAGS_OPCODE = 0x7800,
|
||||
QUERYFLAGS_AA = 0x400,
|
||||
QUERYFLAGS_TC = 0x200,
|
||||
QUERYFLAGS_RD = 0x100,
|
||||
QUERYFLAGS_RA = 0x80,
|
||||
QUERYFLAGS_Z = 0x70,
|
||||
QUERYFLAGS_RCODE = 0xF
|
||||
};
|
||||
|
||||
enum Error
|
||||
{
|
||||
ERROR_NONE,
|
||||
ERROR_UNKNOWN,
|
||||
ERROR_UNLOADED,
|
||||
ERROR_TIMEOUT,
|
||||
ERROR_NOT_AN_ANSWER,
|
||||
ERROR_NONSTANDARD_QUERY,
|
||||
ERROR_FORMAT_ERROR,
|
||||
ERROR_SERVER_FAILURE,
|
||||
ERROR_DOMAIN_NOT_FOUND,
|
||||
ERROR_NOT_IMPLEMENTED,
|
||||
ERROR_REFUSED,
|
||||
ERROR_NO_RECORDS,
|
||||
ERROR_INVALIDTYPE
|
||||
};
|
||||
|
||||
struct Question
|
||||
{
|
||||
Anope::string name;
|
||||
QueryType type;
|
||||
unsigned short qclass;
|
||||
|
||||
Question() : type(QUERY_NONE), qclass(0) { }
|
||||
Question(const Anope::string &n, QueryType t, unsigned short c = 1) : name(n), type(t), qclass(c) { }
|
||||
};
|
||||
|
||||
struct ResourceRecord : public Question
|
||||
{
|
||||
unsigned int ttl;
|
||||
Anope::string rdata;
|
||||
time_t created;
|
||||
|
||||
ResourceRecord(const Anope::string &n, QueryType t, unsigned short c = 1) : Question(n, t, c), ttl(0), created(Anope::CurTime) { }
|
||||
ResourceRecord(const Question &q) : Question(q), ttl(0), created(Anope::CurTime) { }
|
||||
};
|
||||
|
||||
struct Query
|
||||
{
|
||||
std::vector<Question> questions;
|
||||
std::vector<ResourceRecord> answers, authorities, additional;
|
||||
Error error;
|
||||
|
||||
Query() : error(ERROR_NONE) { }
|
||||
Query(const Question &q) : error(ERROR_NONE) { questions.push_back(q); }
|
||||
};
|
||||
|
||||
class Packet : public Query
|
||||
{
|
||||
public:
|
||||
static const int POINTER = 0xC0;
|
||||
static const int LABEL = 0x3F;
|
||||
static const int HEADER_LENGTH = 12;
|
||||
|
||||
virtual ~Packet() { }
|
||||
};
|
||||
|
||||
class ReplySocket;
|
||||
class Request;
|
||||
|
||||
/** DNS manager
|
||||
*/
|
||||
class Manager : public Service
|
||||
{
|
||||
public:
|
||||
Manager(Module *creator) : Service(creator, "DNS::Manager", "dns/manager") { }
|
||||
virtual ~Manager() { }
|
||||
|
||||
virtual void Process(Request *req) = 0;
|
||||
virtual void RemoveRequest(Request *req) = 0;
|
||||
|
||||
virtual bool HandlePacket(ReplySocket *s, const unsigned char *const data, int len, sockaddrs *from) = 0;
|
||||
|
||||
virtual void UpdateSerial() = 0;
|
||||
virtual uint32_t GetSerial() const = 0;
|
||||
};
|
||||
|
||||
/** A DNS query.
|
||||
*/
|
||||
class Request : public Timer, public Question
|
||||
{
|
||||
Manager *manager;
|
||||
public:
|
||||
/* Use result cache if available */
|
||||
bool use_cache;
|
||||
/* Request id */
|
||||
unsigned short id;
|
||||
/* Creator of this request */
|
||||
Module *creator;
|
||||
|
||||
Request(Manager *mgr, Module *c, const Anope::string &addr, QueryType qt, bool cache = false) : Timer(0), Question(addr, qt), manager(mgr),
|
||||
use_cache(cache), id(0), creator(c) { }
|
||||
|
||||
virtual ~Request()
|
||||
{
|
||||
manager->RemoveRequest(this);
|
||||
}
|
||||
|
||||
/** Called when this request succeeds
|
||||
* @param r The query sent back from the nameserver
|
||||
*/
|
||||
virtual void OnLookupComplete(const Query *r) = 0;
|
||||
|
||||
/** Called when this request fails or times out.
|
||||
* @param r The query sent back from the nameserver, check the error code.
|
||||
*/
|
||||
virtual void OnError(const Query *r) { }
|
||||
|
||||
/** Used to time out the query, xalls OnError and lets the TimerManager
|
||||
* delete this request.
|
||||
*/
|
||||
void Tick(time_t) anope_override
|
||||
{
|
||||
Log(LOG_DEBUG_2) << "Resolver: timeout for query " << this->name;
|
||||
Query rr(*this);
|
||||
rr.error = ERROR_TIMEOUT;
|
||||
this->OnError(&rr);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace DNS
|
||||
|
||||
#endif // DNS_H
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -6,8 +6,12 @@
|
||||
*/
|
||||
|
||||
#include "module.h"
|
||||
#include "dns.h"
|
||||
|
||||
using namespace DNS;
|
||||
|
||||
static ServiceReference<XLineManager> akills("XLineManager", "xlinemanager/sgline");
|
||||
static ServiceReference<Manager> dnsmanager("DNS::Manager", "dns/manager");
|
||||
|
||||
struct Blacklist
|
||||
{
|
||||
@@ -19,21 +23,21 @@ struct Blacklist
|
||||
Blacklist(const Anope::string &n, time_t b, const Anope::string &r, const std::map<int, Anope::string> &re) : name(n), bantime(b), reason(r), replies(re) { }
|
||||
};
|
||||
|
||||
class DNSBLResolver : public DNS::Request
|
||||
class DNSBLResolver : public Request
|
||||
{
|
||||
Reference<User> user;
|
||||
Blacklist blacklist;
|
||||
bool add_to_akill;
|
||||
|
||||
public:
|
||||
DNSBLResolver(Module *c, User *u, const Blacklist &b, const Anope::string &host, bool add_akill) : DNS::Request(host, DNS::QUERY_A, true, c), user(u), blacklist(b), add_to_akill(add_akill) { }
|
||||
DNSBLResolver(Module *c, User *u, const Blacklist &b, const Anope::string &host, bool add_akill) : Request(dnsmanager, c, host, QUERY_A, true), user(u), blacklist(b), add_to_akill(add_akill) { }
|
||||
|
||||
void OnLookupComplete(const DNS::Query *record) anope_override
|
||||
void OnLookupComplete(const Query *record) anope_override
|
||||
{
|
||||
if (!user || user->HasExt("m_dnsbl_akilled"))
|
||||
return;
|
||||
|
||||
const DNS::ResourceRecord &ans_record = record->answers[0];
|
||||
const ResourceRecord &ans_record = record->answers[0];
|
||||
// Replies should be in 127.0.0.0/24
|
||||
if (ans_record.rdata.find("127.0.0.") != 0)
|
||||
return;
|
||||
@@ -127,7 +131,7 @@ class ModuleDNSBL : public Module
|
||||
|
||||
void OnUserConnect(Reference<User> &user, bool &exempt) anope_override
|
||||
{
|
||||
if (exempt || !user || (!this->check_on_connect && !Me->IsSynced()))
|
||||
if (exempt || !user || (!this->check_on_connect && !Me->IsSynced()) || !dnsmanager)
|
||||
return;
|
||||
|
||||
if (!this->check_on_netburst && !user->server->IsSynced())
|
||||
@@ -158,7 +162,7 @@ class ModuleDNSBL : public Module
|
||||
{
|
||||
Anope::string dnsbl_host = user_ip.addr() + "." + b.name;
|
||||
DNSBLResolver *res = new DNSBLResolver(this, user, b, dnsbl_host, this->add_to_akill);
|
||||
res->Process();
|
||||
dnsmanager->Process(res);
|
||||
}
|
||||
catch (const SocketException &ex)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user