/*
 * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1994
 *	The Regents of the University of California.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 *	@(#)tcp_input.c	8.5 (Berkeley) 4/10/94
 * tcp_input.c,v 1.10 1994/10/13 18:36:32 wollman Exp
 */

/*
 * Changes and additions relating to SLiRP
 * Copyright (c) 1995 Danny Gasparovski.
 *
 * Please read the file COPYRIGHT for the
 * terms and conditions of the copyright.
 */

#include <slirp.h>
#include "ip_icmp.h"

#define TCPREXMTTHRESH 3

#define TCP_PAWS_IDLE (24 * 24 * 60 * 60 * PR_SLOWHZ)

/* for modulo comparisons of timestamps */
#define TSTMP_LT(a, b) ((int)((a) - (b)) < 0)
#define TSTMP_GEQ(a, b) ((int)((a) - (b)) >= 0)

/*
 * Insert segment ti into reassembly queue of tcp with
 * control block tp.  Return TH_FIN if reassembly now includes
 * a segment with FIN.  The macro form does the common case inline
 * (segment is the next to be received on an established connection,
 * and the queue is empty), avoiding linkage into and removal
 * from the queue and repetition of various conversions.
 * Set DELACK for segments received in order, but ack immediately
 * when segments are out of order (so fast retransmit can work).
 */
#ifdef TCP_ACK_HACK
#define TCP_REASS(tp, ti, m, so, flags)                                \
    {                                                                  \
        if ((ti)->ti_seq == (tp)->rcv_nxt && tcpfrag_list_empty(tp) && \
            (tp)->t_state == TCPS_ESTABLISHED) {                       \
            if (ti->ti_flags & TH_PUSH)                                \
                tp->t_flags |= TF_ACKNOW;                              \
            else                                                       \
                tp->t_flags |= TF_DELACK;                              \
            (tp)->rcv_nxt += (ti)->ti_len;                             \
            flags = (ti)->ti_flags & TH_FIN;                           \
            if (so->so_emu) {                                          \
                if (tcp_emu((so), (m)))                                \
                    sbappend((so), (m));                               \
            } else                                                     \
                sbappend((so), (m));                                   \
        } else {                                                       \
            (flags) = tcp_reass((tp), (ti), (m));                      \
            tp->t_flags |= TF_ACKNOW;                                  \
        }                                                              \
    }
#else
#define TCP_REASS(tp, ti, m, so, flags)                                \
    {                                                                  \
        if ((ti)->ti_seq == (tp)->rcv_nxt && tcpfrag_list_empty(tp) && \
            (tp)->t_state == TCPS_ESTABLISHED) {                       \
            tp->t_flags |= TF_DELACK;                                  \
            (tp)->rcv_nxt += (ti)->ti_len;                             \
            flags = (ti)->ti_flags & TH_FIN;                           \
            if (so->so_emu) {                                          \
                if (tcp_emu((so), (m)))                                \
                    sbappend(so, (m));                                 \
            } else                                                     \
                sbappend((so), (m));                                   \
        } else {                                                       \
            (flags) = tcp_reass((tp), (ti), (m));                      \
            tp->t_flags |= TF_ACKNOW;                                  \
        }                                                              \
    }
#endif
static void tcp_dooptions(struct tcpcb *tp, u_char *cp, int cnt,
                          struct tcpiphdr *ti);
static void tcp_xmit_timer(register struct tcpcb *tp, int rtt);

static int tcp_reass(register struct tcpcb *tp, register struct tcpiphdr *ti,
                     struct mbuf *m)
{
    register struct tcpiphdr *q;
    struct socket *so = tp->t_socket;
    int flags;

    /*
     * Call with ti==NULL after become established to
     * force pre-ESTABLISHED data up to user socket.
     */
    if (ti == NULL)
        goto present;

    /*
     * Find a segment which begins after this one does.
     */
    for (q = tcpfrag_list_first(tp); !tcpfrag_list_end(q, tp);
         q = tcpiphdr_next(q))
        if (SEQ_GT(q->ti_seq, ti->ti_seq))
            break;

    /*
     * If there is a preceding segment, it may provide some of
     * our data already.  If so, drop the data from the incoming
     * segment.  If it provides all of our data, drop us.
     */
    if (!tcpfrag_list_end(tcpiphdr_prev(q), tp)) {
        register int i;
        q = tcpiphdr_prev(q);
        /* conversion to int (in i) handles seq wraparound */
        i = q->ti_seq + q->ti_len - ti->ti_seq;
        if (i > 0) {
            if (i >= ti->ti_len) {
                m_free(m);
                /*
                 * Try to present any queued data
                 * at the left window edge to the user.
                 * This is needed after the 3-WHS
                 * completes.
                 */
                goto present; /* ??? */
            }
            m_adj(m, i);
            ti->ti_len -= i;
            ti->ti_seq += i;
        }
        q = tcpiphdr_next(q);
    }
    ti->ti_mbuf = m;

    /*
     * While we overlap succeeding segments trim them or,
     * if they are completely covered, dequeue them.
     */
    while (!tcpfrag_list_end(q, tp)) {
        register int i = (ti->ti_seq + ti->ti_len) - q->ti_seq;
        if (i <= 0)
            break;
        if (i < q->ti_len) {
            q->ti_seq += i;
            q->ti_len -= i;
            m_adj(q->ti_mbuf, i);
            break;
        }
        q = tcpiphdr_next(q);
        m = tcpiphdr_prev(q)->ti_mbuf;
        remque(tcpiphdr2qlink(tcpiphdr_prev(q)));
        m_free(m);
    }

    /*
     * Stick new segment in its place.
     */
    insque(tcpiphdr2qlink(ti), tcpiphdr2qlink(tcpiphdr_prev(q)));

present:
    /*
     * Present data to user, advancing rcv_nxt through
     * completed sequence space.
     */
    if (!TCPS_HAVEESTABLISHED(tp->t_state))
        return (0);
    ti = tcpfrag_list_first(tp);
    if (tcpfrag_list_end(ti, tp) || ti->ti_seq != tp->rcv_nxt)
        return (0);
    if (tp->t_state == TCPS_SYN_RECEIVED && ti->ti_len)
        return (0);
    do {
        tp->rcv_nxt += ti->ti_len;
        flags = ti->ti_flags & TH_FIN;
        remque(tcpiphdr2qlink(ti));
        m = ti->ti_mbuf;
        ti = tcpiphdr_next(ti);
        if (so->so_state & SS_FCANTSENDMORE)
            m_free(m);
        else {
            if (so->so_emu) {
                if (tcp_emu(so, m))
                    sbappend(so, m);
            } else
                sbappend(so, m);
        }
    } while (ti != (struct tcpiphdr *)tp && ti->ti_seq == tp->rcv_nxt);
    return (flags);
}

