summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/dns.h43
-rw-r--r--src/dns.cpp59
-rw-r--r--src/modules/m_testcommand.cpp24
3 files changed, 103 insertions, 23 deletions
diff --git a/include/dns.h b/include/dns.h
index 8550e5e70..a769f11bc 100644
--- a/include/dns.h
+++ b/include/dns.h
@@ -92,10 +92,13 @@ typedef requestlist::iterator requestlist_iter;
*/
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
@@ -107,6 +110,16 @@ 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.int 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
* also be able to do those, transparent of protocols. Module developers must
@@ -155,9 +168,13 @@ class Resolver : public Extensible
* 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.int. otherwise it will be formatted to ipv4 specs,
+ * e.g. x.x.x.x.in-addr.arpa. This 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
@@ -266,11 +283,21 @@ class DNS : public Extensible
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
*/
int GetIP6(const char *name);
diff --git a/src/dns.cpp b/src/dns.cpp
index fac10d98e..2c4cd807b 100644
--- a/src/dns.cpp
+++ b/src/dns.cpp
@@ -423,6 +423,51 @@ int DNS::GetName(const insp_inaddr *ip)
return id;
}
+/* Start lookup of an IP address to a hostname */
+int DNS::GetNameForce(const char *ip, ForceProtocol fp)
+{
+ char query[128];
+ DNSHeader h;
+ int id;
+ int length;
+
+ if (fp == PROTOCOL_IPV6)
+ {
+ in6_addr i;
+ if (inet_pton(AF_INET6, ip, &i) > 0)
+ {
+ DNS::MakeIP6Int(query, &i);
+ }
+ else
+ /* Invalid IP address */
+ return -1;
+ }
+ else
+ {
+ in_addr i;
+ if (inet_aton(ip, &i))
+ {
+ unsigned char* c = (unsigned char*)&i.s_addr;
+ sprintf(query,"%d.%d.%d.%d.in-addr.arpa",c[3],c[2],c[1],c[0]);
+ }
+ else
+ /* Invalid IP address */
+ return -1;
+ }
+
+ log(DEBUG,"DNS::GetNameForce: %s %d",query, fp);
+
+ if ((length = this->MakePayload(query, DNS_QUERY_PTR, 1, (unsigned char*)&h.payload)) == -1)
+ return -1;
+
+ DNSRequest* req = this->AddQuery(&h, id);
+
+ if ((!req) || (req->SendRequests(&h, length, DNS_QUERY_PTR) == -1))
+ return -1;
+
+ return id;
+}
+
void DNS::MakeIP6Int(char* query, const in6_addr *ip)
{
const char* hex = "0123456789abcdef";
@@ -568,6 +613,10 @@ DNSResult DNS::GetResult()
/* Reverse lookups just come back as char* */
resultstr = std::string((const char*)data.first);
break;
+
+ default:
+ log(DEBUG,"WARNING: Somehow we made a request for a DNS_QUERY_PTR4 or DNS_QUERY_PTR6, but these arent real rr types!");
+ break;
}
@@ -748,6 +797,16 @@ Resolver::Resolver(const std::string &source, QueryType qt) : input(source), que
}
break;
+ case DNS_QUERY_PTR4:
+ querytype = DNS_QUERY_PTR;
+ this->myid = ServerInstance->Res->GetNameForce(source.c_str(), PROTOCOL_IPV4);
+ break;
+
+ case DNS_QUERY_PTR6:
+ querytype = DNS_QUERY_PTR;
+ this->myid = ServerInstance->Res->GetNameForce(source.c_str(), PROTOCOL_IPV6);
+ break;
+
case DNS_QUERY_AAAA:
this->myid = ServerInstance->Res->GetIP6(source.c_str());
break;
diff --git a/src/modules/m_testcommand.cpp b/src/modules/m_testcommand.cpp
index cca30de5d..6f517e8ce 100644
--- a/src/modules/m_testcommand.cpp
+++ b/src/modules/m_testcommand.cpp
@@ -27,24 +27,16 @@ using namespace std;
class MyV6Resolver : public Resolver
{
+ bool fw;
public:
- MyV6Resolver(const std::string &source) : Resolver(source, DNS_QUERY_AAAA) { }
+ MyV6Resolver(const std::string &source, bool forward) : Resolver(source, forward ? DNS_QUERY_AAAA : DNS_QUERY_PTR6)
+ {
+ fw = forward;
+ }
virtual void OnLookupComplete(const std::string &result)
{
- log(DEBUG,"*** RESOLVER COMPLETED LOOKUP, IP IS: '%s'",result.c_str());
-
- char query[128];
- in6_addr n;
- if (inet_pton(AF_INET6, result.c_str(), &n) > 0)
- {
- DNS::MakeIP6Int(query, &n);
- log(DEBUG,"Translation: %s",query);
- }
- else
- {
- log(DEBUG,"Bad IPV6 IP: %s",result.c_str());
- }
+ log(DEBUG,"*** RESOLVER COMPLETED %s LOOKUP, IP IS: '%s'",fw ? "FORWARD" : "REVERSE", result.c_str());
}
virtual void OnError(ResolverError e, const std::string &errormessage)
@@ -70,7 +62,9 @@ class cmd_woot : public command_t
try
{
- MyV6Resolver* r = new MyV6Resolver("shake.stacken.kth.se");
+ MyV6Resolver* r = new MyV6Resolver("shake.stacken.kth.se", true);
+ Srv->AddResolver(r);
+ r = new MyV6Resolver("2001:6b0:1:ea:202:a5ff:fecd:13a6", false);
Srv->AddResolver(r);
}
catch (ModuleException& e)