Parcourir la source

[1452] use a larger number of send attempts for pushTooFast. Linux doubles the
SO_SNDBUF value so 3 didn't work. also make sure bufsize is adjusted only
when the default size is too small.

JINMEI Tatuya il y a 13 ans
Parent
commit
8fda3f02ea
2 fichiers modifiés avec 24 ajouts et 9 suppressions
  1. 12 4
      src/lib/util/io/socketsession.cc
  2. 12 5
      src/lib/util/tests/socketsession_unittest.cc

+ 12 - 4
src/lib/util/io/socketsession.cc

@@ -144,10 +144,18 @@ SocketSessionForwarder::connectToReceiver() {
                   "Failed to make UNIX domain socket non blocking: " <<
                   strerror(errno));
     }
-    if (setsockopt(impl_->fd_, SOL_SOCKET, SO_SNDBUF, &SOCKSESSION_BUFSIZE,
-                   sizeof(SOCKSESSION_BUFSIZE)) == -1) {
-        close();
-        isc_throw(SocketSessionError, "Failed to set send buffer size");
+    // Ensure the socket send buffer is large enough.  If we can't get the
+    // current size, simply set the sufficient size.
+    int sndbuf_size;
+    socklen_t sndbuf_size_len = sizeof(sndbuf_size);
+    if (getsockopt(impl_->fd_, SOL_SOCKET, SO_SNDBUF, &sndbuf_size,
+                   &sndbuf_size_len) == -1 ||
+        sndbuf_size < SOCKSESSION_BUFSIZE) {
+        if (setsockopt(impl_->fd_, SOL_SOCKET, SO_SNDBUF, &SOCKSESSION_BUFSIZE,
+                       sizeof(SOCKSESSION_BUFSIZE)) == -1) {
+            close();
+            isc_throw(SocketSessionError, "Failed to set send buffer size");
+        }
     }
     if (connect(impl_->fd_, convertSockAddr(&impl_->sock_un_),
                 impl_->sock_un_len_) == -1) {

+ 12 - 5
src/lib/util/tests/socketsession_unittest.cc

@@ -662,15 +662,22 @@ TEST_F(ForwardTest, badPush) {
                  SocketSessionError);
 }
 
-// A subroutine for pushTooFast.  Due to the fixed configuration of the
-// send buffer size, we shouldn't be able to forward 3 full-size DNS messages
-// without receiving them.  Exactly how many we can forward depends on the
-// internal system implementation, so we'll at least confirm we can't do for 3.
+// A subroutine for pushTooFast, continuously pushing socket sessions
+// with full-size DNS messages (65535 bytes) without receiving them.  
+// the push attempts will eventually fill the socket send buffer and trigger
+// an exception.  Unfortunately exactly how many we can forward depends on
+// the internal system implementation; it should be close to 3, because
+// in our current implementation it sets the send buffer to a size that
+// is sufficiently large to hold 2 sessions (but not much larger than that),
+// but (for example) Linux internally doubles the specified upper limit.
+// Experimentally we know 10 is enough to produce a reliable result, but
+// if it turns out to be not the case, we should do it a bit harder, e.g.,
+// by probing the actual buffer size by getsockopt(SO_SNDBUF).
 void
 multiPush(SocketSessionForwarder& forwarder, const struct sockaddr& sa,
           const void* data, size_t data_len)
 {
-    for (int i = 0; i < 3; ++i) {
+    for (int i = 0; i < 10; ++i) {
         forwarder.push(1, AF_INET, SOCK_DGRAM, IPPROTO_UDP, sa, sa,
                        data, data_len);
     }