]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
Fix TCP_FASTOPEN_CONNECT detection, add a fastOpen option to sdig
authorRemi Gacogne <remi.gacogne@powerdns.com>
Wed, 24 Feb 2021 13:38:39 +0000 (14:38 +0100)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Tue, 2 Mar 2021 10:39:55 +0000 (11:39 +0100)
docs/manpages/sdig.1.rst
pdns/sdig.cc
pdns/tcpiohandler.hh

index 14c79fceed7306b59da28e09b6b4154da2e6d7a2..612a06ece1c8425e541c86ac6327f852a59a3f1e 100644 (file)
@@ -43,6 +43,8 @@ dot
     use DoT instead of UDP to send a query. Implies tcp.
 insecure
     when using DoT, do not validate the server certificate.
+fastOpen
+    when using TCP or, DoT, enable TCP Fast Open
 subjectName *name*
     when using DoT, verify the server certificate is issued for *name*. The `openssl` provider will accept an empty name and still
     make sure the certificate is issued by a trusted CA, `gnutls` will only do the validation if a name is given.
index c4432a2008558f3717441c7a26766efa2c956683..bec3918ad27e58df45fbcaa52edeef92f9734c66 100644 (file)
@@ -39,7 +39,7 @@ static void usage()
   cerr << "sdig" << endl;
   cerr << "Syntax: sdig IP-ADDRESS-OR-DOH-URL PORT QNAME QTYPE "
           "[dnssec] [ednssubnet SUBNET/MASK] [hidesoadetails] [hidettl] [recurse] [showflags] "
-          "[tcp] [dot] [insecure] [subjectName name] [caStore file] [tlsProvider openssl|gnutls] "
+          "[tcp] [dot] [insecure] [fastOpen] [subjectName name] [caStore file] [tlsProvider openssl|gnutls] "
           "[xpf XPFDATA] [class CLASSNUM] "
           "[proxy UDP(0)/TCP(1) SOURCE-IP-ADDRESS-AND-PORT DESTINATION-IP-ADDRESS-AND-PORT]"
        << endl;
@@ -260,6 +260,8 @@ try {
         dot = true;
       else if (strcmp(argv[i], "insecure") == 0)
         insecureDoT = true;
+      else if (strcmp(argv[i], "fastOpen") == 0)
+        fastOpen = true;
       else if (strcmp(argv[i], "ednssubnet") == 0) {
         if (argc < i + 2) {
           cerr << "ednssubnet needs an argument" << endl;
@@ -409,6 +411,7 @@ try {
     }
     uint16_t counter = 0;
     Socket sock(dest.sin4.sin_family, SOCK_STREAM);
+    setTCPNoDelay(sock.getHandle()); // disable NAGLE, which does not play nicely with delayed ACKs
     TCPIOHandler handler(subjectName, sock.releaseHandle(), timeout, tlsCtx, time(nullptr));
     handler.connect(fastOpen, dest, timeout);
     // we are writing the proxyheader inside the TLS connection. Is that right?
index b9b271e384237d0f30fa2a383421299d529989db..d15daa8cafae5b8d0edd0e4c46cef4fb8900794d 100644 (file)
@@ -1,6 +1,8 @@
 
 #pragma once
 #include <memory>
+/* needed for proper TCP_FASTOPEN_CONNECT detection */
+#include <netinet/tcp.h>
 
 #include "libssl.hh"
 #include "misc.hh"
@@ -250,7 +252,7 @@ public:
       SConnectWithTimeout(d_socket, remote, /* no timeout, we will handle it ourselves */ 0);
     }
 #else
-    SConnectWithTimeout(d_socket, d_ds->remote, /* no timeout, we will handle it ourselves */ 0);
+    SConnectWithTimeout(d_socket, remote, /* no timeout, we will handle it ourselves */ 0);
 #endif /* MSG_FASTOPEN */
 
     if (d_conn) {
@@ -282,7 +284,7 @@ public:
       SConnectWithTimeout(d_socket, remote, timeout);
     }
 #else
-    SConnectWithTimeout(d_socket, d_ds->remote, timeout);
+    SConnectWithTimeout(d_socket, remote, timeout);
 #endif /* MSG_FASTOPEN */
 
     if (d_conn) {
@@ -359,6 +361,7 @@ public:
       return d_conn->tryWrite(buffer, pos, toWrite);
     }
 
+#ifdef MSG_FASTOPEN
     if (d_fastOpen) {
       int socketFlags = MSG_FASTOPEN;
       size_t sent = sendMsgWithOptions(d_socket, reinterpret_cast<const char *>(&buffer.at(pos)), toWrite - pos, &d_remote, nullptr, 0, socketFlags);
@@ -373,6 +376,7 @@ public:
 
       return IOState::Done;
     }
+#endif /* MSG_FASTOPEN */
 
     do {
       ssize_t res = ::write(d_socket, reinterpret_cast<const char*>(&buffer.at(pos)), toWrite - pos);
@@ -401,9 +405,20 @@ public:
     if (d_conn) {
       return d_conn->write(buffer, bufferSize, writeTimeout);
     }
-    else {
-      return writen2WithTimeout(d_socket, buffer, bufferSize, writeTimeout);
+
+#ifdef MSG_FASTOPEN
+    if (d_fastOpen) {
+      int socketFlags = MSG_FASTOPEN;
+      size_t sent = sendMsgWithOptions(d_socket, reinterpret_cast<const char *>(buffer), bufferSize, &d_remote, nullptr, 0, socketFlags);
+      if (sent > 0) {
+        d_fastOpen = false;
+      }
+
+      return sent;
     }
+#endif /* MSG_FASTOPEN */
+
+    return writen2WithTimeout(d_socket, buffer, bufferSize, writeTimeout);
   }
 
   bool hasBufferedData() const
@@ -454,7 +469,9 @@ private:
   std::unique_ptr<TLSConnection> d_conn{nullptr};
   ComboAddress d_remote;
   int d_socket{-1};
+#ifdef MSG_FASTOPEN
   bool d_fastOpen{false};
+#endif
 };
 
 struct TLSContextParameters