North American Network Operators Group

Date Prev | Date Next | Date Index | Thread Index | Author Index | Historical

Re: TCP receive window set to 0; DoS or not?

  • From: Richard A Steenbergen
  • Date: Thu Sep 07 19:27:38 2006

On Thu, Sep 07, 2006 at 03:04:58PM -0700, [email protected] wrote:
> > I've been seeing some systems that stop serving pages, and I also see
> > the Linux "Treason Uncloaked!" kernel messages that indicate a remote
> > system reduced its rcv win from 1 to 0... is there a non-malicious
> > explanation for this, aside from a remote host running out of socket
> > buffers?  Seems to happen too often for that to be the case, and
> > my googling has shown that it may be outside of spec.  Certainly
> > the warning is clear enough...
> I've seen this, quite a bit, on some heavy traffic web clusters. Some 
> impolite web browsers will shrink the TCP window to kill the socket 
> connection instead of a proper fin/reset. 

Advertising a window of 0 is a perfectly valid way of telling the other 
side that you are temporarily out of resoruces, and would like them to 
stop sending you data. This can be caused by any number of things, from a 
completely bogged down box, to an application which isn't read()ing off 
its socket buffer (thus for all intents and purposes the kernel is out of 
resources to buffer any more data for that socket). It doesn't kill the 
TCP session, it just throttles it back. The sender then goes into problem 
the zero window mode, waiting for this condition to go away. It is 
described in RFC 1122 section

            Probing of zero (offered) windows MUST be supported.

            A TCP MAY keep its offered receive window closed
            indefinitely.  As long as the receiving TCP continues to
            send acknowledgments in response to the probe segments, the
            sending TCP MUST allow the connection to stay open.

            etc etc etc

Looking at the Linux code which calls the error message (tcp_timer.c 
tcp_retransmit_timer()), the condition which triggers it is:

         if (!tp->snd_wnd && !sock_flag(sk, SOCK_DEAD) &&
             !((1 << sk->sk_state) & (TCPF_SYN_SENT | TCPF_SYN_RECV))) {
                 /* Receiver dastardly shrinks window. Our retransmits
                  * become zero probes, but we should not timeout this
                  * connection. If the socket is an orphan, time it out,
                  * we cannot allow such beasts to hang infinitely.

It looks like it is just detecting this condition and changing its 
behavior in accordance with the RFC. Since the actual print of the message 
is wrapped in #ifdef TCP_DEBUG, it probably isn't intended to be displayed 
to end users at all. As for the cute "Treason Uncloaked" message, thats 
what you get for running an OS written by/for 14 year olds. :)

Or at least thats make 15 minute take on it, having not touched Linux 
(gleefully) in many, many years.

Richard A Steenbergen <[email protected]>
GPG Key ID: 0xF8B12CBC (7535 7F59 8204 ED1F CC1C 53AF 4C41 5ECA F8B1 2CBC)