Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bpo-32394: Remove some TCP options on old version Windows. #5523

Merged
merged 20 commits into from Feb 26, 2018
Merged

bpo-32394: Remove some TCP options on old version Windows. #5523

merged 20 commits into from Feb 26, 2018

Conversation

ghost
Copy link

@ghost ghost commented Feb 4, 2018

@skn78
Copy link

skn78 commented Feb 4, 2018

Microsoft site says "GetVersionEx may be altered or unavailable for releases after Windows 8.1. Instead, use the Version Helper functions"
VersionHelpers.h has "IsWindows10CreatorsOrGreater()" function for checking Windows 10 Build 15063+ and has "IsWindows10AnniversaryOrGreater()" function for checking Windows 10 Build 14393+.
It are official functions.

zware
zware previously requested changes Feb 4, 2018
Copy link
Member

@zware zware left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed with @skn78, this should use functions from VersionHelpers.h, not the deprecated GetVersionEx.

@bedevere-bot
Copy link

A Python core developer has requested some changes be made to your pull request before we can consider merging it. If you could please address their requests along with any other requests in other reviews from core developers that would be appreciated.

Once you have made the requested changes, please leave a comment on this pull request containing the phrase I have made the requested changes; please review again. I will then notify any core developers who have left a review that you're ready for them to take another look at this pull request.

@ghost
Copy link
Author

ghost commented Feb 5, 2018

Earlier versions of Windows 10 SDK don't have IsWindows10CreatorsOrGreater() function, people will get a build failure with those Win 10 SDK.
I'm thinking a workaround, any ideas?

@ghost
Copy link
Author

ghost commented Feb 6, 2018

Offical VersionHelpers.h doesn't have IsWindows10CreatorsOrGreater() and IsWindows10AnniversaryOrGreater() functions.

The two functions are available in a third part VersionHelpers.h, which using a DDK interface RtlGetVersion(...) to get version infomation.

Now I'm inclined to patch in socket.py again, although sys.getwindowsversion() is also using GetVersionEx(...) in underlying level. At least, it keeps socketmodule.c neat.
A code block like this solves the problem:

if hasattr(sys, 'getwindowsversion'):
    # (new_option, available_build)
    # make sure the list ordered by available_build descendent
    _new_flags = [
        ('TCP_KEEPIDLE',  16299),  # Windows 10 1709
        ('TCP_KEEPINTVL', 16299),
        ('TCP_KEEPCNT',   15063),  # Windows 10 1703
        ('TCP_FASTOPEN',  14393)   # Windows 10 1607
        ]
    _WIN_MAJOR, _WIN_MINOR, _WIN_BUILD, *_ = sys.getwindowsversion()
    
    if _WIN_MAJOR == 10 and _WIN_MINOR == 0:
        for _flag, _build in _new_flags:
            if _WIN_BUILD < _build:
                if hasattr(_socket, _flag):
                    delattr(_socket, _flag)
            else:
                break
    elif _WIN_MAJOR < 10:
        for _flag, _ in _new_flags:
            if hasattr(_socket, _flag):
                delattr(_socket, _flag)

@ghost
Copy link
Author

ghost commented Feb 11, 2018

This PR is prepared for review.

Official VersionHelpers.h uses VerifyVersionInfo(...) function in the inner side.
I'm also using VerifyVersionInfo(...), but made it aware of BuildNumber.

This PR is conflicts with 3.6 branch code.
PR 5585 is prepared for 3.6 branch, besides code conflict, the only difference is that PR 5585 can't recognize the two flags (TCP_KEEPIDLE,TCP_KEEPINTVL) added in 1709 SDK.

@zware zware dismissed their stale review February 12, 2018 17:10

Comment addressed; not qualified for full review.

@ghost
Copy link
Author

ghost commented Feb 13, 2018

@zware
Forgive me for my verdant of GitHub.
This morning I pushed a minor commit, after that, I found there was a message:

zware dismissed their stale review 9 hours ago
Comment addressed; not qualified for full review.

But I can't found any comment, this make me feel very embarrassed.
So if you had addressed a comment, could you please post it again?

@zware
Copy link
Member

zware commented Feb 13, 2018

Look just above the message from @bedevere-bot for my old review comment, which was just formalization of the comment left by @skn78 and which you have addressed already.

