From c030ee465841f5b10d4f4098b1b606ba478f961c Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 29 Aug 2024 08:57:44 -0700 Subject: [PATCH 01/28] Add support for existing TCP_QUICKACK socket setting to Windows On Windows, sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_QUICKACK, 1) throws AttributeError: module 'socket' has no attribute 'TCP_QUICKACK' TCP_QUICKACK already exists and has support on the Linux side, this change just adds support when running on Windows as well. --- Lib/asyncio/base_events.py | 10 ++++++ Lib/test/test_asyncio/test_base_events.py | 23 ++++++++++++++ Lib/test/test_socket.py | 4 ++- Modules/socketmodule.c | 38 +++++++++++++++++++++-- Modules/socketmodule.h | 3 ++ 5 files changed, 75 insertions(+), 3 deletions(-) diff --git a/Lib/asyncio/base_events.py b/Lib/asyncio/base_events.py index 000647f57dd9e3..4bfa9e8723dca4 100644 --- a/Lib/asyncio/base_events.py +++ b/Lib/asyncio/base_events.py @@ -199,6 +199,16 @@ def _set_nodelay(sock): def _set_nodelay(sock): pass +if hasattr(socket, 'TCP_QUICKACK'): + def _set_quickack(sock): + if (sock.family in {socket.AF_INET, socket.AF_INET6} and + sock.type == socket.SOCK_STREAM and + sock.proto == socket.IPPROTO_TCP): + sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_QUICKACK, 1) +else: + def _set_quickack(sock): + pass + def _check_ssl_socket(sock): if ssl is not None and isinstance(sock, ssl.SSLSocket): diff --git a/Lib/test/test_asyncio/test_base_events.py b/Lib/test/test_asyncio/test_base_events.py index c14a0bb180d79b..d9cdefd374d5ba 100644 --- a/Lib/test/test_asyncio/test_base_events.py +++ b/Lib/test/test_asyncio/test_base_events.py @@ -2225,6 +2225,29 @@ def test_set_nodelay(self): sock.setblocking(False) self.check_set_nodelay(sock) + def check_set_quickack(self, sock): + opt = sock.getsockopt(socket.IPPROTO_TCP, socket.TCP_QUICKACK) + self.assertFalse(opt) + + base_events._set_quickack(sock) + + opt = sock.getsockopt(socket.IPPROTO_TCP, socket.TCP_QUICKACK) + self.assertTrue(opt) + + @unittest.skipUnless(hasattr(socket, 'TCP_QUICKACK'), + 'need socket.TCP_QUICKACK') + 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) + + sock = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM, + proto=socket.IPPROTO_TCP) + with sock: + sock.setblocking(False) + self.check_set_quickack(sock) + if __name__ == '__main__': diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py index 7c607a809aa428..0acd441e82c3fb 100644 --- a/Lib/test/test_socket.py +++ b/Lib/test/test_socket.py @@ -6839,7 +6839,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/Modules/socketmodule.c b/Modules/socketmodule.c index 3ffdaa45f16ac7..ea1a39bb473976 100644 --- a/Modules/socketmodule.c +++ b/Modules/socketmodule.c @@ -3166,8 +3166,22 @@ 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; + } + else { + res = setsockopt(s->sock_fd, level, optname, + (char*)&flag, sizeof flag); + } +#else res = setsockopt(s->sock_fd, level, optname, - (char*)&flag, sizeof flag); + (char*)&flag, sizeof flag); +#endif goto done; } @@ -3251,6 +3265,19 @@ 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); + } + else { + flagsize = sizeof flag; + res = getsockopt(s->sock_fd, level, optname, + (void *)&flag, &flagsize); + if (res < 0) + return s->errorhandler(); + return PyLong_FromLong(flag); + } #endif flagsize = sizeof flag; res = getsockopt(s->sock_fd, level, optname, @@ -5315,7 +5342,10 @@ sock_new(PyTypeObject *type, PyObject *args, PyObject *kwds) if (new != NULL) { ((PySocketSockObject *)new)->sock_fd = INVALID_SOCKET; ((PySocketSockObject *)new)->sock_timeout = _PyTime_FromSeconds(-1); - ((PySocketSockObject *)new)->errorhandler = &set_error; + ((PySocketSockObject*)new)->errorhandler = &set_error; +#ifdef MS_WINDOWS + ((PySocketSockObject*)new)->quickack = false; +#endif } return new; } @@ -8616,6 +8646,10 @@ 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 + ADD_INT_MACRO(m, TCP_QUICKACK); +#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 ----------------------------------------------------*/ From 8d510a2ffa405a7700ac014e69464ce3227237b7 Mon Sep 17 00:00:00 2001 From: "blurb-it[bot]" <43283697+blurb-it[bot]@users.noreply.github.com> Date: Thu, 29 Aug 2024 16:13:46 +0000 Subject: [PATCH 02/28] =?UTF-8?q?=F0=9F=93=9C=F0=9F=A4=96=20Added=20by=20b?= =?UTF-8?q?lurb=5Fit.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Windows/2024-08-29-16-13-45.gh-issue-123476.m2DFS4.rst | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 Misc/NEWS.d/next/Windows/2024-08-29-16-13-45.gh-issue-123476.m2DFS4.rst 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..e970b2747a380b --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2024-08-29-16-13-45.gh-issue-123476.m2DFS4.rst @@ -0,0 +1,3 @@ +Setting socket option TCP_QUICKACK is now also possible on Windows, in addition to Linux. + +example: sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_QUICKACK, 1) From 635e385e460b670895b3707cd2bd8e5a811edbd8 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 29 Aug 2024 09:30:47 -0700 Subject: [PATCH 03/28] bugfix in previous commit --- Modules/socketmodule.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c index ea1a39bb473976..1a2bb9b85b0c03 100644 --- a/Modules/socketmodule.c +++ b/Modules/socketmodule.c @@ -5344,7 +5344,7 @@ sock_new(PyTypeObject *type, PyObject *args, PyObject *kwds) ((PySocketSockObject *)new)->sock_timeout = _PyTime_FromSeconds(-1); ((PySocketSockObject*)new)->errorhandler = &set_error; #ifdef MS_WINDOWS - ((PySocketSockObject*)new)->quickack = false; + ((PySocketSockObject*)new)->quickack = 0; #endif } return new; From 183a18e1e49f24d82f7c6650b0a0c10d78068952 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 29 Aug 2024 09:39:43 -0700 Subject: [PATCH 04/28] bugfix in previous commit --- Modules/socketmodule.c | 1 - 1 file changed, 1 deletion(-) diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c index 1a2bb9b85b0c03..f7a6c8977e081b 100644 --- a/Modules/socketmodule.c +++ b/Modules/socketmodule.c @@ -8648,7 +8648,6 @@ socket_exec(PyObject *m) #endif #ifdef SIO_TCP_SET_ACK_FREQUENCY #define TCP_QUICKACK SIO_TCP_SET_ACK_FREQUENCY - ADD_INT_MACRO(m, TCP_QUICKACK); #endif #ifdef TCP_QUICKACK ADD_INT_MACRO(m, TCP_QUICKACK); From e96d9db3d3d78a1691c7107fc6a8582cb63e569a Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 29 Aug 2024 10:27:20 -0700 Subject: [PATCH 05/28] remove test case since it works on windows but fails in the server environment --- Lib/test/test_asyncio/test_base_events.py | 24 ----------------------- 1 file changed, 24 deletions(-) diff --git a/Lib/test/test_asyncio/test_base_events.py b/Lib/test/test_asyncio/test_base_events.py index d9cdefd374d5ba..a633c47744de05 100644 --- a/Lib/test/test_asyncio/test_base_events.py +++ b/Lib/test/test_asyncio/test_base_events.py @@ -2225,30 +2225,6 @@ def test_set_nodelay(self): sock.setblocking(False) self.check_set_nodelay(sock) - def check_set_quickack(self, sock): - opt = sock.getsockopt(socket.IPPROTO_TCP, socket.TCP_QUICKACK) - self.assertFalse(opt) - - base_events._set_quickack(sock) - - opt = sock.getsockopt(socket.IPPROTO_TCP, socket.TCP_QUICKACK) - self.assertTrue(opt) - - @unittest.skipUnless(hasattr(socket, 'TCP_QUICKACK'), - 'need socket.TCP_QUICKACK') - 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) - - sock = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM, - proto=socket.IPPROTO_TCP) - with sock: - sock.setblocking(False) - self.check_set_quickack(sock) - - if __name__ == '__main__': unittest.main() From 8147664f386d696f2165c129a4a1be23520702f5 Mon Sep 17 00:00:00 2001 From: nkinnan Date: Thu, 29 Aug 2024 10:39:25 -0700 Subject: [PATCH 06/28] Update Lib/test/test_socket.py Co-authored-by: Kirill Podoprigora --- Lib/test/test_socket.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py index 0acd441e82c3fb..479edf144e2bca 100644 --- a/Lib/test/test_socket.py +++ b/Lib/test/test_socket.py @@ -6841,7 +6841,7 @@ class TestMSWindowsTCPFlags(unittest.TestCase): 'TCP_KEEPIDLE', 'TCP_KEEPINTVL', # available starting with Windows 7 / Server 2008 R2 - 'TCP_QUICKACK' + 'TCP_QUICKACK', } def test_new_tcp_flags(self): From 02ffa5269148c891cf2c9d71c8076de9a3cbd2d4 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 29 Aug 2024 10:43:25 -0700 Subject: [PATCH 07/28] modify news --- .../next/Windows/2024-08-29-16-13-45.gh-issue-123476.m2DFS4.rst | 2 -- 1 file changed, 2 deletions(-) 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 index e970b2747a380b..b546cc994c7c2c 100644 --- 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 @@ -1,3 +1 @@ Setting socket option TCP_QUICKACK is now also possible on Windows, in addition to Linux. - -example: sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_QUICKACK, 1) From 1ca08b78200bb8a4eaefb654070892b7c312dfd5 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 29 Aug 2024 10:52:09 -0700 Subject: [PATCH 08/28] remove last bit of unit test straggler code --- Lib/asyncio/base_events.py | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/Lib/asyncio/base_events.py b/Lib/asyncio/base_events.py index 4bfa9e8723dca4..000647f57dd9e3 100644 --- a/Lib/asyncio/base_events.py +++ b/Lib/asyncio/base_events.py @@ -199,16 +199,6 @@ def _set_nodelay(sock): def _set_nodelay(sock): pass -if hasattr(socket, 'TCP_QUICKACK'): - def _set_quickack(sock): - if (sock.family in {socket.AF_INET, socket.AF_INET6} and - sock.type == socket.SOCK_STREAM and - sock.proto == socket.IPPROTO_TCP): - sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_QUICKACK, 1) -else: - def _set_quickack(sock): - pass - def _check_ssl_socket(sock): if ssl is not None and isinstance(sock, ssl.SSLSocket): From a0889a5b3f70b74a5a2951cb79a7dc667dd7a806 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 29 Aug 2024 11:01:39 -0700 Subject: [PATCH 09/28] cleanup --- Modules/socketmodule.c | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c index f7a6c8977e081b..33f593a20029f8 100644 --- a/Modules/socketmodule.c +++ b/Modules/socketmodule.c @@ -3173,15 +3173,11 @@ sock_setsockopt(PySocketSockObject *s, PyObject *args) sizeof(flag), NULL, 0, &dummy, NULL, NULL); if (res >= 0) s->quickack = flag; + goto done; } - else { - res = setsockopt(s->sock_fd, level, optname, - (char*)&flag, sizeof flag); - } -#else +#endif res = setsockopt(s->sock_fd, level, optname, (char*)&flag, sizeof flag); -#endif goto done; } @@ -3270,14 +3266,6 @@ sock_getsockopt(PySocketSockObject *s, PyObject *args) if (optname == SIO_TCP_SET_ACK_FREQUENCY) { return PyLong_FromLong(s->quickack); } - else { - flagsize = sizeof flag; - res = getsockopt(s->sock_fd, level, optname, - (void *)&flag, &flagsize); - if (res < 0) - return s->errorhandler(); - return PyLong_FromLong(flag); - } #endif flagsize = sizeof flag; res = getsockopt(s->sock_fd, level, optname, From f2e8ccac3d011731b2b56ab17c76f535fedf21a5 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 29 Aug 2024 11:03:13 -0700 Subject: [PATCH 10/28] whitespace --- Modules/socketmodule.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c index 33f593a20029f8..526cd18c3d5a15 100644 --- a/Modules/socketmodule.c +++ b/Modules/socketmodule.c @@ -3177,7 +3177,7 @@ sock_setsockopt(PySocketSockObject *s, PyObject *args) } #endif res = setsockopt(s->sock_fd, level, optname, - (char*)&flag, sizeof flag); + (char*)&flag, sizeof flag); goto done; } From a607fec8993737ef6cc2dcf545f06b5b150ef676 Mon Sep 17 00:00:00 2001 From: nkinnan Date: Fri, 30 Aug 2024 11:36:30 -0700 Subject: [PATCH 11/28] Update Modules/socketmodule.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit if statement brackets Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com> --- Modules/socketmodule.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c index 526cd18c3d5a15..d32618c3339b14 100644 --- a/Modules/socketmodule.c +++ b/Modules/socketmodule.c @@ -3171,8 +3171,9 @@ sock_setsockopt(PySocketSockObject *s, PyObject *args) int dummy; res = WSAIoctl(s->sock_fd, SIO_TCP_SET_ACK_FREQUENCY, &flag, sizeof(flag), NULL, 0, &dummy, NULL, NULL); - if (res >= 0) + if (res >= 0) { s->quickack = flag; + } goto done; } #endif From 016a2c600e4a37648fe04102e0e24e08785fccf2 Mon Sep 17 00:00:00 2001 From: nkinnan Date: Fri, 30 Aug 2024 11:58:26 -0700 Subject: [PATCH 12/28] Update Misc/NEWS.d/next/Windows/2024-08-29-16-13-45.gh-issue-123476.m2DFS4.rst MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Improve phrasing Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com> --- .../next/Windows/2024-08-29-16-13-45.gh-issue-123476.m2DFS4.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 index b546cc994c7c2c..801214edc315ff 100644 --- 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 @@ -1 +1 @@ -Setting socket option TCP_QUICKACK is now also possible on Windows, in addition to Linux. +Add support for ``socket.TCP_QUICKACK`` on Windows platforms. From ce8c1ab85b88298f51218c5f9f1bd46d2281f778 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 30 Aug 2024 12:35:42 -0700 Subject: [PATCH 13/28] additional documentation in socket.rst -- needs python release version filled in --- Doc/library/socket.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Doc/library/socket.rst b/Doc/library/socket.rst index 253a120e5c0f51..7240066eb3e77e 100644 --- a/Doc/library/socket.rst +++ b/Doc/library/socket.rst @@ -408,6 +408,9 @@ Constants in the Unix header files are defined; for a few symbols, default values are provided. + .. versionchanged:: ?.? On Windows, ``TCP_QUICKACK`` appear if run-time Windows + supports. + .. versionchanged:: 3.6 ``SO_DOMAIN``, ``SO_PROTOCOL``, ``SO_PEERSEC``, ``SO_PASSSEC``, ``TCP_USER_TIMEOUT``, ``TCP_CONGESTION`` were added. From 8185776f6c0c9b1c24b7aeea3cb56759d22fd0b1 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 30 Aug 2024 13:05:20 -0700 Subject: [PATCH 14/28] unit test that should work even if TCP_QUICKACK is already turned on / all OSes --- Lib/asyncio/base_events.py | 22 +++++++++++++++++ Lib/test/test_asyncio/test_base_events.py | 30 +++++++++++++++++++++++ 2 files changed, 52 insertions(+) diff --git a/Lib/asyncio/base_events.py b/Lib/asyncio/base_events.py index 000647f57dd9e3..21ebb87e841448 100644 --- a/Lib/asyncio/base_events.py +++ b/Lib/asyncio/base_events.py @@ -200,6 +200,28 @@ def _set_nodelay(sock): pass +if hasattr(socket, 'TCP_QUICKACK'): + def _set_quickack(sock): + if (sock.family in {socket.AF_INET, socket.AF_INET6} and + sock.type == socket.SOCK_STREAM and + sock.proto == socket.IPPROTO_TCP): + sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_QUICKACK, 1) +else: + def _set_quickack(sock): + pass + + +if hasattr(socket, 'TCP_QUICKACK'): + def _unset_quickack(sock): + if (sock.family in {socket.AF_INET, socket.AF_INET6} and + sock.type == socket.SOCK_STREAM and + sock.proto == socket.IPPROTO_TCP): + sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_QUICKACK, 0) +else: + def _unset_quickack(sock): + pass + + def _check_ssl_socket(sock): if ssl is not None and isinstance(sock, ssl.SSLSocket): raise TypeError("Socket cannot be of type SSLSocket") diff --git a/Lib/test/test_asyncio/test_base_events.py b/Lib/test/test_asyncio/test_base_events.py index a633c47744de05..94e9b3ceee7f28 100644 --- a/Lib/test/test_asyncio/test_base_events.py +++ b/Lib/test/test_asyncio/test_base_events.py @@ -2226,5 +2226,35 @@ def test_set_nodelay(self): self.check_set_nodelay(sock) +class TestSelectorUtils(test_utils.TestCase): + def check_set_quickack(self, sock): + # quickack already true by default on some OSes + opt = sock.getsockopt(socket.IPPROTO_TCP, socket.TCP_QUICKACK) + if opt: + base_events._unset_quickack(sock) + + opt = sock.getsockopt(socket.IPPROTO_TCP, socket.TCP_QUICKACK) + self.assertFalse(opt) + + base_events._set_quickack(sock) + + opt = sock.getsockopt(socket.IPPROTO_TCP, socket.TCP_QUICKACK) + self.assertTrue(opt) + + @unittest.skipUnless(hasattr(socket, 'TCP_QUICKACK'), + 'need socket.TCP_QUICKACK') + 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) + + sock = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM, + proto=socket.IPPROTO_TCP) + with sock: + sock.setblocking(False) + self.check_set_quickack(sock) + + if __name__ == '__main__': unittest.main() From 7616b21b28629e98a552cabc33c392c1df887304 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 30 Aug 2024 13:11:37 -0700 Subject: [PATCH 15/28] lint --- Lib/test/test_asyncio/test_base_events.py | 1 - 1 file changed, 1 deletion(-) diff --git a/Lib/test/test_asyncio/test_base_events.py b/Lib/test/test_asyncio/test_base_events.py index 94e9b3ceee7f28..095ddc819d1818 100644 --- a/Lib/test/test_asyncio/test_base_events.py +++ b/Lib/test/test_asyncio/test_base_events.py @@ -2226,7 +2226,6 @@ def test_set_nodelay(self): self.check_set_nodelay(sock) -class TestSelectorUtils(test_utils.TestCase): def check_set_quickack(self, sock): # quickack already true by default on some OSes opt = sock.getsockopt(socket.IPPROTO_TCP, socket.TCP_QUICKACK) From 4b49a2eca97ed9776beee9f652fbcdc446415abf Mon Sep 17 00:00:00 2001 From: nkinnan Date: Fri, 30 Aug 2024 14:47:01 -0700 Subject: [PATCH 16/28] Update socket.rst putting v 3.13 on spec since I don't know how releases work --- Doc/library/socket.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/socket.rst b/Doc/library/socket.rst index 7240066eb3e77e..5d779ddd391214 100644 --- a/Doc/library/socket.rst +++ b/Doc/library/socket.rst @@ -408,7 +408,7 @@ Constants in the Unix header files are defined; for a few symbols, default values are provided. - .. versionchanged:: ?.? On Windows, ``TCP_QUICKACK`` appear if run-time Windows + .. versionchanged:: 3.13 On Windows, ``TCP_QUICKACK`` appear if run-time Windows supports. .. versionchanged:: 3.6 From 94f9087f6c98a8e24c04a75fff41fe101e33a872 Mon Sep 17 00:00:00 2001 From: nkinnan Date: Sat, 31 Aug 2024 01:11:03 -0700 Subject: [PATCH 17/28] Update Modules/socketmodule.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit make quickack variable boolean Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com> --- Modules/socketmodule.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/socketmodule.h b/Modules/socketmodule.h index a77c620c2ef630..fd5d39ee7a7793 100644 --- a/Modules/socketmodule.h +++ b/Modules/socketmodule.h @@ -326,7 +326,7 @@ typedef struct { 0.0 means non-blocking */ struct _socket_state *state; #ifdef MS_WINDOWS - int quickack; + unsigned int quickack: 1; #endif } PySocketSockObject; From ebd8a9dfe56a322ec6a0c7519b89db82d88f0c41 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 31 Aug 2024 01:41:42 -0700 Subject: [PATCH 18/28] code review comments addressed --- Doc/library/socket.rst | 15 ++++---- Lib/asyncio/base_events.py | 17 ++------- Lib/test/test_asyncio/test_base_events.py | 45 ++++++++++++----------- 3 files changed, 35 insertions(+), 42 deletions(-) diff --git a/Doc/library/socket.rst b/Doc/library/socket.rst index 5d779ddd391214..a2abea3d00952f 100644 --- a/Doc/library/socket.rst +++ b/Doc/library/socket.rst @@ -408,22 +408,19 @@ Constants in the Unix header files are defined; for a few symbols, default values are provided. - .. versionchanged:: 3.13 On Windows, ``TCP_QUICKACK`` appear if run-time Windows - supports. - .. versionchanged:: 3.6 ``SO_DOMAIN``, ``SO_PROTOCOL``, ``SO_PEERSEC``, ``SO_PASSSEC``, ``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. @@ -457,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/asyncio/base_events.py b/Lib/asyncio/base_events.py index 21ebb87e841448..0ed307175e3339 100644 --- a/Lib/asyncio/base_events.py +++ b/Lib/asyncio/base_events.py @@ -201,24 +201,13 @@ def _set_nodelay(sock): if hasattr(socket, 'TCP_QUICKACK'): - def _set_quickack(sock): + def _set_quickack(sock, val): if (sock.family in {socket.AF_INET, socket.AF_INET6} and sock.type == socket.SOCK_STREAM and sock.proto == socket.IPPROTO_TCP): - sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_QUICKACK, 1) + sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_QUICKACK, val) else: - def _set_quickack(sock): - pass - - -if hasattr(socket, 'TCP_QUICKACK'): - def _unset_quickack(sock): - if (sock.family in {socket.AF_INET, socket.AF_INET6} and - sock.type == socket.SOCK_STREAM and - sock.proto == socket.IPPROTO_TCP): - sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_QUICKACK, 0) -else: - def _unset_quickack(sock): + def _set_quickack(sock, val): pass diff --git a/Lib/test/test_asyncio/test_base_events.py b/Lib/test/test_asyncio/test_base_events.py index 095ddc819d1818..180e7c5cae6742 100644 --- a/Lib/test/test_asyncio/test_base_events.py +++ b/Lib/test/test_asyncio/test_base_events.py @@ -2214,28 +2214,30 @@ def check_set_nodelay(self, sock): @unittest.skipUnless(hasattr(socket, 'TCP_NODELAY'), 'need socket.TCP_NODELAY') def test_set_nodelay(self): - sock = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM, - proto=socket.IPPROTO_TCP) - with sock: - self.check_set_nodelay(sock) + with self.subTest('non-blocking'): + sock = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM, + proto=socket.IPPROTO_TCP) + with sock: + self.check_set_nodelay(sock) - sock = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM, - proto=socket.IPPROTO_TCP) - with sock: - sock.setblocking(False) - self.check_set_nodelay(sock) + with self.subTest('blocking'): + sock = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM, + proto=socket.IPPROTO_TCP) + with sock: + sock.setblocking(False) + self.check_set_nodelay(sock) def check_set_quickack(self, sock): # quickack already true by default on some OSes opt = sock.getsockopt(socket.IPPROTO_TCP, socket.TCP_QUICKACK) if opt: - base_events._unset_quickack(sock) + base_events._set_quickack(sock, 0) opt = sock.getsockopt(socket.IPPROTO_TCP, socket.TCP_QUICKACK) self.assertFalse(opt) - base_events._set_quickack(sock) + base_events._set_quickack(sock, 1) opt = sock.getsockopt(socket.IPPROTO_TCP, socket.TCP_QUICKACK) self.assertTrue(opt) @@ -2243,16 +2245,17 @@ def check_set_quickack(self, sock): @unittest.skipUnless(hasattr(socket, 'TCP_QUICKACK'), 'need socket.TCP_QUICKACK') 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) - - sock = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM, - proto=socket.IPPROTO_TCP) - with sock: - sock.setblocking(False) - self.check_set_quickack(sock) + with self.subTest('non-blocking'): + sock = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM, + proto=socket.IPPROTO_TCP) + with sock: + self.check_set_quickack(sock) + with self.subTest('blocking'): + sock = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM, + proto=socket.IPPROTO_TCP) + with sock: + sock.setblocking(False) + self.check_set_quickack(sock) if __name__ == '__main__': From a478e5e825e2f31a65160a343706d182f678ffad Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 31 Aug 2024 01:50:52 -0700 Subject: [PATCH 19/28] lint --- Doc/library/socket.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Doc/library/socket.rst b/Doc/library/socket.rst index a2abea3d00952f..bb609b2939eb8a 100644 --- a/Doc/library/socket.rst +++ b/Doc/library/socket.rst @@ -413,13 +413,13 @@ Constants ``TCP_USER_TIMEOUT``, ``TCP_CONGESTION`` were added. .. versionchanged:: 3.6.5 - Added support for ``TCP_FASTOPEN``, ``TCP_KEEPCNT`` on Windows platforms + Added support for ``TCP_FASTOPEN``, ``TCP_KEEPCNT`` on Windows platforms when available. .. versionchanged:: 3.7 ``TCP_NOTSENT_LOWAT`` was added. - Added support for ``TCP_KEEPIDLE``, ``TCP_KEEPINTVL`` on Windows platforms + Added support for ``TCP_KEEPIDLE``, ``TCP_KEEPINTVL`` on Windows platforms when available. .. versionchanged:: 3.10 @@ -454,7 +454,7 @@ Constants Added missing ``IP_RECVERR``, ``IP_RECVTTL``, and ``IP_RECVORIGDSTADDR`` on Linux. - .. versionchanged:: 3.14 + .. versionchanged:: 3.14 Added support for ``TCP_QUICKACK`` on Windows platforms when available. From 776d231a9ab80f2d9aeccd1c0aa6f8264060b0bd Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 31 Aug 2024 01:54:13 -0700 Subject: [PATCH 20/28] revert CR change due to CR comment updated --- Modules/socketmodule.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/socketmodule.h b/Modules/socketmodule.h index fd5d39ee7a7793..a77c620c2ef630 100644 --- a/Modules/socketmodule.h +++ b/Modules/socketmodule.h @@ -326,7 +326,7 @@ typedef struct { 0.0 means non-blocking */ struct _socket_state *state; #ifdef MS_WINDOWS - unsigned int quickack: 1; + int quickack; #endif } PySocketSockObject; From d0527e33cad034573c23a65fdb112e330377fa04 Mon Sep 17 00:00:00 2001 From: nkinnan Date: Tue, 3 Sep 2024 12:41:42 -0700 Subject: [PATCH 21/28] Update Modules/socketmodule.c formatting style oops Co-authored-by: Steve Dower --- Modules/socketmodule.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c index d32618c3339b14..77e09659514160 100644 --- a/Modules/socketmodule.c +++ b/Modules/socketmodule.c @@ -5331,9 +5331,9 @@ sock_new(PyTypeObject *type, PyObject *args, PyObject *kwds) if (new != NULL) { ((PySocketSockObject *)new)->sock_fd = INVALID_SOCKET; ((PySocketSockObject *)new)->sock_timeout = _PyTime_FromSeconds(-1); - ((PySocketSockObject*)new)->errorhandler = &set_error; + ((PySocketSockObject *)new)->errorhandler = &set_error; #ifdef MS_WINDOWS - ((PySocketSockObject*)new)->quickack = 0; + ((PySocketSockObject *)new)->quickack = 0; #endif } return new; From fe453bcdb9a49d73e25a42303cf86249e9640c76 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 3 Sep 2024 14:19:49 -0700 Subject: [PATCH 22/28] move test case, remove test support code from asyncio --- Lib/asyncio/base_events.py | 11 --------- Lib/test/test_asyncio/test_base_events.py | 30 ----------------------- Lib/test/test_socket.py | 29 ++++++++++++++++++++++ 3 files changed, 29 insertions(+), 41 deletions(-) diff --git a/Lib/asyncio/base_events.py b/Lib/asyncio/base_events.py index 0ed307175e3339..000647f57dd9e3 100644 --- a/Lib/asyncio/base_events.py +++ b/Lib/asyncio/base_events.py @@ -200,17 +200,6 @@ def _set_nodelay(sock): pass -if hasattr(socket, 'TCP_QUICKACK'): - def _set_quickack(sock, val): - if (sock.family in {socket.AF_INET, socket.AF_INET6} and - sock.type == socket.SOCK_STREAM and - sock.proto == socket.IPPROTO_TCP): - sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_QUICKACK, val) -else: - def _set_quickack(sock, val): - pass - - def _check_ssl_socket(sock): if ssl is not None and isinstance(sock, ssl.SSLSocket): raise TypeError("Socket cannot be of type SSLSocket") diff --git a/Lib/test/test_asyncio/test_base_events.py b/Lib/test/test_asyncio/test_base_events.py index 180e7c5cae6742..ff9dc06f3dc3f9 100644 --- a/Lib/test/test_asyncio/test_base_events.py +++ b/Lib/test/test_asyncio/test_base_events.py @@ -2228,35 +2228,5 @@ def test_set_nodelay(self): self.check_set_nodelay(sock) - def check_set_quickack(self, sock): - # quickack already true by default on some OSes - opt = sock.getsockopt(socket.IPPROTO_TCP, socket.TCP_QUICKACK) - if opt: - base_events._set_quickack(sock, 0) - - opt = sock.getsockopt(socket.IPPROTO_TCP, socket.TCP_QUICKACK) - self.assertFalse(opt) - - base_events._set_quickack(sock, 1) - - opt = sock.getsockopt(socket.IPPROTO_TCP, socket.TCP_QUICKACK) - self.assertTrue(opt) - - @unittest.skipUnless(hasattr(socket, 'TCP_QUICKACK'), - 'need socket.TCP_QUICKACK') - def test_set_quickack(self): - with self.subTest('non-blocking'): - sock = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM, - proto=socket.IPPROTO_TCP) - with sock: - self.check_set_quickack(sock) - with self.subTest('blocking'): - sock = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM, - proto=socket.IPPROTO_TCP) - with sock: - sock.setblocking(False) - self.check_set_quickack(sock) - - if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py index 479edf144e2bca..9e26de946a0a9d 100644 --- a/Lib/test/test_socket.py +++ b/Lib/test/test_socket.py @@ -6826,6 +6826,35 @@ class TestMacOSTCPFlags(unittest.TestCase): def test_tcp_keepalive(self): self.assertTrue(socket.TCP_KEEPALIVE) +class TestQuickackFlag(unittest.TestCase): + def test_tcp_keepalive(self): + self.assertTrue(socket.TCP_KEEPALIVE) + +@unittest.skipUnless(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): + for blocking in (False, True): + with self.subTest(blocking=blocking): + sock = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM, + proto=socket.IPPROTO_TCP) + with sock: + sock.setblocking(blocking) + self.check_set_quickack(sock) + @unittest.skipUnless(sys.platform.startswith("win"), "requires Windows") class TestMSWindowsTCPFlags(unittest.TestCase): From ec053add8b0ce9483a3131c5791458fafa7da1b8 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 3 Sep 2024 14:22:55 -0700 Subject: [PATCH 23/28] typo --- Lib/test/test_socket.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py index 9e26de946a0a9d..c1513257dde73d 100644 --- a/Lib/test/test_socket.py +++ b/Lib/test/test_socket.py @@ -6826,10 +6826,6 @@ class TestMacOSTCPFlags(unittest.TestCase): def test_tcp_keepalive(self): self.assertTrue(socket.TCP_KEEPALIVE) -class TestQuickackFlag(unittest.TestCase): - def test_tcp_keepalive(self): - self.assertTrue(socket.TCP_KEEPALIVE) - @unittest.skipUnless(hasattr(socket, 'TCP_QUICKACK'), 'need socket.TCP_QUICKACK') class TestQuickackFlag(unittest.TestCase): def check_set_quickack(self, sock): From 8c068553746e7406fdd36fe68bf842addc0ee399 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 3 Sep 2024 14:24:20 -0700 Subject: [PATCH 24/28] revert change to different test case --- Lib/test/test_asyncio/test_base_events.py | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/Lib/test/test_asyncio/test_base_events.py b/Lib/test/test_asyncio/test_base_events.py index ff9dc06f3dc3f9..e20134da6a800e 100644 --- a/Lib/test/test_asyncio/test_base_events.py +++ b/Lib/test/test_asyncio/test_base_events.py @@ -2214,18 +2214,16 @@ def check_set_nodelay(self, sock): @unittest.skipUnless(hasattr(socket, 'TCP_NODELAY'), 'need socket.TCP_NODELAY') def test_set_nodelay(self): - with self.subTest('non-blocking'): - sock = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM, - proto=socket.IPPROTO_TCP) - with sock: - self.check_set_nodelay(sock) - - with self.subTest('blocking'): - sock = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM, - proto=socket.IPPROTO_TCP) - with sock: - sock.setblocking(False) - self.check_set_nodelay(sock) + sock = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM, + proto=socket.IPPROTO_TCP) + with sock: + self.check_set_nodelay(sock) + + sock = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM, + proto=socket.IPPROTO_TCP) + with sock: + sock.setblocking(False) + self.check_set_nodelay(sock) if __name__ == '__main__': From d7cb4260b7095ea3ec1ee7668a8304bd07635b58 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 3 Sep 2024 14:24:47 -0700 Subject: [PATCH 25/28] whitespace --- Lib/test/test_asyncio/test_base_events.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_asyncio/test_base_events.py b/Lib/test/test_asyncio/test_base_events.py index e20134da6a800e..a633c47744de05 100644 --- a/Lib/test/test_asyncio/test_base_events.py +++ b/Lib/test/test_asyncio/test_base_events.py @@ -2215,12 +2215,12 @@ def check_set_nodelay(self, sock): 'need socket.TCP_NODELAY') def test_set_nodelay(self): sock = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM, - proto=socket.IPPROTO_TCP) + proto=socket.IPPROTO_TCP) with sock: self.check_set_nodelay(sock) sock = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM, - proto=socket.IPPROTO_TCP) + proto=socket.IPPROTO_TCP) with sock: sock.setblocking(False) self.check_set_nodelay(sock) From 1bc9b7ac057be97c3a011b6d19db809e0a13be50 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 3 Sep 2024 14:25:12 -0700 Subject: [PATCH 26/28] whitespace --- Lib/test/test_asyncio/test_base_events.py | 1 + 1 file changed, 1 insertion(+) diff --git a/Lib/test/test_asyncio/test_base_events.py b/Lib/test/test_asyncio/test_base_events.py index a633c47744de05..c14a0bb180d79b 100644 --- a/Lib/test/test_asyncio/test_base_events.py +++ b/Lib/test/test_asyncio/test_base_events.py @@ -2226,5 +2226,6 @@ def test_set_nodelay(self): self.check_set_nodelay(sock) + if __name__ == '__main__': unittest.main() From e9a39b68951e91cbf440d99f55f674aa70f58515 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 5 Sep 2024 13:24:32 -0700 Subject: [PATCH 27/28] test blocking path only for now --- Lib/test/test_socket.py | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py index c1513257dde73d..548484582a27fc 100644 --- a/Lib/test/test_socket.py +++ b/Lib/test/test_socket.py @@ -6843,13 +6843,10 @@ def check_set_quickack(self, sock): self.assertTrue(opt) def test_set_quickack(self): - for blocking in (False, True): - with self.subTest(blocking=blocking): - sock = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM, - proto=socket.IPPROTO_TCP) - with sock: - sock.setblocking(blocking) - self.check_set_quickack(sock) + 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") From 559bbcbe58c1c9cc6570bc53039585012e028a0c Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 5 Sep 2024 13:25:43 -0700 Subject: [PATCH 28/28] whitespace --- Lib/test/test_socket.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py index 548484582a27fc..628f806c78959d 100644 --- a/Lib/test/test_socket.py +++ b/Lib/test/test_socket.py @@ -6844,7 +6844,7 @@ def check_set_quickack(self, sock): def test_set_quickack(self): sock = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM, - proto=socket.IPPROTO_TCP) + proto=socket.IPPROTO_TCP) with sock: self.check_set_quickack(sock)