Skip to content

fix: make SCTPWrite non-blocking to avoid stalling on a full send queue - #90

Open
gomaja wants to merge 1 commit into
ishidawataru:masterfrom
gomaja:sctp-write-dontwait
Open

fix: make SCTPWrite non-blocking to avoid stalling on a full send queue#90
gomaja wants to merge 1 commit into
ishidawataru:masterfrom
gomaja:sctp-write-dontwait

Conversation

@gomaja

@gomaja gomaja commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Split out of #87, where it was buried in an unrelated close-logic change. It alters SCTPWrite's contract for every caller, so it is better reviewed on its own.

SCTPWrite called sendmsg with no flags, so it blocked whenever the send queue was full. A peer that stops reading, or goes away without tearing the association down, parked the writing goroutine indefinitely and left the connection in CLOSE_WAIT with no way for the caller to recover. Passing MSG_DONTWAIT returns EAGAIN instead, so the caller decides what to do.

Compatibility

This is a behaviour change worth stating plainly: callers that relied on the write blocking until there was room must now handle EAGAIN and retry. A plain write loop that ignores the error will drop messages.

EAGAIN is also not limited to a peer that has stopped reading — a writer that outruns an actively reading peer sees it too. The tests measure this rather than assert it away:

  • with a peer that has stopped reading, the writer reports EAGAIN instead of hanging
  • against an actively reading peer, roughly one write in twenty returns EAGAIN once the writer gets ahead
  • a retry loop delivers all 200 messages

The middle case is the one existing callers will notice, so it is a test rather than a comment.

SCTPWrite called sendmsg with no flags, so it blocked whenever the send
queue was full. A peer that stops reading, or goes away without tearing
the association down, therefore parked the writing goroutine
indefinitely and left the connection in CLOSE_WAIT with no way for the
caller to recover. Pass MSG_DONTWAIT so the caller gets EAGAIN and can
decide what to do.

This changes SCTPWrite's contract, so it is worth stating plainly.
Callers that previously relied on the write blocking until there was
room must now handle EAGAIN and retry; a plain write loop that ignores
the error will drop messages. The tests measure this rather than assert
it away: with a peer that has stopped reading the writer reports EAGAIN
instead of hanging, and even against an actively reading peer roughly
one write in twenty returns EAGAIN once the writer outruns the reader.
A retry loop delivers all of them.
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