/* Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
 * Portions Copyright © 1997-1999 Vita Nuova Limited
 * Portions Copyright © 2000-2007 Vita Nuova Holdings Limited
 *                                (www.vitanuova.com)
 * Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
 *
 * Modified for the Akaros operating system:
 * Copyright (c) 2013-2014 The Regents of the University of California
 * Copyright (c) 2013-2017 Google Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE. */

#include <slab.h>
#include <kmalloc.h>
#include <kref.h>
#include <string.h>
#include <stdio.h>
#include <assert.h>
#include <error.h>
#include <cpio.h>
#include <pmap.h>
#include <smp.h>
#include <net/ip.h>
#include <net/tcp.h>

/* Must correspond to the enumeration in tcp.h */
static char *tcpstates[] = {
	"Closed", "Listen", "Syn_sent",
	"Established", "Finwait1", "Finwait2", "Close_wait",
	"Closing", "Last_ack", "Time_wait"
};

static int tcp_irtt = DEF_RTT;			/* Initial guess at round trip time */
static uint16_t tcp_mss = DEF_MSS;		/* Maximum segment size to be sent */

/* Must correspond to the enumeration in tcp.h */
static char *statnames[] = {
	[MaxConn] "MaxConn",
	[ActiveOpens] "ActiveOpens",
	[PassiveOpens] "PassiveOpens",
	[EstabResets] "EstabResets",
	[CurrEstab] "CurrEstab",
	[InSegs] "InSegs",
	[OutSegs] "OutSegs",
	[RetransSegs] "RetransSegs",
	[RetransTimeouts] "RetransTimeouts",
	[InErrs] "InErrs",
	[OutRsts] "OutRsts",
	[CsumErrs] "CsumErrs",
	[HlenErrs] "HlenErrs",
	[LenErrs] "LenErrs",
	[OutOfOrder] "OutOfOrder",
};

/*
 *  Setting tcpporthogdefense to non-zero enables Dong Lin's
 *  solution to hijacked systems staking out port's as a form
 *  of DoS attack.
 *
 *  To avoid stateless Conv hogs, we pick a sequence number at random.  If
 *  it that number gets acked by the other end, we shut down the connection.
 *  Look for tcpporthogedefense in the code.
 */
static int tcpporthogdefense = 0;

static int addreseq(Tcpctl *, struct tcppriv *, Tcp *, struct block *,
                    uint16_t);
static void getreseq(Tcpctl *, Tcp *, struct block **, uint16_t *);
static void localclose(struct conv *, char *unused_char_p_t);
static void procsyn(struct conv *, Tcp *);
static void tcpiput(struct Proto *, struct Ipifc *, struct block *);
static void tcpoutput(struct conv *);
static int tcptrim(Tcpctl *, Tcp *, struct block **, uint16_t *);
static void tcpstart(struct conv *, int);
static void tcptimeout(void *);
static void tcpsndsyn(struct conv *, Tcpctl *);
static void tcprcvwin(struct conv *);
static void tcpacktimer(void *);
static void tcpkeepalive(void *);
static void tcpsetkacounter(Tcpctl *);
static void tcprxmit(struct conv *);
static void tcpsettimer(Tcpctl *);
static void tcpsynackrtt(struct conv *);
static void tcpsetscale(struct conv *, Tcpctl *, uint16_t, uint16_t);
static void tcp_loss_event(struct conv *s, Tcpctl *tcb);
static uint16_t derive_payload_mss(Tcpctl *tcb);
static void set_in_flight(Tcpctl *tcb);

static void limborexmit(struct Proto *);
static void limbo(struct conv *, uint8_t *unused_uint8_p_t, uint8_t *, Tcp *,
				  int);

static void tcpsetstate(struct conv *s, uint8_t newstate)
{
	Tcpctl *tcb;
	uint8_t oldstate;
	struct tcppriv *tpriv;

	tpriv = s->p->priv;

	tcb = (Tcpctl *) s->ptcl;

	oldstate = tcb->state;
	if (oldstate == newstate)
		return;

	if (oldstate == Established)
		tpriv->stats[CurrEstab]--;
	if (newstate == Established)
		tpriv->stats[CurrEstab]++;

	/**
	print( "%d/%d %s->%s CurrEstab=%d\n", s->lport, s->rport,
		tcpstates[oldstate], tcpstates[newstate], tpriv->tstats.tcpCurrEstab );
	**/

	switch (newstate) {
		case Closed:
			qclose(s->rq);
			qclose(s->wq);
			qclose(s->eq);
			break;

		case Close_wait:	/* Remote closes */
			qhangup(s->rq, NULL);
			break;
	}

	tcb->state = newstate;

	if (oldstate == Syn_sent && newstate != Closed)
		Fsconnected(s, NULL);
}

static void tcpconnect(struct conv *c, char **argv, int argc)
{
	Fsstdconnect(c, argv, argc);
	tcpstart(c, TCP_CONNECT);
}

static int tcpstate(struct conv *c, char *state, int n)
{
	Tcpctl *s;

	s = (Tcpctl *) (c->ptcl);

	return snprintf(state, n,
					"%s qin %d qout %d srtt %d mdev %d cwin %u swin %u>>%d rwin %u>>%d timer.start %llu timer.count %llu rerecv %d katimer.start %d katimer.count %d\n",
					tcpstates[s->state],
					c->rq ? qlen(c->rq) : 0,
					c->wq ? qlen(c->wq) : 0,
					s->srtt, s->mdev,
					s->cwind, s->snd.wnd, s->rcv.scale, s->rcv.wnd,
					s->snd.scale, s->timer.start, s->timer.count, s->rerecv,
					s->katimer.start, s->katimer.count);
}

static int tcpinuse(struct conv *c)
{
	Tcpctl *s;

	s = (Tcpctl *) (c->ptcl);
	return s->state != Closed;
}

static void tcpannounce(struct conv *c, char **argv, int argc)
{
	Fsstdannounce(c, argv, argc);
	tcpstart(c, TCP_LISTEN);
	Fsconnected(c, NULL);
}

static void tcpbypass(struct conv *cv, char **argv, int argc)
{
	struct tcppriv *tpriv = cv->p->priv;

	Fsstdbypass(cv, argv, argc);
	iphtadd(&tpriv->ht, cv);
}

static void tcpshutdown(struct conv *c, int how)
{
	Tcpctl *tcb = (Tcpctl*)c->ptcl;

	/* Do nothing for the read side */
	if (how == SHUT_RD)
		return;
	/* Sends a FIN.  If we're in another state (like Listen), we'll run into
	 * issues, since we'll never send the FIN.  We'll be shutdown on our end,
	 * but we'll never tell the distant end.  Might just be an app issue. */
	switch (tcb->state) {
	case Established:
		tcb->flgcnt++;
		tcpsetstate(c, Finwait1);
		tcpoutput(c);
		break;
	}
}

/*
 *  tcpclose is always called with the q locked
 */
static void tcpclose(struct conv *c)
{
	Tcpctl *tcb;

	tcb = (Tcpctl *) c->ptcl;

	qhangup(c->rq, NULL);
	qhangup(c->wq, NULL);
	qhangup(c->eq, NULL);
	qflush(c->rq);

	switch (tcb->state) {
		case Listen:
			/*
			 *  reset any incoming calls to this listener
			 */
			Fsconnected(c, "Hangup");

			localclose(c, NULL);
			break;
		case Closed:
		case Syn_sent:
			localclose(c, NULL);
			break;
		case Established:
			tcb->flgcnt++;
			tcpsetstate(c, Finwait1);
			tcpoutput(c);
			break;
		case Close_wait:
			tcb->flgcnt++;
			tcpsetstate(c, Last_ack);
			tcpoutput(c);
			break;
	}
}

static void tcpkick(void *x)
{
	ERRSTACK(1);
	struct conv *s = x;
	Tcpctl *tcb;

	tcb = (Tcpctl *) s->ptcl;

	qlock(&s->qlock);
	if (waserror()) {
		qunlock(&s->qlock);
		nexterror();
	}

	switch (tcb->state) {
		case Syn_sent:
		case Established:
		case Close_wait:
			/*
			 * Push data
			 */
			tcprcvwin(s);
			tcpoutput(s);
			break;
		default:
			localclose(s, "Hangup");
			break;
	}

	qunlock(&s->qlock);
	poperror();
}

static void tcprcvwin(struct conv *s)
{
	/* Call with tcb locked */
	int w;
	Tcpctl *tcb;

	tcb = (Tcpctl *) s->ptcl;
	w = tcb->window - qlen(s->rq);
	if (w < 0)
		w = 0;

	/* RFC 813: Avoid SWS.  We'll always reduce the window (because the qio
	 * increased - that's legit), and we'll always advertise the window
	 * increases (corresponding to qio drains) when those are greater than MSS.
	 * But we don't advertise increases less than MSS.
	 *
	 * Note we don't shrink the window at all - that'll result in tcptrim()
	 * dropping packets that were sent before the sender gets our update. */
	if ((w < tcb->rcv.wnd) || (w >= tcb->mss))
		tcb->rcv.wnd = w;
	/* We've delayed sending an update to rcv.wnd, and we might never get
	 * another ACK to drive the TCP stack after the qio is drained.  We could
	 * replace this stuff with qio kicks or callbacks, but that might be
	 * trickier with the MSS limitation.  (and 'edge' isn't empty or not). */
	if (w < tcb->mss)
		tcb->rcv.blocked = 1;
}

static void tcpacktimer(void *v)
{
	ERRSTACK(1);
	Tcpctl *tcb;
	struct conv *s;

	s = v;
	tcb = (Tcpctl *) s->ptcl;

	qlock(&s->qlock);
	if (waserror()) {
		qunlock(&s->qlock);
		nexterror();
	}
	if (tcb->state != Closed) {
		tcb->flags |= FORCE;
		tcprcvwin(s);
		tcpoutput(s);
	}
	qunlock(&s->qlock);
	poperror();
}

static void tcpcreate(struct conv *c)
{
	/* We don't use qio limits.  Instead, TCP manages flow control on its own.
	 * We only use qpassnolim().  Note for qio that 0 doesn't mean no limit. */
	c->rq = qopen(0, Qcoalesce, 0, 0);
	c->wq = qopen(8 * QMAX, Qkick, tcpkick, c);
}

static void timerstate(struct tcppriv *priv, Tcptimer *t, int newstate)
{
	if (newstate != TcptimerON) {
		if (t->state == TcptimerON) {
			// unchain
			if (priv->timers == t) {
				priv->timers = t->next;
				if (t->prev != NULL)
					panic("timerstate1");
			}
			if (t->next)
				t->next->prev = t->prev;
			if (t->prev)
				t->prev->next = t->next;
			t->next = t->prev = NULL;
		}
	} else {
		if (t->state != TcptimerON) {
			// chain
			if (t->prev != NULL || t->next != NULL)
				panic("timerstate2");
			t->prev = NULL;
			t->next = priv->timers;
			if (t->next)
				t->next->prev = t;
			priv->timers = t;
		}
	}
	t->state = newstate;
}

static void tcpackproc(void *a)
{
	ERRSTACK(1);
	Tcptimer *t, *tp, *timeo;
	struct Proto *tcp;
	struct tcppriv *priv;
	int loop;

	tcp = a;
	priv = tcp->priv;

	for (;;) {
		kthread_usleep(MSPTICK * 1000);

		qlock(&priv->tl);
		timeo = NULL;
		loop = 0;
		for (t = priv->timers; t != NULL; t = tp) {
			if (loop++ > 10000)
				panic("tcpackproc1");
			tp = t->next;
			if (t->state == TcptimerON) {
				t->count--;
				if (t->count == 0) {
					timerstate(priv, t, TcptimerDONE);
					t->readynext = timeo;
					timeo = t;
				}
			}
		}
		qunlock(&priv->tl);

		loop = 0;
		for (t = timeo; t != NULL; t = t->readynext) {
			if (loop++ > 10000)
				panic("tcpackproc2");
			if (t->state == TcptimerDONE && t->func != NULL) {
				/* discard error style */
				if (!waserror())
					(*t->func) (t->arg);
				poperror();
			}
		}

		limborexmit(tcp);
	}
}

static void tcpgo(struct tcppriv *priv, Tcptimer *t)
{
	if (t == NULL || t->start == 0)
		return;

	qlock(&priv->tl);
	t->count = t->start;
	timerstate(priv, t, TcptimerON);
	qunlock(&priv->tl);
}

static void tcphalt(struct tcppriv *priv, Tcptimer *t)
{
	if (t == NULL)
		return;

	qlock(&priv->tl);
	timerstate(priv, t, TcptimerOFF);
	qunlock(&priv->tl);
}

static int backoff(int n)
{
	return 1 << n;
}

static void localclose(struct conv *s, char *reason)
{
	/* called with tcb locked */
	Tcpctl *tcb;
	Reseq *rp, *rp1;
	struct tcppriv *tpriv;

	tpriv = s->p->priv;
	tcb = (Tcpctl *) s->ptcl;

	iphtrem(&tpriv->ht, s);

	tcphalt(tpriv, &tcb->timer);
	tcphalt(tpriv, &tcb->rtt_timer);
	tcphalt(tpriv, &tcb->acktimer);
	tcphalt(tpriv, &tcb->katimer);

	/* Flush reassembly queue; nothing more can arrive */
	for (rp = tcb->reseq; rp != NULL; rp = rp1) {
		rp1 = rp->next;
		freeblist(rp->bp);
		kfree(rp);
	}
	tcb->reseq = NULL;

	if (tcb->state == Syn_sent)
		Fsconnected(s, reason);

	qhangup(s->rq, reason);
	qhangup(s->wq, reason);

	tcpsetstate(s, Closed);

	/* listener will check the rq state */
	if (s->state == Announced)
		rendez_wakeup(&s->listenr);
}

/* mtu (- TCP + IP hdr len) of 1st hop */
static int tcpmtu(struct Ipifc *ifc, int version, int *scale)
{
	int mtu;

	switch (version) {
		default:
		case V4:
			mtu = DEF_MSS;
			if (ifc != NULL)
				mtu = ifc->maxtu - ifc->m->hsize - (TCP4_PKT + TCP4_HDRSIZE);
			break;
		case V6:
			mtu = DEF_MSS6;
			if (ifc != NULL)
				mtu = ifc->maxtu - ifc->m->hsize - (TCP6_PKT + TCP6_HDRSIZE);
			break;
	}
	*scale = HaveWS | 7;

	return mtu;
}

static void tcb_check_tso(Tcpctl *tcb)
{
	/* This can happen if the netdev isn't up yet. */
	if (!tcb->ifc)
		return;
	if (tcb->ifc->feat & NETF_TSO)
		tcb->flags |= TSO;
	else
		tcb->flags &= ~TSO;
}

