diff options
Diffstat (limited to 'net/sctp/sm_sideeffect.c')
-rw-r--r-- | net/sctp/sm_sideeffect.c | 22 |
1 files changed, 19 insertions, 3 deletions
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c index 534c2e5feb05..167c880cf8da 100644 --- a/net/sctp/sm_sideeffect.c +++ b/net/sctp/sm_sideeffect.c | |||
@@ -670,10 +670,19 @@ static void sctp_cmd_transport_on(sctp_cmd_seq_t *cmds, | |||
670 | /* 8.3 Upon the receipt of the HEARTBEAT ACK, the sender of the | 670 | /* 8.3 Upon the receipt of the HEARTBEAT ACK, the sender of the |
671 | * HEARTBEAT should clear the error counter of the destination | 671 | * HEARTBEAT should clear the error counter of the destination |
672 | * transport address to which the HEARTBEAT was sent. | 672 | * transport address to which the HEARTBEAT was sent. |
673 | * The association's overall error count is also cleared. | ||
674 | */ | 673 | */ |
675 | t->error_count = 0; | 674 | t->error_count = 0; |
676 | t->asoc->overall_error_count = 0; | 675 | |
676 | /* | ||
677 | * Although RFC4960 specifies that the overall error count must | ||
678 | * be cleared when a HEARTBEAT ACK is received, we make an | ||
679 | * exception while in SHUTDOWN PENDING. If the peer keeps its | ||
680 | * window shut forever, we may never be able to transmit our | ||
681 | * outstanding data and rely on the retransmission limit be reached | ||
682 | * to shutdown the association. | ||
683 | */ | ||
684 | if (t->asoc->state != SCTP_STATE_SHUTDOWN_PENDING) | ||
685 | t->asoc->overall_error_count = 0; | ||
677 | 686 | ||
678 | /* Clear the hb_sent flag to signal that we had a good | 687 | /* Clear the hb_sent flag to signal that we had a good |
679 | * acknowledgement. | 688 | * acknowledgement. |
@@ -1201,7 +1210,7 @@ static int sctp_cmd_interpreter(sctp_event_t event_type, | |||
1201 | int local_cork = 0; | 1210 | int local_cork = 0; |
1202 | 1211 | ||
1203 | if (SCTP_EVENT_T_TIMEOUT != event_type) | 1212 | if (SCTP_EVENT_T_TIMEOUT != event_type) |
1204 | chunk = (struct sctp_chunk *) event_arg; | 1213 | chunk = event_arg; |
1205 | 1214 | ||
1206 | /* Note: This whole file is a huge candidate for rework. | 1215 | /* Note: This whole file is a huge candidate for rework. |
1207 | * For example, each command could either have its own handler, so | 1216 | * For example, each command could either have its own handler, so |
@@ -1437,6 +1446,13 @@ static int sctp_cmd_interpreter(sctp_event_t event_type, | |||
1437 | sctp_cmd_setup_t2(commands, asoc, cmd->obj.ptr); | 1446 | sctp_cmd_setup_t2(commands, asoc, cmd->obj.ptr); |
1438 | break; | 1447 | break; |
1439 | 1448 | ||
1449 | case SCTP_CMD_TIMER_START_ONCE: | ||
1450 | timer = &asoc->timers[cmd->obj.to]; | ||
1451 | |||
1452 | if (timer_pending(timer)) | ||
1453 | break; | ||
1454 | /* fall through */ | ||
1455 | |||
1440 | case SCTP_CMD_TIMER_START: | 1456 | case SCTP_CMD_TIMER_START: |
1441 | timer = &asoc->timers[cmd->obj.to]; | 1457 | timer = &asoc->timers[cmd->obj.to]; |
1442 | timeout = asoc->timeouts[cmd->obj.to]; | 1458 | timeout = asoc->timeouts[cmd->obj.to]; |