Only update SACK/DSACK lists when a non-empty segment was received.

This fixes hitting a KASSERT with a valid packet exchange.

Reviewed by:		rrs@, Richard Scheffenegger
MFC after:		3 days
Sponsored by:		Netflix, Inc.
Differential Revision:	https://reviews.freebsd.org/D21567
This commit is contained in:
Michael Tuexen 2019-09-09 16:07:47 +00:00
parent 62ea153efd
commit 6d261981ee
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=352072
2 changed files with 36 additions and 36 deletions

View File

@ -3045,9 +3045,8 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
thflags = tcp_reass(tp, th, &temp, &tlen, m);
tp->t_flags |= TF_ACKNOW;
}
if (tp->t_flags & TF_SACK_PERMIT) {
if (((tlen == 0) && (save_tlen > 0) &&
(SEQ_LT(save_start, save_rnxt)))) {
if ((tp->t_flags & TF_SACK_PERMIT) && (save_tlen > 0)) {
if ((tlen == 0) && (SEQ_LT(save_start, save_rnxt))) {
/*
* DSACK actually handled in the fastpath
* above.
@ -3055,20 +3054,20 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
tcp_update_sack_list(tp, save_start,
save_start + save_tlen);
} else if ((tlen > 0) && SEQ_GT(tp->rcv_nxt, save_rnxt)) {
/*
* Cleaning sackblks by using zero length
* update.
*/
if ((tp->rcv_numsacks >= 1) &&
(tp->sackblks[0].end == save_start)) {
/* partial overlap, recorded at todrop above */
tcp_update_sack_list(tp, tp->sackblks[0].start,
/*
* Partial overlap, recorded at todrop
* above.
*/
tcp_update_sack_list(tp,
tp->sackblks[0].start,
tp->sackblks[0].end);
} else {
tcp_update_dsack_list(tp, save_start,
save_start + save_tlen);
}
} else if ((tlen > 0) && (tlen >= save_tlen)) {
} else if (tlen >= save_tlen) {
/* Update of sackblks. */
tcp_update_dsack_list(tp, save_start,
save_start + save_tlen);

View File

@ -4942,35 +4942,36 @@ rack_process_data(struct mbuf *m, struct tcphdr *th, struct socket *so,
thflags = tcp_reass(tp, th, &temp, &tlen, m);
tp->t_flags |= TF_ACKNOW;
}
if (((tlen == 0) && (save_tlen > 0) &&
(SEQ_LT(save_start, save_rnxt)))) {
/*
* DSACK actually handled in the fastpath
* above.
*/
tcp_update_sack_list(tp, save_start,
save_start + save_tlen);
} else if ((tlen > 0) && SEQ_GT(tp->rcv_nxt, save_rnxt)) {
/*
* Cleaning sackblks by using zero length
* update.
*/
if ((tp->rcv_numsacks >= 1) &&
(tp->sackblks[0].end == save_start)) {
/* partial overlap, recorded at todrop above */
tcp_update_sack_list(tp, tp->sackblks[0].start,
tp->sackblks[0].end);
} else {
if ((tp->t_flags & TF_SACK_PERMIT) && (save_tlen > 0)) {
if ((tlen == 0) && (SEQ_LT(save_start, save_rnxt))) {
/*
* DSACK actually handled in the fastpath
* above.
*/
tcp_update_sack_list(tp, save_start,
save_start + save_tlen);
} else if ((tlen > 0) && SEQ_GT(tp->rcv_nxt, save_rnxt)) {
if ((tp->rcv_numsacks >= 1) &&
(tp->sackblks[0].end == save_start)) {
/*
* Partial overlap, recorded at todrop
* above.
*/
tcp_update_sack_list(tp,
tp->sackblks[0].start,
tp->sackblks[0].end);
} else {
tcp_update_dsack_list(tp, save_start,
save_start + save_tlen);
}
} else if (tlen >= save_tlen) {
/* Update of sackblks. */
tcp_update_dsack_list(tp, save_start,
save_start + save_tlen);
} else if (tlen > 0) {
tcp_update_dsack_list(tp, save_start,
save_start + tlen);
}
} else if ((tlen > 0) && (tlen >= save_tlen)) {
/* Update of sackblks. */
tcp_update_dsack_list(tp, save_start,
save_start + save_tlen);
} else if (tlen > 0) {
tcp_update_dsack_list(tp, save_start,
save_start + tlen);
}
} else {
m_freem(m);