bostic@OKEEFFE.BERKELEY.EDU.UUCP (03/20/87)
4.3BSD network bug (#1, tcp_output)
Index: sys/netinet/tcp_output.c 4.3BSD FIX
Description:
The final change in the send code in TCP in 4.3 was made incorrectly.
In tcp_output (/sys/netinet/tcp_output.c), the output packet flags
are chosen before the packet length is adjusted to reflect the maximum
segment size. Under some cirsumstances, this results in sending a FIN
with a packet which is not the last data packet. This is most often
noticed when the connection implements a one-way transfer of data
and the sender closes while the data is still draining; the result is
unnoticed loss of data.
Fix:
Move the lines in tcp_output that look up the flags to be sent
to a location after the final length adjustment, as follows:
*** /nbsd/sys/netinet/tcp_output.c Thu Jun 5 00:31:36 1986
--- tcp_output.c Wed Aug 20 09:31:34 1986
***************
*** 5,7 ****
*
! * @(#)tcp_output.c 7.1 (Berkeley) 6/5/86
*/
--- 5,7 ----
*
! * @(#)tcp_output.c 7.2 (Berkeley) 8/20/86
*/
***************
*** 82,85 ****
flags = tcp_outflags[tp->t_state];
- if (SEQ_LT(tp->snd_nxt + len, tp->snd_una + so->so_snd.sb_cc))
- flags &= ~TH_FIN;
--- 82,83 ----
***************
*** 118,119 ****
--- 116,119 ----
}
+ if (SEQ_LT(tp->snd_nxt + len, tp->snd_una + so->so_snd.sb_cc))
+ flags &= ~TH_FIN;
win = sbspace(&so->so_rcv);