static void inittcpctl(struct conv *s, int mode)
{
	Tcpctl *tcb;
	Tcp4hdr *h4;
	Tcp6hdr *h6;
	int mss;

	tcb = (Tcpctl *) s->ptcl;

	memset(tcb, 0, sizeof(Tcpctl));

	tcb->ssthresh = UINT32_MAX;
	tcb->srtt = tcp_irtt;
	tcb->mdev = 0;

	/* setup timers */
	tcb->timer.start = tcp_irtt / MSPTICK;
	tcb->timer.func = tcptimeout;
	tcb->timer.arg = s;
	tcb->rtt_timer.start = MAX_TIME;
	tcb->acktimer.start = TCP_ACK / MSPTICK;
	tcb->acktimer.func = tcpacktimer;
	tcb->acktimer.arg = s;
	tcb->katimer.start = DEF_KAT / MSPTICK;
	tcb->katimer.func = tcpkeepalive;
	tcb->katimer.arg = s;

	mss = DEF_MSS;

	/* create a prototype(pseudo) header */
	if (mode != TCP_LISTEN) {
		if (ipcmp(s->laddr, IPnoaddr) == 0)
			findlocalip(s->p->f, s->laddr, s->raddr);

		switch (s->ipversion) {
			case V4:
				h4 = &tcb->protohdr.tcp4hdr;
				memset(h4, 0, sizeof(*h4));
				h4->proto = IP_TCPPROTO;
				hnputs(h4->tcpsport, s->lport);
				hnputs(h4->tcpdport, s->rport);
				v6tov4(h4->tcpsrc, s->laddr);
				v6tov4(h4->tcpdst, s->raddr);
				break;
			case V6:
				h6 = &tcb->protohdr.tcp6hdr;
				memset(h6, 0, sizeof(*h6));
				h6->proto = IP_TCPPROTO;
				hnputs(h6->tcpsport, s->lport);
				hnputs(h6->tcpdport, s->rport);
				ipmove(h6->tcpsrc, s->laddr);
				ipmove(h6->tcpdst, s->raddr);
				mss = DEF_MSS6;
				break;
			default:
				panic("inittcpctl: version %d", s->ipversion);
		}
	}

	tcb->ifc = findipifc(s->p->f, s->laddr, 0);
	tcb->mss = mss;
	tcb->typical_mss = mss;
	tcb->cwind = tcb->typical_mss * CWIND_SCALE;

	/* default is no window scaling */
	tcb->window = QMAX;
	tcb->rcv.wnd = QMAX;
	tcb->rcv.scale = 0;
	tcb->snd.scale = 0;
	tcb_check_tso(tcb);
}

/*
 *  called with s qlocked
 */
static void tcpstart(struct conv *s, int mode)
{
	Tcpctl *tcb;
	struct tcppriv *tpriv;
	char *kpname;

	tpriv = s->p->priv;

	if (tpriv->ackprocstarted == 0) {
		qlock(&tpriv->apl);
		if (tpriv->ackprocstarted == 0) {
			/* tcpackproc needs to free this if it ever exits */
			kpname = kmalloc(KNAMELEN, MEM_WAIT);
			snprintf(kpname, KNAMELEN, "#I%dtcpack", s->p->f->dev);
			ktask(kpname, tcpackproc, s->p);
			tpriv->ackprocstarted = 1;
		}
		qunlock(&tpriv->apl);
	}

	tcb = (Tcpctl *) s->ptcl;

	inittcpctl(s, mode);

	iphtadd(&tpriv->ht, s);
	switch (mode) {
		case TCP_LISTEN:
			tpriv->stats[PassiveOpens]++;
			tcb->flags |= CLONE;
			tcpsetstate(s, Listen);
			break;

		case TCP_CONNECT:
			tpriv->stats[ActiveOpens]++;
			tcb->flags |= ACTIVE;
			tcpsndsyn(s, tcb);
			tcpsetstate(s, Syn_sent);
			tcpoutput(s);
			break;
	}
}

static char *tcpflag(uint16_t flag)
{
	static char buf[128];

	snprintf(buf, sizeof(buf), "%d", flag >> 10);	/* Head len */
	if (flag & URG)
		snprintf(buf, sizeof(buf), "%s%s", buf, " URG");
	if (flag & ACK)
		snprintf(buf, sizeof(buf), "%s%s", buf, " ACK");
	if (flag & PSH)
		snprintf(buf, sizeof(buf), "%s%s", buf, " PSH");
	if (flag & RST)
		snprintf(buf, sizeof(buf), "%s%s", buf, " RST");
	if (flag & SYN)
		snprintf(buf, sizeof(buf), "%s%s", buf, " SYN");
	if (flag & FIN)
		snprintf(buf, sizeof(buf), "%s%s", buf, " FIN");

	return buf;
}

/* Helper, determine if we should send a TCP timestamp.  ts_val was the
 * timestamp from our distant end.  We'll also send a TS on SYN (no ACK). */
static bool tcp_seg_has_ts(Tcp *tcph)
{
	return tcph->ts_val || ((tcph->flags & SYN) && !(tcph->flags & ACK));
}

/* Given a TCP header/segment and default header size (e.g. TCP4_HDRSIZE),
 * return the actual hdr_len and opt_pad */
static void compute_hdrlen_optpad(Tcp *tcph, uint16_t default_hdrlen,
                                  uint16_t *ret_hdrlen, uint16_t *ret_optpad,
                                  Tcpctl *tcb)
{
	uint16_t hdrlen = default_hdrlen;
	uint16_t optpad = 0;

	if (tcph->flags & SYN) {
		if (tcph->mss)
			hdrlen += MSS_LENGTH;
		if (tcph->ws)
			hdrlen += WS_LENGTH;
		if (tcph->sack_ok)
			hdrlen += SACK_OK_LENGTH;
	}
	if (tcp_seg_has_ts(tcph)) {
		hdrlen += TS_LENGTH;
		/* SYNs have other opts, don't do the PREPAD NOOP optimization. */
		if (!(tcph->flags & SYN))
			hdrlen += TS_SEND_PREPAD;
	}
	if (tcb && tcb->rcv.nr_sacks)
		hdrlen += 2 + tcb->rcv.nr_sacks * 8;
	optpad = hdrlen & 3;
	if (optpad)
		optpad = 4 - optpad;
	hdrlen += optpad;
	*ret_hdrlen = hdrlen;
	*ret_optpad = optpad;
}

/* Writes the TCP options for tcph to opt. */
static void write_opts(Tcp *tcph, uint8_t *opt, uint16_t optpad, Tcpctl *tcb)
{
	if (tcph->flags & SYN) {
		if (tcph->mss != 0) {
			*opt++ = MSSOPT;
			*opt++ = MSS_LENGTH;
			hnputs(opt, tcph->mss);
			opt += 2;
		}
		if (tcph->ws != 0) {
			*opt++ = WSOPT;
			*opt++ = WS_LENGTH;
			*opt++ = tcph->ws;
		}
		if (tcph->sack_ok) {
			*opt++ = SACK_OK_OPT;
			*opt++ = SACK_OK_LENGTH;
		}
	}
	if (tcp_seg_has_ts(tcph)) {
		if (!(tcph->flags & SYN)) {
			*opt++ = NOOPOPT;
			*opt++ = NOOPOPT;
		}
		*opt++ = TS_OPT;
		*opt++ = TS_LENGTH;
		/* Setting TSval, our time */
		hnputl(opt, milliseconds());
		opt += 4;
		/* Setting TSecr, the time we last saw from them, stored in ts_val */
		hnputl(opt, tcph->ts_val);
		opt += 4;
	}
	if (tcb && tcb->rcv.nr_sacks) {
		*opt++ = SACK_OPT;
		*opt++ = 2 + tcb->rcv.nr_sacks * 8;
		for (int i = 0; i < tcb->rcv.nr_sacks; i++) {
			hnputl(opt, tcb->rcv.sacks[i].left);
			opt += 4;
			hnputl(opt, tcb->rcv.sacks[i].right);
			opt += 4;
		}
	}
	while (optpad-- > 0)
		*opt++ = NOOPOPT;
}

/* Given a data block (or NULL) returns a block with enough header room that we
 * can send out.  block->wp is set to the beginning of the payload.  Returns
 * NULL on some sort of error. */
static struct block *alloc_or_pad_block(struct block *data,
                                        uint16_t total_hdr_size)
{
	if (data) {
		data = padblock(data, total_hdr_size);
		if (data == NULL)
			return NULL;
	} else {
		/* the 64 pad is to meet mintu's */
		data = block_alloc(total_hdr_size + 64, MEM_WAIT);
		if (data == NULL)
			return NULL;
		data->wp += total_hdr_size;
	}
	return data;
}

static struct block *htontcp6(Tcp *tcph, struct block *data, Tcp6hdr *ph,
                              Tcpctl *tcb)
{
	int dlen = blocklen(data);
	Tcp6hdr *h;
	uint16_t csum;
	uint16_t hdrlen, optpad;

	compute_hdrlen_optpad(tcph, TCP6_HDRSIZE, &hdrlen, &optpad, tcb);

	data = alloc_or_pad_block(data, hdrlen + TCP6_PKT);
	if (data == NULL)
		return NULL;
	/* relative to the block start (bp->rp).  Note TCP structs include IP. */
	data->network_offset = 0;
	data->transport_offset = offsetof(Tcp6hdr, tcpsport);

	/* copy in pseudo ip header plus port numbers */
	h = (Tcp6hdr *) (data->rp);
	memmove(h, ph, TCP6_TCBPHDRSZ);

	/* compose pseudo tcp header, do cksum calculation */
	hnputl(h->vcf, hdrlen + dlen);
	h->ploadlen[0] = h->ploadlen[1] = h->proto = 0;
	h->ttl = ph->proto;

	/* copy in variable bits */
	hnputl(h->tcpseq, tcph->seq);
	hnputl(h->tcpack, tcph->ack);
	hnputs(h->tcpflag, (hdrlen << 10) | tcph->flags);
	hnputs(h->tcpwin, tcph->wnd >> (tcb != NULL ? tcb->snd.scale : 0));
	hnputs(h->tcpurg, tcph->urg);

	write_opts(tcph, h->tcpopt, optpad, tcb);

	if (tcb != NULL && tcb->nochecksum) {
		h->tcpcksum[0] = h->tcpcksum[1] = 0;
	} else {
		csum = ptclcsum(data, TCP6_IPLEN, hdrlen + dlen + TCP6_PHDRSIZE);
		hnputs(h->tcpcksum, csum);
	}

	/* move from pseudo header back to normal ip header */
	memset(h->vcf, 0, 4);
	h->vcf[0] = IP_VER6;
	hnputs(h->ploadlen, hdrlen + dlen);
	h->proto = ph->proto;

	return data;
}

static struct block *htontcp4(Tcp *tcph, struct block *data, Tcp4hdr *ph,
                              Tcpctl *tcb)
{
	int dlen = blocklen(data);
	Tcp4hdr *h;
	uint16_t csum;
	uint16_t hdrlen, optpad;

	compute_hdrlen_optpad(tcph, TCP4_HDRSIZE, &hdrlen, &optpad, tcb);

	data = alloc_or_pad_block(data, hdrlen + TCP4_PKT);
	if (data == NULL)
		return NULL;
	/* relative to the block start (bp->rp).  Note TCP structs include IP. */
	data->network_offset = 0;
	data->transport_offset = offsetof(Tcp4hdr, tcpsport);

	/* copy in pseudo ip header plus port numbers */
	h = (Tcp4hdr *) (data->rp);
	memmove(h, ph, TCP4_TCBPHDRSZ);

	/* copy in variable bits */
	hnputs(h->tcplen, hdrlen + dlen);
	hnputl(h->tcpseq, tcph->seq);
	hnputl(h->tcpack, tcph->ack);
	hnputs(h->tcpflag, (hdrlen << 10) | tcph->flags);
	hnputs(h->tcpwin, tcph->wnd >> (tcb != NULL ? tcb->snd.scale : 0));
	hnputs(h->tcpurg, tcph->urg);

	write_opts(tcph, h->tcpopt, optpad, tcb);

	if (tcb != NULL && tcb->nochecksum) {
		h->tcpcksum[0] = h->tcpcksum[1] = 0;
	} else {
		assert(data->transport_offset == TCP4_IPLEN + TCP4_PHDRSIZE);
		csum = ~ptclcsum(data, TCP4_IPLEN, TCP4_PHDRSIZE);
		hnputs(h->tcpcksum, csum);
		data->tx_csum_offset = ph->tcpcksum - ph->tcpsport;
		data->flag |= Btcpck;
	}

	return data;
}

static void parse_inbound_sacks(Tcp *tcph, uint8_t *opt, uint16_t optlen)
{
	uint8_t nr_sacks;
	uint32_t left, right;

	nr_sacks = (optlen - 2) / 8;
	if (nr_sacks > MAX_NR_SACKS_PER_PACKET)
		return;
	opt += 2;
	for (int i = 0; i < nr_sacks; i++, opt += 8) {
		left = nhgetl(opt);
		right = nhgetl(opt + 4);
		if (seq_ge(left, right)) {
			/* bad / malicious SACK.  Skip it, and adjust. */
			nr_sacks--;
			i--;	/* stay on this array element next loop */
			continue;
		}
		tcph->sacks[i].left = left;
		tcph->sacks[i].right = right;
	}
	tcph->nr_sacks = nr_sacks;
}

static void parse_inbound_opts(Tcp *tcph, uint8_t *opt, uint16_t optsize)
{
	uint16_t optlen;

	while (optsize > 0 && *opt != EOLOPT) {
		if (*opt == NOOPOPT) {
			optsize--;
			opt++;
			continue;
		}
		optlen = opt[1];
		if (optlen < 2 || optlen > optsize)
			break;
		switch (*opt) {
			case MSSOPT:
				if (optlen == MSS_LENGTH)
					tcph->mss = nhgets(opt + 2);
				break;
			case WSOPT:
				if (optlen == WS_LENGTH && *(opt + 2) <= MAX_WS_VALUE)
					tcph->ws = HaveWS | *(opt + 2);
				break;
			case SACK_OK_OPT:
				if (optlen == SACK_OK_LENGTH)
					tcph->sack_ok = TRUE;
				break;
			case SACK_OPT:
				parse_inbound_sacks(tcph, opt, optlen);
				break;
			case TS_OPT:
				if (optlen == TS_LENGTH) {
					tcph->ts_val = nhgetl(opt + 2);
					tcph->ts_ecr = nhgetl(opt + 6);
				}
				break;
		}
		optsize -= optlen;
		opt += optlen;
	}
}

/* Helper, clears the opts.  We'll later set them with e.g. parse_inbound_opts,
 * set them manually, or something else. */
static void clear_tcph_opts(Tcp *tcph)
{
	tcph->mss = 0;
	tcph->ws = 0;
	tcph->sack_ok = FALSE;
	tcph->nr_sacks = 0;
	tcph->ts_val = 0;
	tcph->ts_ecr = 0;
}

static int ntohtcp6(Tcp *tcph, struct block **bpp)
{
	Tcp6hdr *h;
	uint16_t hdrlen;

	*bpp = pullupblock(*bpp, TCP6_PKT + TCP6_HDRSIZE);
	if (*bpp == NULL)
		return -1;

	h = (Tcp6hdr *) ((*bpp)->rp);
	tcph->source = nhgets(h->tcpsport);
	tcph->dest = nhgets(h->tcpdport);
	tcph->seq = nhgetl(h->tcpseq);
	tcph->ack = nhgetl(h->tcpack);
	hdrlen = (h->tcpflag[0] >> 2) & ~3;
	if (hdrlen < TCP6_HDRSIZE) {
		freeblist(*bpp);
		return -1;
	}

	tcph->flags = h->tcpflag[1];
	tcph->wnd = nhgets(h->tcpwin);
	tcph->urg = nhgets(h->tcpurg);
	clear_tcph_opts(tcph);
	tcph->len = nhgets(h->ploadlen) - hdrlen;

	*bpp = pullupblock(*bpp, hdrlen + TCP6_PKT);
	if (*bpp == NULL)
		return -1;
	parse_inbound_opts(tcph, h->tcpopt, hdrlen - TCP6_HDRSIZE);
	return hdrlen;
}

static int ntohtcp4(Tcp *tcph, struct block **bpp)
{
	Tcp4hdr *h;
	uint16_t hdrlen;

	*bpp = pullupblock(*bpp, TCP4_PKT + TCP4_HDRSIZE);
	if (*bpp == NULL)
		return -1;

	h = (Tcp4hdr *) ((*bpp)->rp);
	tcph->source = nhgets(h->tcpsport);
	tcph->dest = nhgets(h->tcpdport);
	tcph->seq = nhgetl(h->tcpseq);
	tcph->ack = nhgetl(h->tcpack);

	hdrlen = (h->tcpflag[0] >> 2) & ~3;
	if (hdrlen < TCP4_HDRSIZE) {
		freeblist(*bpp);
		return -1;
	}

	tcph->flags = h->tcpflag[1];
	tcph->wnd = nhgets(h->tcpwin);
	tcph->urg = nhgets(h->tcpurg);
	clear_tcph_opts(tcph);
	tcph->len = nhgets(h->length) - (hdrlen + TCP4_PKT);

	*bpp = pullupblock(*bpp, hdrlen + TCP4_PKT);
	if (*bpp == NULL)
		return -1;
	parse_inbound_opts(tcph, h->tcpopt, hdrlen - TCP4_HDRSIZE);
	return hdrlen;
}

