#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;
/**
* Result status, used internally
*/
enum QueryType
{
- 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 */
- DNS_QUERY_AAAA = 28, /* 'AAAA' record: an ipv6 address */
+ 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 */
+ DNS_QUERY_AAAA = 28, /* 'AAAA' record: an ipv6 address */
+
+ DNS_QUERY_PTR4 = 0xFFFD, /* Force 'PTR' to use IPV4 scemantics */
+ DNS_QUERY_PTR6 = 0xFFFE, /* Force 'PTR' to use IPV6 scemantics */
};
#ifdef IPV6
const QueryType DNS_QUERY_REVERSE = DNS_QUERY_PTR;
#endif
+/**
+ * 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.arpa for v6.
+ */
+enum ForceProtocol
+{
+ PROTOCOL_IPV4 = 0, /* Forced to use ipv4 */
+ PROTOCOL_IPV6 = 1 /* Forced to use ipv6 */
+};
+
/**
* The Resolver class is a high-level abstraction for resolving DNS entries.
* It can do forward and reverse IPv4 lookups, and where IPv6 is supported, will
class Resolver : public Extensible
{
protected:
+ /**
+ * Pointer to creator
+ */
+ InspIRCd* ServerInstance;
/**
* The input data, either a host or an IP address
*/
* is supported. Use one of the QueryType enum values to initiate this type of
* lookup. Resolution of 'AAAA' ipv6 records is always supported, regardless of
* wether InspIRCd is built with ipv6 support.
- * If you attempt to resolve a 'PTR' record 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.
+ * 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.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.
* @throw ModuleException This class may throw an instance of ModuleException, in the
* 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.
*/
- Resolver(const std::string &source, QueryType qt);
+ Resolver(InspIRCd* Instance, const std::string &source, QueryType qt);
/**
* The default destructor does nothing.
*/
* 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.
*/
insp_inaddr myserver;
- /**
- * File descriptor being used to perform queries
- */
- static int MasterSocket;
-
/**
* A counter used to form part of the pseudo-random id
*/
*/
Resolver* Classes[MAX_REQUEST_ID];
+ /**
+ * 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.
+ */
+ bool ip6munge;
+
/**
* Build a dns packet payload
*/
* 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
*/
int GetIP(const char* name);
/**
- * Start the lookup of a hostname from an ip
+ * Start the lookup of a hostname from an ip,
+ * always using the protocol inspircd is built for,
+ * e.g. use ipv6 reverse lookup when built for ipv6,
+ * or ipv4 lookup when built for ipv4.
*/
int GetName(const insp_inaddr* ip);
+ /**
+ * Start lookup of a hostname from an ip, but
+ * force a specific protocol to be used for the lookup
+ * for example to perform an ipv6 reverse lookup.
+ */
+ int GetNameForce(const char *ip, ForceProtocol fp);
+
/**
* Start lookup of an ipv6 from a hostname
*/
/**
* Handle a SocketEngine read event
+ * Inherited from EventHandler
*/
- void MarshallReads(int fd);
+ void HandleEvent(EventType et);
/**
* 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);
};