| 2557 | } |
| 2558 | |
| 2559 | void |
| 2560 | sctp_sack_check(struct sctp_tcb *stcb, int was_a_gap) |
| 2561 | { |
| 2562 | struct sctp_association *asoc; |
| 2563 | uint32_t highest_tsn; |
| 2564 | int is_a_gap; |
| 2565 | |
| 2566 | sctp_slide_mapping_arrays(stcb); |
| 2567 | asoc = &stcb->asoc; |
| 2568 | if (SCTP_TSN_GT(asoc->highest_tsn_inside_nr_map, asoc->highest_tsn_inside_map)) { |
| 2569 | highest_tsn = asoc->highest_tsn_inside_nr_map; |
| 2570 | } else { |
| 2571 | highest_tsn = asoc->highest_tsn_inside_map; |
| 2572 | } |
| 2573 | /* Is there a gap now? */ |
| 2574 | is_a_gap = SCTP_TSN_GT(highest_tsn, stcb->asoc.cumulative_tsn); |
| 2575 | |
| 2576 | /* |
| 2577 | * Now we need to see if we need to queue a sack or just start the |
| 2578 | * timer (if allowed). |
| 2579 | */ |
| 2580 | if (SCTP_GET_STATE(stcb) == SCTP_STATE_SHUTDOWN_SENT) { |
| 2581 | /* |
| 2582 | * Ok special case, in SHUTDOWN-SENT case. here we maker |
| 2583 | * sure SACK timer is off and instead send a SHUTDOWN and a |
| 2584 | * SACK |
| 2585 | */ |
| 2586 | if (SCTP_OS_TIMER_PENDING(&stcb->asoc.dack_timer.timer)) { |
| 2587 | sctp_timer_stop(SCTP_TIMER_TYPE_RECV, |
| 2588 | stcb->sctp_ep, stcb, NULL, |
| 2589 | SCTP_FROM_SCTP_INDATA + SCTP_LOC_19); |
| 2590 | } |
| 2591 | sctp_send_shutdown(stcb, |
| 2592 | ((stcb->asoc.alternate) ? stcb->asoc.alternate : stcb->asoc.primary_destination)); |
| 2593 | if (is_a_gap) { |
| 2594 | sctp_send_sack(stcb, SCTP_SO_NOT_LOCKED); |
| 2595 | } |
| 2596 | } else { |
| 2597 | /* |
| 2598 | * CMT DAC algorithm: increase number of packets received |
| 2599 | * since last ack |
| 2600 | */ |
| 2601 | stcb->asoc.cmt_dac_pkts_rcvd++; |
| 2602 | |
| 2603 | if ((stcb->asoc.send_sack == 1) || /* We need to send a |
| 2604 | * SACK */ |
| 2605 | ((was_a_gap) && (is_a_gap == 0)) || /* was a gap, but no |
| 2606 | * longer is one */ |
| 2607 | (stcb->asoc.numduptsns) || /* we have dup's */ |
| 2608 | (is_a_gap) || /* is still a gap */ |
| 2609 | (stcb->asoc.delayed_ack == 0) || /* Delayed sack disabled */ |
| 2610 | (stcb->asoc.data_pkts_seen >= stcb->asoc.sack_freq)) { /* hit limit of pkts */ |
| 2611 | if ((stcb->asoc.sctp_cmt_on_off > 0) && |
| 2612 | (SCTP_BASE_SYSCTL(sctp_cmt_use_dac)) && |
| 2613 | (stcb->asoc.send_sack == 0) && |
| 2614 | (stcb->asoc.numduptsns == 0) && |
| 2615 | (stcb->asoc.delayed_ack) && |
| 2616 | (!SCTP_OS_TIMER_PENDING(&stcb->asoc.dack_timer.timer))) { |
no test coverage detected