/*
 *  For outgoing calls, generate an initial sequence
 *  number and put a SYN on the send queue
 */
static void tcpsndsyn(struct conv *s, Tcpctl *tcb)
{
	urandom_read(&tcb->iss, sizeof(tcb->iss));
	tcb->rttseq = tcb->iss;
	tcb->snd.wl2 = tcb->iss;
	tcb->snd.una = tcb->iss;
	tcb->snd.rtx = tcb->rttseq;
	tcb->snd.nxt = tcb->rttseq;
	tcb->flgcnt++;
	tcb->flags |= FORCE;
	tcb->sndsyntime = NOW;

	/* set desired mss and scale */
	tcb->mss = tcpmtu(tcb->ifc, s->ipversion, &tcb->scale);
}

static void sndrst(struct Proto *tcp, uint8_t *source, uint8_t *dest,
                   uint16_t length, Tcp *seg, uint8_t version, char *reason)
{
	struct block *hbp;
	uint8_t rflags;
	struct tcppriv *tpriv;
	Tcp4hdr ph4;
	Tcp6hdr ph6;

	netlog(tcp->f, Logtcpreset, "sndrst: %s\n", reason);

	tpriv = tcp->priv;

	if (seg->flags & RST)
		return;

	/* make pseudo header */
	switch (version) {
		case V4:
			memset(&ph4, 0, sizeof(ph4));
			ph4.vihl = IP_VER4;
			v6tov4(ph4.tcpsrc, dest);
			v6tov4(ph4.tcpdst, source);
			ph4.proto = IP_TCPPROTO;
			hnputs(ph4.tcplen, TCP4_HDRSIZE);
			hnputs(ph4.tcpsport, seg->dest);
			hnputs(ph4.tcpdport, seg->source);
			break;
		case V6:
			memset(&ph6, 0, sizeof(ph6));
			ph6.vcf[0] = IP_VER6;
			ipmove(ph6.tcpsrc, dest);
			ipmove(ph6.tcpdst, source);
			ph6.proto = IP_TCPPROTO;
			hnputs(ph6.ploadlen, TCP6_HDRSIZE);
			hnputs(ph6.tcpsport, seg->dest);
			hnputs(ph6.tcpdport, seg->source);
			break;
		default:
			panic("sndrst: version %d", version);
	}

	tpriv->stats[OutRsts]++;
	rflags = RST;

	/* convince the other end that this reset is in band */
	if (seg->flags & ACK) {
		seg->seq = seg->ack;
		seg->ack = 0;
	} else {
		rflags |= ACK;
		seg->ack = seg->seq;
		seg->seq = 0;
		if (seg->flags & SYN)
			seg->ack++;
		seg->ack += length;
		if (seg->flags & FIN)
			seg->ack++;
	}
	seg->flags = rflags;
	seg->wnd = 0;
	seg->urg = 0;
	seg->mss = 0;
	seg->ws = 0;
	seg->sack_ok = FALSE;
	seg->nr_sacks = 0;
	/* seg->ts_val is already set with their timestamp */
	switch (version) {
		case V4:
			hbp = htontcp4(seg, NULL, &ph4, NULL);
			if (hbp == NULL)
				return;
			ipoput4(tcp->f, hbp, 0, MAXTTL, DFLTTOS, NULL);
			break;
		case V6:
			hbp = htontcp6(seg, NULL, &ph6, NULL);
			if (hbp == NULL)
				return;
			ipoput6(tcp->f, hbp, 0, MAXTTL, DFLTTOS, NULL);
			break;
		default:
			panic("sndrst2: version %d", version);
	}
}

/*
 *  send a reset to the remote side and close the conversation
 *  called with s qlocked
 */
static void tcphangup(struct conv *s)
{
	ERRSTACK(1);
	Tcp seg;
	Tcpctl *tcb;
	struct block *hbp;

	tcb = (Tcpctl *) s->ptcl;
	if (ipcmp(s->raddr, IPnoaddr)) {
		/* discard error style, poperror regardless */
		if (!waserror()) {
			seg.flags = RST | ACK;
			seg.ack = tcb->rcv.nxt;
			tcb->last_ack_sent = seg.ack;
			tcb->rcv.una = 0;
			seg.seq = tcb->snd.nxt;
			seg.wnd = 0;
			seg.urg = 0;
			seg.mss = 0;
			seg.ws = 0;
			seg.sack_ok = FALSE;
			seg.nr_sacks = 0;
			seg.ts_val = tcb->ts_recent;
			switch (s->ipversion) {
				case V4:
					tcb->protohdr.tcp4hdr.vihl = IP_VER4;
					hbp = htontcp4(&seg, NULL, &tcb->protohdr.tcp4hdr, tcb);
					ipoput4(s->p->f, hbp, 0, s->ttl, s->tos, s);
					break;
				case V6:
					tcb->protohdr.tcp6hdr.vcf[0] = IP_VER6;
					hbp = htontcp6(&seg, NULL, &tcb->protohdr.tcp6hdr, tcb);
					ipoput6(s->p->f, hbp, 0, s->ttl, s->tos, s);
					break;
				default:
					panic("tcphangup: version %d", s->ipversion);
			}
		}
		poperror();
	}
	localclose(s, NULL);
}

/*
 *  (re)send a SYN ACK
 */
static int sndsynack(struct Proto *tcp, Limbo *lp)
{
	struct block *hbp;
	Tcp4hdr ph4;
	Tcp6hdr ph6;
	Tcp seg;
	int scale;
	uint8_t flag = 0;

	/* make pseudo header */
	switch (lp->version) {
		case V4:
			memset(&ph4, 0, sizeof(ph4));
			ph4.vihl = IP_VER4;
			v6tov4(ph4.tcpsrc, lp->laddr);
			v6tov4(ph4.tcpdst, lp->raddr);
			ph4.proto = IP_TCPPROTO;
			hnputs(ph4.tcplen, TCP4_HDRSIZE);
			hnputs(ph4.tcpsport, lp->lport);
			hnputs(ph4.tcpdport, lp->rport);
			break;
		case V6:
			memset(&ph6, 0, sizeof(ph6));
			ph6.vcf[0] = IP_VER6;
			ipmove(ph6.tcpsrc, lp->laddr);
			ipmove(ph6.tcpdst, lp->raddr);
			ph6.proto = IP_TCPPROTO;
			hnputs(ph6.ploadlen, TCP6_HDRSIZE);
			hnputs(ph6.tcpsport, lp->lport);
			hnputs(ph6.tcpdport, lp->rport);
			break;
		default:
			panic("sndrst: version %d", lp->version);
	}
	lp->ifc = findipifc(tcp->f, lp->laddr, 0);

	seg.seq = lp->iss;
	seg.ack = lp->irs + 1;
	seg.flags = SYN | ACK;
	seg.urg = 0;
	seg.mss = tcpmtu(lp->ifc, lp->version, &scale);
	seg.wnd = QMAX;
	seg.ts_val = lp->ts_val;
	seg.nr_sacks = 0;

	/* if the other side set scale, we should too */
	if (lp->rcvscale) {
		seg.ws = scale;
		lp->sndscale = scale;
	} else {
		seg.ws = 0;
		lp->sndscale = 0;
	}
	if (SACK_SUPPORTED)
		seg.sack_ok = lp->sack_ok;
	else
		seg.sack_ok = FALSE;

	switch (lp->version) {
		case V4:
			hbp = htontcp4(&seg, NULL, &ph4, NULL);
			if (hbp == NULL)
				return -1;
			ipoput4(tcp->f, hbp, 0, MAXTTL, DFLTTOS, NULL);
			break;
		case V6:
			hbp = htontcp6(&seg, NULL, &ph6, NULL);
			if (hbp == NULL)
				return -1;
			ipoput6(tcp->f, hbp, 0, MAXTTL, DFLTTOS, NULL);
			break;
		default:
			panic("sndsnack: version %d", lp->version);
	}
	lp->lastsend = NOW;
	return 0;
}

#define hashipa(a, p) ( ( (a)[IPaddrlen-2] + (a)[IPaddrlen-1] + p )&LHTMASK )

/*
 *  put a call into limbo and respond with a SYN ACK
 *
 *  called with proto locked
 */
static void limbo(struct conv *s, uint8_t *source, uint8_t *dest, Tcp *seg,
                  int version)
{
	Limbo *lp, **l;
	struct tcppriv *tpriv;
	int h;

	tpriv = s->p->priv;
	h = hashipa(source, seg->source);

	for (l = &tpriv->lht[h]; *l != NULL; l = &lp->next) {
		lp = *l;
		if (lp->lport != seg->dest || lp->rport != seg->source
			|| lp->version != version)
			continue;
		if (ipcmp(lp->raddr, source) != 0)
			continue;
		if (ipcmp(lp->laddr, dest) != 0)
			continue;

		/* each new SYN restarts the retransmits */
		lp->irs = seg->seq;
		break;
	}
	lp = *l;
	if (lp == NULL) {
		if (tpriv->nlimbo >= Maxlimbo && tpriv->lht[h]) {
			lp = tpriv->lht[h];
			tpriv->lht[h] = lp->next;
			lp->next = NULL;
		} else {
			lp = kzmalloc(sizeof(*lp), 0);
			if (lp == NULL)
				return;
			tpriv->nlimbo++;
		}
		*l = lp;
		lp->version = version;
		ipmove(lp->laddr, dest);
		ipmove(lp->raddr, source);
		lp->lport = seg->dest;
		lp->rport = seg->source;
		lp->mss = seg->mss;
		lp->rcvscale = seg->ws;
		lp->sack_ok = seg->sack_ok;
		lp->irs = seg->seq;
		lp->ts_val = seg->ts_val;
		urandom_read(&lp->iss, sizeof(lp->iss));
	}

	if (sndsynack(s->p, lp) < 0) {
		*l = lp->next;
		tpriv->nlimbo--;
		kfree(lp);
	}
}

/*
 *  resend SYN ACK's once every SYNACK_RXTIMER ms.
 */
static void limborexmit(struct Proto *tcp)
{
	struct tcppriv *tpriv;
	Limbo **l, *lp;
	int h;
	int seen;
	uint64_t now;

	tpriv = tcp->priv;

	if (!canqlock(&tcp->qlock))
		return;
	seen = 0;
	now = NOW;
	for (h = 0; h < NLHT && seen < tpriv->nlimbo; h++) {
		for (l = &tpriv->lht[h]; *l != NULL && seen < tpriv->nlimbo;) {
			lp = *l;
			seen++;
			if (now - lp->lastsend < (lp->rexmits + 1) * SYNACK_RXTIMER)
				continue;

			/* time it out after 1 second */
			if (++(lp->rexmits) > 5) {
				tpriv->nlimbo--;
				*l = lp->next;
				kfree(lp);
				continue;
			}

			/* if we're being attacked, don't bother resending SYN ACK's */
			if (tpriv->nlimbo > 100)
				continue;

			if (sndsynack(tcp, lp) < 0) {
				tpriv->nlimbo--;
				*l = lp->next;
				kfree(lp);
				continue;
			}

			l = &lp->next;
		}
	}
	qunlock(&tcp->qlock);
}

/*
 *  lookup call in limbo.  if found, throw it out.
 *
 *  called with proto locked
 */
static void limborst(struct conv *s, Tcp *segp, uint8_t *src, uint8_t *dst,
                     uint8_t version)
{
	Limbo *lp, **l;
	int h;
	struct tcppriv *tpriv;

	tpriv = s->p->priv;

	/* find a call in limbo */
	h = hashipa(src, segp->source);
	for (l = &tpriv->lht[h]; *l != NULL; l = &lp->next) {
		lp = *l;
		if (lp->lport != segp->dest || lp->rport != segp->source
			|| lp->version != version)
			continue;
		if (ipcmp(lp->laddr, dst) != 0)
			continue;
		if (ipcmp(lp->raddr, src) != 0)
			continue;

		/* RST can only follow the SYN */
		if (segp->seq == lp->irs + 1) {
			tpriv->nlimbo--;
			*l = lp->next;
			kfree(lp);
		}
		break;
	}
}

/* The advertised MSS (e.g. 1460) includes any per-packet TCP options, such as
 * TCP timestamps.  A given packet will contain mss bytes, but only typical_mss
 * bytes of *data*.  If we know we'll use those options, we should adjust our
 * typical_mss, which will affect the cwnd. */
static void adjust_typical_mss_for_opts(Tcp *tcph, Tcpctl *tcb)
{
	uint16_t opt_size = 0;

	if (tcph->ts_val)
		opt_size += TS_LENGTH + TS_SEND_PREPAD;
	opt_size = ROUNDUP(opt_size, 4);
	tcb->typical_mss -= opt_size;
}

/*
 *  come here when we finally get an ACK to our SYN-ACK.
 *  lookup call in limbo.  if found, create a new conversation
 *
 *  called with proto locked
 */
static struct conv *tcpincoming(struct conv *s, Tcp *segp, uint8_t *src,
								uint8_t *dst, uint8_t version)
{
	struct conv *new;
	Tcpctl *tcb;
	struct tcppriv *tpriv;
	Tcp4hdr *h4;
	Tcp6hdr *h6;
	Limbo *lp, **l;
	int h;

	/* unless it's just an ack, it can't be someone coming out of limbo */
	if ((segp->flags & SYN) || (segp->flags & ACK) == 0)
		return NULL;

	tpriv = s->p->priv;

	/* find a call in limbo */
	h = hashipa(src, segp->source);
	for (l = &tpriv->lht[h]; (lp = *l) != NULL; l = &lp->next) {
		netlog(s->p->f, Logtcp,
			   "tcpincoming s %I!%d/%I!%d d %I!%d/%I!%d v %d/%d\n", src,
			   segp->source, lp->raddr, lp->rport, dst, segp->dest, lp->laddr,
			   lp->lport, version, lp->version);

		if (lp->lport != segp->dest || lp->rport != segp->source
			|| lp->version != version)
			continue;
		if (ipcmp(lp->laddr, dst) != 0)
			continue;
		if (ipcmp(lp->raddr, src) != 0)
			continue;

		/* we're assuming no data with the initial SYN */
		if (segp->seq != lp->irs + 1 || segp->ack != lp->iss + 1) {
			netlog(s->p->f, Logtcp, "tcpincoming s 0x%lx/0x%lx a 0x%lx 0x%lx\n",
				   segp->seq, lp->irs + 1, segp->ack, lp->iss + 1);
			lp = NULL;
		} else {
			tpriv->nlimbo--;
			*l = lp->next;
		}
		break;
	}
	if (lp == NULL)
		return NULL;

	new = Fsnewcall(s, src, segp->source, dst, segp->dest, version);
	if (new == NULL)
		return NULL;

	memmove(new->ptcl, s->ptcl, sizeof(Tcpctl));
	tcb = (Tcpctl *) new->ptcl;
	tcb->flags &= ~CLONE;
	tcb->timer.arg = new;
	tcb->timer.state = TcptimerOFF;
	tcb->acktimer.arg = new;
	tcb->acktimer.state = TcptimerOFF;
	tcb->katimer.arg = new;
	tcb->katimer.state = TcptimerOFF;
	tcb->rtt_timer.arg = new;
	tcb->rtt_timer.state = TcptimerOFF;

	tcb->irs = lp->irs;
	tcb->rcv.nxt = tcb->irs + 1;
	tcb->rcv.urg = tcb->rcv.nxt;

	tcb->iss = lp->iss;
	tcb->rttseq = tcb->iss;
	tcb->snd.wl2 = tcb->iss;
	tcb->snd.una = tcb->iss + 1;
	tcb->snd.rtx = tcb->iss + 1;
	tcb->snd.nxt = tcb->iss + 1;
	tcb->flgcnt = 0;
	tcb->flags |= SYNACK;

	/* our sending max segment size cannot be bigger than what he asked for */
	if (lp->mss != 0 && lp->mss < tcb->mss) {
		tcb->mss = lp->mss;
		tcb->typical_mss = tcb->mss;
	}
	adjust_typical_mss_for_opts(segp, tcb);

	/* Here's where we record the previously-decided header options.  They were
	 * actually decided on when we agreed to them in the SYNACK we sent.  We
	 * didn't create an actual TCB until now, so we can copy those decisions out
	 * of the limbo tracker and into the TCB. */
	tcb->ifc = lp->ifc;
	tcb->sack_ok = lp->sack_ok;
	/* window scaling */
	tcpsetscale(new, tcb, lp->rcvscale, lp->sndscale);
	tcb_check_tso(tcb);

	tcb->snd.wnd = segp->wnd;
	tcb->cwind = tcb->typical_mss * CWIND_SCALE;

	/* set initial round trip time */
	tcb->sndsyntime = lp->lastsend + lp->rexmits * SYNACK_RXTIMER;
	tcpsynackrtt(new);

	kfree(lp);

	/* set up proto header */
	switch (version) {
		case V4:
			h4 = &tcb->protohdr.tcp4hdr;
			memset(h4, 0, sizeof(*h4));
			h4->proto = IP_TCPPROTO;
			hnputs(h4->tcpsport, new->lport);
			hnputs(h4->tcpdport, new->rport);
			v6tov4(h4->tcpsrc, dst);
			v6tov4(h4->tcpdst, src);
			break;
		case V6:
			h6 = &tcb->protohdr.tcp6hdr;
			memset(h6, 0, sizeof(*h6));
			h6->proto = IP_TCPPROTO;
			hnputs(h6->tcpsport, new->lport);
			hnputs(h6->tcpdport, new->rport);
			ipmove(h6->tcpsrc, dst);
			ipmove(h6->tcpdst, src);
			break;
		default:
			panic("tcpincoming: version %d", new->ipversion);
	}

	tcpsetstate(new, Established);

	iphtadd(&tpriv->ht, new);

	return new;
}

