Re: FIN problem in Berkeley 4.3?


Jeffrey C Honig (jch@devvax.TN.CORNELL.EDU)
Fri, 20 Nov 87 06:52:13 -0500


>We're running a Gould here with Berkeley networking code. It would appear
>that when a TCP connection is closed, and the FIN is retransmitted for some
>reason, it's sequence number is one too low. The sequence number is correct
>on the first transmission.

>I've looked into "tcp_output.c", and it is marked as "7.2.1.1 ... 3/28/87".
>The code looks correct by casual inspection, at least.

>Can anyone shed some light on the problem before I spend time trying to
>debug this in UNIX?

Applying the following fix (in Mike Karel's form) fixed many symptoms of
this problem on a uVAX running 4.3.

Jeff
----------------
>From cpw Tue Sep 1 09:00:12 1987
>To: tcp-ip@sri-nic.arpa
>Subject: Help with broken TCP

>What follows is a TCP scenario observed on our local ethernet. The ftp
>application (A) has just pushed out the last data block to (B) and is
>closing the connection. The first FIN from (A) is lost. An ACK from (B)
>for the last data block arrives. Then there begins a conversation of FIN(A)
>then ACK(B) with longer and longer time intervals between each set of
>FIN(A)/ACK(B) as if the ACK is being dropped and a retransmit timer is
>backing off, firing and a FIN being sent. Notice that the sequence number
>set in the retransmitted FIN packets is one less than that set in the lost
>FIN packet. Are both peers broken or just the sender of the FINs?

>This is a tcpdump. I added an * to indicate the lost packet. (In case
>your curious, the packet is lost because of an inability to handle back
>to back packets on the part of B)

>15:31:36.86 A > B: S -1063845887:-1063845887(0) win 4096 <mss 1024>
>15:31:36.86 B > A: S 253698321:253698321(0) ack -1063845886 win 384 <mss 1024>
>15:31:36.86 A > B: . ack 1 win 4096
>15:31:37.12 A > B: P 1:146(145) ack 1 win 4096
>15:31:37.12 A >* B: F 146:146(0) ack 1 win 4096
>15:31:37.38 B > A: . ack 146 win 384
>15:31:39.12 A > B: F 145:145(0) ack 1 win 4096
>15:31:39.14 B > A: . ack 146 win 384
>15:31:41.12 A > B: F 145:145(0) ack 1 win 4096 urg 1
>15:31:41.14 B > A: . ack 146 win 384
>15:31:45.12 A > B: F 145:145(0) ack 1 win 4096 urg 1
>15:31:45.14 B > A: . ack 146 win 384
>15:31:53.12 A > B: F 145:145(0) ack 1 win 4096 urg 1

>and so on...

>Phil Wood (cpw@lanl.gov)

--------

>From cpw Tue Sep 1 14:28:46 1987
>To: tcp-ip@sri-nic.arpa
>Subject: Re: Help with broken TCP
>Status: RO

>4.3BSD network bug (#9, tcp_output) had a fix for an undetected data
>loss during connection closing. This may well have fixed the data loss
>due to lost data segments, but, apparently it will cause the symptom
>I reported if the data segment with FIN is lost. If the test:

> if (flags & TH_FIN && tp->t_flags & TF_SENTFIN && len == 0)

>succeeds the #9 code decremented tp->sndnxt by one. Instead, I set
>tp->snd_nxt = tp->snd_una, and the symptom went away. I'm not saying
>this is a fix, but it may point more to the problem.

>Phil Wood (cpw@lanl.gov)

Here is a partial diff of the fix I have to tcp_output.c.
*** tcp_output.c.orig Fri Apr 24 12:29:11 1987
--- tcp_output.c Wed Sep 2 12:29:09 1987
*** 231,237 ****
         * If resending a FIN, be sure not to use a new sequence number.
         */
! if (flags & TH_FIN && tp->t_flags & TF_SENTFIN &&
! tp->snd_nxt != tp->snd_una)
                tp->snd_nxt--;
        ti->ti_seq = htonl(tp->snd_nxt);
        ti->ti_ack = htonl(tp->rcv_nxt);
--- 237,246 ----
         * If resending a FIN, be sure not to use a new sequence number.
         */
! if (flags & TH_FIN && tp->t_flags & TF_SENTFIN && len == 0)
! tp->snd_nxt = tp->snd_una;
        ti->ti_seq = htonl(tp->snd_nxt);
        ti->ti_ack = htonl(tp->rcv_nxt);
***************

-------------------

>From: Mike Karels <karels%okeeffe@berkeley.edu>
>To: "C. Philip Wood" <cpw%sneezy@lanl.gov>
>Cc: tcp-ip@sri-nic.arpa
>Subject: Re: Help with broken TCP
>Date: Tue, 01 Sep 87 15:33:38 PDT

>Right you are! I knew that we had such a problem at one time, but didn't
>think it had made it out of Berkeley. Your fix is fine; our current version
>does:
> if (flags & TH_FIN && tp->t_flags & TF_SENTFIN &&
> tp->snd_nxt == tp->snd_max)
> tp->snd_nxt--;

>which should be equivalent.

> Mike



This archive was generated by hypermail 2.0b3 on Thu Mar 09 2000 - 14:39:56 GMT