Bad client may send arbitrary (very large, limited only by connection bandwidth) number of channel request messages regardless of server allowed with requestN, which then are blindly accepted by spring-rsocket and delivered to end user's handler.

Usually user's handler is not prepared to receive more messages than requested, and likely either queues messages in memory, or overwhelms its downstream resources.

Trivial reproducer is at channel-overflow using springboot 2.5.4

./server.sh, ./channel_overflow.sh

Particularly, server reports

2021-09-23 22:20:15.039  INFO 5047 --- [     parallel-2] example.service.Service                  : payload requested: 5, received: 49929
2021-09-23 22:20:16.039  INFO 5047 --- [     parallel-2] example.service.Service                  : payload requested: 5, received: 50076
2021-09-23 22:20:17.039  INFO 5047 --- [     parallel-2] example.service.Service                  : payload requested: 5, received: 50042
2021-09-23 22:20:18.039  INFO 5047 --- [     parallel-2] example.service.Service                  : payload requested: 5, received: 49988
2021-09-23 22:20:19.039  INFO 5047 --- [     parallel-2] example.service.Service                  : payload requested: 5, received: 50023
2021-09-23 22:20:20.039  INFO 5047 --- [     parallel-2] example.service.Service                  : payload requested: 5, received: 49975

Comment From: OlegDokuka

as the spec suggests:

Lack of REQUEST_N frames that stops a stream is an application concern and SHALL NOT be handled by the protocol

The mentioned scenario is an application concern and should be handled by the application https://github.com/rsocket/rsocket/blob/master/Protocol.md#handling-the-unexpected

Comment From: bclozel

Thanks @OlegDokuka , I'll close this issue as invalid since this is covered by the spec already.

Comment From: mostroverkhov

as the spec suggests:

Lack of REQUEST_N frames that stops a stream is an application concern and SHALL NOT be handled by the protocol

The mentioned scenario is an application concern and should be handled by the application https://github.com/rsocket/rsocket/blob/master/Protocol.md#handling-the-unexpected

This is completely not related to the issue reported here - not sure why It was linked:

the reproducer clearly shows there is periodic requestN=5 sent by receiver every second, so stream is not stopped / stalled: payload requested: 5.

The problem reported here is responder does not respect requested demand - and responder is free to send messages at arbitrarily high rate: payload requested: 5, received: 49929 because is allowed to do so by rsocket/rsocket-java.

This is obvious omission - backpressure/flow control has to be enforced on receiver side if this library is intended for servers accessed by non-trusted clients (internet clients, cloud application 3rd party clients) - same way how http2 flow control is enforced on receiver side: if peer receives more bytes than requested by stream, connection is closed.

@bclozel I suggest Spring team to have another look at this and reopen the issue:

The mentioned scenario is an application concern and should be handled by the application

It basically requires from spring / rsocket-java library users to have this for each channel request (pseudocode):

.doOnSignal(signal -> {
     if(signal is requestN) {
        totalRequestN+=requestN.value
     } else if (signal is next) {
        totalRequestN--
        if(totalRequestN<0) {
           rsocket.close("stream flow control violation")
        }
     }
})

When moving over untrusted boundary, protocol rules validation is responsibility of library implementation - not of the application code.

Comment From: rstoyanchev

There is now a separate issue to track this https://github.com/rsocket/rsocket-java/issues/1064.