- if ((tp->tc_flags&TC_FORCE_ONE) && (tp->snd_lst == wind)) {
- tp->snd_lst = tp->snd_nxt + 1;
- forced = 1;
- } else if (tp->snd_nxt >= tp->snd_lst)
- return (0);
- m = tcp_sndcopy(tp, MAX(tp->iss+1,tp->snd_nxt), tp->snd_lst);
- if (tp->snd_end > tp->iss && tp->snd_end <= tp->snd_lst)
- flags |= TH_EOL;
- if ((tp->tc_flags&TC_SND_FIN) && !forced &&
- tp->snd_lst == last &&
- (tp->seq_fin == tp->iss || tp->snd_nxt <= tp->seq_fin)) {
- flags |= TH_FIN;
- tp->seq_fin = tp->snd_lst++;
+ m->m_next = m_copy(so->so_snd.sb_mb, off, len);
+ if (m->m_next == 0)
+ len = 0;
+ } else if (tp->t_flags & TF_ACKNOW)
+ tcpstat.tcps_sndacks++;
+ else if (flags & (TH_SYN|TH_FIN|TH_RST))
+ tcpstat.tcps_sndctrl++;
+ else if (SEQ_GT(tp->snd_up, tp->snd_una))
+ tcpstat.tcps_sndurg++;
+ else
+ tcpstat.tcps_sndwinup++;
+
+ ti = mtod(m, struct tcpiphdr *);
+ if (tp->t_template == 0)
+ panic("tcp_output");
+ bcopy((caddr_t)tp->t_template, (caddr_t)ti, sizeof (struct tcpiphdr));
+
+ /*
+ * Fill in fields, remembering maximum advertised
+ * window for use in delaying messages about window sizes.
+ * If resending a FIN, be sure not to use a new sequence number.
+ */
+ if (flags & TH_FIN && tp->t_flags & TF_SENTFIN &&
+ tp->snd_nxt == tp->snd_max)
+ tp->snd_nxt--;
+ ti->ti_seq = htonl(tp->snd_nxt);
+ ti->ti_ack = htonl(tp->rcv_nxt);
+ /*
+ * Before ESTABLISHED, force sending of initial options
+ * unless TCP set to not do any options.
+ */
+ opt = NULL;
+ if (flags & TH_SYN && (tp->t_flags & TF_NOOPT) == 0) {
+ u_short mss;
+
+ mss = MIN(so->so_rcv.sb_hiwat / 2, tcp_mss(tp));
+ if (mss > IP_MSS - sizeof(struct tcpiphdr)) {
+ opt = tcp_initopt;
+ optlen = sizeof (tcp_initopt);
+ *(u_short *)(opt + 2) = htons(mss);