Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 28 Sep 1998 18:02:45 +0200
From:      "Juan L. Freniche" <jlfreniche@acm.org>
To:        FreeBSD Net <freebsd-net@FreeBSD.ORG>
Subject:   Invalid ACKs in SYN-SENT and T/TCP
Message-ID:  <360FB325.2FD1@acm.org>

next in thread | raw e-mail | index | archive | help
We have two FreeBSD 2.2.7 boxes connected through Ethernet, both with 
T/TCP enabled. We have noted the following behaviour:

1 Assume A started several normal TCP connections to B. Client   
  connections in A use local ports selected in the command line
  when the client is launched. After a while, leave only one such 
  connection in Established.

2 Unplug the Ethernet cable from Box A and reboot Box A.

  Reason to unplug is to avoid that the RST sent by A reach the 
  connection in B.

3 Launch again several connections from A to B, but using a different
  local port than the old still-established socket in B. Finish them
  now normally.

  The reason of the above is to build, in A, a TAO cache for B.

4 Launch a connection from A to B but using the same local port than
  the old still-established socket in B. If tcpdump is used for 
  tracing, we will see:

    - A sends a SYN to B. This new connection is in SYN-SENT in A.
    - B responds with an ACK, probabilistic invalid because it is the
      old still-established socket who is responding.
    - A does not respond with a RST, instead the SYN is retransmitted
      after the retransmission timeout.
    - B again responds with an ACK, invalid.
    - and so on, until the SYN retransmissions are exhausted.


RFC 793 (TCP) states in page 66 that a RST must be send if an invalid 
ACK is received in SYN-SENT (as the received ACK has not the RST bit).
Instead, A is ignoring such invalid ACKs, and then retransmitting the
SYN.

Nothing is said about this in the T/TCP RFCs 1379 and 1644 (at least, 
I could'nt find this case).

I consulted the Stevens book, vol 3, the figure that is identical to 
the source code (file /usr/src/sys/netinet/tcp_input.c):


   case TCPS_SYN_SENT:
        if ((taop = tcp_gettaocache(inp)) == NULL) {
               taop = &tao_noncached;
               bzero(taop, sizeof(*taop));
        }

        if ((tiflags & TH_ACK) &&
            (SEQ_LEQ(ti->ti_ack, tp->iss) ||
             SEQ_GT(ti->ti_ack, tp->snd_max))) {
               /*
                * If we have a cached CCsent for the remote host,
                * hence we haven't just crashed and restarted,
                * do not send a RST.  This may be a retransmission
                * from the other side after our earlier ACK was lost.
                * Our new SYN, when it arrives, will serve as the
                * needed ACK.
                */
                if (taop->tao_ccsent != 0)
                    goto drop;
                else
                    goto dropwithreset;


This explain why A didn't sent RSTs when receiving invalid ACKs: 
A has a valid TAO cache for B, so the invalid ACK is ignored.

My question is: is this behaviour what it was intended? The comment in
the code covers one case, but aborting connections and loosing its RST
is not so unlikely. Should A come back to RFC 793?

-- 
Juan L. Freniche

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-net" in the body of the message



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?360FB325.2FD1>