]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/dns.cpp
Remove check that very rarely equates to true
[user/henk/code/inspircd.git] / src / dns.cpp
index ae0e203cd809f9dfe2545b952024b5acf4c21b54..0436095b6bd30afc315837138fd0f7402a4c1891 100644 (file)
@@ -192,7 +192,7 @@ int DNSRequest::SendRequests(const DNSHeader *header, const int length, QueryTyp
 #endif
        if (sendto(DNS::GetMasterSocket(), payload, length + 12, 0, (sockaddr *) &addr, sizeof(addr)) == -1)
        {
-               log(DEBUG,"Error in sendto!");
+               log(DEBUG,"Error in sendto! (%s)",strerror(errno));
                return -1;
        }
 
@@ -255,7 +255,25 @@ DNS::DNS()
 
        /* Convert the nameserver address into an insp_inaddr */
        if (insp_aton(Config->DNSServer,&addr) > 0)
+       {
                memcpy(&myserver,&addr,sizeof(insp_inaddr));
+               if ((strstr(Config->DNSServer,"::ffff:") == (char*)&Config->DNSServer) ||  (strstr(Config->DNSServer,"::FFFF:") == (char*)&Config->DNSServer))
+               {
+                       /* These dont come back looking like they did when they went in.
+                        * We're forced to turn some checks off.
+                        * If anyone knows how to fix this, let me know. --Brain
+                        */
+                       log(DEFAULT,"WARNING: Using IPv4 addresses over IPv6 forces some DNS checks to be disabled.");
+                       log(DEFAULT,"         This should not cause a problem, however it is recommended you migrate");
+                       log(DEFAULT,"         to a true IPv6 environment.");
+                       this->ip6munge = true;
+               }
+               log(DEBUG,"Added nameserver '%s'",Config->DNSServer);
+       }
+       else
+       {
+               log(DEBUG,"GACK! insp_aton says the nameserver '%s' is invalid!",Config->DNSServer);
+       }
 
        /* Initialize mastersocket */
        MasterSocket = socket(PF_PROTOCOL, SOCK_DGRAM, 0);
@@ -270,6 +288,10 @@ DNS::DNS()
                        MasterSocket = -1;
                }
        }
