[3.6] bpo-32394: Remove some TCP options on older version Windows. (G… · python/cpython@1278c21
@@ -317,6 +317,67 @@ if_indextoname(index) -- return the corresponding interface name\n\
317317#include <VersionHelpers.h>
318318#endif
319319320+/* remove some flags on older version Windows during run-time.
321+ https://msdn.microsoft.com/en-us/library/windows/desktop/ms738596.aspx */
322+typedef struct {
323+DWORD build_number; /* available starting with this Win10 BuildNumber */
324+const char flag_name[20];
325+} FlagRuntimeInfo;
326+327+/* IMPORTANT: make sure the list ordered by descending build_number */
328+static FlagRuntimeInfo win_runtime_flags[] = {
329+/* available starting with Windows 10 1703 */
330+ {15063, "TCP_KEEPCNT"},
331+/* available starting with Windows 10 1607 */
332+ {14393, "TCP_FASTOPEN"}
333+};
334+335+static void
336+remove_unusable_flags(PyObject *m)
337+{
338+PyObject *dict;
339+OSVERSIONINFOEX info;
340+DWORDLONG dwlConditionMask;
341+342+dict = PyModule_GetDict(m);
343+if (dict == NULL) {
344+return;
345+ }
346+347+/* set to Windows 10, except BuildNumber. */
348+memset(&info, 0, sizeof(info));
349+info.dwOSVersionInfoSize = sizeof(info);
350+info.dwMajorVersion = 10;
351+info.dwMinorVersion = 0;
352+353+/* set Condition Mask */
354+dwlConditionMask = 0;
355+VER_SET_CONDITION(dwlConditionMask, VER_MAJORVERSION, VER_GREATER_EQUAL);
356+VER_SET_CONDITION(dwlConditionMask, VER_MINORVERSION, VER_GREATER_EQUAL);
357+VER_SET_CONDITION(dwlConditionMask, VER_BUILDNUMBER, VER_GREATER_EQUAL);
358+359+for (int i=0; i<sizeof(win_runtime_flags)/sizeof(FlagRuntimeInfo); i++) {
360+info.dwBuildNumber = win_runtime_flags[i].build_number;
361+/* greater than or equal to the specified version?
362+ Compatibility Mode will not cheat VerifyVersionInfo(...) */
363+if (VerifyVersionInfo(
364+&info,
365+VER_MAJORVERSION|VER_MINORVERSION|VER_BUILDNUMBER,
366+dwlConditionMask)) {
367+break;
368+ }
369+else {
370+if (PyDict_GetItemString(
371+dict,
372+win_runtime_flags[i].flag_name) != NULL) {
373+PyDict_DelItemString(
374+dict,
375+win_runtime_flags[i].flag_name);
376+ }
377+ }
378+ }
379+}
380+320381#endif
321382322383#include <stddef.h>
@@ -7694,6 +7755,12 @@ PyInit__socket(void)
76947755#if defined(USE_GETHOSTBYNAME_LOCK) || defined(USE_GETADDRINFO_LOCK)
76957756netdb_lock = PyThread_allocate_lock();
76967757#endif
7758+7759+#ifdef MS_WINDOWS
7760+/* removes some flags on older version Windows during run-time */
7761+remove_unusable_flags(m);
7762+#endif
7763+76977764return m;
76987765}
76997766