1
0
mirror of https://github.com/anope/anope.git synced 2026-07-05 23:53:13 +02:00

Move DNS handling to a module

This commit is contained in:
Adam
2012-12-15 01:33:31 -05:00
parent cdec0a3f96
commit dcd34d3728
17 changed files with 1314 additions and 1368 deletions
+7
View File
@@ -506,6 +506,13 @@ namespace Anope
* @param Raw message from the uplink
*/
extern void Process(const Anope::string &);
/** Does a blocking dns query and returns the first IP.
* @param host host to look up
* @param type inet addr type
* @return the IP if it was found, else the host
*/
extern Anope::string Resolve(const Anope::string &host, int type);
}
/** sepstream allows for splitting token seperated lists.
-14
View File
@@ -478,20 +478,6 @@ class CoreExport ServerConfig
Anope::string MailEmailchangeSubject, MailEmailchangeMessage;
Anope::string MailMemoSubject, MailMemoMessage;
/* Nameserver to use for resolving hostnames */
Anope::string NameServer;
/* Time before a DNS query is considered dead */
time_t DNSTimeout;
/* The IP/port DNS queries come in on */
Anope::string DNSIP;
int DNSPort;
/* DNS SOA admin */
Anope::string DNSSOAAdmin;
/* DNS SOA primary NS */
Anope::string DNSSOANS;
/* SOA Refresh time */
unsigned DNSSOARefresh;
/* Prefix of guest nicks when a user gets forced off of a nick */
Anope::string NSGuestNickPrefix;
/* Allow users to set kill immed on */
-1
View File
@@ -48,7 +48,6 @@ class User;
class XLine;
class XLineManager;
struct BadWord;
namespace DNS { struct Query; }
struct Exception;
struct MemoInfo;
struct ModeLock;
-278
View File
@@ -1,278 +0,0 @@
/*
*
* (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
#include "sockets.h"
#include "timers.h"
#include "config.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 CoreExport Question
{
Anope::string name;
QueryType type;
unsigned short qclass;
Question();
Question(const Anope::string &, QueryType, unsigned short = 1);
};
struct CoreExport ResourceRecord : public Question
{
unsigned int ttl;
Anope::string rdata;
time_t created;
ResourceRecord(const Anope::string &, QueryType, unsigned short = 1);
ResourceRecord(const Question &);
};
struct CoreExport Query
{
std::vector<Question> questions;
std::vector<ResourceRecord> answers, authorities, additional;
Error error;
Query();
Query(const Question &q);
};
/** A DNS query.
*/
class CoreExport Request : public Timer, public Question
{
/* Use result cache if available */
bool use_cache;
public:
/* Request id */
unsigned short id;
/* Creator of this request */
Module *creator;
Request(const Anope::string &addr, QueryType qt, bool cache = false, Module *c = NULL);
virtual ~Request();
void Process();
/** 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, Calls OnError and lets the TimerManager
* delete this request.
*/
void Tick(time_t) anope_override;
};
/** A full packet sent or recieved to/from the nameserver
*/
class Packet : public Query
{
static const int POINTER = 0xC0;
static const int LABEL = 0x3F;
void PackName(unsigned char *output, unsigned short output_size, unsigned short &pos, const Anope::string &name);
Anope::string UnpackName(const unsigned char *input, unsigned short input_size, unsigned short &pos);
Question UnpackQuestion(const unsigned char *input, unsigned short input_size, unsigned short &pos);
ResourceRecord UnpackResourceRecord(const unsigned char *input, unsigned short input_size, unsigned short &poss);
public:
static const int HEADER_LENGTH = 12;
/* Source or destination of the packet */
sockaddrs addr;
/* ID for this packet */
unsigned short id;
/* Flags on the packet */
unsigned short flags;
Packet(sockaddrs *a);
void Fill(const unsigned char *input, const unsigned short len);
unsigned short Pack(unsigned char *output, unsigned short output_size);
};
/** DNS manager
*/
class CoreExport Manager : public Timer
{
class ReplySocket : public virtual Socket
{
public:
virtual ~ReplySocket() { }
virtual void Reply(Packet *p) = 0;
};
/* Listens for TCP requests */
class TCPSocket : public ListenSocket
{
/* A TCP client */
class Client : public ClientSocket, public Timer, public ReplySocket
{
TCPSocket *tcpsock;
Packet *packet;
unsigned char packet_buffer[524];
int length;
public:
Client(TCPSocket *ls, int fd, const sockaddrs &addr);
~Client();
/* Times out after a few seconds */
void Tick(time_t) anope_override { }
void Reply(Packet *p) anope_override;
bool ProcessRead() anope_override;
bool ProcessWrite() anope_override;
};
public:
TCPSocket(const Anope::string &ip, int port);
ClientSocket *OnAccept(int fd, const sockaddrs &addr) anope_override;
};
/* Listens for UDP requests */
class UDPSocket : public ReplySocket
{
std::deque<Packet *> packets;
public:
UDPSocket(const Anope::string &ip, int port);
~UDPSocket();
void Reply(Packet *p) anope_override;
std::deque<Packet *>& GetPackets() { return packets; }
bool ProcessRead() anope_override;
bool ProcessWrite() anope_override;
};
typedef std::multimap<Anope::string, ResourceRecord, ci::less> cache_map;
cache_map cache;
bool listen;
uint32_t serial;
public:
TCPSocket *tcpsock;
UDPSocket *udpsock;
sockaddrs addrs;
std::map<unsigned short, Request *> requests;
Manager(const Anope::string &nameserver, const Anope::string &ip, int port);
~Manager();
bool HandlePacket(ReplySocket *s, const unsigned char *const data, int len, sockaddrs *from);
/** Add a record to the dns cache
* @param r The record
*/
void AddCache(Query &r);
/** Check the DNS cache to see if request can be handled by a cached result
* @return true if a cached result was found.
*/
bool CheckCache(Request *request);
/** Tick this timer, used to clear the DNS cache.
*/
void Tick(time_t now) anope_override;
/** Cleanup all pending DNS queries for a module
* @param mod The module
*/
void Cleanup(Module *mod);
void UpdateSerial();
uint32_t GetSerial() const;
/** Does a BLOCKING DNS query and returns the first IP.
* Only use this if you know what you are doing. Unless you specifically
* need a blocking query use the DNSRequest system
*/
static Query BlockingQuery(const Anope::string &mask, QueryType qt);
};
extern CoreExport Manager *Engine;
} // namespace DNS
#endif // DNS_H
-1
View File
@@ -21,7 +21,6 @@
#include "channels.h"
#include "commands.h"
#include "config.h"
#include "dns.h"
#include "extensible.h"
#include "hashcomp.h"
#include "language.h"