bpo-32394: Remove some TCP options on old version Windows. (GH-5523) · python/cpython@53d3f8a

@@ -305,6 +305,70 @@ if_indextoname(index) -- return the corresponding interface name\n\

305305

/* Provides the IsWindows7SP1OrGreater() function */

306306

#include <VersionHelpers.h>

307307308+

/* remove some flags on older version Windows during run-time.

309+

https://msdn.microsoft.com/en-us/library/windows/desktop/ms738596.aspx */

310+

typedef struct {

311+

DWORD build_number; /* available starting with this Win10 BuildNumber */

312+

const char flag_name[20];

313+

} FlagRuntimeInfo;

314+315+

/* IMPORTANT: make sure the list ordered by descending build_number */

316+

static FlagRuntimeInfo win_runtime_flags[] = {

317+

/* available starting with Windows 10 1709 */

318+

{16299, "TCP_KEEPIDLE"},

319+

{16299, "TCP_KEEPINTVL"},

320+

/* available starting with Windows 10 1703 */

321+

{15063, "TCP_KEEPCNT"},

322+

/* available starting with Windows 10 1607 */

323+

{14393, "TCP_FASTOPEN"}

324+

};

325+326+

static void

327+

remove_unusable_flags(PyObject *m)

328+

{

329+

PyObject *dict;

330+

OSVERSIONINFOEX info;

331+

DWORDLONG dwlConditionMask;

332+333+

dict = PyModule_GetDict(m);

334+

if (dict == NULL) {

335+

return;

336+

}

337+338+

/* set to Windows 10, except BuildNumber. */

339+

memset(&info, 0, sizeof(info));

340+

info.dwOSVersionInfoSize = sizeof(info);

341+

info.dwMajorVersion = 10;

342+

info.dwMinorVersion = 0;

343+344+

/* set Condition Mask */

345+

dwlConditionMask = 0;

346+

VER_SET_CONDITION(dwlConditionMask, VER_MAJORVERSION, VER_GREATER_EQUAL);

347+

VER_SET_CONDITION(dwlConditionMask, VER_MINORVERSION, VER_GREATER_EQUAL);

348+

VER_SET_CONDITION(dwlConditionMask, VER_BUILDNUMBER, VER_GREATER_EQUAL);

349+350+

for (int i=0; i<sizeof(win_runtime_flags)/sizeof(FlagRuntimeInfo); i++) {

351+

info.dwBuildNumber = win_runtime_flags[i].build_number;

352+

/* greater than or equal to the specified version?

353+

Compatibility Mode will not cheat VerifyVersionInfo(...) */

354+

if (VerifyVersionInfo(

355+

&info,

356+

VER_MAJORVERSION|VER_MINORVERSION|VER_BUILDNUMBER,

357+

dwlConditionMask)) {

358+

break;

359+

}

360+

else {

361+

if (PyDict_GetItemString(

362+

dict,

363+

win_runtime_flags[i].flag_name) != NULL) {

364+

PyDict_DelItemString(

365+

dict,

366+

win_runtime_flags[i].flag_name);

367+

}

368+

}

369+

}

370+

}

371+308372

#endif

309373310374

#include <stddef.h>

@@ -7890,5 +7954,11 @@ PyInit__socket(void)

78907954

#if defined(USE_GETHOSTBYNAME_LOCK) || defined(USE_GETADDRINFO_LOCK)

78917955

netdb_lock = PyThread_allocate_lock();

78927956

#endif

7957+7958+

#ifdef MS_WINDOWS

7959+

/* remove some flags on older version Windows during run-time */

7960+

remove_unusable_flags(m);

7961+

#endif

7962+78937963

return m;

78947964

}