--- net/ipv4/tcp_output.c-o Wed Dec 10 11:40:57 1997 +++ net/ipv4/tcp_output.c Wed Dec 10 12:19:47 1997 @@ -840,6 +840,7 @@ struct sk_buff *buff; struct device *dev=NULL; int tmp; + int probe0; buff = sock_wmalloc(sk, MAX_RESET_SIZE,1 , GFP_KERNEL); @@ -914,11 +915,14 @@ tcp_send_check(t1, sk->saddr, sk->daddr, sizeof(*t1), buff); /* - * If there is data in the write queue, the fin must be appended to - * the write queue. + * If there is data in the write queue or the remote window is zero, + * the fin must be appended to the write queue. */ + + probe0 = before(sk->window_seq, sk->write_queue.next->end_seq) && + sk->send_head == NULL && sk->ack_backlog == 0; - if (skb_peek(&sk->write_queue) != NULL) + if (probe0 || skb_peek(&sk->write_queue) != NULL) { buff->free = 0; if (buff->next != NULL) @@ -927,6 +931,14 @@ skb_unlink(buff); } skb_queue_tail(&sk->write_queue, buff); + + /* + * A FIN needs sequence space, so we must do zero window + * probing here if the window is 0 (sigh) + */ + if (probe0) + tcp_reset_xmit_timer(sk, TIME_PROBE0, sk->rto); + } else {