Subject: Question on snippet of tcp_input
To: Tech Net <tech-net@netbsd.org>
From: B. James Phillippe \(spamblock\) <bryan-spamtrap4@darkforest.org>
List: tech-net
Date: 08/30/2002 15:43:45
Hello,

I was looking through tcp_input.c (from 1.5 branch, FWIW) and came across
the conditional block at 1111:

        if (so->so_options & SO_ACCEPTCONN) {
            if ((tiflags & (TH_RST|TH_ACK|TH_SYN)) != TH_SYN) {
                if (tiflags & TH_RST) {
                    syn_cache_reset(&src.sa, &dst.sa, th);
                } else if ((tiflags & (TH_ACK|TH_SYN)) ==
                    (TH_ACK|TH_SYN)) {
                    /*
                     * Received a SYN,ACK.  This should
                     * never happen while we are in
                     * LISTEN.  Send an RST.
                     */
                    goto badsyn;
                } else if (tiflags & TH_ACK) {
                    so = syn_cache_get(&src.sa, &dst.sa,
                        th, toff, tlen, so, m);
                    if (so == NULL) {
                        /*
                         * We don't have a SYN for
                         * this ACK; send an RST.

In the above test of TH_ACK, if set then syn_cache_get() is called.  As far
as I can tell, this is the only place syn_cache_get() is ever called.  On
line 2938 of syn_cache_get(), however, there is this test:

    /*
     * Verify the sequence and ack numbers.  Try getting the correct
     * response again.
     */
    if ((th->th_ack != sc->sc_iss + 1) ||
        SEQ_LEQ(th->th_seq, sc->sc_irs) ||
        SEQ_GT(th->th_seq, sc->sc_irs + 1 + sc->sc_win)) {
        (void) syn_cache_respond(sc, m);
        splx(s);
        return ((struct socket *)(-1));
    }

If syn_cache_get() is only ever called for packets which have TH_ACK set
without TH_SYN and without TH_RST set, th->th_seq should always be 0,
correct?  Is there a purpose for the tests of th->th_seq?

thanks,
-bp
--
# bryan_at_darkforest_dot_org
# Software Engineer