* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
- * InspIRCd is copyright (C) 2002-2006 ChatSpike-Dev.
- * E-mail:
- * <brain@chatspike.net>
- * <Craig@chatspike.net>
+ * InspIRCd: (C) 2002-2007 InspIRCd Development Team
+ * See: http://www.inspircd.org/wiki/index.php/Credits
*
- * Written by Craig Edwards, Craig McLure, and others.
* This program is free but copyrighted software; see
- * the file COPYING for details.
+ * the file COPYING for details.
*
* ---------------------------------------------------
*/
#include <string>
#include "inspircd_config.h"
-#include "socket.h"
#include "base.h"
+#include "socketengine.h"
+#include "socket.h"
+
+using namespace std;
+using irc::sockets::insp_aton;
+using irc::sockets::insp_ntoa;
+using irc::sockets::insp_sockaddr;
+using irc::sockets::insp_inaddr;
+
+class InspIRCd;
+class Module;
/**
* Result status, used internally
RESOLVER_NSDOWN = 1,
RESOLVER_NXDOMAIN = 2,
RESOLVER_NOTREADY = 3,
- RESOLVER_BADIP = 4
+ RESOLVER_BADIP = 4,
+ RESOLVER_TIMEOUT = 5,
+ RESLOVER_FORCEUNLOAD = 6
};
/**
*/
class ResourceRecord;
-/**
- * A set of requests keyed by request id
- */
-typedef std::map<int,DNSRequest*> requestlist;
-
-/**
- * An iterator into a set of requests
- */
-typedef requestlist::iterator requestlist_iter;
-
/**
* Query and resource record types
*/
enum QueryType
{
+ DNS_QUERY_NONE = 0, /* Uninitialized Query */
DNS_QUERY_A = 1, /* 'A' record: an ipv4 address */
DNS_QUERY_CNAME = 5, /* 'CNAME' record: An alias */
DNS_QUERY_PTR = 12, /* 'PTR' record: a hostname */
/**
* Used internally to force PTR lookups to use a certain protocol scemantics,
- * e.g. x.x.x.x.in-addr.arpa for v4, and *.ip6.int for v6.
+ * e.g. x.x.x.x.in-addr.arpa for v4, and *.ip6.arpa for v6.
*/
enum ForceProtocol
{
class Resolver : public Extensible
{
protected:
+ /**
+ * Pointer to creator
+ */
+ InspIRCd* ServerInstance;
+ /**
+ * Pointer to creator module (if any, or NULL)
+ */
+ Module* Creator;
/**
* The input data, either a host or an IP address
*/
* wether InspIRCd is built with ipv6 support.
* If you attempt to resolve a 'PTR' record using DNS_QUERY_PTR, and InspIRCd is
* built with ipv6 support, the 'PTR' record will be formatted to ipv6 specs,
- * e.g. x.x.x.x.x....ip6.int. otherwise it will be formatted to ipv4 specs,
- * e.g. x.x.x.x.in-addr.arpa. This is automatic.
+ * e.g. x.x.x.x.x....ip6.arpa. otherwise it will be formatted to ipv4 specs,
+ * e.g. x.x.x.x.in-addr.arpa. This translation is automatic.
* To get around this automatic behaviour, you must use one of the values
* DNS_QUERY_PTR4 or DNS_QUERY_PTR6 to force ipv4 or ipv6 behaviour on the lookup,
* irrespective of what protocol InspIRCd has been built for.
* event a lookup could not be allocated, or a similar hard error occurs such as
* the network being down. This will also be thrown if an invalid IP address is
* passed when resolving a 'PTR' record.
+ *
+ * NOTE: If you are instantiating your DNS lookup from a module, you should set the
+ * value of creator to point at your Module class. This way if your module is unloaded
+ * whilst lookups are in progress, they can be safely removed and your module will not
+ * crash the server.
*/
- Resolver(const std::string &source, QueryType qt);
+ Resolver(InspIRCd* Instance, const std::string &source, QueryType qt, Module* creator = NULL);
+
/**
* The default destructor does nothing.
*/
* this method will return -1.
*/
int GetId();
+
+ /**
+ * Returns the creator module, or NULL
+ */
+ Module* GetCreator();
};
/** DNS is a singleton class used by the core to dispatch dns
* back to Resolver objects, based upon the request ID. You
* should never use this class yourself.
*/
-class DNS : public Extensible
+class DNS : public EventHandler
{
private:
+ InspIRCd* ServerInstance;
+
/**
* The maximum value of a dns request id,
* 16 bits wide, 0xFFFF.
*/
static const int MAX_REQUEST_ID = 0xFFFF;
- /**
- * Requests that are currently 'in flight'
- */
- requestlist requests;
-
/**
* Server address being used currently
*/
insp_inaddr myserver;
- /**
- * File descriptor being used to perform queries
- */
- static int MasterSocket;
-
/**
* A counter used to form part of the pseudo-random id
*/
int currid;
/**
- * Currently active Resolver classes
+ * We have to turn off a few checks on received packets
+ * when people are using 4in6 (e.g. ::ffff:xxxx). This is
+ * a temporary kludge, Please let me know if you know how
+ * to fix it.
*/
- Resolver* Classes[MAX_REQUEST_ID];
+ bool ip6munge;
/**
* Build a dns packet payload
int MakePayload(const char* name, const QueryType rr, const unsigned short rr_class, unsigned char* payload);
public:
+ /**
+ * Currently active Resolver classes
+ */
+ Resolver* Classes[MAX_REQUEST_ID];
+ /**
+ * Requests that are currently 'in flight'
+ */
+ DNSRequest* requests[MAX_REQUEST_ID];
/**
* The port number DNS requests are made on,
* and replies have as a source-port number.
* Empty out a header into a data stream ready for transmission "on the wire"
*/
static void EmptyHeader(unsigned char *output, const DNSHeader *header, const int length);
- /**
- * Get the master socket fd, used internally
- */
- static int GetMasterSocket();
-
/**
* Start the lookup of an ipv4 from a hostname
*/
/**
* Handle a SocketEngine read event
+ * Inherited from EventHandler
*/
- void MarshallReads(int fd);
+ void HandleEvent(EventType et, int errornum = 0);
/**
* Add a Resolver* to the list of active classes
* The constructor initialises the dns socket,
* and clears the request lists.
*/
- DNS();
+ DNS(InspIRCd* Instance);
/**
* Destructor
unsigned long PRNG();
/**
- * Turn an in6_addr into a .ip6.int domain
+ * Turn an in6_addr into a .ip6.arpa domain
*/
static void MakeIP6Int(char* query, const in6_addr *ip);
+
+ /**
+ * Clean out all dns resolvers owned by a particular
+ * module, to make unloading a module safe if there
+ * are dns requests currently in progress.
+ */
+ void CleanResolvers(Module* module);
};
#endif