diff options
Diffstat (limited to 'freebsd/sys/netinet/tcp_input.c')
-rw-r--r-- | freebsd/sys/netinet/tcp_input.c | 45 |
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 |