tcp_sack.c (dcdfe44901eca56254ac41b11b6c7b730a276935) tcp_sack.c (440f4ba18e3ab7be912858bbcb96a419fcf14809)
1/*-
2 * SPDX-License-Identifier: BSD-3-Clause
3 *
4 * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1994, 1995
5 * The Regents of the University of California.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without

--- 992 unchanged lines hidden (view full) ---

1001 * and also don't create a hole, if only
1002 * the ACK for a FIN is outstanding.
1003 */
1004 tcp_seq highdata = tp->snd_max;
1005 if (tp->t_flags & TF_SENTFIN)
1006 highdata--;
1007 highdata = SEQ_MIN(highdata, tp->snd_recover);
1008 if (SEQ_LT(th->th_ack, highdata)) {
1/*-
2 * SPDX-License-Identifier: BSD-3-Clause
3 *
4 * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1994, 1995
5 * The Regents of the University of California.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without

--- 992 unchanged lines hidden (view full) ---

1001 * and also don't create a hole, if only
1002 * the ACK for a FIN is outstanding.
1003 */
1004 tcp_seq highdata = tp->snd_max;
1005 if (tp->t_flags & TF_SENTFIN)
1006 highdata--;
1007 highdata = SEQ_MIN(highdata, tp->snd_recover);
1008 if (SEQ_LT(th->th_ack, highdata)) {
1009 tp->snd_fack = th->th_ack;
1009 tp->snd_fack = SEQ_MAX(th->th_ack, tp->snd_fack);
1010 if ((temp = tcp_sackhole_insert(tp, SEQ_MAX(th->th_ack,
1011 highdata - maxseg), highdata, NULL)) != NULL) {
1012 tp->sackhint.hole_bytes +=
1013 temp->end - temp->start;
1014 }
1015 }
1016 }
1017 (void) tcp_output(tp);

--- 53 unchanged lines hidden (view full) ---

1071 }
1072 return (hole);
1073}
1074
1075/*
1076 * After a timeout, the SACK list may be rebuilt. This SACK information
1077 * should be used to avoid retransmitting SACKed data. This function
1078 * traverses the SACK list to see if snd_nxt should be moved forward.
1010 if ((temp = tcp_sackhole_insert(tp, SEQ_MAX(th->th_ack,
1011 highdata - maxseg), highdata, NULL)) != NULL) {
1012 tp->sackhint.hole_bytes +=
1013 temp->end - temp->start;
1014 }
1015 }
1016 }
1017 (void) tcp_output(tp);

--- 53 unchanged lines hidden (view full) ---

1071 }
1072 return (hole);
1073}
1074
1075/*
1076 * After a timeout, the SACK list may be rebuilt. This SACK information
1077 * should be used to avoid retransmitting SACKed data. This function
1078 * traverses the SACK list to see if snd_nxt should be moved forward.
1079 * In addition, cwnd will be inflated by the sacked bytes traversed when
1080 * moving snd_nxt forward. This prevents a traffic burst after the final
1081 * full ACK, and also keeps ACKs coming back.
1079 */
1082 */
1080void
1083int
1081tcp_sack_adjust(struct tcpcb *tp)
1082{
1084tcp_sack_adjust(struct tcpcb *tp)
1085{
1086 int sacked = 0;
1083 struct sackhole *p, *cur = TAILQ_FIRST(&tp->snd_holes);
1084
1085 INP_WLOCK_ASSERT(tptoinpcb(tp));
1086 if (cur == NULL) {
1087 /* No holes */
1087 struct sackhole *p, *cur = TAILQ_FIRST(&tp->snd_holes);
1088
1089 INP_WLOCK_ASSERT(tptoinpcb(tp));
1090 if (cur == NULL) {
1091 /* No holes */
1088 return;
1092 return (0);
1089 }
1090 if (SEQ_GEQ(tp->snd_nxt, tp->snd_fack)) {
1091 /* We're already beyond any SACKed blocks */
1093 }
1094 if (SEQ_GEQ(tp->snd_nxt, tp->snd_fack)) {
1095 /* We're already beyond any SACKed blocks */
1092 return;
1096 return (tp->sackhint.sacked_bytes);
1093 }
1097 }
1094 /*-
1098 /*
1095 * Two cases for which we want to advance snd_nxt:
1096 * i) snd_nxt lies between end of one hole and beginning of another
1097 * ii) snd_nxt lies between end of last hole and snd_fack
1098 */
1099 while ((p = TAILQ_NEXT(cur, scblink)) != NULL) {
1100 if (SEQ_LT(tp->snd_nxt, cur->end)) {
1099 * Two cases for which we want to advance snd_nxt:
1100 * i) snd_nxt lies between end of one hole and beginning of another
1101 * ii) snd_nxt lies between end of last hole and snd_fack
1102 */
1103 while ((p = TAILQ_NEXT(cur, scblink)) != NULL) {
1104 if (SEQ_LT(tp->snd_nxt, cur->end)) {
1101 return;
1105 return (sacked);
1102 }
1106 }
1107 sacked += p->start - cur->end;
1103 if (SEQ_GEQ(tp->snd_nxt, p->start)) {
1104 cur = p;
1105 } else {
1106 tp->snd_nxt = p->start;
1108 if (SEQ_GEQ(tp->snd_nxt, p->start)) {
1109 cur = p;
1110 } else {
1111 tp->snd_nxt = p->start;
1107 return;
1112 return (sacked);
1108 }
1109 }
1110 if (SEQ_LT(tp->snd_nxt, cur->end)) {
1113 }
1114 }
1115 if (SEQ_LT(tp->snd_nxt, cur->end)) {
1111 return;
1116 return (sacked);
1112 }
1113 tp->snd_nxt = tp->snd_fack;
1117 }
1118 tp->snd_nxt = tp->snd_fack;
1119 return (tp->sackhint.sacked_bytes);
1114}
1115
1116/*
1117 * Lost Retransmission Detection
1118 * Check is FACK is beyond the rexmit of the leftmost hole.
1119 * If yes, we restart sending from still existing holes,
1120 * and adjust cwnd via the congestion control module.
1121 */

--- 46 unchanged lines hidden ---
1120}
1121
1122/*
1123 * Lost Retransmission Detection
1124 * Check is FACK is beyond the rexmit of the leftmost hole.
1125 * If yes, we restart sending from still existing holes,
1126 * and adjust cwnd via the congestion control module.
1127 */

--- 46 unchanged lines hidden ---