/*
 * TCP input routine, follows pages 65-76 of the
 * protocol specification dated September, 1981 very closely.
 */
void tcp_input(struct mbuf *m, int iphlen, struct socket *inso)
{
    struct ip save_ip, *ip;
    register struct tcpiphdr *ti;
    caddr_t optp = NULL;
    int optlen = 0;
    int len, tlen, off;
    register struct tcpcb *tp = NULL;
    register int tiflags;
    struct socket *so = NULL;
    int todrop, acked, ourfinisacked, needoutput = 0;
    int iss = 0;
    u_long tiwin;
    int ret;
    struct ex_list *ex_ptr;
    Slirp *slirp;

    DEBUG_CALL("tcp_input");
    DEBUG_ARGS((dfd, " m = %8lx  iphlen = %2d  inso = %lx\n", (long)m, iphlen,
                (long)inso));

    /*
     * If called with m == 0, then we're continuing the connect
     */
    if (m == NULL) {
        so = inso;
        slirp = so->slirp;

        /* Re-set a few variables */
        tp = sototcpcb(so);
        m = so->so_m;
        so->so_m = NULL;
        ti = so->so_ti;
        tiwin = ti->ti_win;
        tiflags = ti->ti_flags;

        goto cont_conn;
    }
    slirp = m->slirp;

    /*
     * Get IP and TCP header together in first mbuf.
     * Note: IP leaves IP header in first mbuf.
     */
    ti = mtod(m, struct tcpiphdr *);
    if (iphlen > sizeof(struct ip)) {
        ip_stripoptions(m, (struct mbuf *)0);
        iphlen = sizeof(struct ip);
    }
    /* XXX Check if too short */


    /*
     * Save a copy of the IP header in case we want restore it
     * for sending an ICMP error message in response.
     */
    ip = mtod(m, struct ip *);
    save_ip = *ip;
    save_ip.ip_len += iphlen;

    /*
     * Checksum extended TCP header and data.
     */
    tlen = ((struct ip *)ti)->ip_len;
    tcpiphdr2qlink(ti)->next = tcpiphdr2qlink(ti)->prev = NULL;
    memset(&ti->ti_i.ih_mbuf, 0, sizeof(struct mbuf_ptr));
    ti->ti_x1 = 0;
    ti->ti_len = htons((uint16_t)tlen);
    len = sizeof(struct ip) + tlen;
    if (cksum(m, len)) {
        goto drop;
    }

    /*
     * Check that TCP offset makes sense,
     * pull out TCP options and adjust length.		XXX
     */
    off = ti->ti_off << 2;
    if (off < sizeof(struct tcphdr) || off > tlen) {
        goto drop;
    }
    tlen -= off;
    ti->ti_len = tlen;
    if (off > sizeof(struct tcphdr)) {
        optlen = off - sizeof(struct tcphdr);
        optp = mtod(m, caddr_t) + sizeof(struct tcpiphdr);
    }
    tiflags = ti->ti_flags;

    /*
     * Convert TCP protocol specific fields to host format.
     */
    NTOHL(ti->ti_seq);
    NTOHL(ti->ti_ack);
    NTOHS(ti->ti_win);
    NTOHS(ti->ti_urp);

    /*
     * Drop TCP, IP headers and TCP options.
     */
    m->m_data += sizeof(struct tcpiphdr) + off - sizeof(struct tcphdr);
    m->m_len -= sizeof(struct tcpiphdr) + off - sizeof(struct tcphdr);

    /*
     * Locate pcb for segment.
     */
findso:
    so = slirp->tcp_last_so;
    if (so->so_fport != ti->ti_dport || so->so_lport != ti->ti_sport ||
        so->so_laddr.s_addr != ti->ti_src.s_addr ||
        so->so_faddr.s_addr != ti->ti_dst.s_addr) {
        so = solookup(&slirp->tcb, ti->ti_src, ti->ti_sport, ti->ti_dst,
                      ti->ti_dport);
        if (so)
            slirp->tcp_last_so = so;
    }

    /*
     * If the state is CLOSED (i.e., TCB does not exist) then
     * all data in the incoming segment is discarded.
     * If the TCB exists but is in CLOSED state, it is embryonic,
     * but should either do a listen or a connect soon.
     *
     * state == CLOSED means we've done socreate() but haven't
     * attached it to a protocol yet...
     *
     * XXX If a TCB does not exist, and the TH_SYN flag is
     * the only flag set, then create a session, mark it
     * as if it was LISTENING, and continue...
     */
    if (so == NULL) {
        if (slirp->restricted) {
            /* Any hostfwds will have an existing socket, so we only get here
             * for non-hostfwd connections. These should be dropped, unless it
             * happens to be a guestfwd.
             */
            for (ex_ptr = slirp->exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) {
                if (ex_ptr->ex_fport == ti->ti_dport &&
                    ti->ti_dst.s_addr == ex_ptr->ex_addr.s_addr) {
                    break;
                }
            }
            if (!ex_ptr) {
                goto dropwithreset;
            }
        }

        if ((tiflags & (TH_SYN | TH_FIN | TH_RST | TH_URG | TH_ACK)) != TH_SYN)
            goto dropwithreset;

        if ((so = socreate(slirp)) == NULL)
            goto dropwithreset;
        if (tcp_attach(so) < 0) {
            free(so); /* Not sofree (if it failed, it's not insqued) */
            goto dropwithreset;
        }

        sbreserve(&so->so_snd, TCP_SNDSPACE);
        sbreserve(&so->so_rcv, TCP_RCVSPACE);

        so->so_laddr = ti->ti_src;
        so->so_lport = ti->ti_sport;
        so->so_faddr = ti->ti_dst;
        so->so_fport = ti->ti_dport;

        if ((so->so_iptos = tcp_tos(so)) == 0)
            so->so_iptos = ((struct ip *)ti)->ip_tos;

        tp = sototcpcb(so);
        tp->t_state = TCPS_LISTEN;
    }

    /*
     * If this is a still-connecting socket, this probably
     * a retransmit of the SYN.  Whether it's a retransmit SYN
     * or something else, we nuke it.
     */
    if (so->so_state & SS_ISFCONNECTING)
        goto drop;

    tp = sototcpcb(so);

    /* XXX Should never fail */
    if (tp == NULL)
        goto dropwithreset;
    if (tp->t_state == TCPS_CLOSED)
        goto drop;

    tiwin = ti->ti_win;

    /*
     * Segment received on connection.
     * Reset idle time and keep-alive timer.
     */
    tp->t_idle = 0;
    if (SO_OPTIONS)
        tp->t_timer[TCPT_KEEP] = TCPTV_KEEPINTVL;
    else
        tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_IDLE;

    /*
     * Process options if not in LISTEN state,
     * else do it below (after getting remote address).
     */
    if (optp && tp->t_state != TCPS_LISTEN)
        tcp_dooptions(tp, (u_char *)optp, optlen, ti);

    /*
     * Header prediction: check for the two common cases
     * of a uni-directional data xfer.  If the packet has
     * no control flags, is in-sequence, the window didn't
     * change and we're not retransmitting, it's a
     * candidate.  If the length is zero and the ack moved
     * forward, we're the sender side of the xfer.  Just
     * free the data acked & wake any higher level process
     * that was blocked waiting for space.  If the length
     * is non-zero and the ack didn't move, we're the
     * receiver side.  If we're getting packets in-order
     * (the reassembly queue is empty), add the data to
     * the socket buffer and note that we need a delayed ack.
     *
     * XXX Some of these tests are not needed
     * eg: the tiwin == tp->snd_wnd prevents many more
     * predictions.. with no *real* advantage..
     */
    if (tp->t_state == TCPS_ESTABLISHED &&
        (tiflags & (TH_SYN | TH_FIN | TH_RST | TH_URG | TH_ACK)) == TH_ACK &&
        ti->ti_seq == tp->rcv_nxt && tiwin && tiwin == tp->snd_wnd &&
        tp->snd_nxt == tp->snd_max) {
        if (ti->ti_len == 0) {
            if (SEQ_GT(ti->ti_ack, tp->snd_una) &&
                SEQ_LEQ(ti->ti_ack, tp->snd_max) &&
                tp->snd_cwnd >= tp->snd_wnd) {
                /*
                 * this is a pure ack for outstanding data.
                 */
                if (tp->t_rtt && SEQ_GT(ti->ti_ack, tp->t_rtseq))
                    tcp_xmit_timer(tp, tp->t_rtt);
                acked = ti->ti_ack - tp->snd_una;
                sbdrop(&so->so_snd, acked);
                tp->snd_una = ti->ti_ack;
                m_free(m);

                /*
                 * If all outstanding data are acked, stop
                 * retransmit timer, otherwise restart timer
                 * using current (possibly backed-off) value.
                 * If process is waiting for space,
                 * wakeup/selwakeup/signal.  If data
                 * are ready to send, let tcp_output
                 * decide between more output or persist.
                 */
                if (tp->snd_una == tp->snd_max)
                    tp->t_timer[TCPT_REXMT] = 0;
                else if (tp->t_timer[TCPT_PERSIST] == 0)
                    tp->t_timer[TCPT_REXMT] = tp->t_rxtcur;

                /*
                 * This is called because sowwakeup might have
                 * put data into so_snd.  Since we don't so sowwakeup,
                 * we don't need this.. XXX???
                 */
                if (so->so_snd.sb_cc)
                    (void)tcp_output(tp);

                return;
            }
        } else if (ti->ti_ack == tp->snd_una && tcpfrag_list_empty(tp) &&
                   ti->ti_len <= sbspace(&so->so_rcv)) {
            /*
             * this is a pure, in-sequence data packet
             * with nothing on the reassembly queue and
             * we have enough buffer space to take it.
             */
            tp->rcv_nxt += ti->ti_len;
            /*
             * Add data to socket buffer.
             */
            if (so->so_emu) {
                if (tcp_emu(so, m))
                    sbappend(so, m);
            } else
                sbappend(so, m);

            /*
             * If this is a short packet, then ACK now - with Nagel
             *	congestion avoidance sender won't send more until
             *	he gets an ACK.
             *
             * It is better to not delay acks at all to maximize
             * TCP throughput.  See RFC 2581.
             */
            tp->t_flags |= TF_ACKNOW;
            tcp_output(tp);
            return;
        }
    } /* header prediction */
    /*
     * Calculate amount of space in receive window,
     * and then do TCP input processing.
     * Receive window is amount of space in rcv queue,
     * but not less than advertised window.
     */
    {
        int win;
        win = sbspace(&so->so_rcv);
        if (win < 0)
            win = 0;
        tp->rcv_wnd = max(win, (int)(tp->rcv_adv - tp->rcv_nxt));
    }

    switch (tp->t_state) {
    /*
     * If the state is LISTEN then ignore segment if it contains an RST.
     * If the segment contains an ACK then it is bad and send a RST.
     * If it does not contain a SYN then it is not interesting; drop it.
     * Don't bother responding if the destination was a broadcast.
     * Otherwise initialize tp->rcv_nxt, and tp->irs, select an initial
     * tp->iss, and send a segment:
     *     <SEQ=ISS><ACK=RCV_NXT><CTL=SYN,ACK>
     * Also initialize tp->snd_nxt to tp->iss+1 and tp->snd_una to tp->iss.
     * Fill in remote peer address fields if not previously specified.
     * Enter SYN_RECEIVED state, and process any other fields of this
     * segment in this state.
     */
    case TCPS_LISTEN: {
        if (tiflags & TH_RST)
            goto drop;
        if (tiflags & TH_ACK)
            goto dropwithreset;
        if ((tiflags & TH_SYN) == 0)
            goto drop;

        /*
         * This has way too many gotos...
         * But a bit of spaghetti code never hurt anybody :)
         */

        /*
         * If this is destined for the control address, then flag to
         * tcp_ctl once connected, otherwise connect
         */
        if ((so->so_faddr.s_addr & slirp->vnetwork_mask.s_addr) ==
            slirp->vnetwork_addr.s_addr) {
            if (so->so_faddr.s_addr != slirp->vhost_addr.s_addr &&
                so->so_faddr.s_addr != slirp->vnameserver_addr.s_addr) {
                /* May be an add exec */
                for (ex_ptr = slirp->exec_list; ex_ptr;
                     ex_ptr = ex_ptr->ex_next) {
                    if (ex_ptr->ex_fport == so->so_fport &&
                        so->so_faddr.s_addr == ex_ptr->ex_addr.s_addr) {
                        so->so_state |= SS_CTL;
                        break;
                    }
                }
                if (so->so_state & SS_CTL) {
                    goto cont_input;
                }
            }
            /* CTL_ALIAS: Do nothing, tcp_fconnect will be called on it */
        }

        if (so->so_emu & EMU_NOCONNECT) {
            so->so_emu &= ~EMU_NOCONNECT;
            goto cont_input;
        }

        if ((tcp_fconnect(so) == -1) && (errno != EINPROGRESS) &&
            (errno != EWOULDBLOCK)) {
            u_char code = ICMP_UNREACH_NET;
            DEBUG_MISC(
                (dfd, " tcp fconnect errno = %d-%s\n", errno, strerror(errno)));
            if (errno == ECONNREFUSED) {
                /* ACK the SYN, send RST to refuse the connection */
                tcp_respond(tp, ti, m, ti->ti_seq + 1, (tcp_seq)0,
                            TH_RST | TH_ACK);
            } else {
                if (errno == EHOSTUNREACH)
                    code = ICMP_UNREACH_HOST;
                HTONL(ti->ti_seq); /* restore tcp header */
                HTONL(ti->ti_ack);
                HTONS(ti->ti_win);
                HTONS(ti->ti_urp);
                m->m_data -=
                    sizeof(struct tcpiphdr) + off - sizeof(struct tcphdr);
                m->m_len +=
                    sizeof(struct tcpiphdr) + off - sizeof(struct tcphdr);
                *ip = save_ip;
                icmp_error(m, ICMP_UNREACH, code, 0, strerror(errno));
            }
            tcp_close(tp);
            m_free(m);
        } else {
            /*
             * Haven't connected yet, save the current mbuf
             * and ti, and return
             * XXX Some OS's don't tell us whether the connect()
             * succeeded or not.  So we must time it out.
             */
            so->so_m = m;
            so->so_ti = ti;
            tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT;
            tp->t_state = TCPS_SYN_RECEIVED;
            tcp_template(tp);
        }
        return;

    cont_conn:
        /* m==NULL
         * Check if the connect succeeded
         */
        if (so->so_state & SS_NOFDREF) {
            tp = tcp_close(tp);
            goto dropwithreset;
        }
    cont_input:
        tcp_template(tp);

        if (optp)
            tcp_dooptions(tp, (u_char *)optp, optlen, ti);

        if (iss)
            tp->iss = iss;
        else
            tp->iss = slirp->tcp_iss;
        slirp->tcp_iss += TCP_ISSINCR / 2;
        tp->irs = ti->ti_seq;
        tcp_sendseqinit(tp);
        tcp_rcvseqinit(tp);
        tp->t_flags |= TF_ACKNOW;
        tp->t_state = TCPS_SYN_RECEIVED;
        tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT;
        goto trimthenstep6;
    } /* case TCPS_LISTEN */

    /*
     * If the state is SYN_SENT:
     *	if seg contains an ACK, but not for our SYN, drop the input.
     *	if seg contains a RST, then drop the connection.
     *	if seg does not contain SYN, then drop it.
     * Otherwise this is an acceptable SYN segment
     *	initialize tp->rcv_nxt and tp->irs
     *	if seg contains ack then advance tp->snd_una
     *	if SYN has been acked change to ESTABLISHED else SYN_RCVD state
     *	arrange for segment to be acked (eventually)
     *	continue processing rest of data/controls, beginning with URG
     */
    case TCPS_SYN_SENT:
        if ((tiflags & TH_ACK) &&
            (SEQ_LEQ(ti->ti_ack, tp->iss) || SEQ_GT(ti->ti_ack, tp->snd_max)))
            goto dropwithreset;

        if (tiflags & TH_RST) {
            if (tiflags & TH_ACK) {
                tcp_drop(tp, 0); /* XXX Check t_softerror! */
            }
            goto drop;
        }

        if ((tiflags & TH_SYN) == 0)
            goto drop;
        if (tiflags & TH_ACK) {
            tp->snd_una = ti->ti_ack;
            if (SEQ_LT(tp->snd_nxt, tp->snd_una))
                tp->snd_nxt = tp->snd_una;
        }

        tp->t_timer[TCPT_REXMT] = 0;
        tp->irs = ti->ti_seq;
        tcp_rcvseqinit(tp);
        tp->t_flags |= TF_ACKNOW;
        if (tiflags & TH_ACK && SEQ_GT(tp->snd_una, tp->iss)) {
            soisfconnected(so);
            tp->t_state = TCPS_ESTABLISHED;

            (void)tcp_reass(tp, (struct tcpiphdr *)0, (struct mbuf *)0);
            /*
             * if we didn't have to retransmit the SYN,
             * use its rtt as our initial srtt & rtt var.
             */
            if (tp->t_rtt)
                tcp_xmit_timer(tp, tp->t_rtt);
        } else
            tp->t_state = TCPS_SYN_RECEIVED;

    trimthenstep6:
        /*
         * Advance ti->ti_seq to correspond to first data byte.
         * If data, trim to stay within window,
         * dropping FIN if necessary.
         */
        ti->ti_seq++;
        if (ti->ti_len > tp->rcv_wnd) {
            todrop = ti->ti_len - tp->rcv_wnd;
            m_adj(m, -todrop);
            ti->ti_len = tp->rcv_wnd;
            tiflags &= ~TH_FIN;
        }
        tp->snd_wl1 = ti->ti_seq - 1;
        tp->rcv_up = ti->ti_seq;
        goto step6;
    } /* switch tp->t_state */
    /*
     * States other than LISTEN or SYN_SENT.
     * Check that at least some bytes of segment are within
     * receive window.  If segment begins before rcv_nxt,
     * drop leading data (and SYN); if nothing left, just ack.
     */
    todrop = tp->rcv_nxt - ti->ti_seq;
    if (todrop > 0) {
        if (tiflags & TH_SYN) {
            tiflags &= ~TH_SYN;
            ti->ti_seq++;
            if (ti->ti_urp > 1)
                ti->ti_urp--;
            else
                tiflags &= ~TH_URG;
            todrop--;
        }
        /*
         * Following if statement from Stevens, vol. 2, p. 960.
         */
        if (todrop > ti->ti_len ||
            (todrop == ti->ti_len && (tiflags & TH_FIN) == 0)) {
            /*
             * Any valid FIN must be to the left of the window.
             * At this point the FIN must be a duplicate or out
             * of sequence; drop it.
             */
            tiflags &= ~TH_FIN;

            /*
             * Send an ACK to resynchronize and drop any data.
             * But keep on processing for RST or ACK.
             */
            tp->t_flags |= TF_ACKNOW;
            todrop = ti->ti_len;
        }
        m_adj(m, todrop);
        ti->ti_seq += todrop;
        ti->ti_len -= todrop;
        if (ti->ti_urp > todrop)
            ti->ti_urp -= todrop;
        else {
            tiflags &= ~TH_URG;
            ti->ti_urp = 0;
        }
    }
    /*
     * If new data are received on a connection after the
     * user processes are gone, then RST the other end.
     */
    if ((so->so_state & SS_NOFDREF) && tp->t_state > TCPS_CLOSE_WAIT &&
        ti->ti_len) {
        tp = tcp_close(tp);
        goto dropwithreset;
    }

    /*
     * If segment ends after window, drop trailing data
     * (and PUSH and FIN); if nothing left, just ACK.
     */
    todrop = (ti->ti_seq + ti->ti_len) - (tp->rcv_nxt + tp->rcv_wnd);
    if (todrop > 0) {
        if (todrop >= ti->ti_len) {
            /*
             * If a new connection request is received
             * while in TIME_WAIT, drop the old connection
             * and start over if the sequence numbers
             * are above the previous ones.
             */
            if (tiflags & TH_SYN && tp->t_state == TCPS_TIME_WAIT &&
                SEQ_GT(ti->ti_seq, tp->rcv_nxt)) {
                iss = tp->rcv_nxt + TCP_ISSINCR;
                tp = tcp_close(tp);
                goto findso;
            }
            /*
             * If window is closed can only take segments at
             * window edge, and have to drop data and PUSH from
             * incoming segments.  Continue processing, but
             * remember to ack.  Otherwise, drop segment
             * and ack.
             */
            if (tp->rcv_wnd == 0 && ti->ti_seq == tp->rcv_nxt) {
                tp->t_flags |= TF_ACKNOW;
            } else {
                goto dropafterack;
            }
        }
        m_adj(m, -todrop);
        ti->ti_len -= todrop;
        tiflags &= ~(TH_PUSH | TH_FIN);
    }

    /*
     * If the RST bit is set examine the state:
     *    SYN_RECEIVED STATE:
     *	If passive open, return to LISTEN state.
     *	If active open, inform user that connection was refused.
     *    ESTABLISHED, FIN_WAIT_1, FIN_WAIT2, CLOSE_WAIT STATES:
     *	Inform user that connection was reset, and close tcb.
     *    CLOSING, LAST_ACK, TIME_WAIT STATES
     *	Close the tcb.
     */
    if (tiflags & TH_RST)
        switch (tp->t_state) {
        case TCPS_SYN_RECEIVED:
        case TCPS_ESTABLISHED:
        case TCPS_FIN_WAIT_1:
        case TCPS_FIN_WAIT_2:
        case TCPS_CLOSE_WAIT:
            tp->t_state = TCPS_CLOSED;
            tcp_close(tp);
            goto drop;

        case TCPS_CLOSING:
        case TCPS_LAST_ACK:
        case TCPS_TIME_WAIT:
            tcp_close(tp);
            goto drop;
        }

    /*
     * If a SYN is in the window, then this is an
     * error and we send an RST and drop the connection.
     */
    if (tiflags & TH_SYN) {
        tp = tcp_drop(tp, 0);
        goto dropwithreset;
    }

    /*
     * If the ACK bit is off we drop the segment and return.
     */
    if ((tiflags & TH_ACK) == 0)
        goto drop;

    /*
     * Ack processing.
     */
    switch (tp->t_state) {
    /*
     * In SYN_RECEIVED state if the ack ACKs our SYN then enter
     * ESTABLISHED state and continue processing, otherwise
     * send an RST.  una<=ack<=max
     */
    case TCPS_SYN_RECEIVED:

        if (SEQ_GT(tp->snd_una, ti->ti_ack) || SEQ_GT(ti->ti_ack, tp->snd_max))
            goto dropwithreset;
        tp->t_state = TCPS_ESTABLISHED;
        /*
         * The sent SYN is ack'ed with our sequence number +1
         * The first data byte already in the buffer will get
         * lost if no correction is made.  This is only needed for
         * SS_CTL since the buffer is empty otherwise.
         * tp->snd_una++; or:
         */
        tp->snd_una = ti->ti_ack;
        if (so->so_state & SS_CTL) {
            /* So tcp_ctl reports the right state */
            ret = tcp_ctl(so);
            if (ret == 1) {
                soisfconnected(so);
                so->so_state &= ~SS_CTL; /* success XXX */
            } else if (ret == 2) {
                so->so_state &= SS_PERSISTENT_MASK;
                so->so_state |= SS_NOFDREF; /* CTL_CMD */
            } else {
                needoutput = 1;
                tp->t_state = TCPS_FIN_WAIT_1;
            }
        } else {
            soisfconnected(so);
        }

        (void)tcp_reass(tp, (struct tcpiphdr *)0, (struct mbuf *)0);
        tp->snd_wl1 = ti->ti_seq - 1;
        /* Avoid ack processing; snd_una==ti_ack  =>  dup ack */
        goto synrx_to_est;
        /* fall into ... */

    /*
     * In ESTABLISHED state: drop duplicate ACKs; ACK out of range
     * ACKs.  If the ack is in the range
     *	tp->snd_una < ti->ti_ack <= tp->snd_max
     * then advance tp->snd_una to ti->ti_ack and drop
     * data from the retransmission queue.  If this ACK reflects
     * more up to date window information we update our window information.
     */
    case TCPS_ESTABLISHED:
    case TCPS_FIN_WAIT_1:
    case TCPS_FIN_WAIT_2:
    case TCPS_CLOSE_WAIT:
    case TCPS_CLOSING:
    case TCPS_LAST_ACK:
    case TCPS_TIME_WAIT:

        if (SEQ_LEQ(ti->ti_ack, tp->snd_una)) {
            if (ti->ti_len == 0 && tiwin == tp->snd_wnd) {
                DEBUG_MISC(
                    (dfd, " dup ack  m = %lx  so = %lx\n", (long)m, (long)so));
                /*
                 * If we have outstanding data (other than
                 * a window probe), this is a completely
                 * duplicate ack (ie, window info didn't
                 * change), the ack is the biggest we've
                 * seen and we've seen exactly our rexmt
                 * threshold of them, assume a packet
                 * has been dropped and retransmit it.
                 * Kludge snd_nxt & the congestion
                 * window so we send only this one
                 * packet.
                 *
                 * We know we're losing at the current
                 * window size so do congestion avoidance
                 * (set ssthresh to half the current window
                 * and pull our congestion window back to
                 * the new ssthresh).
                 *
                 * Dup acks mean that packets have left the
                 * network (they're now cached at the receiver)
                 * so bump cwnd by the amount in the receiver
                 * to keep a constant cwnd packets in the
                 * network.
                 */
                if (tp->t_timer[TCPT_REXMT] == 0 || ti->ti_ack != tp->snd_una)
                    tp->t_dupacks = 0;
                else if (++tp->t_dupacks == TCPREXMTTHRESH) {
                    tcp_seq onxt = tp->snd_nxt;
                    u_int win =
                        min(tp->snd_wnd, tp->snd_cwnd) / 2 / tp->t_maxseg;

                    if (win < 2)
                        win = 2;
                    tp->snd_ssthresh = win * tp->t_maxseg;
                    tp->t_timer[TCPT_REXMT] = 0;
                    tp->t_rtt = 0;
                    tp->snd_nxt = ti->ti_ack;
                    tp->snd_cwnd = tp->t_maxseg;
                    (void)tcp_output(tp);
                    tp->snd_cwnd =
                        tp->snd_ssthresh + tp->t_maxseg * tp->t_dupacks;
                    if (SEQ_GT(onxt, tp->snd_nxt))
                        tp->snd_nxt = onxt;
                    goto drop;
                } else if (tp->t_dupacks > TCPREXMTTHRESH) {
                    tp->snd_cwnd += tp->t_maxseg;
                    (void)tcp_output(tp);
                    goto drop;
                }
            } else
                tp->t_dupacks = 0;
            break;
        }
    synrx_to_est:
        /*
         * If the congestion window was inflated to account
         * for the other side's cached packets, retract it.
         */
        if (tp->t_dupacks > TCPREXMTTHRESH && tp->snd_cwnd > tp->snd_ssthresh)
            tp->snd_cwnd = tp->snd_ssthresh;
        tp->t_dupacks = 0;
        if (SEQ_GT(ti->ti_ack, tp->snd_max)) {
            goto dropafterack;
        }
        acked = ti->ti_ack - tp->snd_una;

        /*
         * If transmit timer is running and timed sequence
         * number was acked, update smoothed round trip time.
         * Since we now have an rtt measurement, cancel the
         * timer backoff (cf., Phil Karn's retransmit alg.).
         * Recompute the initial retransmit timer.
         */
        if (tp->t_rtt && SEQ_GT(ti->ti_ack, tp->t_rtseq))
            tcp_xmit_timer(tp, tp->t_rtt);

        /*
         * If all outstanding data is acked, stop retransmit
         * timer and remember to restart (more output or persist).
         * If there is more data to be acked, restart retransmit
         * timer, using current (possibly backed-off) value.
         */
        if (ti->ti_ack == tp->snd_max) {
            tp->t_timer[TCPT_REXMT] = 0;
            needoutput = 1;
        } else if (tp->t_timer[TCPT_PERSIST] == 0)
            tp->t_timer[TCPT_REXMT] = tp->t_rxtcur;
        /*
         * When new data is acked, open the congestion window.
         * If the window gives us less than ssthresh packets
         * in flight, open exponentially (maxseg per packet).
         * Otherwise open linearly: maxseg per window
         * (maxseg^2 / cwnd per packet).
         */
        {
            register u_int cw = tp->snd_cwnd;
            register u_int incr = tp->t_maxseg;

            if (cw > tp->snd_ssthresh)
                incr = incr * incr / cw;
            tp->snd_cwnd = min(cw + incr, TCP_MAXWIN << tp->snd_scale);
        }
        if (acked > so->so_snd.sb_cc) {
            tp->snd_wnd -= so->so_snd.sb_cc;
            sbdrop(&so->so_snd, (int)so->so_snd.sb_cc);
            ourfinisacked = 1;
        } else {
            sbdrop(&so->so_snd, acked);
            tp->snd_wnd -= acked;
            ourfinisacked = 0;
        }
        tp->snd_una = ti->ti_ack;
        if (SEQ_LT(tp->snd_nxt, tp->snd_una))
            tp->snd_nxt = tp->snd_una;

        switch (tp->t_state) {
        /*
         * In FIN_WAIT_1 STATE in addition to the processing
         * for the ESTABLISHED state if our FIN is now acknowledged
         * then enter FIN_WAIT_2.
         */
        case TCPS_FIN_WAIT_1:
            if (ourfinisacked) {
                /*
                 * If we can't receive any more
                 * data, then closing user can proceed.
                 * Starting the timer is contrary to the
                 * specification, but if we don't get a FIN
                 * we'll hang forever.
                 */
                if (so->so_state & SS_FCANTRCVMORE) {
                    tp->t_timer[TCPT_2MSL] = TCP_MAXIDLE;
                }
                tp->t_state = TCPS_FIN_WAIT_2;
            }
            break;

        /*
         * In CLOSING STATE in addition to the processing for
         * the ESTABLISHED state if the ACK acknowledges our FIN
         * then enter the TIME-WAIT state, otherwise ignore
         * the segment.
         */
        case TCPS_CLOSING:
            if (ourfinisacked) {
                tp->t_state = TCPS_TIME_WAIT;
                tcp_canceltimers(tp);
                tp->t_timer[TCPT_2MSL] = 2 * TCPTV_MSL;
            }
            break;

        /*
         * In LAST_ACK, we may still be waiting for data to drain
         * and/or to be acked, as well as for the ack of our FIN.
         * If our FIN is now acknowledged, delete the TCB,
         * enter the closed state and return.
         */
        case TCPS_LAST_ACK:
            if (ourfinisacked) {
                tcp_close(tp);
                goto drop;
            }
            break;

        /*
         * In TIME_WAIT state the only thing that should arrive
         * is a retransmission of the remote FIN.  Acknowledge
         * it and restart the finack timer.
         */
        case TCPS_TIME_WAIT:
            tp->t_timer[TCPT_2MSL] = 2 * TCPTV_MSL;
            goto dropafterack;
        }
    } /* switch(tp->t_state) */

step6:
    /*
     * Update window information.
     * Don't look at window if no ACK: TAC's send garbage on first SYN.
     */
    if ((tiflags & TH_ACK) &&
        (SEQ_LT(tp->snd_wl1, ti->ti_seq) ||
         (tp->snd_wl1 == ti->ti_seq &&
          (SEQ_LT(tp->snd_wl2, ti->ti_ack) ||
           (tp->snd_wl2 == ti->ti_ack && tiwin > tp->snd_wnd))))) {
        tp->snd_wnd = tiwin;
        tp->snd_wl1 = ti->ti_seq;
        tp->snd_wl2 = ti->ti_ack;
        if (tp->snd_wnd > tp->max_sndwnd)
            tp->max_sndwnd = tp->snd_wnd;
        needoutput = 1;
    }

    /*
     * Process segments with URG.
     */
    if ((tiflags & TH_URG) && ti->ti_urp &&
        TCPS_HAVERCVDFIN(tp->t_state) == 0) {
        /*
         * This is a kludge, but if we receive and accept
         * random urgent pointers, we'll crash in
         * soreceive.  It's hard to imagine someone
         * actually wanting to send this much urgent data.
         */
        if (ti->ti_urp + so->so_rcv.sb_cc > so->so_rcv.sb_datalen) {
            ti->ti_urp = 0;
            tiflags &= ~TH_URG;
            goto dodata;
        }
        /*
         * If this segment advances the known urgent pointer,
         * then mark the data stream.  This should not happen
         * in CLOSE_WAIT, CLOSING, LAST_ACK or TIME_WAIT STATES since
         * a FIN has been received from the remote side.
         * In these states we ignore the URG.
         *
         * According to RFC961 (Assigned Protocols),
         * the urgent pointer points to the last octet
         * of urgent data.  We continue, however,
         * to consider it to indicate the first octet
         * of data past the urgent section as the original
         * spec states (in one of two places).
         */
        if (SEQ_GT(ti->ti_seq + ti->ti_urp, tp->rcv_up)) {
            tp->rcv_up = ti->ti_seq + ti->ti_urp;
            so->so_urgc =
                so->so_rcv.sb_cc + (tp->rcv_up - tp->rcv_nxt); /* -1; */
            tp->rcv_up = ti->ti_seq + ti->ti_urp;
        }
    } else
        /*
         * If no out of band data is expected,
         * pull receive urgent pointer along
         * with the receive window.
         */
        if (SEQ_GT(tp->rcv_nxt, tp->rcv_up))
        tp->rcv_up = tp->rcv_nxt;
dodata:

    /*
     * If this is a small packet, then ACK now - with Nagel
     *      congestion avoidance sender won't send more until
     *      he gets an ACK.
     */
    if (ti->ti_len && (unsigned)ti->ti_len <= 5 &&
        ((struct tcpiphdr_2 *)ti)->first_char == (char)27) {
        tp->t_flags |= TF_ACKNOW;
    }

    /*
     * Process the segment text, merging it into the TCP sequencing queue,
     * and arranging for acknowledgment of receipt if necessary.
     * This process logically involves adjusting tp->rcv_wnd as data
     * is presented to the user (this happens in tcp_usrreq.c,
     * case PRU_RCVD).  If a FIN has already been received on this
     * connection then we just ignore the text.
     */
    if ((ti->ti_len || (tiflags & TH_FIN)) &&
        TCPS_HAVERCVDFIN(tp->t_state) == 0) {
        TCP_REASS(tp, ti, m, so, tiflags);
    } else {
        m_free(m);
        tiflags &= ~TH_FIN;
    }

    /*
     * If FIN is received ACK the FIN and let the user know
     * that the connection is closing.
     */
    if (tiflags & TH_FIN) {
        if (TCPS_HAVERCVDFIN(tp->t_state) == 0) {
            /*
             * If we receive a FIN we can't send more data,
             * set it SS_FDRAIN
             * Shutdown the socket if there is no rx data in the
             * buffer.
             * soread() is called on completion of shutdown() and
             * will got to TCPS_LAST_ACK, and use tcp_output()
             * to send the FIN.
             */
            sofwdrain(so);

            tp->t_flags |= TF_ACKNOW;
            tp->rcv_nxt++;
        }
        switch (tp->t_state) {
        /*
         * In SYN_RECEIVED and ESTABLISHED STATES
         * enter the CLOSE_WAIT state.
         */
        case TCPS_SYN_RECEIVED:
        case TCPS_ESTABLISHED:
            if (so->so_emu == EMU_CTL) /* no shutdown on socket */
                tp->t_state = TCPS_LAST_ACK;
            else
                tp->t_state = TCPS_CLOSE_WAIT;
            break;

        /*
         * If still in FIN_WAIT_1 STATE FIN has not been acked so
         * enter the CLOSING state.
         */
        case TCPS_FIN_WAIT_1:
            tp->t_state = TCPS_CLOSING;
            break;

        /*
         * In FIN_WAIT_2 state enter the TIME_WAIT state,
         * starting the time-wait timer, turning off the other
         * standard timers.
         */
        case TCPS_FIN_WAIT_2:
            tp->t_state = TCPS_TIME_WAIT;
            tcp_canceltimers(tp);
            tp->t_timer[TCPT_2MSL] = 2 * TCPTV_MSL;
            break;

        /*
         * In TIME_WAIT state restart the 2 MSL time_wait timer.
         */
        case TCPS_TIME_WAIT:
            tp->t_timer[TCPT_2MSL] = 2 * TCPTV_MSL;
            break;
        }
    }

    /*
     * Return any desired output.
     */
    if (needoutput || (tp->t_flags & TF_ACKNOW)) {
        (void)tcp_output(tp);
    }
    return;

dropafterack:
    /*
     * Generate an ACK dropping incoming segment if it occupies
     * sequence space, where the ACK reflects our state.
     */
    if (tiflags & TH_RST)
        goto drop;
    m_free(m);
    tp->t_flags |= TF_ACKNOW;
    (void)tcp_output(tp);
    return;

dropwithreset:
    /* reuses m if m!=NULL, m_free() unnecessary */
    if (tiflags & TH_ACK)
        tcp_respond(tp, ti, m, (tcp_seq)0, ti->ti_ack, TH_RST);
    else {
        if (tiflags & TH_SYN)
            ti->ti_len++;
        tcp_respond(tp, ti, m, ti->ti_seq + ti->ti_len, (tcp_seq)0,
                    TH_RST | TH_ACK);
    }

    return;

drop:
    /*
     * Drop space held by incoming segment and return.
     */
    m_free(m);
}

