lkml.org 
[lkml]   [2020]   [Jul]   [30]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.4 14/19] sctp: shrink stream outq when fails to do addstream reconf
    Date
    From: Xin Long <lucien.xin@gmail.com>

    [ Upstream commit 3ecdda3e9ad837cf9cb41b6faa11b1af3a5abc0c ]

    When adding a stream with stream reconf, the new stream firstly is in
    CLOSED state but new out chunks can still be enqueued. Then once gets
    the confirmation from the peer, the state will change to OPEN.

    However, if the peer denies, it needs to roll back the stream. But when
    doing that, it only sets the stream outcnt back, and the chunks already
    in the new stream don't get purged. It caused these chunks can still be
    dequeued in sctp_outq_dequeue_data().

    As its stream is still in CLOSE, the chunk will be enqueued to the head
    again by sctp_outq_head_data(). This chunk will never be sent out, and
    the chunks after it can never be dequeued. The assoc will be 'hung' in
    a dead loop of sending this chunk.

    To fix it, this patch is to purge these chunks already in the new
    stream by calling sctp_stream_shrink_out() when failing to do the
    addstream reconf.

    Fixes: 11ae76e67a17 ("sctp: implement receiver-side procedures for the Reconf Response Parameter")
    Reported-by: Ying Xu <yinxu@redhat.com>
    Signed-off-by: Xin Long <lucien.xin@gmail.com>
    Signed-off-by: David S. Miller <davem@davemloft.net>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    net/sctp/stream.c | 6 ++++--
    1 file changed, 4 insertions(+), 2 deletions(-)

    --- a/net/sctp/stream.c
    +++ b/net/sctp/stream.c
    @@ -1045,11 +1045,13 @@ struct sctp_chunk *sctp_process_strreset
    nums = ntohs(addstrm->number_of_streams);
    number = stream->outcnt - nums;

    - if (result == SCTP_STRRESET_PERFORMED)
    + if (result == SCTP_STRRESET_PERFORMED) {
    for (i = number; i < stream->outcnt; i++)
    SCTP_SO(stream, i)->state = SCTP_STREAM_OPEN;
    - else
    + } else {
    + sctp_stream_shrink_out(stream, number);
    stream->outcnt = number;
    + }

    *evp = sctp_ulpevent_make_stream_change_event(asoc, flags,
    0, nums, GFP_ATOMIC);

    \
     
     \ /
      Last update: 2020-07-30 10:21    [W:4.198 / U:0.144 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site