18b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*
28b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Copyright (c) 1982, 1986, 1988, 1990, 1993
38b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *	The Regents of the University of California.  All rights reserved.
48b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *
58b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Redistribution and use in source and binary forms, with or without
68b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * modification, are permitted provided that the following conditions
78b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * are met:
88b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 1. Redistributions of source code must retain the above copyright
98b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *    notice, this list of conditions and the following disclaimer.
108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright
118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *    notice, this list of conditions and the following disclaimer in the
128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *    documentation and/or other materials provided with the distribution.
135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * 3. Neither the name of the University nor the names of its contributors
148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *    may be used to endorse or promote products derived from this software
158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *    without specific prior written permission.
168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *
178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * SUCH DAMAGE.
288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *
298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *	@(#)tcp_output.c	8.3 (Berkeley) 12/30/93
308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * tcp_output.c,v 1.3 1994/09/15 10:36:55 davidg Exp
318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */
328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*
348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Changes and additions relating to SLiRP
358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Copyright (c) 1995 Danny Gasparovski.
365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner *
375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * Please read the file COPYRIGHT for the
388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * terms and conditions of the copyright.
398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */
408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <slirp.h>
428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*
448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Since this is only used in "stats socket", we give meaning
458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * names instead of the REAL names
468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */
475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerconst char * const tcpstates[] = {
488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*	"CLOSED",       "LISTEN",       "SYN_SENT",     "SYN_RCVD", */
498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	"REDIRECT",	"LISTEN",	"SYN_SENT",     "SYN_RCVD",
508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	"ESTABLISHED",  "CLOSE_WAIT",   "FIN_WAIT_1",   "CLOSING",
518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	"LAST_ACK",     "FIN_WAIT_2",   "TIME_WAIT",
528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project};
538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic const u_char  tcp_outflags[TCP_NSTATES] = {
558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	TH_RST|TH_ACK, 0,      TH_SYN,        TH_SYN|TH_ACK,
565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	TH_ACK,        TH_ACK, TH_FIN|TH_ACK, TH_FIN|TH_ACK,
578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	TH_FIN|TH_ACK, TH_ACK, TH_ACK,
588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project};
598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define MAX_TCPOPTLEN	32	/* max # bytes that go in options */
628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*
648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Tcp output routine: figure out what should be sent and send it.
658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */
668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint
675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnertcp_output(struct tcpcb *tp)
688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	register struct socket *so = tp->t_socket;
708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	register long len, win;
718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	int off, flags, error;
725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	register struct mbuf *m;
738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	register struct tcpiphdr *ti;
748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	u_char opt[MAX_TCPOPTLEN];
758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	unsigned optlen, hdrlen;
768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	int idle, sendalot;
775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	DEBUG_CALL("tcp_output");
798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	DEBUG_ARG("tp = %lx", (long )tp);
805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	/*
828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 * Determine length of data that should be transmitted,
838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 * and flags that will be used.
848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 * If there is some data or critical controls (SYN, RST)
858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 * to send, then transmit; otherwise, investigate further.
868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 */
878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	idle = (tp->snd_max == tp->snd_una);
888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	if (idle && tp->t_idle >= tp->t_rxtcur)
898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		/*
908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		 * We have been idle for "a while" and no acks are
918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		 * expected to clock out any data we send --
928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		 * slow start to get ack "clock" running again.
938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		 */
948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		tp->snd_cwnd = tp->t_maxseg;
958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectagain:
968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	sendalot = 0;
978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	off = tp->snd_nxt - tp->snd_una;
988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	win = min(tp->snd_wnd, tp->snd_cwnd);
998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	flags = tcp_outflags[tp->t_state];
1015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	DEBUG_MISC((dfd, " --- tcp_output flags = 0x%x\n",flags));
1035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	/*
1058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 * If in persist timeout with window of 0, send 1 byte.
1068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 * Otherwise, if window is small but nonzero
1078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 * and timer expired, we will send what we can
1088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 * and go to transmit state.
1098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 */
1108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	if (tp->t_force) {
1118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		if (win == 0) {
1128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project			/*
1138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project			 * If we still have some data to send, then
1148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project			 * clear the FIN bit.  Usually this would
1158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project			 * happen below when it realizes that we
1168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project			 * aren't sending all the data.  However,
1178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project			 * if we have exactly 1 byte of unset data,
1188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project			 * then it won't clear the FIN bit below,
1198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project			 * and if we are in persist state, we wind
1208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project			 * up sending the packet without recording
1218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project			 * that we sent the FIN bit.
1228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project			 *
1238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project			 * We can't just blindly clear the FIN bit,
1248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project			 * because if we don't have any more data
1258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project			 * to send then the probe will be the FIN
1268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project			 * itself.
1278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project			 */
1288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project			if (off < so->so_snd.sb_cc)
1298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project				flags &= ~TH_FIN;
1308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project			win = 1;
1318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		} else {
1328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project			tp->t_timer[TCPT_PERSIST] = 0;
1338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project			tp->t_rxtshift = 0;
1348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		}
1358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	}
1368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	len = min(so->so_snd.sb_cc, win) - off;
1388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	if (len < 0) {
1408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		/*
1418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		 * If FIN has been sent but not acked,
1428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		 * but we haven't been called to retransmit,
1438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		 * len will be -1.  Otherwise, window shrank
1448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		 * after we sent into it.  If window shrank to 0,
1458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		 * cancel pending retransmit and pull snd_nxt
1468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		 * back to (closed) window.  We will enter persist
1478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		 * state below.  If the window didn't close completely,
1488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		 * just wait for an ACK.
1498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		 */
1508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		len = 0;
1518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		if (win == 0) {
1528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project			tp->t_timer[TCPT_REXMT] = 0;
1538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project			tp->snd_nxt = tp->snd_una;
1548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		}
1558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	}
1565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	if (len > tp->t_maxseg) {
1588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		len = tp->t_maxseg;
1598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		sendalot = 1;
1608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	}
1618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	if (SEQ_LT(tp->snd_nxt + len, tp->snd_una + so->so_snd.sb_cc))
1628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		flags &= ~TH_FIN;
1638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	win = sbspace(&so->so_rcv);
1658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	/*
1678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 * Sender silly window avoidance.  If connection is idle
1688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 * and can send all data, a maximum segment,
1698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 * at least a maximum default-size segment do it,
1708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 * or are forced, do it; otherwise don't bother.
1718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 * If peer's buffer is tiny, then send
1728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 * when window is at least half open.
1738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 * If retransmitting (possibly after persist timer forced us
1748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 * to send into a small window), then must resend.
1758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 */
1768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	if (len) {
1778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		if (len == tp->t_maxseg)
1788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project			goto send;
1798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		if ((1 || idle || tp->t_flags & TF_NODELAY) &&
1808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		    len + off >= so->so_snd.sb_cc)
1818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project			goto send;
1828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		if (tp->t_force)
1838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project			goto send;
1848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		if (len >= tp->max_sndwnd / 2 && tp->max_sndwnd > 0)
1858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project			goto send;
1868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		if (SEQ_LT(tp->snd_nxt, tp->snd_max))
1878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project			goto send;
1888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	}
1898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	/*
1918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 * Compare available window to amount of window
1928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 * known to peer (as advertised window less
1938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 * next expected input).  If the difference is at least two
1948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 * max size segments, or at least 50% of the maximum possible
1958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 * window, then want to send a window update to peer.
1968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 */
1978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	if (win > 0) {
1985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		/*
1998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		 * "adv" is the amount we can increase the window,
2008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		 * taking into account that we are limited by
2018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		 * TCP_MAXWIN << tp->rcv_scale.
2028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		 */
2038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		long adv = min(win, (long)TCP_MAXWIN << tp->rcv_scale) -
2048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project			(tp->rcv_adv - tp->rcv_nxt);
2058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		if (adv >= (long) (2 * tp->t_maxseg))
2078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project			goto send;
2088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		if (2 * adv >= (long) so->so_rcv.sb_datalen)
2098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project			goto send;
2108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	}
2118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	/*
2138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 * Send if we owe peer an ACK.
2148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 */
2158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	if (tp->t_flags & TF_ACKNOW)
2168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		goto send;
2178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	if (flags & (TH_SYN|TH_RST))
2188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		goto send;
2198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	if (SEQ_GT(tp->snd_up, tp->snd_una))
2208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		goto send;
2218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	/*
2228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 * If our state indicates that FIN should be sent
2238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 * and we have not yet done so, or we're retransmitting the FIN,
2248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 * then we need to send.
2258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 */
2268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	if (flags & TH_FIN &&
2278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	    ((tp->t_flags & TF_SENTFIN) == 0 || tp->snd_nxt == tp->snd_una))
2288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		goto send;
2298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	/*
2318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 * TCP window updates are not reliable, rather a polling protocol
2328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 * using ``persist'' packets is used to insure receipt of window
2338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 * updates.  The three ``states'' for the output side are:
2348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 *	idle			not doing retransmits or persists
2358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 *	persisting		to move a small or zero window
2368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 *	(re)transmitting	and thereby not persisting
2378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 *
2388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 * tp->t_timer[TCPT_PERSIST]
2398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 *	is set when we are in persist state.
2408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 * tp->t_force
2418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 *	is set when we are called to send a persist packet.
2428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 * tp->t_timer[TCPT_REXMT]
2438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 *	is set when we are retransmitting
2448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 * The output side is idle when both timers are zero.
2458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 *
2468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 * If send window is too small, there is data to transmit, and no
2478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 * retransmit or persist is pending, then go to persist state.
2488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 * If nothing happens soon, send when timer expires:
2498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 * if window is nonzero, transmit what we can,
2508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 * otherwise force out a byte.
2518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 */
2528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	if (so->so_snd.sb_cc && tp->t_timer[TCPT_REXMT] == 0 &&
2538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	    tp->t_timer[TCPT_PERSIST] == 0) {
2548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		tp->t_rxtshift = 0;
2558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		tcp_setpersist(tp);
2568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	}
2578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	/*
2598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 * No reason to send a segment, just return.
2608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 */
2615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	STAT(tcpstat.tcps_didnuttin++);
2625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	return (0);
2648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsend:
2668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	/*
2678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 * Before ESTABLISHED, force sending of initial options
2688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 * unless TCP set not to do any options.
2698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 * NOTE: we assume that the IP/TCP header plus TCP options
2708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 * always fit in a single mbuf, leaving room for a maximum
2718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 * link header, i.e.
2728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 *	max_linkhdr + sizeof (struct tcpiphdr) + optlen <= MHLEN
2738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 */
2748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	optlen = 0;
2758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	hdrlen = sizeof (struct tcpiphdr);
2768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	if (flags & TH_SYN) {
2778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		tp->snd_nxt = tp->iss;
2788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		if ((tp->t_flags & TF_NOOPT) == 0) {
2798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project			u_int16_t mss;
2808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project			opt[0] = TCPOPT_MAXSEG;
2828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project			opt[1] = 4;
2838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project			mss = htons((u_int16_t) tcp_mss(tp, 0));
2848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project			memcpy((caddr_t)(opt + 2), (caddr_t)&mss, sizeof(mss));
2858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project			optlen = 4;
2868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*			if ((tp->t_flags & TF_REQ_SCALE) &&
2888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *			    ((flags & TH_ACK) == 0 ||
2898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *			    (tp->t_flags & TF_RCVD_SCALE))) {
2908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *				*((u_int32_t *) (opt + optlen)) = htonl(
2918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *					TCPOPT_NOP << 24 |
2928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *					TCPOPT_WINDOW << 16 |
2938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *					TCPOLEN_WINDOW << 8 |
2948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *					tp->request_r_scale);
2958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *				optlen += 4;
2968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *			}
2978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */
2988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		}
2998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 	}
3005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
3018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 	/*
3025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	 * Send a timestamp and echo-reply if this is a SYN and our side
3038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 * wants to use timestamps (TF_REQ_TSTMP is set) or both our side
3048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 * and our peer have sent timestamps in our SYN's.
3058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 	 */
3068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* 	if ((tp->t_flags & (TF_REQ_TSTMP|TF_NOOPT)) == TF_REQ_TSTMP &&
3078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *	     (flags & TH_RST) == 0 &&
3088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *	    ((flags & (TH_SYN|TH_ACK)) == TH_SYN ||
3098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *	     (tp->t_flags & TF_RCVD_TSTMP))) {
3108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *		u_int32_t *lp = (u_int32_t *)(opt + optlen);
3118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *
3128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *		/ * Form timestamp option as shown in appendix A of RFC 1323. *  /
3138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *		*lp++ = htonl(TCPOPT_TSTAMP_HDR);
3148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *		*lp++ = htonl(tcp_now);
3158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *		*lp   = htonl(tp->ts_recent);
3168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *		optlen += TCPOLEN_TSTAMP_APPA;
3178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *	}
3188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */
3198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 	hdrlen += optlen;
3205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
3218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	/*
3228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 * Adjust data length if insertion of options will
3238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 * bump the packet length beyond the t_maxseg length.
3248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 */
3258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 if (len > tp->t_maxseg - optlen) {
3268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		len = tp->t_maxseg - optlen;
3278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		sendalot = 1;
3288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 }
3298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	/*
3318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 * Grab a header mbuf, attaching a copy of data to
3328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 * be transmitted, and initialize the header from
3338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 * the template for sends on this connection.
3348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 */
3358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	if (len) {
3368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		if (tp->t_force && len == 1)
3375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			STAT(tcpstat.tcps_sndprobe++);
3388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		else if (SEQ_LT(tp->snd_nxt, tp->snd_max)) {
3395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			STAT(tcpstat.tcps_sndrexmitpack++);
3405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			STAT(tcpstat.tcps_sndrexmitbyte += len);
3418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		} else {
3425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			STAT(tcpstat.tcps_sndpack++);
3435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			STAT(tcpstat.tcps_sndbyte += len);
3448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		}
3458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		m = m_get();
3478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		if (m == NULL) {
3488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*			error = ENOBUFS; */
3498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project			error = 1;
3508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project			goto out;
3518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		}
3525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		m->m_data += IF_MAXLINKHDR;
3538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		m->m_len = hdrlen;
3545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
3555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		/*
3568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		 * This will always succeed, since we make sure our mbufs
3578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		 * are big enough to hold one MSS packet + header + ... etc.
3588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		 */
3598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*		if (len <= MHLEN - hdrlen - max_linkhdr) { */
3608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			sbcopy(&so->so_snd, off, (int) len, mtod(m, caddr_t) + hdrlen);
3628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project			m->m_len += len;
3638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*		} else {
3655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner *			m->m_next = m_copy(so->so_snd.sb_mb, off, (int) len);
3668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *			if (m->m_next == 0)
3678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *				len = 0;
3688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *		}
3698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */
3708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		/*
3718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		 * If we're sending everything we've got, set PUSH.
3728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		 * (This will keep happy those implementations which only
3738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		 * give data to the user when a buffer fills or
3748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		 * a PUSH comes in.)
3758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		 */
3768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		if (off + len == so->so_snd.sb_cc)
3778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project			flags |= TH_PUSH;
3788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	} else {
3798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		if (tp->t_flags & TF_ACKNOW)
3805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			STAT(tcpstat.tcps_sndacks++);
3818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		else if (flags & (TH_SYN|TH_FIN|TH_RST))
3825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			STAT(tcpstat.tcps_sndctrl++);
3838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		else if (SEQ_GT(tp->snd_up, tp->snd_una))
3845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			STAT(tcpstat.tcps_sndurg++);
3858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		else
3865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner			STAT(tcpstat.tcps_sndwinup++);
3878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		m = m_get();
3898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		if (m == NULL) {
3908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*			error = ENOBUFS; */
3918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project			error = 1;
3928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project			goto out;
3938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		}
3945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		m->m_data += IF_MAXLINKHDR;
3958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		m->m_len = hdrlen;
3968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	}
3978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	ti = mtod(m, struct tcpiphdr *);
3995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	memcpy((caddr_t)ti, &tp->t_template, sizeof (struct tcpiphdr));
4018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	/*
4038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 * Fill in fields, remembering maximum advertised
4048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 * window for use in delaying messages about window sizes.
4058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 * If resending a FIN, be sure not to use a new sequence number.
4068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 */
4075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	if (flags & TH_FIN && tp->t_flags & TF_SENTFIN &&
4088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	    tp->snd_nxt == tp->snd_max)
4098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		tp->snd_nxt--;
4108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	/*
4118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 * If we are doing retransmissions, then snd_nxt will
4128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 * not reflect the first unsent octet.  For ACK only
4138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 * packets, we do not want the sequence number of the
4148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 * retransmitted packet, we want the sequence number
4158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 * of the next unsent octet.  So, if there is no data
4168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 * (and no SYN or FIN), use snd_max instead of snd_nxt
4178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 * when filling in ti_seq.  But if we are in persist
4188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 * state, snd_max might reflect one byte beyond the
4198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 * right edge of the window, so use snd_nxt in that
4208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 * case, since we know we aren't doing a retransmission.
4218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 * (retransmit and persist are mutually exclusive...)
4228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 */
4238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	if (len || (flags & (TH_SYN|TH_FIN)) || tp->t_timer[TCPT_PERSIST])
4248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		ti->ti_seq = htonl(tp->snd_nxt);
4258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	else
4268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		ti->ti_seq = htonl(tp->snd_max);
4278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	ti->ti_ack = htonl(tp->rcv_nxt);
4288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	if (optlen) {
4298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		memcpy((caddr_t)(ti + 1), (caddr_t)opt, optlen);
4308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		ti->ti_off = (sizeof (struct tcphdr) + optlen) >> 2;
4318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	}
4328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	ti->ti_flags = flags;
4338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	/*
4348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 * Calculate receive window.  Don't shrink window,
4358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 * but avoid silly window syndrome.
4368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 */
4378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	if (win < (long)(so->so_rcv.sb_datalen / 4) && win < (long)tp->t_maxseg)
4388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		win = 0;
4398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	if (win > (long)TCP_MAXWIN << tp->rcv_scale)
4408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		win = (long)TCP_MAXWIN << tp->rcv_scale;
4418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	if (win < (long)(tp->rcv_adv - tp->rcv_nxt))
4428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		win = (long)(tp->rcv_adv - tp->rcv_nxt);
4438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	ti->ti_win = htons((u_int16_t) (win>>tp->rcv_scale));
4445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	if (SEQ_GT(tp->snd_up, tp->snd_una)) {
4468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		ti->ti_urp = htons((u_int16_t)(tp->snd_up - ntohl(ti->ti_seq)));
4475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef notdef
4488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	if (SEQ_GT(tp->snd_up, tp->snd_nxt)) {
4498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		ti->ti_urp = htons((u_int16_t)(tp->snd_up - tp->snd_nxt));
4508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
4518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		ti->ti_flags |= TH_URG;
4528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	} else
4538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		/*
4548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		 * If no urgent pointer to send, then we pull
4558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		 * the urgent pointer to the left edge of the send window
4568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		 * so that it doesn't drift into the send window on sequence
4578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		 * number wraparound.
4588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		 */
4598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		tp->snd_up = tp->snd_una;		/* drag it along */
4608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	/*
4628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 * Put TCP length in extended header, and then
4638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 * checksum extended header and data.
4648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 */
4658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	if (len + optlen)
4668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		ti->ti_len = htons((u_int16_t)(sizeof (struct tcphdr) +
4678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		    optlen + len));
4688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	ti->ti_sum = cksum(m, (int)(hdrlen + len));
4698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	/*
4718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 * In transmit state, time the transmission and arrange for
4728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 * the retransmit.  In persist state, just set snd_max.
4738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 */
4748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	if (tp->t_force == 0 || tp->t_timer[TCPT_PERSIST] == 0) {
4758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		tcp_seq startseq = tp->snd_nxt;
4768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		/*
4788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		 * Advance snd_nxt over sequence space of this segment.
4798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		 */
4808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		if (flags & (TH_SYN|TH_FIN)) {
4818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project			if (flags & TH_SYN)
4828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project				tp->snd_nxt++;
4838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project			if (flags & TH_FIN) {
4848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project				tp->snd_nxt++;
4858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project				tp->t_flags |= TF_SENTFIN;
4868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project			}
4878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		}
4888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		tp->snd_nxt += len;
4898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		if (SEQ_GT(tp->snd_nxt, tp->snd_max)) {
4908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project			tp->snd_max = tp->snd_nxt;
4918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project			/*
4928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project			 * Time this transmission if not a retransmission and
4938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project			 * not currently timing anything.
4948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project			 */
4958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project			if (tp->t_rtt == 0) {
4968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project				tp->t_rtt = 1;
4978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project				tp->t_rtseq = startseq;
4985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner				STAT(tcpstat.tcps_segstimed++);
4998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project			}
5008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		}
5018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		/*
5038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		 * Set retransmit timer if not currently set,
5048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		 * and not doing an ack or a keep-alive probe.
5058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		 * Initial value for retransmit timer is smoothed
5068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		 * round-trip time + 2 * round-trip time variance.
5078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		 * Initialize shift counter which is used for backoff
5088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		 * of retransmit time.
5098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		 */
5108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		if (tp->t_timer[TCPT_REXMT] == 0 &&
5118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		    tp->snd_nxt != tp->snd_una) {
5128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project			tp->t_timer[TCPT_REXMT] = tp->t_rxtcur;
5138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project			if (tp->t_timer[TCPT_PERSIST]) {
5148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project				tp->t_timer[TCPT_PERSIST] = 0;
5158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project				tp->t_rxtshift = 0;
5168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project			}
5178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		}
5188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	} else
5198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		if (SEQ_GT(tp->snd_nxt + len, tp->snd_max))
5208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project			tp->snd_max = tp->snd_nxt + len;
5218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	/*
5238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 * Fill in IP length and desired time to live and
5248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 * send to IP level.  There should be a better way
5258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 * to handle ttl and tos; we could keep them in
5268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 * the template, but need a way to checksum without them.
5278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 */
5288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	m->m_len = hdrlen + len; /* XXX Needed? m_len should be correct */
5295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
5308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    {
5315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
5328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	((struct ip *)ti)->ip_len = m->m_len;
5338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	((struct ip *)ti)->ip_ttl = IPDEFTTL;
5358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	((struct ip *)ti)->ip_tos = so->so_iptos;
5365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
5378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* #if BSD >= 43 */
5388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	/* Don't do IP options... */
5398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*	error = ip_output(m, tp->t_inpcb->inp_options, &tp->t_inpcb->inp_route,
5408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *	    so->so_options & SO_DONTROUTE, 0);
5418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */
5428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	error = ip_output(so, m);
5438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* #else
5455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner *	error = ip_output(m, (struct mbuf *)0, &tp->t_inpcb->inp_route,
5468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *	    so->so_options & SO_DONTROUTE);
5478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * #endif
5488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */
5498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
5508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	if (error) {
5518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectout:
5528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*		if (error == ENOBUFS) {
5538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *			tcp_quench(tp->t_inpcb, 0);
5548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *			return (0);
5558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *		}
5568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */
5578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*		if ((error == EHOSTUNREACH || error == ENETDOWN)
5588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *		    && TCPS_HAVERCVDSYN(tp->t_state)) {
5598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *			tp->t_softerror = error;
5608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *			return (0);
5618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *		}
5628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */
5638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		return (error);
5648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	}
5655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	STAT(tcpstat.tcps_sndtotal++);
5668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	/*
5688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 * Data sent (as far as we can tell).
5698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 * If this advertises a larger window than any other segment,
5708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 * then remember the size of the advertised window.
5718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 * Any pending ACK has now been sent.
5728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 */
5738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	if (win > 0 && SEQ_GT(tp->rcv_nxt+win, tp->rcv_adv))
5748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		tp->rcv_adv = tp->rcv_nxt + win;
5758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	tp->last_ack_sent = tp->rcv_nxt;
5768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	tp->t_flags &= ~(TF_ACKNOW|TF_DELACK);
5778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	if (sendalot)
5788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		goto again;
5798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	return (0);
5818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
5828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid
5845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnertcp_setpersist(struct tcpcb *tp)
5858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
5868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int t = ((tp->t_srtt >> 2) + tp->t_rttvar) >> 1;
5878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*	if (tp->t_timer[TCPT_REXMT])
5898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *		panic("tcp_output REXMT");
5908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */
5918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	/*
5928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 * Start/restart persistence timer.
5938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 */
5948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	TCPT_RANGESET(tp->t_timer[TCPT_PERSIST],
5958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	    t * tcp_backoff[tp->t_rxtshift],
5968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	    TCPTV_PERSMIN, TCPTV_PERSMAX);
5978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	if (tp->t_rxtshift < TCP_MAXRXTSHIFT)
5988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		tp->t_rxtshift++;
5998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
600