static void tcp_dooptions(struct tcpcb *tp, u_char *cp, int cnt,
                          struct tcpiphdr *ti)
{
    uint16_t mss;
    int opt, optlen;

    DEBUG_CALL("tcp_dooptions");
    DEBUG_ARGS((dfd, " tp = %lx  cnt=%i\n", (long)tp, cnt));

    for (; cnt > 0; cnt -= optlen, cp += optlen) {
        opt = cp[0];
        if (opt == TCPOPT_EOL)
            break;
        if (opt == TCPOPT_NOP)
            optlen = 1;
        else {
            optlen = cp[1];
            if (optlen <= 0)
                break;
        }
        switch (opt) {
        default:
            continue;

        case TCPOPT_MAXSEG:
            if (optlen != TCPOLEN_MAXSEG)
                continue;
            if (!(ti->ti_flags & TH_SYN))
                continue;
            memcpy((char *)&mss, (char *)cp + 2, sizeof(mss));
            NTOHS(mss);
            (void)tcp_mss(tp, mss); /* sets t_maxseg */
            break;
        }
    }
}


/*
 * Pull out of band byte out of a segment so
 * it doesn't appear in the user's data queue.
 * It is still reflected in the segment length for
 * sequencing purposes.
 */

#ifdef notdef

void tcp_pulloutofband(so, ti, m) struct socket *so;
struct tcpiphdr *ti;
register struct mbuf *m;
{
    int cnt = ti->ti_urp - 1;

    while (cnt >= 0) {
        if (m->m_len > cnt) {
            char *cp = mtod(m, caddr_t) + cnt;
            struct tcpcb *tp = sototcpcb(so);

            tp->t_iobc = *cp;
            tp->t_oobflags |= TCPOOB_HAVEDATA;
            memcpy(sp, cp + 1, (unsigned)(m->m_len - cnt - 1));
            m->m_len--;
            return;
        }
        cnt -= m->m_len;
        m = m->m_next; /* XXX WRONG! Fix it! */
        if (m == 0)
            break;
    }
    panic("tcp_pulloutofband");
}