/*
 *  use the time between the first SYN and it's ack as the
 *  initial round trip time
 */
static void tcpsynackrtt(struct conv *s)
{
	Tcpctl *tcb;
	uint64_t delta;
	struct tcppriv *tpriv;

	tcb = (Tcpctl *) s->ptcl;
	tpriv = s->p->priv;

	delta = NOW - tcb->sndsyntime;
	tcb->srtt = delta;
	tcb->mdev = delta / 2;

	/* halt round trip timer */
	tcphalt(tpriv, &tcb->rtt_timer);
}

/* For LFNs (long/fat), our default tx queue doesn't hold enough data, and TCP
 * blocks on the application - even if the app already has the data ready to go.
 * We need to hold the sent, unacked data (1x cwnd), plus all the data we might
 * send next RTT (1x cwnd).  Note this is called after cwnd was expanded. */
static void adjust_tx_qio_limit(struct conv *s)
{
	Tcpctl *tcb = (Tcpctl *) s->ptcl;
	size_t ideal_limit = tcb->cwind * 2;

	/* This is called for every ACK, and it's not entirely free to update the
	 * limit (locks, CVs, taps).  Updating in chunks of mss seems reasonable.
	 * During SS, we'll update this on most ACKs (given each ACK increased the
	 * cwind by > MSS).
	 *
	 * We also don't want a lot of tiny blocks from the user, but the way qio
	 * works, you can put in as much as you want (Maxatomic) and then get
	 * flow-controlled. */
	if (qgetlimit(s->wq) + tcb->typical_mss < ideal_limit)
		qsetlimit(s->wq, ideal_limit);
	/* TODO: we could shrink the qio limit too, if we had a better idea what the
	 * actual threshold was.  We want the limit to be the 'stable' cwnd * 2. */
}

/* Attempts to merge later sacks into sack 'into' (index in the array) */
static void merge_sacks_into(Tcpctl *tcb, int into)
{
	struct sack_block *into_sack = &tcb->snd.sacks[into];
	struct sack_block *tcb_sack;
	int shift = 0;

	for (int i = into + 1; i < tcb->snd.nr_sacks; i++) {
		tcb_sack = &tcb->snd.sacks[i];
		if (seq_lt(into_sack->right, tcb_sack->left))
			break;
		if (seq_gt(tcb_sack->right, into_sack->right))
			into_sack->right = tcb_sack->right;
		shift++;
	}
	if (shift) {
		memmove(tcb->snd.sacks + into + 1,
		        tcb->snd.sacks + into + 1 + shift,
		        sizeof(struct sack_block) * (tcb->snd.nr_sacks - into - 1
				                             - shift));
		tcb->snd.nr_sacks -= shift;
	}
}

/* If we update a sack, it means they received a packet (possibly out of order),
 * but they have not received earlier packets.  Otherwise, they would do a full
 * ACK.
 *
 * The trick is in knowing whether the reception growing this sack is due to a
 * retrans or due to packets from before our last loss event.  The rightmost
 * sack tends to grow a lot with packets we sent before the loss.  However,
 * intermediate sacks that grow are signs of a loss, since they only grow as a
 * result of retrans.
 *
 * This is only true for the first time through a retrans.  After we've gone
 * through a full retrans blast, the sack that hinted at the retrans loss (and
 * there could be multiple of them!) will continue to grow.  We could come up
 * with some tracking for this, but instead we'll just do a one-time deal.  You
 * can recover from one detected sack retrans loss.  After that, you'll have to
 * use the RTO.
 *
 * This won't catch some things, like a sack that grew and merged with the
 * rightmost sack.  This also won't work if you have a single sack.  We can't
 * tell where the retrans ends and the sending begins. */
static bool sack_hints_at_loss(Tcpctl *tcb, struct sack_block *tcb_sack)
{
	if (tcb->snd.recovery != SACK_RETRANS_RECOVERY)
		return FALSE;
	return &tcb->snd.sacks[tcb->snd.nr_sacks - 1] != tcb_sack;
}

static bool sack_contains(struct sack_block *tcb_sack, uint32_t seq)
{
	return seq_le(tcb_sack->left, seq) && seq_lt(seq, tcb_sack->right);
}

/* Debugging helper! */
static void sack_asserter(Tcpctl *tcb, char *str)
{
	struct sack_block *tcb_sack;

	for (int i = 0; i < tcb->snd.nr_sacks; i++) {
		tcb_sack = &tcb->snd.sacks[i];
		/* Checking invariants: snd.rtx is never inside a sack, sacks are always
		 * mutually exclusive. */
		if (sack_contains(tcb_sack, tcb->snd.rtx) ||
		    ((i + 1 < tcb->snd.nr_sacks) && seq_ge(tcb_sack->right,
			                                       (tcb_sack + 1)->left))) {
			printk("SACK ASSERT ERROR at %s\n", str);
			printk("rtx %u una %u nxt %u, sack [%u, %u)\n",
			       tcb->snd.rtx, tcb->snd.una, tcb->snd.nxt, tcb_sack->left,
				   tcb_sack->right);
			for (int i = 0; i < tcb->snd.nr_sacks; i++)
				printk("\t %d: [%u, %u)\n", i, tcb->snd.sacks[i].left,
				       tcb->snd.sacks[i].right);
			backtrace();
			panic("");
		}
	}
}

/* Updates bookkeeping whenever a sack is added or updated */
static void sack_has_changed(struct conv *s, Tcpctl *tcb,
                             struct sack_block *tcb_sack)
{
	/* Due to the change, snd.rtx might be in the middle of this sack.  Advance
	 * it to the right edge. */
	if (sack_contains(tcb_sack, tcb->snd.rtx))
		tcb->snd.rtx = tcb_sack->right;

	/* This is a sack for something we retransed and we think it means there was
	 * another loss.  Instead of waiting for the RTO, we can take action. */
	if (sack_hints_at_loss(tcb, tcb_sack)) {
		if (++tcb->snd.sack_loss_hint == TCPREXMTTHRESH) {
			netlog(s->p->f, Logtcprxmt,
			       "%I.%d -> %I.%d: sack rxmit loss: snd.rtx %u, sack [%u,%u), una %u, recovery_pt %u\n",
			       s->laddr, s->lport, s->raddr, s->rport,
			       tcb->snd.rtx, tcb_sack->left, tcb_sack->right, tcb->snd.una,
			       tcb->snd.recovery_pt);
			/* Redo retrans, but keep the sacks and recovery point */
			tcp_loss_event(s, tcb);
			tcb->snd.rtx = tcb->snd.una;
			tcb->snd.sack_loss_hint = 0;
			/* Act like an RTO.  We just detected it earlier.  This prevents us
			 * from getting another sack hint loss this recovery period and from
			 * advancing the opportunistic right edge. */
			tcb->snd.recovery = RTO_RETRANS_RECOVERY;
			/* We didn't actually time out yet and we expect to keep getting
			 * sacks, so we don't want to flush or worry about in_flight.  If we
			 * messed something up, the RTO will still fire. */
			set_in_flight(tcb);
		}
	}
}

/* Advances tcb_sack's right edge, if new_right is farther, and updates the
 * bookkeeping due to the change. */
static void update_right_edge(struct conv *s, Tcpctl *tcb,
                              struct sack_block *tcb_sack, uint32_t new_right)
{
	if (seq_le(new_right, tcb_sack->right))
		return;
	tcb_sack->right = new_right;
	merge_sacks_into(tcb, tcb_sack - tcb->snd.sacks);
	sack_has_changed(s, tcb, tcb_sack);
}

static void update_or_insert_sack(struct conv *s, Tcpctl *tcb,
                                  struct sack_block *seg_sack)
{
	struct sack_block *tcb_sack;

	for (int i = 0; i < tcb->snd.nr_sacks; i++) {
		tcb_sack = &tcb->snd.sacks[i];
		if (seq_lt(tcb_sack->left, seg_sack->left)) {
			/* This includes adjacent (which I've seen!) and overlap. */
			if (seq_le(seg_sack->left, tcb_sack->right)) {
				update_right_edge(s, tcb, tcb_sack, seg_sack->right);
				return;
			}
			continue;
		}
		/* Update existing sack */
		if (tcb_sack->left == seg_sack->left) {
			update_right_edge(s, tcb, tcb_sack, seg_sack->right);
			return;
		}
		/* Found our slot */
		if (seq_gt(tcb_sack->left, seg_sack->left)) {
			if (tcb->snd.nr_sacks == MAX_NR_SND_SACKS) {
				/* Out of room, but it is possible this sack overlaps later
				 * sacks, including the max sack's right edge. */
				if (seq_ge(seg_sack->right, tcb_sack->left)) {
					/* Take over the sack */
					tcb_sack->left = seg_sack->left;
					update_right_edge(s, tcb, tcb_sack, seg_sack->right);
				}
				return;
			}
			/* O/W, it's our slot and we have room (at least one spot). */
			memmove(&tcb->snd.sacks[i + 1], &tcb->snd.sacks[i],
			        sizeof(struct sack_block) * (tcb->snd.nr_sacks - i));
			tcb_sack->left = seg_sack->left;
			tcb_sack->right = seg_sack->right;
			tcb->snd.nr_sacks++;
			merge_sacks_into(tcb, i);
			sack_has_changed(s, tcb, tcb_sack);
			return;
		}
	}
	if (tcb->snd.nr_sacks == MAX_NR_SND_SACKS) {
		/* We didn't find space in the sack array. */
		tcb_sack = &tcb->snd.sacks[MAX_NR_SND_SACKS - 1];
		/* Need to always maintain the rightmost sack, discarding the prev */
		if (seq_gt(seg_sack->right, tcb_sack->right)) {
			tcb_sack->left = seg_sack->left;
			tcb_sack->right = seg_sack->right;
			sack_has_changed(s, tcb, tcb_sack);
		}
		return;
	}
	tcb_sack = &tcb->snd.sacks[tcb->snd.nr_sacks];
	tcb->snd.nr_sacks++;
	tcb_sack->left = seg_sack->left;
	tcb_sack->right = seg_sack->right;
	sack_has_changed(s, tcb, tcb_sack);
}

/* Given the packet seg, track the sacks in TCB.  There are a few things: if seg
 * acks new data, some sacks might no longer be needed.  Some sacks might grow,
 * we might add new sacks, either of which can cause a merger.
 *
 * The important thing is that we always have the max sack entry: it must be
 * inserted for sure and findable.  We need that for our measurement of what
 * packets are in the network.
 *
 * Note that we keep sacks that are below snd.rtx (and above
 * seg.ack/tcb->snd.una) as best we can - we don't prune them.  We'll need those
 * for the in_flight estimate.
 *
 * When we run out of room, we'll have to throw away a sack.  Anything we throw
 * away below snd.rtx will be counted as 'in flight', even though it isn't.  If
 * we throw away something greater than snd.rtx, we'll also retrans it.  For
 * simplicity, we throw-away / replace the rightmost sack, since we're always
 * maintaining a highest sack. */
static void update_sacks(struct conv *s, Tcpctl *tcb, Tcp *seg)
{
	int prune = 0;
	struct sack_block *tcb_sack;

	for (int i = 0; i < tcb->snd.nr_sacks; i++) {
		tcb_sack = &tcb->snd.sacks[i];
		/* For the equality case, if they acked up to, but not including an old
		 * sack, they must have reneged it.  Otherwise they would have acked
		 * beyond the sack. */
		if (seq_lt(seg->ack, tcb_sack->left))
			break;
		prune++;
	}
	if (prune) {
		memmove(tcb->snd.sacks, tcb->snd.sacks + prune,
		        sizeof(struct sack_block) * (tcb->snd.nr_sacks - prune));
		tcb->snd.nr_sacks -= prune;
	}
	for (int i = 0; i < seg->nr_sacks; i++) {
		/* old sacks */
		if (seq_lt(seg->sacks[i].left, seg->ack))
			continue;
		/* buggy sack: out of range */
		if (seq_gt(seg->sacks[i].right, tcb->snd.nxt))
			continue;
		update_or_insert_sack(s, tcb, &seg->sacks[i]);
	}
}

/* This is a little bit of an under estimate, since we assume a packet is lost
 * once we have any sacks above it.  Overall, it's at most 2 * MSS of an
 * overestimate.
 *
 * If we have no sacks (either reneged or never used) we'll assume all packets
 * above snd.rtx are lost.  This will be the case for sackless fast rxmit
 * (Dong's stuff) or for a timeout.  In the former case, this is probably not
 * true, and in_flight should be higher, but we have no knowledge without the
 * sacks. */
static void set_in_flight(Tcpctl *tcb)
{
	struct sack_block *tcb_sack;
	uint32_t in_flight = 0;
	uint32_t from;

	if (!tcb->snd.nr_sacks) {
		tcb->snd.in_flight = tcb->snd.rtx - tcb->snd.una;
		return;
	}

	/* Everything to the right of the unsacked */
	tcb_sack = &tcb->snd.sacks[tcb->snd.nr_sacks - 1];
	in_flight += tcb->snd.nxt - tcb_sack->right;

	/* Everything retransed (from una to snd.rtx, minus sacked regions.  Note
	 * we only retrans at most the last sack's left edge.  snd.rtx will be
	 * advanced to the right edge of some sack (possibly the last one). */
	from = tcb->snd.una;
	for (int i = 0; i < tcb->snd.nr_sacks; i++) {
		tcb_sack = &tcb->snd.sacks[i];
		if (seq_ge(tcb_sack->left, tcb->snd.rtx))
			break;
		assert(seq_ge(tcb->snd.rtx, tcb_sack->right));
		in_flight += tcb_sack->left - from;
		from = tcb_sack->right;
	}
	in_flight += tcb->snd.rtx - from;

	tcb->snd.in_flight = in_flight;
}

