GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — Refactor SSL shutdown process by fantix · Pull Request #385 · MagicStack/uvloop

Conversation

@fantix

@fantix fantix commented Jan 30, 2021 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Member

Changes made to the SSL protocol implementation:

EOF

If the peer shuts down its writing end of the TCP connection (transport.write_eof() or socket.shutdown(SHUT_WR)) without sending a graceful SSL CLOSE NOTIFY (ssl_sock.unwrap()), we will now close the connection immediately, discard any data in the send buffer.

  • Application's eof_received() will be called in asyncio, but uvloop won't do so after this PR.
  • Application's connection_lost() will be called with parameter None in asyncio. Q: should we use put a ConnectionResetError instead?

Refs RFC 8446, Section 6.1:

Either party MAY initiate a close of its write side of the connection by sending a "close_notify" alert. Any data received after a closure alert has been received MUST be ignored. If a transport-level close is received prior to a "close_notify", the receiver cannot know that all the data that was sent has been received.

Note: It is assumed that closing the write side of a connection reliably delivers pending data before destroying the transport.

In asyncio, eof_received() should be treated as a sign of "the peer's pending data is reliably delivered". But in case we received an EOF on the TCP connection, we don't know if the peer has flushed all the pending data or not, so we shouldn't call eof_received() on the SSL level. On the other hand, as many software is sending TCP EOF before CLOSE_NOTIFY, we don't want to be too picky to fail connection_lost() with an exception. So I think the proposed behavior is appropriate.

Clean Shutdown

The shutdown process is now refactored to be more strict to follow the API.

After transport.close() is called:

  • The only protocol callback that will be triggered is connection_lost().
  • None of data_received(), get_buffer(), buffer_updated(), pause_writing(), resume_writing() will ever be called again. This means application data received after transport.close() will be discarded silently.
  • Calling pause_reading() or resume_reading() has no effect - the shutdown process will procceed unaffected.
  • In the future, we could add a feature by implementing write_eof() in addition to transport.close() to receive trailing data during the shutdown process.

Other Fixes

  • Use _call_soon_handle() internally when possible.
  • Typo fix: clear _handshake_timeout_handle correctly.
  • Refactored internal methods to be more atomic and easy to reason about.
  • Bugfix: not all buffered data is flushed in the shutdown process if the peer's TCP receiving buffer is full.
  • Bugfix: the connection is closed too early before the CLOSE NOTIFY is sent when the peer's TCP receiving buffer is full.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@fantix
fantix force-pushed the ssl-shutdown-while-pause-reading branch from 692dd88 to 3fab31c Compare February 1, 2021 01:05
@fantix
Refactor SSL shutdown process
59a69e6
@fantix
fantix force-pushed the ssl-shutdown-while-pause-reading branch from 3fab31c to 59a69e6 Compare February 1, 2021 04:49
@fantix
fantix marked this pull request as ready for review February 1, 2021 05:51
@fantix
fantix requested a review from 1st1 February 1, 2021 05:51
1st1
1st1 reviewed Feb 3, 2021
View reviewed changes
Comment thread tests/test_tcp.py Resolved

Uh oh!

There was an error while loading. Please reload this page.

1st1
1st1 reviewed Feb 3, 2021
View reviewed changes
Comment thread uvloop/sslproto.pyx Resolved

Uh oh!

There was an error while loading. Please reload this page.

1st1
1st1 approved these changes Feb 3, 2021
View reviewed changes

@1st1 1st1 left a comment

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

Looks reasonable to me. I don't know the code intimately well anymore, so I trust you with this change! Great work.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@fantix

fantix commented Feb 3, 2021

Copy link
Copy Markdown
Member Author

Thanks! I'll create a bpo!

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@fantix Yury Selivanov
grammar fix
76436b0
Co-authored-by: Yury Selivanov <[email protected]>
@fantix fantix mentioned this pull request Feb 5, 2021
bpo-44011: New asyncio ssl implementation python/cpython#17975
Merged
@fantix

fantix commented Feb 5, 2021

Copy link
Copy Markdown
Member Author

OK this PR does fix bpo-39951, I'm merging it now.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@fantix
fantix merged commit 98e113e into MagicStack:master Feb 5, 2021
@fantix
fantix deleted the ssl-shutdown-while-pause-reading branch February 5, 2021 15:27
@fantix fantix mentioned this pull request Feb 5, 2021
Add tests for bpo-39951 #386
Merged
@fantix fantix mentioned this pull request Oct 1, 2022
_SSLProtocolTransport.close() cannot close the connection until timeout or EOF #471
Open
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@1st1 1st1 1st1 approved these changes

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Uh oh!

There was an error while loading. Please reload this page.

2 participants

@fantix @1st1
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.