* Returns the next hole to retransmit and the number of retransmitted bytes * from the scoreboard. We store both the next hole and the number of * retransmitted bytes as hints (and recompute these on the fly upon SACK/ACK * reception). This avoids scoreboard traversals completely. * * The loop here will traverse *at most* one link. Here's the argument. For * the loop to traverse more tha
| 847 | * from the scoreboard. |
| 848 | */ |
| 849 | struct sackhole * |
| 850 | tcp_sack_output(struct tcpcb *tp, int *sack_bytes_rexmt) |
| 851 | { |
| 852 | struct sackhole *hole = NULL; |
| 853 | |
| 854 | INP_WLOCK_ASSERT(tp->t_inpcb); |
| 855 | *sack_bytes_rexmt = tp->sackhint.sack_bytes_rexmit; |
| 856 | hole = tp->sackhint.nexthole; |
| 857 | if (hole == NULL || SEQ_LT(hole->rxmit, hole->end)) |
| 858 | goto out; |
| 859 | while ((hole = TAILQ_NEXT(hole, scblink)) != NULL) { |
| 860 | if (SEQ_LT(hole->rxmit, hole->end)) { |
| 861 | tp->sackhint.nexthole = hole; |
| 862 | break; |
| 863 | } |
| 864 | } |
| 865 | out: |
| 866 | return (hole); |
| 867 | } |
| 868 | |
| 869 | /* |
| 870 | * After a timeout, the SACK list may be rebuilt. This SACK information |