static void reset_recovery(struct conv *s, Tcpctl *tcb)
{
	netlog(s->p->f, Logtcprxmt,
	       "%I.%d -> %I.%d: recovery complete, una %u, rtx %u, nxt %u, recovery %u\n",
	       s->laddr, s->lport, s->raddr, s->rport,
	       tcb->snd.una, tcb->snd.rtx, tcb->snd.nxt, tcb->snd.recovery_pt);
	tcb->snd.recovery = 0;
	tcb->snd.recovery_pt = 0;
	tcb->snd.loss_hint = 0;
	tcb->snd.flush_sacks = FALSE;
	tcb->snd.sack_loss_hint = 0;
}

static bool is_dup_ack(Tcpctl *tcb, Tcp *seg)
{
	/* this is a pure ack w/o window update */
	return (seg->ack == tcb->snd.una) &&
	       (tcb->snd.una != tcb->snd.nxt) &&
	       (seg->len == 0) &&
	       (seg->wnd == tcb->snd.wnd);
}

/* If we have sacks, we'll ignore dupacks and look at the sacks ahead of una
 * (which are managed by the TCB).  The tcb will not have old sacks (below
 * ack/snd.rtx).  Receivers often send sacks below their ack point when we are
 * coming out of a loss, and we don't want those to count.
 *
 * Note the tcb could have sacks (in the future), but the receiver stopped using
 * them (reneged).  We'll catch that with the RTO.  If we try to catch it here,
 * we could get in a state where we never allow them to renege. */
static bool is_potential_loss(Tcpctl *tcb, Tcp *seg)
{
	if (seg->nr_sacks > 0)
		return tcb->snd.nr_sacks > 0;
	else
		return is_dup_ack(tcb, seg);
}

/* When we use timestamps for RTTM, RFC 7323 suggests scaling by
 * expected_samples (per cwnd).  They say:
 *
 * ExpectedSamples = ceiling(FlightSize / (SMSS * 2))
 *
 * However, SMMS * 2 is really "number of bytes expected to be acked in a
 * packet.".  We'll use 'acked' to approximate that.  When the receiver uses
 * LRO, they'll send back large ACKs, which decreases the number of samples.
 *
 * If it turns out that all the divides are bad, we can just go back to not
 * using expected_samples at all. */
static int expected_samples_ts(Tcpctl *tcb, uint32_t acked)
{
	assert(acked);
	return MAX(DIV_ROUND_UP(tcb->snd.nxt - tcb->snd.una, acked), 1);
}

/* Updates the RTT, given the currently sampled RTT and the number samples per
 * cwnd.  For non-TS RTTM, that'll be 1. */
static void update_rtt(Tcpctl *tcb, int rtt_sample, int expected_samples)
{
	int delta;

	tcb->backoff = 0;
	tcb->backedoff = 0;
	if (tcb->srtt == 0) {
		tcb->srtt = rtt_sample;
		tcb->mdev = rtt_sample / 2;
	} else {
		delta = rtt_sample - tcb->srtt;
		tcb->srtt += (delta >> RTTM_ALPHA_SHIFT) / expected_samples;
		if (tcb->srtt <= 0)
			tcb->srtt = 1;
		tcb->mdev += ((abs(delta) - tcb->mdev) >> RTTM_BRAVO_SHIFT) /
		             expected_samples;
		if (tcb->mdev <= 0)
			tcb->mdev = 1;
	}
	tcpsettimer(tcb);
}

static void update(struct conv *s, Tcp *seg)
{
	int rtt;
	Tcpctl *tcb;
	uint32_t acked, expand;
	struct tcppriv *tpriv;

	tpriv = s->p->priv;
	tcb = (Tcpctl *) s->ptcl;

	if (!seq_within(seg->ack, tcb->snd.una, tcb->snd.nxt))
		return;

	acked = seg->ack - tcb->snd.una;
	tcb->snd.una = seg->ack;
	if (seq_gt(seg->ack, tcb->snd.rtx))
		tcb->snd.rtx = seg->ack;

	update_sacks(s, tcb, seg);
	set_in_flight(tcb);

	/* We treat either a dupack or forward SACKs as a hint that there is a loss.
	 * The RFCs suggest three dupacks before treating it as a loss (alternative
	 * is reordered packets).  We'll treat three SACKs the same way. */
	if (is_potential_loss(tcb, seg) && !tcb->snd.recovery) {
		tcb->snd.loss_hint++;
		if (tcb->snd.loss_hint == TCPREXMTTHRESH) {
			netlog(s->p->f, Logtcprxmt,
			       "%I.%d -> %I.%d: loss hint thresh, nr sacks %u, nxt %u, una %u, cwnd %u\n",
			       s->laddr, s->lport, s->raddr, s->rport,
			       tcb->snd.nr_sacks, tcb->snd.nxt, tcb->snd.una, tcb->cwind);
			tcp_loss_event(s, tcb);
			tcb->snd.recovery_pt = tcb->snd.nxt;
			if (tcb->snd.nr_sacks) {
				tcb->snd.recovery = SACK_RETRANS_RECOVERY;
				tcb->snd.flush_sacks = FALSE;
				tcb->snd.sack_loss_hint = 0;
			} else {
				tcb->snd.recovery = FAST_RETRANS_RECOVERY;
			}
			tcprxmit(s);
		}
	}

	/*
	 *  update window
	 */
	if (seq_gt(seg->ack, tcb->snd.wl2)
		|| (tcb->snd.wl2 == seg->ack && seg->wnd > tcb->snd.wnd)) {
		tcb->snd.wnd = seg->wnd;
		tcb->snd.wl2 = seg->ack;
	}

	if (!acked) {
		/*
		 *  don't let us hangup if sending into a closed window and
		 *  we're still getting acks
		 */
		if (tcb->snd.recovery && (tcb->snd.wnd == 0))
			tcb->backedoff = MAXBACKMS / 4;
		return;
	}
	/* At this point, they have acked something new. (positive ack, ack > una).
	 *
	 * If we hadn't reached the threshold for recovery yet, the positive ACK
	 * will reset our loss_hint count. */
	if (!tcb->snd.recovery)
		tcb->snd.loss_hint = 0;
	else if (seq_ge(seg->ack, tcb->snd.recovery_pt))
		reset_recovery(s, tcb);

	/* avoid slow start and timers for SYN acks */
	if ((tcb->flags & SYNACK) == 0) {
		tcb->flags |= SYNACK;
		acked--;
		tcb->flgcnt--;
		goto done;
	}

	/* slow start as long as we're not recovering from lost packets */
	if (tcb->cwind < tcb->snd.wnd && !tcb->snd.recovery) {
		if (tcb->cwind < tcb->ssthresh) {
			/* We increase the cwind by every byte we receive.  We want to
			 * increase the cwind by one MSS for every MSS that gets ACKed.
			 * Note that multiple MSSs can be ACKed in a single ACK.  If we had
			 * a remainder of acked / MSS, we'd add just that remainder - not 0
			 * or 1 MSS. */
			expand = acked;
		} else {
			/* Every RTT, which consists of CWND bytes, we're supposed to expand
			 * by MSS bytes.  The classic algorithm was
			 * 		expand = (tcb->mss * tcb->mss) / tcb->cwind;
			 * which assumes the ACK was for MSS bytes.  Instead, for every
			 * 'acked' bytes, we increase the window by acked / CWND (in units
			 * of MSS). */
			expand = MAX(acked, tcb->typical_mss) * tcb->typical_mss
			         / tcb->cwind;
		}

		if (tcb->cwind + expand < tcb->cwind)
			expand = tcb->snd.wnd - tcb->cwind;
		if (tcb->cwind + expand > tcb->snd.wnd)
			expand = tcb->snd.wnd - tcb->cwind;
		tcb->cwind += expand;
	}
	adjust_tx_qio_limit(s);

	if (tcb->ts_recent) {
		update_rtt(tcb, abs(milliseconds() - seg->ts_ecr),
		           expected_samples_ts(tcb, acked));
	} else if (tcb->rtt_timer.state == TcptimerON &&
	           seq_ge(seg->ack, tcb->rttseq)) {
		/* Adjust the timers according to the round trip time */
		tcphalt(tpriv, &tcb->rtt_timer);
		if (!tcb->snd.recovery) {
			rtt = tcb->rtt_timer.start - tcb->rtt_timer.count;
			if (rtt == 0)
				rtt = 1;	/* o/w all close systems will rexmit in 0 time */
			rtt *= MSPTICK;
			update_rtt(tcb, rtt, 1);
		}
	}

done:
	if (qdiscard(s->wq, acked) < acked) {
		tcb->flgcnt--;
		/* This happened due to another bug where acked was very large
		 * (negative), which was interpreted as "hey, one less flag, since they
		 * acked one of our flags (like a SYN).  If flgcnt goes negative,
		 * get_xmit_segment() will attempt to send out large packets. */
		assert(tcb->flgcnt >= 0);
	}

	if (seq_gt(seg->ack, tcb->snd.urg))
		tcb->snd.urg = seg->ack;

	if (tcb->snd.una != tcb->snd.nxt)
		tcpgo(tpriv, &tcb->timer);
	else
		tcphalt(tpriv, &tcb->timer);

	tcb->backoff = 0;
	tcb->backedoff = 0;
}

static void update_tcb_ts(Tcpctl *tcb, Tcp *seg)
{
	/* Get timestamp info from the tcp header.  Even though the timestamps
	 * aren't sequence numbers, we still need to protect for wraparound.  Though
	 * if the values were 0, assume that means we need an update.  We could have
	 * an initial ts_val that appears negative (signed). */
	if (!tcb->ts_recent || !tcb->last_ack_sent ||
	    (seq_ge(seg->ts_val, tcb->ts_recent) &&
	     seq_le(seg->seq, tcb->last_ack_sent)))
		tcb->ts_recent = seg->ts_val;
}

/* Overlap happens when one sack's left edge is inside another sack. */
static bool sacks_overlap(struct sack_block *x, struct sack_block *y)
{
	return (seq_le(x->left, y->left) && seq_le(y->left, x->right)) ||
	       (seq_le(y->left, x->left) && seq_le(x->left, y->right));
}

static void make_sack_first(Tcpctl *tcb, struct sack_block *tcb_sack)
{
	struct sack_block temp;

	if (tcb_sack == &tcb->rcv.sacks[0])
		return;
	temp = tcb->rcv.sacks[0];
	tcb->rcv.sacks[0] = *tcb_sack;
	*tcb_sack = temp;
}

/* Track sack in our tcb for a block of data we received.  This handles all the
 * stuff: making sure sack is first (since it's the most recent sack change),
 * updating or merging sacks, and dropping excess sacks (we only need to
 * maintain 3).  Unlike on the snd side, our tcb sacks are *not* sorted. */
static void track_rcv_sack(Tcpctl *tcb, uint32_t left, uint32_t right)
{
	struct sack_block *tcb_sack;
	struct sack_block sack[1];

	if (!tcb->sack_ok)
		return;
	if (left == right)
		return;
	assert(seq_lt(left, right));
	sack->left = left;
	sack->right = right;
	/* We can reuse an existing sack if we're merging or overlapping. */
	for (int i = 0; i < tcb->rcv.nr_sacks; i++) {
		tcb_sack = &tcb->rcv.sacks[i];
		if (sacks_overlap(tcb_sack, sack)) {
			tcb_sack->left = seq_min(tcb_sack->left, sack->left);
			tcb_sack->right = seq_max(tcb_sack->right, sack->right);
			make_sack_first(tcb, tcb_sack);
			return;
		}
	}
	/* We can discard the last sack (right shift) - we should have sent it at
	 * least once by now.  If not, oh well. */
	memmove(tcb->rcv.sacks + 1, tcb->rcv.sacks, sizeof(struct sack_block) *
	        MIN(MAX_NR_RCV_SACKS - 1, tcb->rcv.nr_sacks));
	tcb->rcv.sacks[0] = *sack;
	if (tcb->rcv.nr_sacks < MAX_NR_RCV_SACKS)
		tcb->rcv.nr_sacks++;
}

/* Once we receive everything and move rcv.nxt past a sack, we don't need to
 * track it.  I've seen Linux report sacks in the past, but we probably
 * shouldn't. */
static void drop_old_rcv_sacks(Tcpctl *tcb)
{
	struct sack_block *tcb_sack;

	for (int i = 0; i < tcb->rcv.nr_sacks; i++) {
		tcb_sack = &tcb->rcv.sacks[i];
		/* Moving up to or past the left is enough to drop it. */
		if (seq_ge(tcb->rcv.nxt, tcb_sack->left)) {
			memmove(tcb->rcv.sacks + i, tcb->rcv.sacks + i + 1,
			        sizeof(struct sack_block) * (tcb->rcv.nr_sacks - i - 1));
			tcb->rcv.nr_sacks--;
			i--;
		}
	}
}

