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 --- |