#endif /* notdef */

/*
 * Collect new round-trip time estimate
 * and update averages and current timeout.
 */

static void tcp_xmit_timer(register struct tcpcb *tp, int rtt)
{
    register short delta;

    DEBUG_CALL("tcp_xmit_timer");
    DEBUG_ARG("tp = %lx", (long)tp);
    DEBUG_ARG("rtt = %d", rtt);

    if (tp->t_srtt != 0) {
        /*
         * srtt is stored as fixed point with 3 bits after the
         * binary point (i.e., scaled by 8).  The following magic
         * is equivalent to the smoothing algorithm in rfc793 with
         * an alpha of .875 (srtt = rtt/8 + srtt*7/8 in fixed
         * point).  Adjust rtt to origin 0.
         */
        delta = rtt - 1 - (tp->t_srtt >> TCP_RTT_SHIFT);
        if ((tp->t_srtt += delta) <= 0)
            tp->t_srtt = 1;
        /*
         * We accumulate a smoothed rtt variance (actually, a
         * smoothed mean difference), then set the retransmit
         * timer to smoothed rtt + 4 times the smoothed variance.
         * rttvar is stored as fixed point with 2 bits after the
         * binary point (scaled by 4).  The following is
         * equivalent to rfc793 smoothing with an alpha of .75
         * (rttvar = rttvar*3/4 + |delta| / 4).  This replaces
         * rfc793's wired-in beta.
         */
        if (delta < 0)
            delta = -delta;
        delta -= (tp->t_rttvar >> TCP_RTTVAR_SHIFT);
        if ((tp->t_rttvar += delta) <= 0)
            tp->t_rttvar = 1;
    } else {
        /*
         * No rtt measurement yet - use the unsmoothed rtt.
         * Set the variance to half the rtt (so our first
         * retransmit happens at 3*rtt).
         */
        tp->t_srtt = rtt << TCP_RTT_SHIFT;
        tp->t_rttvar = rtt << (TCP_RTTVAR_SHIFT - 1);
    }
    tp->t_rtt = 0;
    tp->t_rxtshift = 0;

    /*
     * the retransmit should happen at rtt + 4 * rttvar.
     * Because of the way we do the smoothing, srtt and rttvar
     * will each average +1/2 tick of bias.  When we compute
     * the retransmit timer, we want 1/2 tick of rounding and
     * 1 extra tick because of +-1/2 tick uncertainty in the
     * firing of the timer.  The bias will give us exactly the
     * 1.5 tick we need.  But, because the bias is
     * statistical, we have to test that we don't drop below
     * the minimum feasible timer (which is 2 ticks).
     */
    TCPT_RANGESET(tp->t_rxtcur, TCP_REXMTVAL(tp), (short)tp->t_rttmin,
                  TCPTV_REXMTMAX); /* XXX */

    /*
     * We received an ack for a packet that wasn't retransmitted;
     * it is probably safe to discard any error indications we've
     * received recently.  This isn't quite right, but close enough
     * for now (a route might have failed after we sent a segment,
     * and the return path might not be symmetrical).
     */
    tp->t_softerror = 0;
}

