Skip to content

STREAM_DATA_BLOCKED and DATA_BLOCKED sent prematurely? #3645

@larseggert

Description

@larseggert

I may have always misunderstood the RFC, or maybe we have an actual bug?

I see STREAM_DATA_BLOCKED and DATA_BLOCKED frames sent already when the application's write buffer is larger than remaining flow control credit, not when credit is actually exhausted. I think this violates RFC 9000 Section 4.1:

"If a sender has sent data up to the limit, it will be unable to send new data and is considered blocked. A sender SHOULD send a STREAM_DATA_BLOCKED or DATA_BLOCKED frame to indicate to the receiver that it has data to write but is blocked by flow control limits."

The frame should be sent when available() == 0, not when available() < app_write_size?

fn send_blocked_if_space_needed(&mut self, needed_space: usize) {
    if fc.available() <= needed_space {    // stream-level
        fc.blocked();
    }
    if conn_fc.borrow().available() <= needed_space {  // connection-level
        conn_fc.borrow_mut().blocked();
    }
}

When an application writes 100MB to a stream with a 1MB FC limit, blocked() fires immediately (1MB < 100MB) even though the sender has nearly 1MB of credit remaining.

The other call site, send_blocked_if_space_needed(0) after mark_as_sent, is correct — it checks for actual credit exhaustion.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions