MagicStack / MagicStack/uvloop

start_tls: AssertionError if writing is paused

Open
#564 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Cython
Stars
11.9k
Forks
616
PR merge metrics
No merged PRs in 30d

Description

First found in the CPython port of sslproto (see https://github.com/python/cpython/issues/109051 but disregard the title, it's not platform-specific), and it can be reproduced in uvloop.

Traceback

protocol.resume_writing() failed
protocol: <uvloop.loop.SSLProtocol object at 0x1033910c0>
transport: <TCPTransport closed=False reading=True 0x1098351c0>
Traceback (most recent call last):
  File "uvloop/handles/basetransport.pyx", line 96, in uvloop.loop.UVBaseTransport._maybe_resume_protocol
    run_in_context(
  File "uvloop/loop.pyx", line 101, in uvloop.loop.run_in_context
    return context.run(method)
  File "uvloop/sslproto.pyx", line 922, in uvloop.loop.SSLProtocol.resume_writing
    assert self._ssl_writing_paused
AssertionError

Simplest way to reproduce is to increase payload size in test_start_tls_server_1. Send will block and transport will request to pause writing. After start_tls(), the transport will attempt to resume the now-switched protocol, which was not aware it was ever supposed to be paused.

I commented further in the original bug with some notes. The CPython implementation is a bit different (it has a redundant buffering mechanism with a deque which I believe is unnecessary) but the fundamental issue is the same.

Question: what is the motivation for the extra flow control layer in SSLProtocol? It seems it was introduced in uvloop first. I suggested it can be removed and let the original protocol and original transport deal with flow control (which would also fix the bug). But it wouldn't be a good idea to remove it if it's solving a known problem.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with tests/test_tcp.py, especially test_start_tls_server_1, and reproduce the large-payload case described in the issue. Then inspect uvloop/sslproto.pyx around SSLProtocol.resume_writing and start_tls to understand the flow-control transition. Done should include a confirmed fix for the assertion and a regression test covering a paused write during TLS startup.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
networking
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.