static void tcpiput(struct Proto *tcp, struct Ipifc *unused, struct block *bp)
{
	ERRSTACK(1);
	Tcp seg;
	Tcp4hdr *h4;
	Tcp6hdr *h6;
	int hdrlen;
	Tcpctl *tcb;
	uint16_t length;
	uint8_t source[IPaddrlen], dest[IPaddrlen];
	struct conv *s;
	struct Fs *f;
	struct tcppriv *tpriv;
	uint8_t version;

	f = tcp->f;
	tpriv = tcp->priv;

	tpriv->stats[InSegs]++;

	h4 = (Tcp4hdr *) (bp->rp);
	h6 = (Tcp6hdr *) (bp->rp);

	if ((h4->vihl & 0xF0) == IP_VER4) {
		uint8_t ttl;

		version = V4;
		length = nhgets(h4->length);
		v4tov6(dest, h4->tcpdst);
		v4tov6(source, h4->tcpsrc);

		/* ttl isn't part of the xsum pseudo header, but bypass needs it. */
		ttl = h4->Unused;
		h4->Unused = 0;
		hnputs(h4->tcplen, length - TCP4_PKT);
		if (!(bp->flag & Btcpck) && (h4->tcpcksum[0] || h4->tcpcksum[1]) &&
			ptclcsum(bp, TCP4_IPLEN, length - TCP4_IPLEN)) {
			tpriv->stats[CsumErrs]++;
			tpriv->stats[InErrs]++;
			netlog(f, Logtcp, "bad tcp proto cksum\n");
			freeblist(bp);
			return;
		}
		h4->Unused = ttl;

		hdrlen = ntohtcp4(&seg, &bp);
		if (hdrlen < 0) {
			tpriv->stats[HlenErrs]++;
			tpriv->stats[InErrs]++;
			netlog(f, Logtcp, "bad tcp hdr len\n");
			return;
		}

		s = iphtlook(&tpriv->ht, source, seg.source, dest, seg.dest);
		if (s && s->state == Bypass) {
			bypass_or_drop(s, bp);
			return;
		}

		/* trim the packet to the size claimed by the datagram */
		length -= hdrlen + TCP4_PKT;
		bp = trimblock(bp, hdrlen + TCP4_PKT, length);
		if (bp == NULL) {
			tpriv->stats[LenErrs]++;
			tpriv->stats[InErrs]++;
			netlog(f, Logtcp, "tcp len < 0 after trim\n");
			return;
		}
	} else {
		int ttl = h6->ttl;
		int proto = h6->proto;

		version = V6;
		length = nhgets(h6->ploadlen);
		ipmove(dest, h6->tcpdst);
		ipmove(source, h6->tcpsrc);

		h6->ploadlen[0] = h6->ploadlen[1] = h6->proto = 0;
		h6->ttl = proto;
		hnputl(h6->vcf, length);
		if ((h6->tcpcksum[0] || h6->tcpcksum[1]) &&
			ptclcsum(bp, TCP6_IPLEN, length + TCP6_PHDRSIZE)) {
			tpriv->stats[CsumErrs]++;
			tpriv->stats[InErrs]++;
			netlog(f, Logtcp, "bad tcp proto cksum\n");
			freeblist(bp);
			return;
		}
		h6->ttl = ttl;
		h6->proto = proto;
		hnputs(h6->ploadlen, length);

		hdrlen = ntohtcp6(&seg, &bp);
		if (hdrlen < 0) {
			tpriv->stats[HlenErrs]++;
			tpriv->stats[InErrs]++;
			netlog(f, Logtcp, "bad tcp hdr len\n");
			return;
		}

		s = iphtlook(&tpriv->ht, source, seg.source, dest, seg.dest);
		if (s && s->state == Bypass) {
			bypass_or_drop(s, bp);
			return;
		}

		/* trim the packet to the size claimed by the datagram */
		length -= hdrlen;
		bp = trimblock(bp, hdrlen + TCP6_PKT, length);
		if (bp == NULL) {
			tpriv->stats[LenErrs]++;
			tpriv->stats[InErrs]++;
			netlog(f, Logtcp, "tcp len < 0 after trim\n");
			return;
		}
	}

	/* s, the conv matching the n-tuple, was set above */
	if (s == NULL) {
		netlog(f, Logtcpreset, "iphtlook failed: src %I:%u, dst %I:%u\n",
		       source, seg.source, dest, seg.dest);
reset:
		sndrst(tcp, source, dest, length, &seg, version, "no conversation");
		freeblist(bp);
		return;
	}

	/* lock protocol for unstate Plan 9 invariants.  funcs like limbo or
	 * incoming might rely on it. */
	qlock(&tcp->qlock);

	/* if it's a listener, look for the right flags and get a new conv */
	tcb = (Tcpctl *) s->ptcl;
	if (tcb->state == Listen) {
		if (seg.flags & RST) {
			limborst(s, &seg, source, dest, version);
			qunlock(&tcp->qlock);
			freeblist(bp);
			return;
		}

		/* if this is a new SYN, put the call into limbo */
		if ((seg.flags & SYN) && (seg.flags & ACK) == 0) {
			limbo(s, source, dest, &seg, version);
			qunlock(&tcp->qlock);
			freeblist(bp);
			return;
		}

		/* if there's a matching call in limbo, tcpincoming will return it */
		s = tcpincoming(s, &seg, source, dest, version);
		if (s == NULL) {
			qunlock(&tcp->qlock);
			goto reset;
		}
	}

	/* The rest of the input state machine is run with the control block
	 * locked and implements the state machine directly out of the RFC.
	 * Out-of-band data is ignored - it was always a bad idea.
	 */
	tcb = (Tcpctl *) s->ptcl;
	if (waserror()) {
		qunlock(&s->qlock);
		nexterror();
	}
	qlock(&s->qlock);
	qunlock(&tcp->qlock);

	update_tcb_ts(tcb, &seg);
	/* fix up window */
	seg.wnd <<= tcb->rcv.scale;

	/* every input packet in puts off the keep alive time out */
	tcpsetkacounter(tcb);

	switch (tcb->state) {
		case Closed:
			sndrst(tcp, source, dest, length, &seg, version,
				   "sending to Closed");
			goto raise;
		case Syn_sent:
			if (seg.flags & ACK) {
				if (!seq_within(seg.ack, tcb->iss + 1, tcb->snd.nxt)) {
					sndrst(tcp, source, dest, length, &seg, version,
						   "bad seq in Syn_sent");
					goto raise;
				}
			}
			if (seg.flags & RST) {
				if (seg.flags & ACK)
					localclose(s, "connection refused");
				goto raise;
			}

			if (seg.flags & SYN) {
				procsyn(s, &seg);
				if (seg.flags & ACK) {
					update(s, &seg);
					tcpsynackrtt(s);
					tcpsetstate(s, Established);
					/* Here's where we get the results of header option
					 * negotiations for connections we started. (SYNACK has the
					 * response) */
					tcpsetscale(s, tcb, seg.ws, tcb->scale);
					tcb->sack_ok = seg.sack_ok;
				} else {
					sndrst(tcp, source, dest, length, &seg, version,
						   "Got SYN with no ACK");
					goto raise;
				}

				if (length != 0 || (seg.flags & FIN))
					break;

				freeblist(bp);
				goto output;
			} else
				freeblist(bp);

			qunlock(&s->qlock);
			poperror();
			return;
	}

	/*
	 *  One DOS attack is to open connections to us and then forget about them,
	 *  thereby tying up a conv at no long term cost to the attacker.
	 *  This is an attempt to defeat these stateless DOS attacks.  See
	 *  corresponding code in tcpsendka().
	 */
	if ((seg.flags & RST) == 0) {
		if (tcpporthogdefense
			&& seq_within(seg.ack, tcb->snd.una - (1 << 31),
						  tcb->snd.una - (1 << 29))) {
			printd("stateless hog %I.%d->%I.%d f 0x%x 0x%lx - 0x%lx - 0x%lx\n",
				   source, seg.source, dest, seg.dest, seg.flags,
				   tcb->snd.una - (1 << 31), seg.ack, tcb->snd.una - (1 << 29));
			localclose(s, "stateless hog");
		}
	}

	/* Cut the data to fit the receive window */
	if (tcptrim(tcb, &seg, &bp, &length) == -1) {
		netlog(f, Logtcp, "%I.%d -> %I.%d: tcp len < 0, %lu %d\n",
		       s->raddr, s->rport, s->laddr, s->lport, seg.seq, length);
		update(s, &seg);
		if (qlen(s->wq) + tcb->flgcnt == 0 && tcb->state == Closing) {
			tcphalt(tpriv, &tcb->rtt_timer);
			tcphalt(tpriv, &tcb->acktimer);
			tcphalt(tpriv, &tcb->katimer);
			tcpsetstate(s, Time_wait);
			tcb->timer.start = MSL2 * (1000 / MSPTICK);
			tcpgo(tpriv, &tcb->timer);
		}
		if (!(seg.flags & RST)) {
			tcb->flags |= FORCE;
			goto output;
		}
		qunlock(&s->qlock);
		poperror();
		return;
	}

	/* Cannot accept so answer with a rst */
	if (length && tcb->state == Closed) {
		sndrst(tcp, source, dest, length, &seg, version, "sending to Closed");
		goto raise;
	}

	/* The segment is beyond the current receive pointer so
	 * queue the data in the resequence queue
	 */
	if (seg.seq != tcb->rcv.nxt)
		if (length != 0 || (seg.flags & (SYN | FIN))) {
			update(s, &seg);
			if (addreseq(tcb, tpriv, &seg, bp, length) < 0)
				printd("reseq %I.%d -> %I.%d\n", s->raddr, s->rport, s->laddr,
					   s->lport);
			tcb->flags |= FORCE;
			goto output;
		}

	/*
	 *  keep looping till we've processed this packet plus any
	 *  adjacent packets in the resequence queue
	 */
	for (;;) {
		if (seg.flags & RST) {
			if (tcb->state == Established) {
				tpriv->stats[EstabResets]++;
				if (tcb->rcv.nxt != seg.seq)
					printd
						("out of order RST rcvd: %I.%d -> %I.%d, rcv.nxt 0x%lx seq 0x%lx\n",
						 s->raddr, s->rport, s->laddr, s->lport, tcb->rcv.nxt,
						 seg.seq);
			}
			localclose(s, "connection refused");
			goto raise;
		}

		if ((seg.flags & ACK) == 0)
			goto raise;

		switch (tcb->state) {
			case Established:
			case Close_wait:
				update(s, &seg);
				break;
			case Finwait1:
				update(s, &seg);
				if (qlen(s->wq) + tcb->flgcnt == 0) {
					tcphalt(tpriv, &tcb->rtt_timer);
					tcphalt(tpriv, &tcb->acktimer);
					tcpsetkacounter(tcb);
					tcb->time = NOW;
					tcpsetstate(s, Finwait2);
					tcb->katimer.start = MSL2 * (1000 / MSPTICK);
					tcpgo(tpriv, &tcb->katimer);
				}
				break;
			case Finwait2:
				update(s, &seg);
				break;
			case Closing:
				update(s, &seg);
				if (qlen(s->wq) + tcb->flgcnt == 0) {
					tcphalt(tpriv, &tcb->rtt_timer);
					tcphalt(tpriv, &tcb->acktimer);
					tcphalt(tpriv, &tcb->katimer);
					tcpsetstate(s, Time_wait);
					tcb->timer.start = MSL2 * (1000 / MSPTICK);
					tcpgo(tpriv, &tcb->timer);
				}
				break;
			case Last_ack:
				update(s, &seg);
				if (qlen(s->wq) + tcb->flgcnt == 0) {
					localclose(s, NULL);
					goto raise;
				}
			case Time_wait:
				tcb->flags |= FORCE;
				if (tcb->timer.state != TcptimerON)
					tcpgo(tpriv, &tcb->timer);
		}

		if ((seg.flags & URG) && seg.urg) {
			if (seq_gt(seg.urg + seg.seq, tcb->rcv.urg)) {
				tcb->rcv.urg = seg.urg + seg.seq;
				pullblock(&bp, seg.urg);
			}
		} else if (seq_gt(tcb->rcv.nxt, tcb->rcv.urg))
			tcb->rcv.urg = tcb->rcv.nxt;

		if (length == 0) {
			if (bp != NULL)
				freeblist(bp);
		} else {
			switch (tcb->state) {
				default:
					/* Ignore segment text */
					if (bp != NULL)
						freeblist(bp);
					break;

				case Established:
				case Finwait1:
					/* If we still have some data place on
					 * receive queue
					 */
					if (bp) {
						bp = packblock(bp);
						if (bp == NULL)
							panic("tcp packblock");
						qpassnolim(s->rq, bp);
						bp = NULL;

						/*
						 *  Force an ack every 2 data messages.  This is
						 *  a hack for rob to make his home system run
						 *  faster.
						 *
						 *  this also keeps the standard TCP congestion
						 *  control working since it needs an ack every
						 *  2 max segs worth.  This is not quite that,
						 *  but under a real stream is equivalent since
						 *  every packet has a max seg in it.
						 */
						if (++(tcb->rcv.una) >= 2)
							tcb->flags |= FORCE;
					}
					tcb->rcv.nxt += length;
					drop_old_rcv_sacks(tcb);

					/*
					 *  update our rcv window
					 */
					tcprcvwin(s);

					/*
					 *  turn on the acktimer if there's something
					 *  to ack
					 */
					if (tcb->acktimer.state != TcptimerON)
						tcpgo(tpriv, &tcb->acktimer);

					break;
				case Finwait2:
					/* no process to read the data, send a reset */
					if (bp != NULL)
						freeblist(bp);
					sndrst(tcp, source, dest, length, &seg, version,
						   "send to Finwait2");
					qunlock(&s->qlock);
					poperror();
					return;
			}
		}

		if (seg.flags & FIN) {
			tcb->flags |= FORCE;

			switch (tcb->state) {
				case Established:
					tcb->rcv.nxt++;
					tcpsetstate(s, Close_wait);
					break;
				case Finwait1:
					tcb->rcv.nxt++;
					if (qlen(s->wq) + tcb->flgcnt == 0) {
						tcphalt(tpriv, &tcb->rtt_timer);
						tcphalt(tpriv, &tcb->acktimer);
						tcphalt(tpriv, &tcb->katimer);
						tcpsetstate(s, Time_wait);
						tcb->timer.start = MSL2 * (1000 / MSPTICK);
						tcpgo(tpriv, &tcb->timer);
					} else
						tcpsetstate(s, Closing);
					break;
				case Finwait2:
					tcb->rcv.nxt++;
					tcphalt(tpriv, &tcb->rtt_timer);
					tcphalt(tpriv, &tcb->acktimer);
					tcphalt(tpriv, &tcb->katimer);
					tcpsetstate(s, Time_wait);
					tcb->timer.start = MSL2 * (1000 / MSPTICK);
					tcpgo(tpriv, &tcb->timer);
					break;
				case Close_wait:
				case Closing:
				case Last_ack:
					break;
				case Time_wait:
					tcpgo(tpriv, &tcb->timer);
					break;
			}
		}

		/*
		 *  get next adjacent segment from the resequence queue.
		 *  dump/trim any overlapping segments
		 */
		for (;;) {
			if (tcb->reseq == NULL)
				goto output;

			if (seq_ge(tcb->rcv.nxt, tcb->reseq->seg.seq) == 0)
				goto output;

			getreseq(tcb, &seg, &bp, &length);

			if (tcptrim(tcb, &seg, &bp, &length) == 0)
				break;
		}
	}
output:
	tcpoutput(s);
	qunlock(&s->qlock);
	poperror();
	return;
raise:
	qunlock(&s->qlock);
	poperror();
	freeblist(bp);
	tcpkick(s);
}

/* The advertised mss = data + TCP headers */
static uint16_t derive_payload_mss(Tcpctl *tcb)
{
	uint16_t payload_mss = tcb->mss;
	uint16_t opt_size = 0;

	if (tcb->ts_recent) {
		opt_size += TS_LENGTH;
		/* Note that when we're a SYN, we overestimate slightly.  This is safe,
		 * and not really a problem. */
		opt_size += TS_SEND_PREPAD;
	}
	if (tcb->rcv.nr_sacks)
		opt_size += 2 + tcb->rcv.nr_sacks * 8;
	opt_size = ROUNDUP(opt_size, 4);
	payload_mss -= opt_size;
	return payload_mss;
}

/* Decreases the xmit amt, given the MSS / TSO. */
static uint32_t throttle_for_mss(Tcpctl *tcb, uint32_t ssize,
                                 uint16_t payload_mss, bool retrans)
{
	if (ssize > payload_mss) {
		if ((tcb->flags & TSO) == 0) {
			ssize = payload_mss;
		} else {
			/* Don't send too much.  32K is arbitrary.. */
			if (ssize > 32 * 1024)
				ssize = 32 * 1024;
			if (!retrans) {
				/* Clamp xmit to an integral MSS to avoid ragged tail segments
				 * causing poor link utilization. */
				ssize = ROUNDDOWN(ssize, payload_mss);
			}
		}
	}
	return ssize;
}

/* Reduces ssize for a variety of reasons.  Returns FALSE if we should abort
 * sending the packet.  o/w returns TRUE and modifies ssize by reference. */
static bool throttle_ssize(struct conv *s, Tcpctl *tcb, uint32_t *ssize_p,
                           uint16_t payload_mss, bool retrans)
{
	struct Fs *f = s->p->f;
	uint32_t usable;
	uint32_t ssize = *ssize_p;

	/* Compute usable segment based on offered window and limit
	 * window probes to one */
	if (tcb->snd.wnd == 0) {
		if (tcb->snd.in_flight != 0) {
			if ((tcb->flags & FORCE) == 0)
				return FALSE;
		}
		usable = 1;
	} else {
		usable = tcb->cwind;
		if (tcb->snd.wnd < usable)
			usable = tcb->snd.wnd;
		if (usable > tcb->snd.in_flight)
			usable -= tcb->snd.in_flight;
		else
			usable = 0;
		/* Avoid Silly Window Syndrome.  This is a little different thant RFC
		 * 813.  I took their additional enhancement of "< MSS" as an AND, not
		 * an OR.  25% of a large snd.wnd is pretty large, and our main goal is
		 * to avoid packets smaller than MSS.  I still use the 25% threshold,
		 * because it is important that there is *some* data in_flight.  If
		 * usable < MSS because snd.wnd is very small (but not 0), we might
		 * never get an ACK and would need to set up a timer.
		 *
		 * Also, I'm using 'ssize' as a proxy for a PSH point.  If there's just
		 * a small blob in the qio (or retrans!), then we might as well just
		 * send it. */
		if ((usable < tcb->typical_mss) && (usable < tcb->snd.wnd >> 2)
		    && (usable < ssize)) {
			return FALSE;
		}
	}
	if (ssize && usable < 2)
		netlog(s->p->f, Logtcpverbose,
		       "%I.%d -> %I.%d: throttled snd.wnd %lu cwind %lu\n",
		       s->laddr, s->lport, s->raddr, s->rport,
		       tcb->snd.wnd, tcb->cwind);
	if (usable < ssize)
		ssize = usable;

	ssize = throttle_for_mss(tcb, ssize, payload_mss, retrans);

	*ssize_p = ssize;
	return TRUE;
}

