https://github.com/python/cpython/commit/b5aa271f86229f126c21805ff2bd3b95526818a4
commit: b5aa271f86229f126c21805ff2bd3b95526818a4
branch: main
author: nkinnan <[email protected]>
committer: vstinner <[email protected]>
date: 2024-09-05T22:59:48+02:00
summary:

gh-123476: Add support for TCP_QUICKACK socket setting to Windows (#123478)

Co-authored-by: Kirill Podoprigora <[email protected]>
Co-authored-by: Bénédikt Tran <[email protected]>
Co-authored-by: Steve Dower <[email protected]>

files:
A Misc/NEWS.d/next/Windows/2024-08-29-16-13-45.gh-issue-123476.m2DFS4.rst
M Doc/library/socket.rst
M Lib/test/test_socket.py
M Modules/socketmodule.c
M Modules/socketmodule.h

diff --git a/Doc/library/socket.rst b/Doc/library/socket.rst
index a81e11549d5c54..8e3b020d8d7a34 100644
--- a/Doc/library/socket.rst
+++ b/Doc/library/socket.rst
@@ -413,14 +413,14 @@ Constants
       ``TCP_USER_TIMEOUT``, ``TCP_CONGESTION`` were added.
 
    .. versionchanged:: 3.6.5
-      On Windows, ``TCP_FASTOPEN``, ``TCP_KEEPCNT`` appear if run-time Windows
-      supports.
+      Added support for ``TCP_FASTOPEN``, ``TCP_KEEPCNT`` on Windows platforms
+      when available.
 
    .. versionchanged:: 3.7
       ``TCP_NOTSENT_LOWAT`` was added.
 
-      On Windows, ``TCP_KEEPIDLE``, ``TCP_KEEPINTVL`` appear if run-time 
Windows
-      supports.
+      Added support for ``TCP_KEEPIDLE``, ``TCP_KEEPINTVL`` on Windows 
platforms
+      when available.
 
    .. versionchanged:: 3.10
       ``IP_RECVTOS`` was added.
@@ -454,6 +454,10 @@ Constants
       Added missing ``IP_RECVERR``, ``IP_RECVTTL``, and ``IP_RECVORIGDSTADDR``
       on Linux.
 
+   .. versionchanged:: 3.14
+      Added support for ``TCP_QUICKACK`` on Windows platforms when available.
+
+
 .. data:: AF_CAN
           PF_CAN
           SOL_CAN_*
diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py
index 7c607a809aa428..628f806c78959d 100644
--- a/Lib/test/test_socket.py
+++ b/Lib/test/test_socket.py
@@ -6826,6 +6826,28 @@ class TestMacOSTCPFlags(unittest.TestCase):
     def test_tcp_keepalive(self):
         self.assertTrue(socket.TCP_KEEPALIVE)
 
[email protected](hasattr(socket, 'TCP_QUICKACK'), 'need 
socket.TCP_QUICKACK')
+class TestQuickackFlag(unittest.TestCase):
+    def check_set_quickack(self, sock):
+        # quickack already true by default on some OS distributions
+        opt = sock.getsockopt(socket.IPPROTO_TCP, socket.TCP_QUICKACK)
+        if opt:
+            sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_QUICKACK, 0)
+
+        opt = sock.getsockopt(socket.IPPROTO_TCP, socket.TCP_QUICKACK)
+        self.assertFalse(opt)
+
+        sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_QUICKACK, 1)
+
+        opt = sock.getsockopt(socket.IPPROTO_TCP, socket.TCP_QUICKACK)
+        self.assertTrue(opt)
+
+    def test_set_quickack(self):
+        sock = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM,
+                             proto=socket.IPPROTO_TCP)
+        with sock:
+            self.check_set_quickack(sock)
+
 
 @unittest.skipUnless(sys.platform.startswith("win"), "requires Windows")
 class TestMSWindowsTCPFlags(unittest.TestCase):
@@ -6839,7 +6861,9 @@ class TestMSWindowsTCPFlags(unittest.TestCase):
                        'TCP_KEEPCNT',
                        # available starting with Windows 10 1709
                        'TCP_KEEPIDLE',
