]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/dns.cpp
Add 'no such server' on remote stats to invalid name
[user/henk/code/inspircd.git] / src / dns.cpp
index 285d546937449bb545aa124483fd6ed221b07a3b..0436095b6bd30afc315837138fd0f7402a4c1891 100644 (file)
@@ -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);
@@ -430,7 +453,7 @@ int DNS::GetNameForce(const char *ip, ForceProtocol fp)
        DNSHeader h;
        int id;
        int length;
-
+#ifdef SUPPORT_IP6LINKS
        if (fp == PROTOCOL_IPV6)
        {
                in6_addr i;
@@ -443,6 +466,7 @@ int DNS::GetNameForce(const char *ip, ForceProtocol fp)
                        return -1;
        }
        else
+#endif
        {
                in_addr i;
                if (inet_aton(ip, &i))
@@ -470,6 +494,7 @@ int DNS::GetNameForce(const char *ip, ForceProtocol fp)
 
 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 */
        {
@@ -482,6 +507,9 @@ void DNS::MakeIP6Int(char* query, const in6_addr *ip)
                *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 */
@@ -503,8 +531,11 @@ DNSResult DNS::GetResult()
 
        /* 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
@@ -523,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);
@@ -605,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;
 
@@ -852,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())
        {