8000 gh-123476: Add support for TCP_QUICKACK socket setting to Windows (#1… · python/cpython@b5aa271 · GitHub
[go: up one dir, main page]

Skip to content

Commit b5aa271

Browse files
nkinnanEclips4picnixzzooba
authored
gh-123476: Add support for TCP_QUICKACK socket setting to Windows (#123478)
Co-authored-by: Kirill Podoprigora <kirill.bast9@mail.ru> Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com> Co-authored-by: Steve Dower <steve.dower@microsoft.com>
1 parent 6e43928 commit b5aa271

File tree

5 files changed

+59
-5
lines changed

5 files changed

+59
-5
lines changed

Doc/library/socket.rst

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -413,14 +413,14 @@ Constants
413413
``TCP_USER_TIMEOUT``, ``TCP_CONGESTION`` were added.
414414

415415
.. versionchanged:: 3.6.5
416-
On Windows, ``TCP_FASTOPEN``, ``TCP_KEEPCNT`` appear if run-time Windows
417-
supports.
416+
Added support for ``TCP_FASTOPEN``, ``TCP_KEEPCNT`` on Windows platforms
417+
when available.
418418

419419
.. versionchanged:: 3.7
420420
``TCP_NOTSENT_LOWAT`` was added.
421421

422-
On Windows, ``TCP_KEEPIDLE``, ``TCP_KEEPINTVL`` appear if run-time Windows
423-
supports.
422+
Added support for ``TCP_KEEPIDLE``, ``TCP_KEEPINTVL`` on Windows platforms
423+
when available.
424424

425425
.. versionchanged:: 3.10
426426
``IP_RECVTOS`` was added.
@@ -454,6 +454,10 @@ Constants
454454
Added missing ``IP_RECVERR``, ``IP_RECVTTL``, and ``IP_RECVORIGDSTADDR``
455455
on Linux.
456456

457+
.. versionchanged:: 3.14
458+
Added support for ``TCP_QUICKACK`` on Windows platforms when available.
459+
460+
457461
.. data:: AF_CAN
458462
PF_CAN
459463
SOL_CAN_*

Lib/test/test_socket.py

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6826,6 +6826,28 @@ class TestMacOSTCPFlags(unittest.TestCase):
68266826
def test_tcp_keepalive(self):
68276827
self.assertTrue(socket.TCP_KEEPALIVE)
68286828

6829+
@unittest.skipUnless(hasattr(socket, 'TCP_QUICKACK'), 'need socket.TCP_QUICKACK')
6830+
class TestQuickackFlag(unittest.TestCase):
6831+
def check_set_quickack(self, sock):
6832+
# quickack already true by default on some OS distributions
6833+
opt = sock.getsockopt(socket.IPPROTO_TCP, socket.TCP_QUICKACK)
6834+
if opt:
6835+
sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_QUICKACK, 0)
6836+
6837+
opt = sock.getsockopt(socket.IPPROTO_TCP, socket.TCP_QUICKACK)
6838+
self.assertFalse(opt)
6839+
6840+
sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_QUICKACK, 1)
6841+
6842+
opt = sock.getsockopt(socket.IPPROTO_TCP, socket.TCP_QUICKACK)
6843+
self.assertTrue(opt)
6844+
6845+
def test_set_quickack(self):
6846+
sock = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM,
6847+
proto=socket.IPPROTO_TCP)
6848+
with sock:
6849+
self.check_set_quickack(sock)
6850+
68296851

68306852
@unittest.skipUnless(sys.platform.startswith("win"), "requires Windows")
68316853
class TestMSWindowsTCPFlags(unittest.TestCase):
@@ -6839,7 +6861,9 @@ class TestMSWindowsTCPFlags(unittest.TestCase):
68396861
'TCP_KEEPCNT',
68406862
# available starting with Windows 10 1709
68416863
'TCP_KEEPIDLE',
6842-
'TCP_KEEPINTVL'
6864+
'TCP_KEEPINTVL',
6865+
# available starting with Windows 7 / Server 2008 R2
6866+
'TCP_QUICKACK',
68436867
}
68446868

68456869
def test_new_tcp_flags(self):
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Add support for ``socket.TCP_QUICKACK`` on Windows platforms.

Modules/socketmodule.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3166,6 +3166,17 @@ sock_setsockopt(PySocketSockObject *s, PyObject *args)
31663166
/* setsockopt(level, opt, flag) */
31673167
if (PyArg_ParseTuple(args, "iii:setsockopt",
31683168
&level, &optname, &flag)) {
3169+
#ifdef MS_WINDOWS
3170+
if (optname == SIO_TCP_SET_ACK_FREQUENCY) {
3171+
int dummy;
3172+
res = WSAIoctl(s->sock_fd, SIO_TCP_SET_ACK_FREQUENCY, &flag,
3173+
sizeof(flag), NULL, 0, &dummy, NULL, NULL);
3174+
if (res >= 0) {
3175+
s->quickack = flag;
3176+
}
3177+
goto done;
3178+
}
3179+
#endif
31693180
res = setsockopt(s->sock_fd, level, optname,
31703181
(char*)&flag, sizeof flag);
31713182
goto done;
@@ -3251,6 +3262,11 @@ sock_getsockopt(PySocketSockObject *s, PyObject *args)
32513262
return s->errorhandler();
32523263
return PyLong_FromUnsignedLong(vflag);
32533264
}
3265+
#endif
3266+
#ifdef MS_WINDOWS
3267+
if (optname == SIO_TCP_SET_ACK_FREQUENCY) {
3268+
return PyLong_FromLong(s->quickack);
3269+
}
32543270
#endif
32553271
flagsize = sizeof flag;
32563272
res = getsockopt(s->sock_fd, level, optname,
@@ -5316,6 +5332,9 @@ sock_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
53165332
((PySocketSockObject *)new)->sock_fd = INVALID_SOCKET;
53175333
((PySocketSockObject *)new)->sock_timeout = _PyTime_FromSeconds(-1);
53185334
((PySocketSockObject *)new)->errorhandler = &set_error;
5335+
#ifdef MS_WINDOWS
5336+
((PySocketSockObject *)new)->quickack = 0;
5337+
#endif
53195338
}
53205339
return new;
53215340
}
@@ -8616,6 +8635,9 @@ socket_exec(PyObject *m)
86168635
#ifdef TCP_CONNECTION_INFO
86178636
ADD_INT_MACRO(m, TCP_CONNECTION_INFO);
86188637
#endif
8638+
#ifdef SIO_TCP_SET_ACK_FREQUENCY
8639+
#define TCP_QUICKACK SIO_TCP_SET_ACK_FREQUENCY
8640+
#endif
86198641
#ifdef TCP_QUICKACK
86208642
ADD_INT_MACRO(m, TCP_QUICKACK);
86218643
#endif

Modules/socketmodule.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,9 @@ typedef struct {
325325
PyTime_t sock_timeout; /* Operation timeout in seconds;
326326
0.0 means non-blocking */
327327
struct _socket_state *state;
328+
#ifdef MS_WINDOWS
329+
int quickack;
330+
#endif
328331
} PySocketSockObject;
329332

330333
/* --- C API ----------------------------------------------------*/

0 commit comments

Comments
 (0)
0