Skip to content

Wait for the peer to confirm the disconnect request - #987

Open
gijzelaerr wants to merge 1 commit into
masterfrom
fix/disconnect-close-sequence
Open

gijzelaerr wants to merge 1 commit into
masterfrom
fix/disconnect-close-sequence

Conversation

@gijzelaerr

Copy link
Copy Markdown
Owner

Refs #972. The reporter tested #979 and the CP 343-1 still keeps a connection resource after each disconnect().

What the new capture shows. #979 works: the DR now goes to the CP's reference (06 80 4431 0001 …). What's still wrong is the close sequence:

10.110431  client → CP   DR  03 00 00 0c 06 80 4431 0001 00 00
10.110479  client → CP   FIN            (48 µs after the DR)
10.111586  CP → client   RST
10.112294  CP → client   RST
10.608075  CP → client   ACK            (the CP still thinks the connection is alive)
10.608114  client → CP   RST

The CP never gets the chance to send a DC. The first capture (before #979) has the same sequence.

Changes, in both clients:

  • disconnect() waits up to DISCONNECT_CONFIRM_TIMEOUT (1 s, and at most the connection timeout) for a COTP DC, or for the peer to close or reset the connection, before closing the socket. Other frames still in flight are skipped. The emulator server already answers a DR with a DC, so the test suite isn't slower.
  • The DR loses the zero byte it carried after its header. The length indicator is 6 (type, both references, reason), so that byte was DR user data, which class 0 doesn't allow. TPKT length goes from 12 to 11.

Whether either change frees the CP's resource needs the reporter's hardware. Their next capture will show whether the CP now sends a DC.

Tests: socket-pair tests check that no FIN reaches the peer before it sends its DC, that disconnect() returns at once when the peer closes, that a silent peer is bounded by the timeout, and that a late data frame before the DC is skipped. An asyncio-server test does the same for the async client. Full suite: 1657 passed, 62 skipped (Windows, Python 3.13). Pre-commit and mypy are clean.

🤖 Generated with Claude Code

A CP 343-1 kept the connection's resource after disconnect() even with
the DR addressed to its reference (#979): the capture shows our FIN 7 us
after the DR and the CP answering both with a reset, never with a DC.
disconnect() now waits up to one second for a DC, or for the peer to
close or reset the connection, before closing the socket, in both
clients.

The DR also carried a zero byte after its header, outside the length
indicator. Class 0 allows no user data in a DR, so it is dropped.

Refs #972.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@gijzelaerr
gijzelaerr force-pushed the fix/disconnect-close-sequence branch from 488de24 to db0747e Compare November 11, 2026 13:41

This branch has not been deployed

No deployments
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.

1 participant