diff options
author | animalize <animalize@users.noreply.github.com> | 2018-02-26 18:10:36 (GMT) |
---|---|---|
committer | Steve Dower <steve.dower@microsoft.com> | 2018-02-26 18:10:36 (GMT) |
commit | 19e7d48ce89422091f9af93038b9fee075d46e9e (patch) | |
tree | edb6bbcbf2c7658f14be062ea4fe1c17dd44c78e /Modules/socketmodule.c | |
parent | 3f2e6f15d64d81633b1fc0b308afc0d6e9026b61 (diff) | |
download | cpython-19e7d48ce89422091f9af93038b9fee075d46e9e.zip cpython-19e7d48ce89422091f9af93038b9fee075d46e9e.tar.gz cpython-19e7d48ce89422091f9af93038b9fee075d46e9e.tar.bz2 |
bpo-32394: Remove some TCP options on old version Windows. (GH-5523)
Diffstat (limited to 'Modules/socketmodule.c')
-rw-r--r-- | Modules/socketmodule.c | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c index aa715bf..c7a0751 100644 --- a/Modules/socketmodule.c +++ b/Modules/socketmodule.c @@ -305,6 +305,70 @@ http://cvsweb.netbsd.org/bsdweb.cgi/src/lib/libc/net/getaddrinfo.c.diff?r1=1.82& /* Provides the IsWindows7SP1OrGreater() function */ #include <VersionHelpers.h> +/* 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 1709 */ + {16299, "TCP_KEEPIDLE"}, + {16299, "TCP_KEEPINTVL"}, + /* 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> @@ -7890,5 +7954,11 @@ PyInit__socket(void) #if defined(USE_GETHOSTBYNAME_LOCK) || defined(USE_GETADDRINFO_LOCK) netdb_lock = PyThread_allocate_lock(); #endif + +#ifdef MS_WINDOWS + /* remove some flags on older version Windows during run-time */ + remove_unusable_flags(m); +#endif + return m; } |