diff options
Diffstat (limited to 'net/sctp/sm_sideeffect.c')
-rw-r--r-- | net/sctp/sm_sideeffect.c | 43 |
1 files changed, 25 insertions, 18 deletions
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c index b5495aecab60..e2020eb2c8ca 100644 --- a/net/sctp/sm_sideeffect.c +++ b/net/sctp/sm_sideeffect.c | |||
@@ -434,7 +434,8 @@ sctp_timer_event_t *sctp_timer_events[SCTP_NUM_TIMEOUT_TYPES] = { | |||
434 | * | 434 | * |
435 | */ | 435 | */ |
436 | static void sctp_do_8_2_transport_strike(struct sctp_association *asoc, | 436 | static void sctp_do_8_2_transport_strike(struct sctp_association *asoc, |
437 | struct sctp_transport *transport) | 437 | struct sctp_transport *transport, |
438 | int is_hb) | ||
438 | { | 439 | { |
439 | /* The check for association's overall error counter exceeding the | 440 | /* The check for association's overall error counter exceeding the |
440 | * threshold is done in the state function. | 441 | * threshold is done in the state function. |
@@ -461,9 +462,15 @@ static void sctp_do_8_2_transport_strike(struct sctp_association *asoc, | |||
461 | * expires, set RTO <- RTO * 2 ("back off the timer"). The | 462 | * expires, set RTO <- RTO * 2 ("back off the timer"). The |
462 | * maximum value discussed in rule C7 above (RTO.max) may be | 463 | * maximum value discussed in rule C7 above (RTO.max) may be |
463 | * used to provide an upper bound to this doubling operation. | 464 | * used to provide an upper bound to this doubling operation. |
465 | * | ||
466 | * Special Case: the first HB doesn't trigger exponential backoff. | ||
467 | * The first unacknowleged HB triggers it. We do this with a flag | ||
468 | * that indicates that we have an outstanding HB. | ||
464 | */ | 469 | */ |
465 | transport->last_rto = transport->rto; | 470 | if (!is_hb || transport->hb_sent) { |
466 | transport->rto = min((transport->rto * 2), transport->asoc->rto_max); | 471 | transport->last_rto = transport->rto; |
472 | transport->rto = min((transport->rto * 2), transport->asoc->rto_max); | ||
473 | } | ||
467 | } | 474 | } |
468 | 475 | ||
469 | /* Worker routine to handle INIT command failure. */ | 476 | /* Worker routine to handle INIT command failure. */ |
@@ -621,6 +628,11 @@ static void sctp_cmd_transport_on(sctp_cmd_seq_t *cmds, | |||
621 | t->error_count = 0; | 628 | t->error_count = 0; |
622 | t->asoc->overall_error_count = 0; | 629 | t->asoc->overall_error_count = 0; |
623 | 630 | ||
631 | /* Clear the hb_sent flag to signal that we had a good | ||
632 | * acknowledgement. | ||
633 | */ | ||
634 | t->hb_sent = 0; | ||
635 | |||
624 | /* Mark the destination transport address as active if it is not so | 636 | /* Mark the destination transport address as active if it is not so |
625 | * marked. | 637 | * marked. |
626 | */ | 638 | */ |
@@ -646,18 +658,6 @@ static void sctp_cmd_transport_on(sctp_cmd_seq_t *cmds, | |||
646 | sctp_transport_hold(t); | 658 | sctp_transport_hold(t); |
647 | } | 659 | } |
648 | 660 | ||
649 | /* Helper function to do a transport reset at the expiry of the hearbeat | ||
650 | * timer. | ||
651 | */ | ||
652 | static void sctp_cmd_transport_reset(sctp_cmd_seq_t *cmds, | ||
653 | struct sctp_association *asoc, | ||
654 | struct sctp_transport *t) | ||
655 | { | ||
656 | sctp_transport_lower_cwnd(t, SCTP_LOWER_CWND_INACTIVE); | ||
657 | |||
658 | /* Mark one strike against a transport. */ | ||
659 | sctp_do_8_2_transport_strike(asoc, t); | ||
660 | } | ||
661 | 661 | ||
662 | /* Helper function to process the process SACK command. */ | 662 | /* Helper function to process the process SACK command. */ |
663 | static int sctp_cmd_process_sack(sctp_cmd_seq_t *cmds, | 663 | static int sctp_cmd_process_sack(sctp_cmd_seq_t *cmds, |
@@ -1458,12 +1458,19 @@ static int sctp_cmd_interpreter(sctp_event_t event_type, | |||
1458 | 1458 | ||
1459 | case SCTP_CMD_STRIKE: | 1459 | case SCTP_CMD_STRIKE: |
1460 | /* Mark one strike against a transport. */ | 1460 | /* Mark one strike against a transport. */ |
1461 | sctp_do_8_2_transport_strike(asoc, cmd->obj.transport); | 1461 | sctp_do_8_2_transport_strike(asoc, cmd->obj.transport, |
1462 | 0); | ||
1463 | break; | ||
1464 | |||
1465 | case SCTP_CMD_TRANSPORT_IDLE: | ||
1466 | t = cmd->obj.transport; | ||
1467 | sctp_transport_lower_cwnd(t, SCTP_LOWER_CWND_INACTIVE); | ||
1462 | break; | 1468 | break; |
1463 | 1469 | ||
1464 | case SCTP_CMD_TRANSPORT_RESET: | 1470 | case SCTP_CMD_TRANSPORT_HB_SENT: |
1465 | t = cmd->obj.transport; | 1471 | t = cmd->obj.transport; |
1466 | sctp_cmd_transport_reset(commands, asoc, t); | 1472 | sctp_do_8_2_transport_strike(asoc, t, 1); |
1473 | t->hb_sent = 1; | ||
1467 | break; | 1474 | break; |
1468 | 1475 | ||
1469 | case SCTP_CMD_TRANSPORT_ON: | 1476 | case SCTP_CMD_TRANSPORT_ON: |