-                       'TCP_KEEPINTVL'
+                       'TCP_KEEPINTVL',
+                       # available starting with Windows 7 / Server 2008 R2
+                       'TCP_QUICKACK',
                        }
 
     def test_new_tcp_flags(self):
diff --git 
a/Misc/NEWS.d/next/Windows/2024-08-29-16-13-45.gh-issue-123476.m2DFS4.rst 
b/Misc/NEWS.d/next/Windows/2024-08-29-16-13-45.gh-issue-123476.m2DFS4.rst
new file mode 100644
index 00000000000000..801214edc315ff
--- /dev/null
+++ b/Misc/NEWS.d/next/Windows/2024-08-29-16-13-45.gh-issue-123476.m2DFS4.rst
@@ -0,0 +1 @@
+Add support for ``socket.TCP_QUICKACK`` on Windows platforms.
diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c
index 3ffdaa45f16ac7..77e09659514160 100644
--- a/Modules/socketmodule.c
+++ b/Modules/socketmodule.c
@@ -3166,6 +3166,17 @@ sock_setsockopt(PySocketSockObject *s, PyObject *args)
     /* setsockopt(level, opt, flag) */
     if (PyArg_ParseTuple(args, "iii:setsockopt",
                          &level, &optname, &flag)) {
+#ifdef MS_WINDOWS
+        if (optname == SIO_TCP_SET_ACK_FREQUENCY) {
+            int dummy;
+            res = WSAIoctl(s->sock_fd, SIO_TCP_SET_ACK_FREQUENCY, &flag,
+                           sizeof(flag), NULL, 0, &dummy, NULL, NULL);
+            if (res >= 0) {
+                s->quickack = flag;
+            }
+            goto done;
+        }
+#endif
         res = setsockopt(s->sock_fd, level, optname,
                          (char*)&flag, sizeof flag);
         goto done;
@@ -3251,6 +3262,11 @@ sock_getsockopt(PySocketSockObject *s, PyObject *args)
                 return s->errorhandler();
             return PyLong_FromUnsignedLong(vflag);
         }
+#endif
+#ifdef MS_WINDOWS
+        if (optname == SIO_TCP_SET_ACK_FREQUENCY) {
+            return PyLong_FromLong(s->quickack);
+        }
 #endif
         flagsize = sizeof flag;
         res = getsockopt(s->sock_fd, level, optname,
@@ -5316,6 +5332,9 @@ sock_new(PyTypeObject *type, PyObject *args, PyObject 
*kwds)
         ((PySocketSockObject *)new)->sock_fd = INVALID_SOCKET;
         ((PySocketSockObject *)new)->sock_timeout = _PyTime_FromSeconds(-1);
         ((PySocketSockObject *)new)->errorhandler = &set_error;
+#ifdef MS_WINDOWS
+        ((PySocketSockObject *)new)->quickack = 0;
+#endif
     }
     return new;
 }
@@ -8616,6 +8635,9 @@ socket_exec(PyObject *m)
 #ifdef  TCP_CONNECTION_INFO
     ADD_INT_MACRO(m, TCP_CONNECTION_INFO);
 #endif
+#ifdef  SIO_TCP_SET_ACK_FREQUENCY
+#define TCP_QUICKACK SIO_TCP_SET_ACK_FREQUENCY
+#endif
 #ifdef  TCP_QUICKACK
     ADD_INT_MACRO(m, TCP_QUICKACK);
 #endif
diff --git a/Modules/socketmodule.h b/Modules/socketmodule.h
index 09fd70f351f1d8..a77c620c2ef630 100644
--- a/Modules/socketmodule.h
+++ b/Modules/socketmodule.h
@@ -325,6 +325,9 @@ typedef struct {
     PyTime_t sock_timeout;     /* Operation timeout in seconds;
                                         0.0 means non-blocking */
     struct _socket_state *state;
+#ifdef MS_WINDOWS
+    int quickack;
+#endif
 } PySocketSockObject;
 
 /* --- C API ----------------------------------------------------*/

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: [email protected]

Reply via email to