aboutsummaryrefslogtreecommitdiffstats
path: root/net/sctp
diff options
context:
space:
mode:
authorVlad Yasevich <vladislav.yasevich@hp.com>2009-09-04 18:20:59 -0400
committerVlad Yasevich <vladislav.yasevich@hp.com>2009-09-04 18:20:59 -0400
commitd4d6fb5787a6ef6e1dab731d617ebda6be73d561 (patch)
treeafdf56288c5cdbfa40f95ef4a618d37f5b3f5092 /net/sctp
parent4d3c46e6833208428d366630aa708f6876e61fc1 (diff)
sctp: Try not to change a_rwnd when faking a SACK from SHUTDOWN.
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>
Diffstat (limited to 'net/sctp')
-rw-r--r--net/sctp/sm_sideeffect.c7
1 files changed, 4 insertions, 3 deletions
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c
index 694f7491731d..8674d4919556 100644
--- a/net/sctp/sm_sideeffect.c
+++ b/net/sctp/sm_sideeffect.c
@@ -1533,7 +1533,8 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
1533 case SCTP_CMD_PROCESS_CTSN: 1533 case SCTP_CMD_PROCESS_CTSN:
1534 /* Dummy up a SACK for processing. */ 1534 /* Dummy up a SACK for processing. */
1535 sackh.cum_tsn_ack = cmd->obj.be32; 1535 sackh.cum_tsn_ack = cmd->obj.be32;
1536 sackh.a_rwnd = 0; 1536 sackh.a_rwnd = asoc->peer.rwnd +
1537 asoc->outqueue.outstanding_bytes;
1537 sackh.num_gap_ack_blocks = 0; 1538 sackh.num_gap_ack_blocks = 0;
1538 sackh.num_dup_tsns = 0; 1539 sackh.num_dup_tsns = 0;
1539 sctp_add_cmd_sf(commands, SCTP_CMD_PROCESS_SACK, 1540 sctp_add_cmd_sf(commands, SCTP_CMD_PROCESS_SACK,
@@ -1632,9 +1633,9 @@ out:
1632 */ 1633 */
1633 if (asoc && SCTP_EVENT_T_CHUNK == event_type && chunk) { 1634 if (asoc && SCTP_EVENT_T_CHUNK == event_type && chunk) {
1634 if (chunk->end_of_packet || chunk->singleton) 1635 if (chunk->end_of_packet || chunk->singleton)
1635 sctp_outq_uncork(&asoc->outqueue); 1636 error = sctp_outq_uncork(&asoc->outqueue);
1636 } else if (local_cork) 1637 } else if (local_cork)
1637 sctp_outq_uncork(&asoc->outqueue); 1638 error = sctp_outq_uncork(&asoc->outqueue);
1638 return error; 1639 return error;
1639nomem: 1640nomem:
1640 error = -ENOMEM; 1641 error = -ENOMEM;