I'm afraid that's about the extent of my ability to review this one, though.

@ghost
Copy link
Author

ghost commented Feb 14, 2018

ok

Copy link
Member

@zooba zooba left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's nothing really wrong here, just a few suggestions and some code-quality items that we really can't let through (I don't think we have linting for them, and we probably can't add it easily at this stage, but newer projects would simply forbid mis-named methods).

'TCP_KEEPINTVL'
}

def testNewTCPFlags(self):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use words_with_underscores style for new test names.

"see issue32394.\n"
"Full avaliable TCP flags on this system: %s"
) % (unknown, provided)
raise Exception(msg)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be as simple as:

self.assertEqual([], unknown, "New TCP flags were discovered. See bpo-32394 for more information")

info.dwBuildNumber = flags[i].build_number;
/* greater than or equal to the specified version?
Compatibility Mode will not cheat VerifyVersionInfo(...) */
if (VerifyVersionInfo(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The IsWindowsVersionOrGreater function should always be available, which will simplify this call.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IsWindowsVersionOrGreater is only aware of MajorVersion, MinorVersion, ServicePackMajor. While we need to compare BuildNumber.

IsWindowsVersionOrGreater uses VerifyVersionInfo in the inner side, I'm also using this function, but made it aware of MajorVersion, MinorVersion, BuildNumber, these three fields fit in with our task.

Copy link
Author

@ghost ghost Feb 20, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To make sure it works, I have tested here in several ways:

  1. change build_number in the array.
  2. change info.dwMajorVersion and info.dwMinorVersion.
  3. operate setsockopt(), getsockopt() under Compatibility Mode.
  4. upset the order of macro VER_SET_CONDITION().

@@ -305,6 +305,69 @@ if_indextoname(index) -- return the corresponding interface name\n\
/* Provides the IsWindows7SP1OrGreater() function */
#include <VersionHelpers.h>

/* This block removes some flags on older version Windows during run-time.
https://msdn.microsoft.com/en-us/library/windows/desktop/ms738596.aspx */
#if 1
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need for the #if 1 (I assume this is already within an MS_WINDOWS block)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought some IDEs can fold this code block, I removed it.

} FlagRuntimeInfo;

/* IMPORTANT: make sure the list ordered by descending build_number */
static FlagRuntimeInfo flags[] = {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a big module - using a name more like tcp_flag_windows_version will avoid conflicts with other parts.

@@ -7883,5 +7946,10 @@ PyInit__socket(void)
#if defined(USE_GETHOSTBYNAME_LOCK) || defined(USE_GETADDRINFO_LOCK)
netdb_lock = PyThread_allocate_lock();
#endif

#ifdef MS_WINDOWS
return remove_unusable_flags(m);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make this remove_unusable_flags(m) and then leave the return outside the if block (it's easier to reason about an optional action than a potential transformation, and the same object is always returned)

@ghost
Copy link
Author

ghost commented Feb 20, 2018

I have modified, sorry for my unskillful patch.

@miss-islington
Copy link
Contributor

Thanks @animalize for the PR, and @zooba for merging it 🌮🎉.. I'm working now to backport this PR to: 3.6, 3.7.
🐍🍒⛏🤖

@bedevere-bot
Copy link

GH-5910 is a backport of this pull request to the 3.7 branch.

miss-islington pushed a commit to miss-islington/cpython that referenced this pull request Feb 26, 2018
…5523)

(cherry picked from commit 19e7d48)

Co-authored-by: animalize <animalize@users.noreply.github.com>
@miss-islington
Copy link
Contributor

Sorry, @animalize and @zooba, I could not cleanly backport this to 3.6 due to a conflict.
Please backport using cherry_picker on command line.
cherry_picker 19e7d48ce89422091f9af93038b9fee075d46e9e 3.6

@bedevere-bot
Copy link

GH-5585 is a backport of this pull request to the 3.6 branch.

@zooba
Copy link
Member

zooba commented Feb 26, 2018

Thanks @animalize!

miss-islington added a commit that referenced this pull request Feb 26, 2018
(cherry picked from commit 19e7d48)

Co-authored-by: animalize <animalize@users.noreply.github.com>
@ghost ghost deleted the issue32394 branch February 27, 2018 09:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants