summaryrefslogtreecommitdiff
path: root/src/dns.cpp
diff options
context:
space:
mode:
authorbrain <brain@e03df62e-2008-0410-955e-edbf42e46eb7>2006-08-02 18:44:13 +0000
committerbrain <brain@e03df62e-2008-0410-955e-edbf42e46eb7>2006-08-02 18:44:13 +0000
commite65b2c70e43882a8b4f31df78b5f9242140320f9 (patch)
treea6cb1a4c91aec13418e8c0322be3968e71227876 /src/dns.cpp
parent29342eb55763c5a7c4a1749db34d7dcdd69c9ac1 (diff)
Add error messages to Resolver::OnError()
Add exception handling to several places that use Resolver (it can throw) Remove Resolver::ProcessResult(), its now handled within the bowels of dns.cpp git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@4646 e03df62e-2008-0410-955e-edbf42e46eb7
Diffstat (limited to 'src/dns.cpp')
-rw-r--r--src/dns.cpp138
1 files changed, 68 insertions, 70 deletions
diff --git a/src/dns.cpp b/src/dns.cpp
index 1adf5f8a2..3beb6b7c5 100644
--- a/src/dns.cpp
+++ b/src/dns.cpp
@@ -56,6 +56,11 @@ enum QueryType
DNS_QRY_PTR = 12
};
+enum QueryInfo
+{
+ ERROR_MASK = 0x10000
+};
+
enum QueryFlags
{
FLAGS_MASK_RD = 0x01,
@@ -120,8 +125,8 @@ class dns_connection
delete[] res;
}
- unsigned char* result_ready(dns_header &h, int length);
- int send_requests(const dns_header *header, const int length, QueryType qt);
+ DNSInfo result_ready(dns_header &h, int length);
+ int send_requests(const dns_header *header, const int length, QueryType qt);
};
/*
@@ -313,7 +318,7 @@ int dns_build_query_payload(const char * const name, const unsigned short rr, co
return payloadpos + 4;
}
-int DNS::dns_getip4(const char *name)
+int DNS::dns_getip(const char *name)
{
dns_header h;
int id;
@@ -331,7 +336,7 @@ int DNS::dns_getip4(const char *name)
return id;
}
-int DNS::dns_getname4(const insp_inaddr *ip)
+int DNS::dns_getname(const insp_inaddr *ip)
{
#ifdef IPV6
return -1;
@@ -393,34 +398,35 @@ DNSResult DNS::dns_getresult()
/* We don't delete c here, because its done later when needed */
connections.erase(n_iter);
}
- unsigned char* data = req->result_ready(header, length);
+ DNSInfo data = req->result_ready(header, length);
std::string resultstr;
- if (data == NULL)
+ if (data.first == NULL)
{
- resultstr = "";
+ delete req;
+ return std::make_pair(this_id | ERROR_MASK, data.second);
}
else
{
if (req->type == DNS_QRY_A)
{
char formatted[16];
- snprintf(formatted,16,"%u.%u.%u.%u",data[0],data[1],data[2],data[3]);
+ snprintf(formatted,16,"%u.%u.%u.%u",data.first[0],data.first[1],data.first[2],data.first[3]);
resultstr = formatted;
}
else
{
- resultstr = std::string((const char*)data);
+ resultstr = std::string((const char*)data.first);
}
- }
- delete req;
- return std::make_pair(this_id,resultstr);
+ delete req;
+ return std::make_pair(this_id,resultstr);
+ }
}
/** A result is ready, process it
*/
-unsigned char* dns_connection::result_ready(dns_header &header, int length)
+DNSInfo dns_connection::result_ready(dns_header &header, int length)
{
int i = 0;
int q = 0;
@@ -429,25 +435,17 @@ unsigned char* dns_connection::result_ready(dns_header &header, int length)
unsigned short p;
if (!(header.flags1 & FLAGS_MASK_QR))
- {
- log(DEBUG,"DNS: didnt get a query result");
- return NULL;
- }
+ return std::make_pair((unsigned char*)NULL,"Not a query result");
+
if (header.flags1 & FLAGS_MASK_OPCODE)
- {
- log(DEBUG,"DNS: got an OPCODE and didnt want one");
- return NULL;
- }
+ return std::make_pair((unsigned char*)NULL,"Unexpected value in DNS reply packet");
+
if (header.flags2 & FLAGS_MASK_RCODE)
- {
- log(DEBUG,"DNS lookup failed due to SERVFAIL");
- return NULL;
- }
+ return std::make_pair((unsigned char*)NULL,"Internal server error (SERVFAIL)");
+
if (header.ancount < 1)
- {
- log(DEBUG,"DNS: no answers!");
- return NULL;
- }
+ return std::make_pair((unsigned char*)NULL,"No resource records returned");
+
length -= 12;
while ((unsigned int)q < header.qdcount && i < length)
{
@@ -488,9 +486,8 @@ unsigned char* dns_connection::result_ready(dns_header &header, int length)
}
}
if (length - i < 10)
- {
- return NULL;
- }
+ return std::make_pair((unsigned char*)NULL,"Incorrectly sized DNS reply");
+
dns_fill_rr(&rr,&header.payload[i]);
i += 10;
if (rr.type != this->type)
@@ -508,23 +505,23 @@ unsigned char* dns_connection::result_ready(dns_header &header, int length)
break;
}
if ((unsigned int)curanswer == header.ancount)
- return NULL;
+ return std::make_pair((unsigned char*)NULL,"No valid answers");
+
if (i + rr.rdlength > (unsigned int)length)
- return NULL;
+ return std::make_pair((unsigned char*)NULL,"Resource record larger than stated");
+
if (rr.rdlength > 1023)
- return NULL;
+ return std::make_pair((unsigned char*)NULL,"Resource record too large");
switch (rr.type)
{
case DNS_QRY_PTR:
- log(DEBUG,"DNS: got a result of type DNS_QRY_PTR");
o = 0;
q = 0;
while (q == 0 && i < length && o + 256 < 1023)
{
if (header.payload[i] > 63)
{
- log(DEBUG,"DNS: h.payload[i] > 63");
memcpy(&p,&header.payload[i],2);
i = ntohs(p) - 0xC000 - 12;
}
@@ -548,7 +545,6 @@ unsigned char* dns_connection::result_ready(dns_header &header, int length)
res[o] = '\0';
break;
case DNS_QRY_A:
- log(DEBUG,"DNS: got a result of type DNS_QRY_A");
memcpy(res,&header.payload[i],rr.rdlength);
res[rr.rdlength] = '\0';
break;
@@ -557,7 +553,7 @@ unsigned char* dns_connection::result_ready(dns_header &header, int length)
res[rr.rdlength] = '\0';
break;
}
- return res;
+ return std::make_pair(res,"No error");;
}
DNS::DNS()
@@ -573,7 +569,7 @@ Resolver::Resolver(const std::string &source, bool forward) : input(source), fwd
if (forward)
{
log(DEBUG,"Resolver: Forward lookup on %s",source.c_str());
- this->myid = Res->dns_getip4(source.c_str());
+ this->myid = Res->dns_getip(source.c_str());
}
else
{
@@ -582,13 +578,19 @@ Resolver::Resolver(const std::string &source, bool forward) : input(source), fwd
if (insp_aton(source.c_str(), &binip) > 0)
{
/* Valid ip address */
- this->myid = Res->dns_getname4(&binip);
+ this->myid = Res->dns_getname(&binip);
+ }
+ else
+ {
+ this->OnError(RESOLVER_BADIP, "Bad IP address for reverse lookup");
+ throw ModuleException("Resolver: Bad IP address");
+ return;
}
}
if (this->myid == -1)
{
log(DEBUG,"Resolver::Resolver: Could not get an id!");
- this->OnError(RESOLVER_NSDOWN);
+ this->OnError(RESOLVER_NSDOWN, "Nameserver is down");
throw ModuleException("Resolver: Couldnt get an id to make a request");
/* We shouldnt get here really */
return;
@@ -597,11 +599,11 @@ Resolver::Resolver(const std::string &source, bool forward) : input(source), fwd
log(DEBUG,"Resolver::Resolver: this->myid=%d",this->myid);
}
-void Resolver::OnLookupComplete(const std::string &result)
-{
-}
+//void Resolver::OnLookupComplete(const std::string &result)
+//{
+//}
-void Resolver::OnError(ResolverError e)
+void Resolver::OnError(ResolverError e, const std::string &errormessage)
{
}
@@ -615,25 +617,6 @@ int Resolver::GetId()
return this->myid;
}
-bool Resolver::ProcessResult(const std::string &result)
-{
- log(DEBUG,"Resolver::ProcessResult");
-
- if (!result.length())
- {
- log(DEBUG,"Resolver::OnError(RESOLVER_NXDOMAIN)");
- this->OnError(RESOLVER_NXDOMAIN);
- return false;
- }
- else
- {
-
- log(DEBUG,"Resolver::OnLookupComplete(%s)",result.c_str());
- this->OnLookupComplete(result);
- return true;
- }
-}
-
void dns_deal_with_classes(int fd)
{
log(DEBUG,"dns_deal_with_classes(%d)",fd);
@@ -642,12 +625,27 @@ void dns_deal_with_classes(int fd)
DNSResult res = Res->dns_getresult();
if (res.first != -1)
{
- log(DEBUG,"Result available, id=%d",res.first);
- if (dns_classes[res.first])
+ if (res.first & ERROR_MASK)
{
- dns_classes[res.first]->ProcessResult(res.second);
- delete dns_classes[res.first];
- dns_classes[res.first] = NULL;
+ res.first -= ERROR_MASK;
+
+ log(DEBUG,"Error available, id=%d",res.first);
+ if (dns_classes[res.first])
+ {
+ dns_classes[res.first]->OnError(RESOLVER_NXDOMAIN, res.second);
+ delete dns_classes[res.first];
+ dns_classes[res.first] = NULL;
+ }
+ }
+ else
+ {
+ log(DEBUG,"Result available, id=%d",res.first);
+ if (dns_classes[res.first])
+ {
+ dns_classes[res.first]->OnLookupComplete(res.second);
+ delete dns_classes[res.first];
+ dns_classes[res.first] = NULL;
+ }
}
}
}