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>