+       else
+       {
+               log(DEBUG,"I cant socket() this socket! (%s)",strerror(errno));
+       }
        /* Have we got a socket and is it nonblocking? */
        if (MasterSocket != -1)
        {
@@ -278,7 +300,7 @@ DNS::DNS()
                memset(&addr,0,sizeof(addr));
                addr.sin6_family = AF_FAMILY;
                addr.sin6_port = 0;
-               memset(&addr.sin6_addr,255,sizeof(in6_addr));
+               addr.sin6_addr = in6addr_any;
 #else
                insp_sockaddr addr;
                memset(&addr,0,sizeof(addr));
@@ -298,6 +320,7 @@ DNS::DNS()
 
                if (MasterSocket >= 0)
                {
+                       log(DEBUG,"Add master socket %d",MasterSocket);
                        /* Hook the descriptor into the socket engine */
                        if (ServerInstance && ServerInstance->SE)
                                ServerInstance->SE->AddFd(MasterSocket,true,X_ESTAB_DNS);
@@ -399,47 +422,13 @@ int DNS::GetCName(const char *alias)
 /* Start lookup of an IP address to a hostname */
 int DNS::GetName(const insp_inaddr *ip)
 {
-       char query[29];
+       char query[128];
        DNSHeader h;
        int id;
        int length;
 
 #ifdef IPV6
-       /* XXX: This SUCKS. and i mean REALLY, REALLY sucks. Anyone who rewrites it pretty gets a cookie. */
-       sprintf(query,"%0x.%0x.%0x.%0x.%0x.%0x.%0x.%0x.%0x.%0x.%0x.%0x.%0x.%0x.%0x.%0x.%0x.%0x.%0x.%0x.%0x.%0x.%0x.%0x.%0x.%0x.%0x.%0x.%0x.%0x.%0x.%0x.ip6.int",
-                       ip->s6_addr[15] & 0x0f,
-                       (ip->s6_addr[15] & 0xf0) >> 4,
-                       ip->s6_addr[14] & 0x0f,
-                       (ip->s6_addr[14] & 0xf0) >> 4,
-                       ip->s6_addr[13] & 0x0f,
-                       (ip->s6_addr[13] & 0xf0) >> 4,
-                       ip->s6_addr[12] & 0x0f,
-                       (ip->s6_addr[12] & 0xf0) >> 4,
-                       ip->s6_addr[11] & 0x0f,
-                       (ip->s6_addr[11] & 0xf0) >> 4,
-                       ip->s6_addr[10] & 0x0f,
-                       (ip->s6_addr[10] & 0xf0) >> 4,
-                       ip->s6_addr[9] & 0x0f,
-                       (ip->s6_addr[9] & 0xf0) >> 4,
-                       ip->s6_addr[8] & 0x0f,
-                       (ip->s6_addr[8] & 0xf0) >> 4,
-                       ip->s6_addr[7] & 0x0f,
-                       (ip->s6_addr[7] & 0xf0) >> 4,
-                       ip->s6_addr[6] & 0x0f,
-                       (ip->s6_addr[6] & 0xf0) >> 4,
-                       ip->s6_addr[5] & 0x0f,
-                       (ip->s6_addr[5] & 0xf0) >> 4,
-                       ip->s6_addr[4] & 0x0f,
-                       (ip->s6_addr[4] & 0xf0) >> 4,
-                       ip->s6_addr[3] & 0x0f,
-                       (ip->s6_addr[3] & 0xf0) >> 4,
-                       ip->s6_addr[2] & 0x0f,
-                       (ip->s6_addr[2] & 0xf0) >> 4,
-                       ip->s6_addr[1] & 0x0f,
-                       (ip->s6_addr[1] & 0xf0) >> 4,
-                       ip->s6_addr[0] & 0x0f,
-                       (ip->s6_addr[0] & 0xf0) >> 4
-                       );
+       DNS::MakeIP6Int(query, (in6_addr*)ip);
 #else
        unsigned char* c = (unsigned char*)&ip->s_addr;
 
@@ -457,6 +446,72 @@ 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;
+#ifdef SUPPORT_IP6LINKS
+       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
+#endif
+       {
+               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)
+{
+#ifdef SUPPORT_IP6LINKS
+       const char* hex = "0123456789abcdef";
+       for (int index = 31; index >= 0; index--) /* for() loop steps twice per byte */
+       {
+               if (index % 2)
+                       /* low nibble */
+                       *query++ = hex[ip->s6_addr[index / 2] & 0x0F];
+               else
+                       /* high nibble */
+                       *query++ = hex[(ip->s6_addr[index / 2] & 0xF0) >> 4];
+               *query++ = '.'; /* Seperator */
+       }
+       strcpy(query,"ip6.arpa"); /* Suffix the string */
+#else
+       *query = 0;
+#endif
+}
+
 /* Return the next id which is ready, and the result attached to it */
 DNSResult DNS::GetResult()
 {
@@ -471,10 +526,16 @@ DNSResult DNS::GetResult()
 
        int length = recvfrom(MasterSocket,buffer,sizeof(DNSHeader),0,&from,&x);
 
+       if (length < 0)
+               log(DEBUG,"Error in recvfrom()! (%s)",strerror(errno));
+
        /* Did we get the whole header? */
        if (length < 12)
+       {
                /* Nope - something screwed up. */
+               log(DEBUG,"Whole header not read!");
                return std::make_pair(-1,"");
+       }
 
        /* Check wether the reply came from a different DNS
         * server to the one we sent it to, or the source-port
@@ -493,8 +554,17 @@ DNSResult DNS::GetResult()
        port_from = ntohs(((sockaddr_in*)&from)->sin_port);
 #endif
 
-       if ((port_from != DNS::QUERY_PORT) || (strcasecmp(ipaddr_from, Config->DNSServer)))
-               return std::make_pair(-1,"");
+       /* We cant perform this security check if you're using 4in6.
+        * Tough luck to you, choose one or't other!
+        */
+       if (!ip6munge)
+       {
+               if ((port_from != DNS::QUERY_PORT) || (strcasecmp(ipaddr_from, Config->DNSServer)))
+               {
+                       log(DEBUG,"port %d is not 53, or %s is not %s",port_from, ipaddr_from, Config->DNSServer);
+                       return std::make_pair(-1,"");
+               }
+       }
 
        /* Put the read header info into a header class */
        DNS::FillHeader(&header,buffer,length - 12);
@@ -575,6 +645,14 @@ DNSResult DNS::GetResult()
                                                memmove(formatted,formatted + 1, strlen(formatted + 1) + 1);
                                }
                                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 = "0" + resultstr;
                        }
                        break;
 
@@ -585,6 +663,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;
                        
                }
 
@@ -765,6 +847,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;
@@ -808,6 +900,7 @@ int Resolver::GetId()
 /* Process a socket read event */
 void DNS::MarshallReads(int fd)
 {
+       log(DEBUG,"Marshall reads: %d %d",fd,GetMasterSocket());
        /* We are only intrested in our single fd */
        if (fd == GetMasterSocket())
        {