summaryrefslogtreecommitdiffstats
path: root/freebsd/sys/netinet/tcp_input.c
diff options
context:
space:
mode:
Diffstat (limited to 'freebsd/sys/netinet/tcp_input.c')
-rw-r--r--freebsd/sys/netinet/tcp_input.c45
1 files changed, 26 insertions, 19 deletions
diff --git a/freebsd/sys/netinet/tcp_input.c b/freebsd/sys/netinet/tcp_input.c
index e1fa55c7..05891306 100644
--- a/freebsd/sys/netinet/tcp_input.c
+++ b/freebsd/sys/netinet/tcp_input.c
@@ -1508,7 +1508,6 @@ tcp_autorcvbuf(struct mbuf *m, struct tcphdr *th, struct socket *so,
} else {
tp->rfbuf_cnt += tlen; /* add up */
}
-
return (newsize);
}
@@ -2287,7 +2286,8 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
* DSACK - add SACK block for dropped range
*/
if (tp->t_flags & TF_SACK_PERMIT) {
- tcp_update_sack_list(tp, th->th_seq, th->th_seq+tlen);
+ tcp_update_sack_list(tp, th->th_seq,
+ th->th_seq + todrop);
/*
* ACK now, as the next in-sequence segment
* will clear the DSACK block again
@@ -3067,28 +3067,35 @@ dodata: /* XXX */
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.
*/
- 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.
- */
- tcp_update_sack_list(tp, save_start, save_start);
- } else
- if ((tlen > 0) && (tlen >= save_tlen)) {
+ 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_sack_list(tp, save_start, save_start + save_tlen);
- } else
- if (tlen > 0) {
- tcp_update_sack_list(tp, save_start, save_start+tlen);
+ 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);
}
}
#if 0