+ /* Somehow we got a DNS response for a request we never made... */
+ ServerInstance->Logs->Log("RESOLVER",DEBUG,"Hmm, got a result that we didn't ask for (id=%lx). Ignoring.", this_id);
+ return DNSResult(-1,"",0,"");
+ }
+ else
+ {
+ /* Remove the query from the list of pending queries */
+ req = requests[this_id];
+ requests[this_id] = NULL;
+ }
+
+ /* Inform the DNSRequest class that it has a result to be read.
+ * When its finished it will return a DNSInfo which is a pair of
+ * unsigned char* resource record data, and an error message.
+ */
+ DNSInfo data = req->ResultIsReady(header, length);
+ std::string resultstr;
+
+ /* Check if we got a result, if we didnt, its an error */
+ if (data.first == NULL)
+ {
+ /* An error.
+ * Mask the ID with the value of ERROR_MASK, so that
+ * the dns_deal_with_classes() function knows that its
+ * an error response and needs to be treated uniquely.
+ * Put the error message in the second field.
+ */
+ std::string ro = req->orig;
+ delete req;
+ return DNSResult(this_id | ERROR_MASK, data.second, 0, ro);
+ }
+ else
+ {
+ unsigned long ttl = req->ttl;
+ char formatted[128];
+
+ /* Forward lookups come back as binary data. We must format them into ascii */
+ switch (req->type)
+ {
+ case DNS_QUERY_A:
+ snprintf(formatted,16,"%u.%u.%u.%u",data.first[0],data.first[1],data.first[2],data.first[3]);
+ resultstr = formatted;
+ break;
+
+ case DNS_QUERY_AAAA:
+ {
+ if (!inet_ntop(AF_INET6, data.first, formatted, sizeof(formatted)))
+ {
+ std::string ro = req->orig;
+ delete req;
+ return DNSResult(this_id | ERROR_MASK, "inet_ntop() failed", 0, ro);
+ }
+
+ resultstr = formatted;
+
+ /* Special case. Sending ::1 around between servers
+ * and to clients is dangerous, because the : on the
+ * start makes the client or server interpret the IP
+ * as the last parameter on the line with a value ":1".
+ */
+ if (*formatted == ':')
+ resultstr.insert(0, "0");
+ }
+ break;
+
+ case DNS_QUERY_CNAME:
+ /* Identical handling to PTR */
+
+ case DNS_QUERY_PTR:
+ {
+ /* Reverse lookups just come back as char* */
+ resultstr = std::string((const char*)data.first);
+ if (resultstr.find_first_not_of("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.-") != std::string::npos)
+ {
+ std::string ro = req->orig;
+ delete req;
+ return DNSResult(this_id | ERROR_MASK, "Invalid char(s) in reply", 0, ro);
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ /* Build the reply with the id and hostname/ip in it */
+ std::string ro = req->orig;
+ DNSResult result = DNSResult(this_id,resultstr,ttl,ro,req->type);
+ delete req;
+ return result;