/*
 * Determine a reasonable value for maxseg size.
 * If the route is known, check route for mtu.
 * If none, use an mss that can be handled on the outgoing
 * interface without forcing IP to fragment; if bigger than
 * an mbuf cluster (MCLBYTES), round down to nearest multiple of MCLBYTES
 * to utilize large mbufs.  If no route is found, route has no mtu,
 * or the destination isn't local, use a default, hopefully conservative
 * size (usually 512 or the default IP max size, but no more than the mtu
 * of the interface), as we can't discover anything about intervening
 * gateways or networks.  We also initialize the congestion/slow start
 * window to be a single segment if the destination isn't local.
 * While looking at the routing entry, we also initialize other path-dependent
 * parameters from pre-set or cached values in the routing entry.
 */

int tcp_mss(struct tcpcb *tp, u_int offer)
{
    struct socket *so = tp->t_socket;
    int mss;

    DEBUG_CALL("tcp_mss");
    DEBUG_ARG("tp = %lx", (long)tp);
    DEBUG_ARG("offer = %d", offer);

    mss = min(IF_MTU, IF_MRU) - sizeof(struct tcpiphdr);
    if (offer)
        mss = min(mss, offer);
    mss = max(mss, 32);
    if (mss < tp->t_maxseg || offer != 0)
        tp->t_maxseg = mss;

    tp->snd_cwnd = mss;

    sbreserve(&so->so_snd,
              TCP_SNDSPACE +
                  ((TCP_SNDSPACE % mss) ? (mss - (TCP_SNDSPACE % mss)) : 0));
    sbreserve(&so->so_rcv,
              TCP_RCVSPACE +
                  ((TCP_RCVSPACE % mss) ? (mss - (TCP_RCVSPACE % mss)) : 0));

    DEBUG_MISC((dfd, " returning mss = %d\n", mss));

    return mss;
}
