sctp: Try not to change a_rwnd when faking a SACK from SHUTDOWN.
authorVlad Yasevich <vladislav.yasevich@hp.com>
Fri, 4 Sep 2009 22:20:59 +0000 (18:20 -0400)
committerVlad Yasevich <vladislav.yasevich@hp.com>
Fri, 4 Sep 2009 22:20:59 +0000 (18:20 -0400)
We currently set a_rwnd to 0 when faking a SACK from SHUTDOWN.
This results in an hung association if the remote only uses
SHUTDOWNs (which it's allowed to do) to acknowlege DATA when
closing.  The reason for that is that we simply honor the a_rwnd
from the sack, but since we faked it to be 0, we enter 0-window
probing.  The fix is to use the peers old rwnd and add our flight
size to it.

Signed-off-by: Vlad Yasevich <vladislav.yasevich@hp.com>
net/sctp/sm_sideeffect.c

index 694f7491731dba82cc2c5365adf62f60398f811c..8674d49195561fc7ed33a5b086eb4014d80f46a7 100644 (file)
@@ -1533,7 +1533,8 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
                case SCTP_CMD_PROCESS_CTSN:
                        /* Dummy up a SACK for processing. */
                        sackh.cum_tsn_ack = cmd->obj.be32;
-                       sackh.a_rwnd = 0;
+                       sackh.a_rwnd = asoc->peer.rwnd +
+                                       asoc->outqueue.outstanding_bytes;
                        sackh.num_gap_ack_blocks = 0;
                        sackh.num_dup_tsns = 0;
                        sctp_add_cmd_sf(commands, SCTP_CMD_PROCESS_SACK,
@@ -1632,9 +1633,9 @@ out:
         */
        if (asoc && SCTP_EVENT_T_CHUNK == event_type && chunk) {
                if (chunk->end_of_packet || chunk->singleton)
-                       sctp_outq_uncork(&asoc->outqueue);
+                       error = sctp_outq_uncork(&asoc->outqueue);
        } else if (local_cork)
-                       sctp_outq_uncork(&asoc->outqueue);
+               error = sctp_outq_uncork(&asoc->outqueue);
        return error;
 nomem:
        error = -ENOMEM;