[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)

76957756

netdb_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+76977764

return m;

76987765

}

76997766