/* Helper, picks the next segment to send, which is possibly a retransmission.
 * Returns TRUE if we have a segment, FALSE o/w.  Returns ssize, from_seq, and
 * sent by reference.
 *
 * from_seq is the seq number we are transmitting from.
 *
 * sent includes all seq from una to from_seq *including* any previously sent
 * flags (part of tcb->flgcnt), for instance an unacknowledged SYN (which counts
 * as a seq number).  Those flags are in the e.g. snd.nxt - snd.una range, and
 * they get dropped after qdiscard.
 *
 * ssize is the amount of data we are sending, starting from from_seq, and it
 * will include any *new* flags, which haven't been accounted for yet.
 *
 * tcb->flgcnt consists of the flags both in ssize and in sent.
 *
 * Note that we could be in recovery and not sack_retrans a segment. */
static bool get_xmit_segment(struct conv *s, Tcpctl *tcb, uint16_t payload_mss,
                             uint32_t *from_seq_p, uint32_t *sent_p,
                             uint32_t *ssize_p)
{
	struct Fs *f = s->p->f;
	struct tcppriv *tpriv = s->p->priv;
	uint32_t ssize, sent, from_seq;
	bool sack_retrans = FALSE;
	struct sack_block *tcb_sack = 0;

	for (int i = 0; i < tcb->snd.nr_sacks; i++) {
		tcb_sack = &tcb->snd.sacks[i];
		if (seq_lt(tcb->snd.rtx, tcb_sack->left)) {
			/* So ssize is supposed to include any *new* flags to flgcnt, which
			 * at this point would be a FIN.
			 *
			 * It might be possible that flgcnt is incremented so we send a FIN,
			 * even for an intermediate sack retrans.  Perhaps the user closed
			 * the conv.
			 *
			 * However, the way the "flgcnt for FIN" works is that it inflates
			 * the desired amount we'd like to send (qlen + flgcnt).
			 * Eventually, we reach the end of the queue and fail to extract all
			 * of dsize.  At that point, we put on the FIN, and that's where the
			 * extra 'byte' comes from.
			 *
			 * For sack retrans, since we're extracting from parts of the qio
			 * that aren't the right-most edge, we don't need to consider flgcnt
			 * when setting ssize. */
			from_seq = tcb->snd.rtx;
			sent = from_seq - tcb->snd.una;
			ssize = tcb_sack->left - from_seq;
			sack_retrans = TRUE;
			break;
		}
	}
	/* SACK holes have first dibs, but we can still opportunisitically send new
	 * data.
	 *
	 * During other types of recovery, we'll just send from the retrans point.
	 * If we're in an RTO while we still have sacks, we could be resending data
	 * that wasn't lost.  Consider a sack that is still growing (usually the
	 * right-most), but we haven't received the ACK yet.  rxt may be included in
	 * that area.  Given we had two losses or otherwise timed out, I'm not too
	 * concerned.
	 *
	 * Note that Fast and RTO can send data beyond nxt.  If we change that,
	 * change the accounting below. */
	if (!sack_retrans) {
		switch (tcb->snd.recovery) {
		default:
		case SACK_RETRANS_RECOVERY:
			from_seq = tcb->snd.nxt;
			break;
		case FAST_RETRANS_RECOVERY:
		case RTO_RETRANS_RECOVERY:
			from_seq = tcb->snd.rtx;
			break;
		}
		sent = from_seq - tcb->snd.una;
		/* qlen + flgcnt is every seq we want to have sent, including unack'd
		 * data, unacked flags, and new flags. */
		ssize = qlen(s->wq) + tcb->flgcnt - sent;
	}

	if (!throttle_ssize(s, tcb, &ssize, payload_mss, sack_retrans))
		return FALSE;

	/* This counts flags, which is a little hokey, but it's okay since in_flight
	 * gets reset on each ACK */
	tcb->snd.in_flight += ssize;
	/* Log and track rxmit.  This covers both SACK (retrans) and fast rxmit. */
	if (ssize && seq_lt(tcb->snd.rtx, tcb->snd.nxt)) {
		netlog(f, Logtcpverbose,
		       "%I.%d -> %I.%d: rxmit: rtx %u amt %u, nxt %u\n",
		       s->laddr, s->lport, s->raddr, s->rport,
		       tcb->snd.rtx, MIN(tcb->snd.nxt - tcb->snd.rtx, ssize),
		       tcb->snd.nxt);
		tpriv->stats[RetransSegs]++;
	}
	if (sack_retrans) {
		/* If we'll send up to the left edge, advance snd.rtx to the right.
		 *
		 * This includes the largest sack.  It might get removed later, in which
		 * case we'll underestimate the amount in-flight.  The alternative is to
		 * not count the rightmost sack, but when it gets removed, we'll retrans
		 * it anyway.  No matter what, we'd count it. */
		tcb->snd.rtx += ssize;
		if (tcb->snd.rtx == tcb_sack->left)
			tcb->snd.rtx = tcb_sack->right;
		/* RFC 6675 says we MAY rearm the RTO timer on each retrans, since we
		 * might not be getting ACKs for a while. */
		tcpsettimer(tcb);
	} else {
		switch (tcb->snd.recovery) {
		default:
			/* under normal op, we drag rtx along with nxt.  this prevents us
			 * from sending sacks too early (up above), since rtx doesn't get
			 * reset to una until we have a loss (e.g. 3 dupacks/sacks). */
			tcb->snd.nxt += ssize;
			tcb->snd.rtx = tcb->snd.nxt;
			break;
		case SACK_RETRANS_RECOVERY:
			/* We explicitly do not want to increase rtx here.  We might still
			 * need it to fill in a sack gap below nxt if we get new, higher
			 * sacks. */
			tcb->snd.nxt += ssize;
			break;
		case FAST_RETRANS_RECOVERY:
		case RTO_RETRANS_RECOVERY:
			tcb->snd.rtx += ssize;
			/* Fast and RTO can send new data, advancing nxt. */
			if (seq_gt(tcb->snd.rtx, tcb->snd.nxt))
				tcb->snd.nxt = tcb->snd.rtx;
			break;
		}
	}
	*from_seq_p = from_seq;
	*sent_p = sent;
	*ssize_p = ssize;

	return TRUE;
}

/*
 *  always enters and exits with the s locked.  We drop
 *  the lock to ipoput the packet so some care has to be
 *  taken by callers.
 */
static void tcpoutput(struct conv *s)
{
	Tcp seg;
	int msgs;
	int next_yield = 1;
	Tcpctl *tcb;
	struct block *hbp, *bp;
	uint32_t ssize, dsize, sent, from_seq;
	struct Fs *f;
	struct tcppriv *tpriv;
	uint8_t version;
	uint16_t payload_mss;

	f = s->p->f;
	tpriv = s->p->priv;
	version = s->ipversion;

	for (msgs = 0; msgs < 100; msgs++) {
		tcb = (Tcpctl *) s->ptcl;

		switch (tcb->state) {
			case Listen:
			case Closed:
			case Finwait2:
				return;
		}

		/* force an ack when a window has opened up */
		if (tcb->rcv.blocked && tcb->rcv.wnd >= tcb->mss) {
			tcb->rcv.blocked = 0;
			tcb->flags |= FORCE;
		}

		/* Don't send anything else until our SYN has been acked */
		if (tcb->snd.nxt != tcb->iss && (tcb->flags & SYNACK) == 0)
			break;

		/* payload_mss is the actual amount of data in the packet, which is the
		 * advertised (mss - header opts).  This varies from packet to packet,
		 * based on the options that might be present (e.g. always timestamps,
		 * sometimes SACKs) */
		payload_mss = derive_payload_mss(tcb);

		if (!get_xmit_segment(s, tcb, payload_mss, &from_seq, &sent, &ssize))
			break;

		dsize = ssize;
		seg.urg = 0;

		if (ssize == 0)
			if ((tcb->flags & FORCE) == 0)
				break;

		tcb->flags &= ~FORCE;
		tcprcvwin(s);

		/* By default we will generate an ack, so we can normally turn off the
		 * timer.  If we're blocked, we'll want the timer so we can send a
		 * window update. */
		if (!tcb->rcv.blocked)
			tcphalt(tpriv, &tcb->acktimer);
		tcb->rcv.una = 0;
		seg.source = s->lport;
		seg.dest = s->rport;
		seg.flags = ACK;
		seg.mss = 0;
		seg.ws = 0;
		seg.sack_ok = FALSE;
		seg.nr_sacks = 0;
		/* When outputting, Syn_sent means "send the Syn", for connections we
		 * initiate.  SYNACKs are sent from sndsynack directly. */
		if (tcb->state == Syn_sent) {
			seg.flags = 0;
			seg.sack_ok = SACK_SUPPORTED;	/* here's where we advertise SACK */
			if (tcb->snd.nxt - ssize == tcb->iss) {
				seg.flags |= SYN;
				dsize--;
				seg.mss = tcb->mss;
				seg.ws = tcb->scale;
			} else {
				/* TODO: Not sure why we'd get here. */
				warn("TCP: weird Syn_sent state, tell someone you saw this");
			}
		}
		seg.seq = from_seq;
		seg.ack = tcb->rcv.nxt;
		tcb->last_ack_sent = seg.ack;
		seg.wnd = tcb->rcv.wnd;
		seg.ts_val = tcb->ts_recent;

		/* Pull out data to send */
		bp = NULL;
		if (dsize != 0) {
			bp = qcopy(s->wq, dsize, sent);
			if (BLEN(bp) != dsize) {
				/* Here's where the flgcnt kicked in.  Note dsize is
				 * decremented, but ssize isn't.  Not that we use ssize for much
				 * anymore.  Decrementing dsize prevents us from sending a PSH
				 * with the FIN. */
				seg.flags |= FIN;
				dsize--;
			}
			if (BLEN(bp) > payload_mss) {
				bp->flag |= Btso;
				bp->mss = payload_mss;
			}
		}

		if (sent + dsize == qlen(s->wq) + tcb->flgcnt)
			seg.flags |= PSH;

		/* Build header, link data and compute cksum */
		switch (version) {
			case V4:
				tcb->protohdr.tcp4hdr.vihl = IP_VER4;
				hbp = htontcp4(&seg, bp, &tcb->protohdr.tcp4hdr, tcb);
				if (hbp == NULL) {
					freeblist(bp);
					return;
				}
				break;
			case V6:
				tcb->protohdr.tcp6hdr.vcf[0] = IP_VER6;
				hbp = htontcp6(&seg, bp, &tcb->protohdr.tcp6hdr, tcb);
				if (hbp == NULL) {
					freeblist(bp);
					return;
				}
				break;
			default:
				hbp = NULL;	/* to suppress a warning */
				panic("tcpoutput: version %d", version);
		}

		/* Start the transmission timers if there is new data and we
		 * expect acknowledges
		 */
		if (ssize != 0) {
			if (tcb->timer.state != TcptimerON)
				tcpgo(tpriv, &tcb->timer);

			if (!tcb->ts_recent && (tcb->rtt_timer.state != TcptimerON)) {
				/* If round trip timer isn't running, start it. */
				tcpgo(tpriv, &tcb->rtt_timer);
				tcb->rttseq = from_seq + ssize;
			}
		}

		tpriv->stats[OutSegs]++;

		/* put off the next keep alive */
		tcpgo(tpriv, &tcb->katimer);

		switch (version) {
			case V4:
				if (ipoput4(f, hbp, 0, s->ttl, s->tos, s) < 0) {
					/* a negative return means no route */
					localclose(s, "no route");
				}
				break;
			case V6:
				if (ipoput6(f, hbp, 0, s->ttl, s->tos, s) < 0) {
					/* a negative return means no route */
					localclose(s, "no route");
				}
				break;
			default:
				panic("tcpoutput2: version %d", version);
		}
		if (ssize) {
			/* The outer loop thinks we sent one packet.  If we used TSO, we
			 * might have sent several.  Minus one for the loop increment. */
			msgs += DIV_ROUND_UP(ssize, payload_mss) - 1;
		}
		/* Old Plan 9 tidbit - yield every four messages.  We want to break out
		 * and unlock so we can process inbound ACKs which might do things like
		 * say "slow down". */
		if (msgs >= next_yield) {
			next_yield = msgs + 4;
			qunlock(&s->qlock);
			kthread_yield();
			qlock(&s->qlock);
		}
	}
}

/*
 *  the BSD convention (hack?) for keep alives.  resend last uint8_t acked.
 */
static void tcpsendka(struct conv *s)
{
	Tcp seg;
	Tcpctl *tcb;
	struct block *hbp, *dbp;

	tcb = (Tcpctl *) s->ptcl;

	dbp = NULL;
	seg.urg = 0;
	seg.source = s->lport;
	seg.dest = s->rport;
	seg.flags = ACK | PSH;
	seg.mss = 0;
	seg.ws = 0;
	seg.sack_ok = FALSE;
	seg.nr_sacks = 0;
	if (tcpporthogdefense)
		urandom_read(&seg.seq, sizeof(seg.seq));
	else
		seg.seq = tcb->snd.una - 1;
	seg.ack = tcb->rcv.nxt;
	tcb->last_ack_sent = seg.ack;
	tcb->rcv.una = 0;
	seg.wnd = tcb->rcv.wnd;
	seg.ts_val = tcb->ts_recent;
	if (tcb->state == Finwait2) {
		seg.flags |= FIN;
	} else {
		dbp = block_alloc(1, MEM_WAIT);
		dbp->wp++;
	}

	if (isv4(s->raddr)) {
		/* Build header, link data and compute cksum */
		tcb->protohdr.tcp4hdr.vihl = IP_VER4;
		hbp = htontcp4(&seg, dbp, &tcb->protohdr.tcp4hdr, tcb);
		if (hbp == NULL) {
			freeblist(dbp);
			return;
		}
		ipoput4(s->p->f, hbp, 0, s->ttl, s->tos, s);
	} else {
		/* Build header, link data and compute cksum */
		tcb->protohdr.tcp6hdr.vcf[0] = IP_VER6;
		hbp = htontcp6(&seg, dbp, &tcb->protohdr.tcp6hdr, tcb);
		if (hbp == NULL) {
			freeblist(dbp);
			return;
		}
		ipoput6(s->p->f, hbp, 0, s->ttl, s->tos, s);
	}
}

/*
 *  set connection to time out after 12 minutes
 */
static void tcpsetkacounter(Tcpctl *tcb)
{
	tcb->kacounter = (12 * 60 * 1000) / (tcb->katimer.start * MSPTICK);
	if (tcb->kacounter < 3)
		tcb->kacounter = 3;
}

/*
 *  if we've timed out, close the connection
 *  otherwise, send a keepalive and restart the timer
 */
static void tcpkeepalive(void *v)
{
	ERRSTACK(1);
	Tcpctl *tcb;
	struct conv *s;

	s = v;
	tcb = (Tcpctl *) s->ptcl;
	qlock(&s->qlock);
	if (waserror()) {
		qunlock(&s->qlock);
		nexterror();
	}
	if (tcb->state != Closed) {
		if (--(tcb->kacounter) <= 0) {
			localclose(s, "connection timed out");
		} else {
			tcpsendka(s);
			tcpgo(s->p->priv, &tcb->katimer);
		}
	}
	qunlock(&s->qlock);
	poperror();
}

/*
 *  start keepalive timer
 */
static void tcpstartka(struct conv *s, char **f, int n)
{
	Tcpctl *tcb;
	int x;

	tcb = (Tcpctl *) s->ptcl;
	if (tcb->state != Established)
		error(ENOTCONN, "connection must be in Establised state");
	if (n > 1) {
		x = atoi(f[1]);
		if (x >= MSPTICK)
			tcb->katimer.start = x / MSPTICK;
	}
	tcpsetkacounter(tcb);
	tcpgo(s->p->priv, &tcb->katimer);
}

/*
 *  turn checksums on/off
 */
static void tcpsetchecksum(struct conv *s, char **f, int unused)
{
	Tcpctl *tcb;

	tcb = (Tcpctl *) s->ptcl;
	tcb->nochecksum = !atoi(f[1]);
}

