+ win = MIN(tp->snd_wnd, tp->snd_cwnd);
+
+ /*
+ * If in persist timeout with window of 0, send 1 byte.
+ * Otherwise, if window is small but nonzero
+ * and timer expired, we will send what we can
+ * and go to transmit state.
+ */
+ if (tp->t_force) {
+ if (win == 0)
+ win = 1;
+ else {
+ tp->t_timer[TCPT_PERSIST] = 0;
+ tp->t_rxtshift = 0;
+ }
+ }
+
+ len = MIN(so->so_snd.sb_cc, win) - off;
+ flags = tcp_outflags[tp->t_state];
+
+ if (len < 0) {
+ /*
+ * If FIN has been sent but not acked,
+ * but we haven't been called to retransmit,
+ * len will be -1; transmit if acking, otherwise no need.
+ * Otherwise, window shrank after we sent into it.
+ * If window shrank to 0, cancel pending retransmit
+ * and pull snd_nxt back to (closed) window.
+ * We will enter persist state below.
+ * If the window didn't close completely,
+ * just wait for an ACK.
+ */
+ if (flags & TH_FIN) {
+ if (tp->t_flags & TF_ACKNOW)
+ len = 0;
+ else
+ return (0);
+ } else if (win == 0) {
+ tp->t_timer[TCPT_REXMT] = 0;
+ tp->snd_nxt = tp->snd_una;
+ len = 0;
+ } else
+ return (0);
+ }