*/
if (needoutput || (tp->t_flags & TF_ACKNOW))
tcp_output(tp);
+ tcp_sack_report_cleanup(tp);
return(IPPROTO_DONE);
dropafterack:
m_freem(m);
tp->t_flags |= TF_ACKNOW;
tcp_output(tp);
+ tcp_sack_report_cleanup(tp);
return(IPPROTO_DONE);
dropwithreset:
tcp_respond(tp, mtod(m, void *), th, m, th->th_seq + tlen,
(tcp_seq)0, TH_RST | TH_ACK);
}
+ if (tp != NULL)
+ tcp_sack_report_cleanup(tp);
return(IPPROTO_DONE);
drop:
tcp_trace(TA_DROP, ostate, tp, tcp_saveipgen, &tcp_savetcp, 0);
#endif
m_freem(m);
+ if (tp != NULL)
+ tcp_sack_report_cleanup(tp);
return(IPPROTO_DONE);
}
}
/*
+ * Cleanup the reported SACK block information
+ */
+void
+tcp_sack_report_cleanup(struct tcpcb *tp)
+{
+ tp->t_flags &= ~(TF_DUPSEG | TF_ENCLOSESEG | TF_SACKLEFT);
+ tp->reportblk.rblk_start = tp->reportblk.rblk_end;
+}
+
+/*
* Returns 0 if not D-SACK block,
* 1 if D-SACK,
* 2 if duplicate of out-of-order D-SACK block.
tcp_rtlookup (struct in_conninfo *);
int tcp_sack_bytes_below(struct scoreboard *scb, tcp_seq seq);
void tcp_sack_cleanup(struct scoreboard *scb);
+void tcp_sack_report_cleanup(struct tcpcb *tp);
int tcp_sack_ndsack_blocks(struct raw_sackblock *blocks,
const int numblocks, tcp_seq snd_una);
void tcp_sack_fill_report(struct tcpcb *tp, u_char *opt, u_int *plen);