]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Split-Stack enable DNS sockets.
authorAmos Jeffries <squid3@treenet.co.nz>
Sat, 30 May 2009 13:50:46 +0000 (01:50 +1200)
committerAmos Jeffries <squid3@treenet.co.nz>
Sat, 30 May 2009 13:50:46 +0000 (01:50 +1200)
This breaks the DNS sockets into two when split-stack mode is used.
DnsSocketA becomes IPv4-only and DnsSocketB becomes used as IPv6-only.
Without Split-stack mode DnsSocketA is the only one actually used.

src/comm_poll.cc
src/comm_select.cc
src/comm_select_win32.cc
src/dns_internal.cc
src/globals.h

index 881ee904638782359d2630885ecad6cadd9048d5..5dc17b609048da680dac4951aafafdbabfb1fac0 100644 (file)
@@ -165,7 +165,10 @@ fdIsIcp(int fd)
 static int
 fdIsDns(int fd)
 {
-    if (fd == DnsSocket)
+    if (fd == DnsSocketA)
+        return 1;
+
+    if (fd == DnsSocketB)
         return 1;
 
     return 0;
@@ -577,10 +580,15 @@ comm_poll_dns_incoming(void)
     int nevents;
     dns_io_events = 0;
 
-    if (DnsSocket < 0)
+    if (DnsSocketA < 0)
         return;
 
-    fds[nfds++] = DnsSocket;
+    fds[nfds++] = DnsSocketA;
+
+#if IPV6_SPECIAL_SPLITSTACK
+    if (DnsSocketB > 0)
+        fds[nfds++] = DnsSocketB;
+#endif
 
     nevents = comm_check_incoming_poll_handlers(nfds, fds);
 
index 6e426f05e1852c705f036ddccd7a8dd57d4131e9..d701faf95c350643582bef5103a94ae641424b26 100644 (file)
@@ -176,7 +176,10 @@ fdIsIcp(int fd)
 static int
 fdIsDns(int fd)
 {
-    if (fd == DnsSocket)
+    if (fd == DnsSocketA)
+        return 1;
+
+    if (fd == DnsSocketB)
         return 1;
 
     return 0;
@@ -626,14 +629,19 @@ static void
 comm_select_dns_incoming(void)
 {
     int nfds = 0;
-    int fds[2];
+    int fds[3];
     int nevents;
     dns_io_events = 0;
 
-    if (DnsSocket < 0)
+    if (DnsSocketA < 0)
         return;
 
-    fds[nfds++] = DnsSocket;
+    fds[nfds++] = DnsSocketA;
+
+#if IPV6_SPECIAL_SPLITSTACK
+    if (DnsSocketB > 0)
+        fds[nfds++] = DnsSocketB;
+#endif
 
     nevents = comm_check_incoming_select_handlers(nfds, fds);
 
index 041fa4e3ce50d6df5136ffa5008df7d17f51f9c2..397acf15a66f84c4de512880088140ff0a8d2521 100644 (file)
@@ -176,7 +176,10 @@ fdIsIcp(int fd)
 static int
 fdIsDns(int fd)
 {
-    if (fd == DnsSocket)
+    if (fd == DnsSocketA)
+        return 1;
+
+    if (fd == DnsSocketB)
         return 1;
 
     return 0;
@@ -648,14 +651,19 @@ static void
 comm_select_dns_incoming(void)
 {
     int nfds = 0;
-    int fds[2];
+    int fds[3];
     int nevents;
     dns_io_events = 0;
 
-    if (DnsSocket < 0)
+    if (DnsSocketA < 0)
         return;
 
-    fds[nfds++] = DnsSocket;
+    fds[nfds++] = DnsSocketA;
+
+#if IPV6_SPECIAL_SPLITSTACK
+    if (DnsSocketB > 0)
+        fds[nfds++] = DnsSocketB;
+#endif
 
     nevents = comm_check_incoming_select_handlers(nfds, fds);
 
index fbd7d488a504f9ec4953383869893ff94eee26ec..224de5c20cfbd47a1dc3be55ddba248e89e822dc 100644 (file)
@@ -791,10 +791,7 @@ idnsSendQueryVC(idns_query * q, int ns)
 static void
 idnsSendQuery(idns_query * q)
 {
-    int x;
-    int ns;
-
-    if (DnsSocket < 0) {
+    if (DnsSocketA < 0 && DnsSocketB < 0) {
         debugs(78, 1, "WARNING: idnsSendQuery: Can't send query, no DNS socket!");
         return;
     }
@@ -808,28 +805,49 @@ idnsSendQuery(idns_query * q)
 
     assert(q->lru.prev == NULL);
 
+    int x = -1, y = -1;
+    int ns;
+
     do {
         ns = q->nsends % nns;
 
         if (q->need_vc) {
             idnsSendQueryVC(q, ns);
-            x = 0;
+            x = y = 0;
         } else {
-            x = comm_udp_sendto(DnsSocket, nameservers[ns].S, q->buf, q->sz);
+#if IPV6_SPECIAL_SPLITSTACK
+            if (nameservers[ns].S.IsIPv6() && DnsSocketB > 0)
+                y = comm_udp_sendto(DnsSocketB, nameservers[ns].S, q->buf, q->sz);
+            else
+#endif
+                x = comm_udp_sendto(DnsSocketA, nameservers[ns].S, q->buf, q->sz);
         }
 
         q->nsends++;
 
         q->queue_t = q->sent_t = current_time;
 
+#if IPV6_SPECIAL_SPLITSTACK
+        if (y < 0 && nameservers[ns].S.IsIPv6())
+            debugs(50, 1, "idnsSendQuery: FD " << DnsSocketB << ": sendto: " << xstrerror());
+        if (x < 0 && nameservers[ns].S.IsIPv4())
+#else
         if (x < 0)
-            debugs(50, 1, "idnsSendQuery: FD " << DnsSocket << ": sendto: " << xstrerror());
+#endif
+            debugs(50, 1, "idnsSendQuery: FD " << DnsSocketA << ": sendto: " << xstrerror());
+
+    } while ( (x<0 && y<0) && q->nsends % nns != 0);
 
-    } while ( x<0 && q->nsends % nns != 0);
+#if IPV6_SPECIAL_SPLITSTACK
+    if (y >= 0) {
+        fd_bytes(DnsSocketB, y, FD_WRITE);
+        commSetSelect(DnsSocketB, COMM_SELECT_READ, idnsRead, NULL, 0);
+    }
+#endif
 
     if (x >= 0) {
-        fd_bytes(DnsSocket, x, FD_WRITE);
-        commSetSelect(DnsSocket, COMM_SELECT_READ, idnsRead, NULL, 0);
+        fd_bytes(DnsSocketA, x, FD_WRITE);
+        commSetSelect(DnsSocketA, COMM_SELECT_READ, idnsRead, NULL, 0);
     }
 
     nameservers[ns].nqueries++;
@@ -1153,7 +1171,13 @@ idnsRead(int fd, void *data)
             break;
         }
 
-        fd_bytes(DnsSocket, len, FD_READ);
+#if IPV6_SPECIAL_SPLITSTACK
+        if ( from.IsIPv6() )
+            fd_bytes(DnsSocketB, len, FD_READ);
+        else
+#endif
+            fd_bytes(DnsSocketA, len, FD_READ);
+
         assert(N);
         (*N)++;
 
@@ -1179,8 +1203,14 @@ idnsRead(int fd, void *data)
         idnsGrokReply(rbuf, len);
     }
 
-    if (lru_list.head)
-        commSetSelect(DnsSocket, COMM_SELECT_READ, idnsRead, NULL, 0);
+    if (lru_list.head) {
+#if IPV6_SPECIAL_SPLITSTACK
+        if ( from.IsIPv6() )
+            commSetSelect(DnsSocketB, COMM_SELECT_READ, idnsRead, NULL, 0);
+        else
+#endif
+            commSetSelect(DnsSocketA, COMM_SELECT_READ, idnsRead, NULL, 0);
+    }
 }
 
 static void
@@ -1327,7 +1357,7 @@ idnsInit(void)
     CBDATA_INIT_TYPE(nsvc);
     CBDATA_INIT_TYPE(idns_query);
 
-    if (DnsSocket < 0) {
+    if (DnsSocketA < 0 && DnsSocketB < 0) {
         int port;
 
         IpAddress addr; // since we don't want to alter Config.Addrs.udp_* and dont have one of our own.
@@ -1338,21 +1368,44 @@ idnsInit(void)
             addr = Config.Addrs.udp_incoming;
 
         debugs(78, 2, "idnsInit: attempt open DNS socket to: " << addr);
-        DnsSocket = comm_open_listener(SOCK_DGRAM,
-                              IPPROTO_UDP,
-                              addr,
-                              COMM_NONBLOCKING,
-                              "DNS Socket");
+#if IPV6_SPECIAL_SPLITSTACK
+        if ( addr.IsAnyAddr() || addr.IsIPv6() )
+            DnsSocketB = comm_open_listener(SOCK_DGRAM,
+                                  IPPROTO_UDP,
+                                  addr,
+                                  COMM_NONBLOCKING,
+                                  "DNS Socket v6");
+
+        if ( addr.IsAnyAddr() || addr.IsIPv4() )
+            DnsSocketA = comm_open_listener(SOCK_DGRAM,
+                                  IPPROTO_UDP,
+                                  addr,
+                                  COMM_NONBLOCKING,
+                                  "DNS Socket v4");
+#else
+            DnsSocketA = comm_open_listener(SOCK_DGRAM,
+                                  IPPROTO_UDP,
+                                  addr,
+                                  COMM_NONBLOCKING,
+                                  "DNS Socket");
+#endif
 
-        if (DnsSocket < 0)
+        if (DnsSocketA < 0 && DnsSocketB < 0)
             fatal("Could not create a DNS socket");
 
         /* Ouch... we can't call functions using debug from a debug
          * statement. Doing so messes up the internal Debug::level
          */
-        port = comm_local_port(DnsSocket);
-
-        debugs(78, 1, "DNS Socket created at " << addr << ", FD " << DnsSocket);
+#if IPV6_SPECIAL_SPLITSTACK
+        if(DnsSocketB >= 0) {
+            port = comm_local_port(DnsSocketB);
+            debugs(78, 1, "DNS Socket created at " << addr << ", FD " << DnsSocketB);
+        }
+#endif
+        if(DnsSocketA >= 0) {
+            port = comm_local_port(DnsSocketA);
+            debugs(78, 1, "DNS Socket created at " << addr << ", FD " << DnsSocketA);
+        }
     }
 
     assert(0 == nns);
@@ -1397,12 +1450,20 @@ idnsInit(void)
 void
 idnsShutdown(void)
 {
-    if (DnsSocket < 0)
+    if (DnsSocketA < 0 && DnsSocketB < 0)
         return;
 
-    comm_close(DnsSocket);
+    if(DnsSocketA >= 0 ) {
+        comm_close(DnsSocketA);
+        DnsSocketA = -1;
+    }
 
-    DnsSocket = -1;
+#if IPV6_SPECIAL_SPLITSTACK
+    if(DnsSocketA >= 0 ) {
+        comm_close(DnsSocketB);
+        DnsSocketB = -1;
+    }
+#endif
 
     for (int i = 0; i < nns; i++) {
         if (nsvc *vc = nameservers[i].vc) {
@@ -1412,7 +1473,6 @@ idnsShutdown(void)
     }
 
     idnsFreeNameservers();
-
     idnsFreeSearchpath();
 }
 
index 7ed98b6ac10346616ef489356102c22bfbe06343..0da0a0e04b19e5369c5df1224fd0e34bbf0b0c15 100644 (file)
@@ -102,7 +102,8 @@ extern "C"
     extern int syslog_enable;  /* 0 */
     extern int theInIcpConnection;     /* -1 */
     extern int theOutIcpConnection;    /* -1 */
-    extern int DnsSocket;              /* -1 */
+    extern int DnsSocketA;             /* -1 */
+    extern int DnsSocketB;             /* -1 */
 #ifdef SQUID_SNMP
 
     extern int theInSnmpConnection;    /* -1 */