static void tcp_loss_event(struct conv *s, Tcpctl *tcb)
{
	uint32_t old_cwnd = tcb->cwind;

	/* Reno */
	tcb->ssthresh = tcb->cwind / 2;
	tcb->cwind = tcb->ssthresh;
	netlog(s->p->f, Logtcprxmt,
	       "%I.%d -> %I.%d: loss event, cwnd was %d, now %d\n",
	       s->laddr, s->lport, s->raddr, s->rport,
	       old_cwnd, tcb->cwind);
}

/* Called when we need to retrans the entire outstanding window (everything
 * previously sent, but unacknowledged). */
static void tcprxmit(struct conv *s)
{
	Tcpctl *tcb;

	tcb = (Tcpctl *) s->ptcl;

	tcb->flags |= FORCE;
	tcb->snd.rtx = tcb->snd.una;
	set_in_flight(tcb);

	tcpoutput(s);
}

/* The original RFC said to drop sacks on a timeout, since the receiver could
 * renege.  Later RFCs say we can keep them around, so long as we are careful.
 *
 * We'll go with a "flush if we have two timeouts" plan.  This doesn't have to
 * be perfect - there might be cases where we accidentally flush the sacks too
 * often.  Perhaps we never get dup_acks to start fast/sack rxmit.  The main
 * thing is that after multiple timeouts we flush the sacks, since the receiver
 * might renege.
 *
 * We also have an Akaros-specific problem.  We use the sacks to determine
 * in_flight.  Specifically, the (snd.nxt - upper right edge) is tracked as in
 * flight.  Usually the receiver will keep sacking that right edge all the way
 * up to snd.nxt, but they might not, and the gap might be quite large.  After a
 * timeout, that data is definitely not in flight.  If that block's size is
 * greater than cwnd, we'll never transmit.  This should be rare, and in that
 * case we can just dump the sacks.  The typical_mss fudge factor is so we can
 * send a reasonably-sized packet. */
static void timeout_handle_sacks(Tcpctl *tcb)
{
	struct sack_block *last_sack;

	if (tcb->snd.nr_sacks) {
		last_sack = &tcb->snd.sacks[tcb->snd.nr_sacks - 1];
		if (tcb->snd.flush_sacks || (tcb->snd.nxt - last_sack->right >=
		                             tcb->cwind - tcb->typical_mss)) {
			tcb->snd.nr_sacks = 0;
			tcb->snd.flush_sacks = FALSE;
		} else {
			tcb->snd.flush_sacks = TRUE;
		}
	}
}

static void tcptimeout(void *arg)
{
	ERRSTACK(1);
	struct conv *s;
	Tcpctl *tcb;
	int maxback;
	struct tcppriv *tpriv;

	s = (struct conv *)arg;
	tpriv = s->p->priv;
	tcb = (Tcpctl *) s->ptcl;

	qlock(&s->qlock);
	if (waserror()) {
		qunlock(&s->qlock);
		nexterror();
	}
	switch (tcb->state) {
		default:
			tcb->backoff++;
			if (tcb->state == Syn_sent)
				maxback = MAXBACKMS / 2;
			else
				maxback = MAXBACKMS;
			tcb->backedoff += tcb->timer.start * MSPTICK;
			if (tcb->backedoff >= maxback) {
				localclose(s, "connection timed out");
				break;
			}
			netlog(s->p->f, Logtcprxmt,
			       "%I.%d -> %I.%d: timeout rxmit una %u, rtx %u, nxt %u, in_flight %u, timer.start %u\n",
			       s->laddr, s->lport, s->raddr, s->rport,
			       tcb->snd.una, tcb->snd.rtx, tcb->snd.nxt, tcb->snd.in_flight,
			       tcb->timer.start);
			tcpsettimer(tcb);
			tcp_loss_event(s, tcb);
			/* Advance the recovery point.  Any dupacks/sacks below this won't
			 * trigger a new loss, since we won't reset_recovery() until we ack
			 * past recovery_pt. */
			tcb->snd.recovery = RTO_RETRANS_RECOVERY;
			tcb->snd.recovery_pt = tcb->snd.nxt;
			timeout_handle_sacks(tcb);
			tcprxmit(s);
			tpriv->stats[RetransTimeouts]++;
			break;
		case Time_wait:
			localclose(s, NULL);
			break;
		case Closed:
			break;
	}
	qunlock(&s->qlock);
	poperror();
}

static int inwindow(Tcpctl *tcb, int seq)
{
	return seq_within(seq, tcb->rcv.nxt, tcb->rcv.nxt + tcb->rcv.wnd - 1);
}

/*
 *  set up state for a received SYN (or SYN ACK) packet
 */
static void procsyn(struct conv *s, Tcp *seg)
{
	Tcpctl *tcb;

	tcb = (Tcpctl *) s->ptcl;
	tcb->flags |= FORCE;

	tcb->rcv.nxt = seg->seq + 1;
	tcb->rcv.urg = tcb->rcv.nxt;
	tcb->irs = seg->seq;

	/* our sending max segment size cannot be bigger than what he asked for */
	if (seg->mss != 0 && seg->mss < tcb->mss) {
		tcb->mss = seg->mss;
		tcb->typical_mss = tcb->mss;
	}
	adjust_typical_mss_for_opts(seg, tcb);

	tcb->snd.wnd = seg->wnd;
	tcb->cwind = tcb->typical_mss * CWIND_SCALE;
}

static int addreseq(Tcpctl *tcb, struct tcppriv *tpriv, Tcp *seg,
                    struct block *bp, uint16_t length)
{
	Reseq *rp, *rp1;
	int i, rqlen, qmax;

	rp = kzmalloc(sizeof(Reseq), 0);
	if (rp == NULL) {
		freeblist(bp);	/* bp always consumed by add_reseq */
		return 0;
	}

	rp->seg = *seg;
	rp->bp = bp;
	rp->length = length;

	track_rcv_sack(tcb, seg->seq, seg->seq + length);
	/* Place on reassembly list sorting by starting seq number */
	rp1 = tcb->reseq;
	if (rp1 == NULL || seq_lt(seg->seq, rp1->seg.seq)) {
		rp->next = rp1;
		tcb->reseq = rp;
		if (rp->next != NULL)
			tpriv->stats[OutOfOrder]++;
		return 0;
	}

	rqlen = 0;
	for (i = 0;; i++) {
		rqlen += rp1->length;
		if (rp1->next == NULL || seq_lt(seg->seq, rp1->next->seg.seq)) {
			rp->next = rp1->next;
			rp1->next = rp;
			if (rp->next != NULL)
				tpriv->stats[OutOfOrder]++;
			break;
		}
		rp1 = rp1->next;
	}
	qmax = QMAX << tcb->rcv.scale;
	/* Here's where we're reneging on previously reported sacks. */
	if (rqlen > qmax) {
		printd("resequence queue > window: %d > %d\n", rqlen, qmax);
		i = 0;
		for (rp1 = tcb->reseq; rp1 != NULL; rp1 = rp1->next) {
			printd("0x%#lx 0x%#lx 0x%#x\n", rp1->seg.seq,
				   rp1->seg.ack, rp1->seg.flags);
			if (i++ > 10) {
				printd("...\n");
				break;
			}
		}

		// delete entire reassembly queue; wait for retransmit.
		// - should we be smarter and only delete the tail?
		for (rp = tcb->reseq; rp != NULL; rp = rp1) {
			rp1 = rp->next;
			freeblist(rp->bp);
			kfree(rp);
		}
		tcb->reseq = NULL;
		tcb->rcv.nr_sacks = 0;

		return -1;
	}
	return 0;
}

static void getreseq(Tcpctl *tcb, Tcp *seg, struct block **bp, uint16_t *length)
{
	Reseq *rp;

	rp = tcb->reseq;
	if (rp == NULL)
		return;

	tcb->reseq = rp->next;

	*seg = rp->seg;
	*bp = rp->bp;
	*length = rp->length;

	kfree(rp);
}

static int tcptrim(Tcpctl *tcb, Tcp *seg, struct block **bp, uint16_t *length)
{
	uint16_t len;
	uint8_t accept;
	int dupcnt, excess;

	accept = 0;
	len = *length;
	if (seg->flags & SYN)
		len++;
	if (seg->flags & FIN)
		len++;

	if (tcb->rcv.wnd == 0) {
		if (len == 0 && seg->seq == tcb->rcv.nxt)
			return 0;
	} else {
		/* Some part of the segment should be in the window */
		if (inwindow(tcb, seg->seq))
			accept++;
		else if (len != 0) {
			if (inwindow(tcb, seg->seq + len - 1) ||
				seq_within(tcb->rcv.nxt, seg->seq, seg->seq + len - 1))
				accept++;
		}
	}
	if (!accept) {
		freeblist(*bp);
		return -1;
	}
	dupcnt = tcb->rcv.nxt - seg->seq;
	if (dupcnt > 0) {
		tcb->rerecv += dupcnt;
		if (seg->flags & SYN) {
			seg->flags &= ~SYN;
			seg->seq++;

			if (seg->urg > 1)
				seg->urg--;
			else
				seg->flags &= ~URG;
			dupcnt--;
		}
		if (dupcnt > 0) {
			pullblock(bp, (uint16_t) dupcnt);
			seg->seq += dupcnt;
			*length -= dupcnt;

			if (seg->urg > dupcnt)
				seg->urg -= dupcnt;
			else {
				seg->flags &= ~URG;
				seg->urg = 0;
			}
		}
	}
	excess = seg->seq + *length - (tcb->rcv.nxt + tcb->rcv.wnd);
	if (excess > 0) {
		tcb->rerecv += excess;
		*length -= excess;
		*bp = trimblock(*bp, 0, *length);
		if (*bp == NULL)
			panic("presotto is a boofhead");
		seg->flags &= ~FIN;
	}
	return 0;
}

static void tcpadvise(struct Proto *tcp, struct block *bp, char *msg)
{
	Tcp4hdr *h4;
	Tcp6hdr *h6;
	Tcpctl *tcb;
	uint8_t source[IPaddrlen];
	uint8_t dest[IPaddrlen];
	uint16_t psource, pdest;
	struct conv *s, **p;

	h4 = (Tcp4hdr *) (bp->rp);
	h6 = (Tcp6hdr *) (bp->rp);

	if ((h4->vihl & 0xF0) == IP_VER4) {
		v4tov6(dest, h4->tcpdst);
		v4tov6(source, h4->tcpsrc);
		psource = nhgets(h4->tcpsport);
		pdest = nhgets(h4->tcpdport);
	} else {
		ipmove(dest, h6->tcpdst);
		ipmove(source, h6->tcpsrc);
		psource = nhgets(h6->tcpsport);
		pdest = nhgets(h6->tcpdport);
	}

	/* Look for a connection */
	for (p = tcp->conv; *p; p++) {
		s = *p;
		tcb = (Tcpctl *) s->ptcl;
		if (s->rport == pdest)
			if (s->lport == psource)
				if (tcb->state != Closed)
					if (ipcmp(s->raddr, dest) == 0)
						if (ipcmp(s->laddr, source) == 0) {
							qlock(&s->qlock);
							switch (tcb->state) {
								case Syn_sent:
									localclose(s, msg);
									break;
							}
							qunlock(&s->qlock);
							freeblist(bp);
							return;
						}
	}
	freeblist(bp);
}

static void tcpporthogdefensectl(char *val)
{
	if (strcmp(val, "on") == 0)
		tcpporthogdefense = 1;
	else if (strcmp(val, "off") == 0)
		tcpporthogdefense = 0;
	else
		error(EINVAL, "unknown value for tcpporthogdefense");
}

/* called with c qlocked */
static void tcpctl(struct conv *c, char **f, int n)
{
	if (n == 1 && strcmp(f[0], "hangup") == 0)
		tcphangup(c);
	else if (n >= 1 && strcmp(f[0], "keepalive") == 0)
		tcpstartka(c, f, n);
	else if (n >= 1 && strcmp(f[0], "checksum") == 0)
		tcpsetchecksum(c, f, n);
	else if (n >= 1 && strcmp(f[0], "tcpporthogdefense") == 0)
		tcpporthogdefensectl(f[1]);
	else
		error(EINVAL, "unknown command to %s", __func__);
}

static int tcpstats(struct Proto *tcp, char *buf, int len)
{
	struct tcppriv *priv;
	char *p, *e;
	int i;

	priv = tcp->priv;
	p = buf;
	e = p + len;
	for (i = 0; i < Nstats; i++)
		p = seprintf(p, e, "%s: %u\n", statnames[i], priv->stats[i]);
	return p - buf;
}

/*
 *  garbage collect any stale conversations:
 *	- SYN received but no SYN-ACK after 5 seconds (could be the SYN attack)
 *	- Finwait2 after 5 minutes
 *
 *  this is called whenever we run out of channels.  Both checks are
 *  of questionable validity so we try to use them only when we're
 *  up against the wall.
 */
static int tcpgc(struct Proto *tcp)
{
	struct conv *c, **pp, **ep;
	int n;
	Tcpctl *tcb;

	n = 0;
	ep = &tcp->conv[tcp->nc];
	for (pp = tcp->conv; pp < ep; pp++) {
		c = *pp;
		if (c == NULL)
			break;
		if (!canqlock(&c->qlock))
			continue;
		tcb = (Tcpctl *) c->ptcl;
		if (tcb->state == Finwait2) {
			if (NOW - tcb->time > 5 * 60 * 1000) {
				localclose(c, "timed out");
				n++;
			}
		}
		qunlock(&c->qlock);
	}
	return n;
}

static void tcpsettimer(Tcpctl *tcb)
{
	int x;

	/* round trip dependency */
	x = backoff(tcb->backoff) * (tcb->srtt + MAX(4 * tcb->mdev, MSPTICK));
	x = DIV_ROUND_UP(x, MSPTICK);

	/* Bounded twixt 1/2 and 64 seconds.  RFC 6298 suggested min is 1 second. */
	if (x < 500 / MSPTICK)
		x = 500 / MSPTICK;
	else if (x > (64000 / MSPTICK))
		x = 64000 / MSPTICK;
	tcb->timer.start = x;
}

static struct tcppriv *debug_priv;

/* Kfunc this */
int dump_tcp_ht(void)
{
	if (!debug_priv)
		return -1;
	dump_ipht(&debug_priv->ht);
	return 0;
}

void tcpinit(struct Fs *fs)
{
	struct Proto *tcp;
	struct tcppriv *tpriv;

	tcp = kzmalloc(sizeof(struct Proto), 0);
	tpriv = tcp->priv = kzmalloc(sizeof(struct tcppriv), 0);
	debug_priv = tpriv;
	qlock_init(&tpriv->tl);
	qlock_init(&tpriv->apl);
	tcp->name = "tcp";
	tcp->connect = tcpconnect;
	tcp->announce = tcpannounce;
	tcp->bypass = tcpbypass;
	tcp->ctl = tcpctl;
	tcp->state = tcpstate;
	tcp->create = tcpcreate;
	tcp->close = tcpclose;
	tcp->shutdown = tcpshutdown;
	tcp->rcv = tcpiput;
	tcp->advise = tcpadvise;
	tcp->stats = tcpstats;
	tcp->inuse = tcpinuse;
	tcp->gc = tcpgc;
	tcp->ipproto = IP_TCPPROTO;
	tcp->nc = 4096;
	tcp->ptclsize = sizeof(Tcpctl);
	tpriv->stats[MaxConn] = tcp->nc;

	Fsproto(fs, tcp);
}

static void tcpsetscale(struct conv *s, Tcpctl *tcb, uint16_t rcvscale,
                        uint16_t sndscale)
{
	if (rcvscale) {
		tcb->rcv.scale = rcvscale & 0xff;
		tcb->snd.scale = sndscale & 0xff;
		tcb->window = QMAX << tcb->rcv.scale;
	} else {
		tcb->rcv.scale = 0;
		tcb->snd.scale = 0;
		tcb->window = QMAX;
	}
}
