diff options
author | animalize <animalize@users.noreply.github.com> | 2018-02-26 18:13:51 (GMT) |
---|---|---|
committer | Steve Dower <steve.dower@microsoft.com> | 2018-02-26 18:13:51 (GMT) |
commit | 1278c21f5234477aab21531773d65ca7ebd1b81f (patch) | |
tree | f7a01b88c0d4a332ff95b8de42be55137695c336 | |
parent | fbf7aac36bd1017bc87964b5d17dce0e101ff2d6 (diff) | |
download | cpython-1278c21f5234477aab21531773d65ca7ebd1b81f.zip cpython-1278c21f5234477aab21531773d65ca7ebd1b81f.tar.gz cpython-1278c21f5234477aab21531773d65ca7ebd1b81f.tar.bz2 |
[3.6] bpo-32394: Remove some TCP options on older version Windows. (GH-5585)
-rw-r--r-- | Doc/library/socket.rst | 4 | ||||
-rw-r--r-- | Lib/test/test_socket.py | 19 | ||||
-rw-r--r-- | Misc/NEWS.d/next/Library/2018-02-08-08-18-26.bpo-32394.6E_7X7.rst | 2 | ||||
-rw-r--r-- | Modules/socketmodule.c | 67 |
4 files changed, 92 insertions, 0 deletions
diff --git a/Doc/library/socket.rst b/Doc/library/socket.rst index 678e32c..512c38e 100644 --- a/Doc/library/socket.rst +++ b/Doc/library/socket.rst @@ -303,6 +303,10 @@ Constants ``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. + .. data:: AF_CAN PF_CAN SOL_CAN_* diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py index 0023762..faa4868 100644 --- a/Lib/test/test_socket.py +++ b/Lib/test/test_socket.py @@ -5583,6 +5583,24 @@ class LinuxKernelCryptoAPI(unittest.TestCase): with self.assertRaises(TypeError): sock.sendmsg_afalg(op=socket.ALG_OP_ENCRYPT, assoclen=-1) +@unittest.skipUnless(sys.platform.startswith("win"), "requires Windows") +class TestMSWindowsTCPFlags(unittest.TestCase): + knownTCPFlags = { + # avaliable since long time ago + 'TCP_MAXSEG', + 'TCP_NODELAY', + # available starting with Windows 10 1607 + 'TCP_FASTOPEN', + # available starting with Windows 10 1703 + 'TCP_KEEPCNT', + } + + def test_new_tcp_flags(self): + provided = [s for s in dir(socket) if s.startswith('TCP')] + unknown = [s for s in provided if s not in self.knownTCPFlags] + + self.assertEqual([], unknown, + "New TCP flags were discovered. See bpo-32394 for more information") def test_main(): tests = [GeneralModuleTests, BasicTCPTest, TCPCloserTest, TCPTimeoutTest, @@ -5639,6 +5657,7 @@ def test_main(): SendfileUsingSendTest, SendfileUsingSendfileTest, ]) + tests.append(TestMSWindowsTCPFlags) thread_info = support.threading_setup() support.run_unittest(*tests) diff --git a/Misc/NEWS.d/next/Library/2018-02-08-08-18-26.bpo-32394.6E_7X7.rst b/Misc/NEWS.d/next/Library/2018-02-08-08-18-26.bpo-32394.6E_7X7.rst new file mode 100644 index 0000000..f7fb42d --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-02-08-08-18-26.bpo-32394.6E_7X7.rst @@ -0,0 +1,2 @@ +socket: Remove TCP_FASTOPEN, TCP_KEEPCNT flags on older version Windows +during run-time. diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c index 8d9915a..b455021 100644 --- a/Modules/socketmodule.c +++ b/Modules/socketmodule.c @@ -317,6 +317,67 @@ http://cvsweb.netbsd.org/bsdweb.cgi/src/lib/libc/net/getaddrinfo.c.diff?r1=1.82& #include <VersionHelpers.h> #endif +/* remove some flags on older version Windows during run-time. + https://msdn.microsoft.com/en-us/library/windows/desktop/ms738596.aspx */ +typedef struct { + DWORD build_number; /* available starting with this Win10 BuildNumber */ + const char flag_name[20]; +} FlagRuntimeInfo; + +/* IMPORTANT: make sure the list ordered by descending build_number */ +static FlagRuntimeInfo win_runtime_flags[] = { + /* available starting with Windows 10 1703 */ + {15063, "TCP_KEEPCNT"}, + /* available starting with Windows 10 1607 */ + {14393, "TCP_FASTOPEN"} +}; + +static void +remove_unusable_flags(PyObject *m) +{ + PyObject *dict; + OSVERSIONINFOEX info; + DWORDLONG dwlConditionMask; + + dict = PyModule_GetDict(m); + if (dict == NULL) { + return; + } + + /* set to Windows 10, except BuildNumber. */ + memset(&info, 0, sizeof(info)); + info.dwOSVersionInfoSize = sizeof(info); + info.dwMajorVersion = 10; + info.dwMinorVersion = 0; + + /* set Condition Mask */ + dwlConditionMask = 0; + VER_SET_CONDITION(dwlConditionMask, VER_MAJORVERSION, VER_GREATER_EQUAL); + VER_SET_CONDITION(dwlConditionMask, VER_MINORVERSION, VER_GREATER_EQUAL); + VER_SET_CONDITION(dwlConditionMask, VER_BUILDNUMBER, VER_GREATER_EQUAL); + + for (int i=0; i<sizeof(win_runtime_flags)/sizeof(FlagRuntimeInfo); i++) { + info.dwBuildNumber = win_runtime_flags[i].build_number; + /* greater than or equal to the specified version? + Compatibility Mode will not cheat VerifyVersionInfo(...) */ + if (VerifyVersionInfo( + &info, + VER_MAJORVERSION|VER_MINORVERSION|VER_BUILDNUMBER, + dwlConditionMask)) { + break; + } + else { + if (PyDict_GetItemString( + dict, + win_runtime_flags[i].flag_name) != NULL) { + PyDict_DelItemString( + dict, + win_runtime_flags[i].flag_name); + } + } + } +} + #endif #include <stddef.h> @@ -7694,6 +7755,12 @@ PyInit__socket(void) #if defined(USE_GETHOSTBYNAME_LOCK) || defined(USE_GETADDRINFO_LOCK) netdb_lock = PyThread_allocate_lock(); #endif + +#ifdef MS_WINDOWS + /* removes some flags on older version Windows during run-time */ + remove_unusable_flags(m); +#endif + return m; } |