/* SPDX-License-Identifier: BSD-3-Clause */
/*
 * 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.
 */

#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).
 */
#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;                                  \
        }                                                              \
    }

static void tcp_dooptions(struct tcpcb *tp, uint8_t *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,
               unsigned short af)
{
    struct ip save_ip, *ip;
    struct ip6 save_ip6, *ip6;
    register struct tcpiphdr *ti;
    char *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;
    uint32_t tiwin;
    int ret;
    struct sockaddr_storage lhost, fhost;
    struct sockaddr_in *lhost4, *fhost4;
    struct sockaddr_in6 *lhost6, *fhost6;
    struct gfwd_list *ex_ptr;
    Slirp *slirp;

    DEBUG_CALL("tcp_input");
    DEBUG_ARG("m = %p  iphlen = %2d  inso = %p", m, iphlen, 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;

    ip = mtod(m, struct ip *);
    ip6 = mtod(m, struct ip6 *);

    switch (af) {
    case AF_INET:
        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.
         */
        save_ip = *ip;
        save_ip.ip_len += iphlen;

        /*
         * Get IP and TCP header together in first mbuf.
         * Note: IP leaves IP header in first mbuf.
         */
        m->m_data -=
            sizeof(struct tcpiphdr) - sizeof(struct ip) - sizeof(struct tcphdr);
        m->m_len +=
            sizeof(struct tcpiphdr) - sizeof(struct ip) - sizeof(struct tcphdr);
        ti = mtod(m, struct tcpiphdr *);

        /*
         * Checksum extended TCP header and data.
         */
        tlen = ip->ip_len;
        tcpiphdr2qlink(ti)->next = tcpiphdr2qlink(ti)->prev = NULL;
        memset(&ti->ih_mbuf, 0, sizeof(struct mbuf_ptr));
        memset(&ti->ti, 0, sizeof(ti->ti));
        ti->ti_x0 = 0;
        ti->ti_src = save_ip.ip_src;
        ti->ti_dst = save_ip.ip_dst;
        ti->ti_pr = save_ip.ip_p;
        ti->ti_len = htons((uint16_t)tlen);
        break;

    case AF_INET6:
        /*
         * Save a copy of the IP header in case we want restore it
         * for sending an ICMP error message in response.
         */
        save_ip6 = *ip6;
        /*
         * Get IP and TCP header together in first mbuf.
         * Note: IP leaves IP header in first mbuf.
         */
        m->m_data -= sizeof(struct tcpiphdr) -
                     (sizeof(struct ip6) + sizeof(struct tcphdr));
        m->m_len += sizeof(struct tcpiphdr) -
                    (sizeof(struct ip6) + sizeof(struct tcphdr));
        ti = mtod(m, struct tcpiphdr *);

        tlen = ip6->ip_pl;
        tcpiphdr2qlink(ti)->next = tcpiphdr2qlink(ti)->prev = NULL;
        memset(&ti->ih_mbuf, 0, sizeof(struct mbuf_ptr));
        memset(&ti->ti, 0, sizeof(ti->ti));
        ti->ti_x0 = 0;
        ti->ti_src6 = save_ip6.ip_src;
        ti->ti_dst6 = save_ip6.ip_dst;
        ti->ti_nh6 = save_ip6.ip_nh;
        ti->ti_len = htons((uint16_t)tlen);
        break;

    default:
        g_assert_not_reached();
    }

    len = ((sizeof(struct tcpiphdr) - sizeof(struct tcphdr)) + 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, char *) + 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:
    lhost.ss_family = af;
    fhost.ss_family = af;
    switch (af) {
    case AF_INET:
        lhost4 = (struct sockaddr_in *)&lhost;
        lhost4->sin_addr = ti->ti_src;
        lhost4->sin_port = ti->ti_sport;
        fhost4 = (struct sockaddr_in *)&fhost;
        fhost4->sin_addr = ti->ti_dst;
        fhost4->sin_port = ti->ti_dport;
        break;
    case AF_INET6:
        lhost6 = (struct sockaddr_in6 *)&lhost;
        lhost6->sin6_addr = ti->ti_src6;
        lhost6->sin6_port = ti->ti_sport;
        fhost6 = (struct sockaddr_in6 *)&fhost;
        fhost6->sin6_addr = ti->ti_dst6;
        fhost6->sin6_port = ti->ti_dport;
        break;
    default:
        g_assert_not_reached();
    }

    so = solookup(&slirp->tcp_last_so, &slirp->tcb, &lhost, &fhost);

    /*
     * 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) {
        /* TODO: IPv6 */
        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->guestfwd_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;

        so = socreate(slirp);
        tcp_attach(so);

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

        so->lhost.ss = lhost;
        so->fhost.ss = fhost;

        so->so_iptos = tcp_tos(so);
        if (so->so_iptos == 0) {
            switch (af) {
            case AF_INET:
                so->so_iptos = ((struct ip *)ti)->ip_tos;
                break;
            case AF_INET6:
                break;
            default:
                g_assert_not_reached();
            }
        }

        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 (slirp_do_keepalive)
        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, (uint8_t *)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;
                sodrop(so, 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)
                    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
         */
        /* TODO: IPv6 */
        if (af == AF_INET &&
            (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->guestfwd_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, so->so_ffamily) == -1) && (errno != EAGAIN) &&
            (errno != EINPROGRESS) && (errno != EWOULDBLOCK)) {
            uint8_t code;
            DEBUG_MISC(" tcp fconnect errno = %d-%s", 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, af);
            } else {
                switch (af) {
                case AF_INET:
                    code = ICMP_UNREACH_NET;
                    if (errno == EHOSTUNREACH) {
                        code = ICMP_UNREACH_HOST;
                    }
                    break;
                case AF_INET6:
                    code = ICMP6_UNREACH_NO_ROUTE;
                    if (errno == EHOSTUNREACH) {
                        code = ICMP6_UNREACH_ADDRESS;
                    }
                    break;
                default:
                    g_assert_not_reached();
                }
                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);
                switch (af) {
                case AF_INET:
                    m->m_data += sizeof(struct tcpiphdr) - sizeof(struct ip) -
                                 sizeof(struct tcphdr);
                    m->m_len -= sizeof(struct tcpiphdr) - sizeof(struct ip) -
                                sizeof(struct tcphdr);
                    *ip = save_ip;
                    icmp_send_error(m, ICMP_UNREACH, code, 0, strerror(errno));
                    break;
                case AF_INET6:
                    m->m_data += sizeof(struct tcpiphdr) -
                                 (sizeof(struct ip6) + sizeof(struct tcphdr));
                    m->m_len -= sizeof(struct tcpiphdr) -
                                (sizeof(struct ip6) + sizeof(struct tcphdr));
                    *ip6 = save_ip6;
                    icmp6_send_error(m, ICMP6_UNREACH, code);
                    break;
                default:
                    g_assert_not_reached();
                }
            }
            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;
            /*
             * Initialize receive sequence numbers now so that we can send a
             * valid RST if the remote end rejects our connection.
             */
            tp->irs = ti->ti_seq;
            tcp_rcvseqinit(tp);
            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, (uint8_t *)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;

            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);
        }

        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(" dup ack  m = %p  so = %p", m, 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;
                    unsigned 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;
                    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;
                    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 unsigned cw = tp->snd_cwnd;
            register unsigned 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;
            sodrop(so, (int)so->so_snd.sb_cc);
            ourfinisacked = 1;
        } else {
            sodrop(so, 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)) {
        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;
    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, af);
    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, af);
    }

    return;

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

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

    DEBUG_CALL("tcp_dooptions");
    DEBUG_ARG("tp = %p  cnt=%i", 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);
            tcp_mss(tp, mss); /* sets t_maxseg */
            break;
        }
    }
}

/*
 * 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 = %p", 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, unsigned offer)
{
    struct socket *so = tp->t_socket;
    int mss;

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

    switch (so->so_ffamily) {
    case AF_INET:
        mss = MIN(so->slirp->if_mtu, so->slirp->if_mru) -
              sizeof(struct tcphdr) - sizeof(struct ip);
        break;
    case AF_INET6:
        mss = MIN(so->slirp->if_mtu, so->slirp->if_mru) -
              sizeof(struct tcphdr) - sizeof(struct ip6);
        break;
    default:
        g_assert_not_reached();
    }

    if (offer)
        mss = MIN(mss, offer);
    mss = MAX(mss, 32);
    if (mss < tp->t_maxseg || offer != 0)
        tp->t_maxseg = MIN(mss, TCP_MAXSEG_MAX);

    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(" returning mss = %d", mss);

    return mss;
}
