Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 2 Jul 2006 13:30:56 +0200
From:      Stefan Bethke <stb@lassitu.de>
To:        Mikhail Teterin <mi+mx@aldan.algebra.com>
Cc:        rizzo@icir.org, net@freebsd.org
Subject:   Re: using ipfw seems to interfere with socket communication
Message-ID:  <7024797F-62A3-43C0-A119-50A3DD34B279@lassitu.de>
In-Reply-To: <200606271813.29980.mi%2Bmx@aldan.algebra.com>
References:  <200606271813.29980.mi%2Bmx@aldan.algebra.com>

next in thread | previous in thread | raw e-mail | index | archive | help
Am 28.06.2006 um 00:13 schrieb Mikhail Teterin:

>     fconfigure $sock -blocking 0
>     lappend result c:[gets $sock]
>
> was always returning empty string, instead of the string "two",  
> that was
> written into the socket and flushed.
>
> Is the test wrong, and such result is possible, or is dummynet  
> triggering a
> bug? Unloading the dummynet module allows the test to succeed...

The test is wrong. See recvfrom(2), which the gets will eventually  
invoke:
      If no messages are available at the socket, the receive call  
waits for a
      message to arrive, unless the socket is nonblocking (see fcntl 
(2)) in
      which case the value -1 is returned and the external variable  
errno set
      to EAGAIN.

And Tcl gets(n):
        If  end  of  file occurs while scanning for an end of line,  
the command
        returns whatever input is available up to the end of  file.    
If  chan-
        nelId  is  in  nonblocking  mode  and there is not a full  
line of input
        available, the command returns an empty string and does not  
consume any
        input.  If varName is specified and an empty string is  
returned in var-
        Name because of end-of-file or because of  insufficient   
data  in  non-
        blocking  mode,  then  the return count is -1.  Note that if  
varName is
        not specified then the end-of-file and no-full-line-available  
cases can
        produce the same results as if there were an input line  
consisting only
        of the end-of-line character(s).

Essentially, dummynet delays processing of that "two" line just long  
enough to break the code's assumption that TCP over the loopback  
interface is instantaneous. If my fading memory of TCP/IP Illustrated  
Vol 2 serves me right, that was actually the case at least back then:  
the sendto system call would push the data all the way down to lo0,  
which would immediately pass it back up until it ended up in the  
receiving socket buffer.  Dummynet will queue the packet, regardless,  
so it won't get delivered until the next time dummynet processes queues.

In non-blocking mode, you must always be prepared to wait for data.


Stefan

-- 
Stefan Bethke <stb@lassitu.de>   Fon +49 170 346 0140





Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?7024797F-62A3-43C0-A119-50A3DD34B279>