Strangeness when write()-ing zero-length datagrams

3 messages, 2 authors, 2004-08-09 · open the first message on its own page

Strangeness when write()-ing zero-length datagrams

From: Michael T Kerrisk <hidden>
Date: 2004-08-09 14:38:13

Godday,

On Linux 2.4.26 and 2.6.7, if we connect a datagram socket and 
then use write() to send 0 bytes, a datagram is NOT generated 
(this happens in both the Unix and Internet domains).  
Datagrams are generated in this case for send() and sendto() 
though.  

As far as I can work out, this occurs because of the 
following code in net/socket.c::sock_write/sock_aio_write():

    if(size==0)        /* Match SYS5 behaviour */
        return 0;

Is the Linux behaviour intended?  It seems counterintuitive, 
and it does not match what I see on other systems:

Solaris 8 does not behave like Linux in this case -– a zero 
length datagram is sent and read by the receiver (tested for 
Internet and Unix domain sockets).

Tru64 5.1 is the same as Solaris 8 (tested for Internet and 
Unix domain sockets)

HP-UX 11 is the same as Solaris 8 (tested for Internet and 
Unix domain sockets)

FreeBSD 4.9 and 5.1 are the same as Solaris 8 (tested for 
Internet and Unix domain sockets)

Cheers,

Michael

-- 
Michael Kerrisk
mtk-lists@gmx.net

NEU: WLAN-Router für 0,- EUR* - auch für DSL-Wechsler!
GMX DSL = supergünstig & kabellos http://www.gmx.net/de/go/dsl

Re: Strangeness when write()-ing zero-length datagrams

From: bert hubert <hidden>
Date: 2004-08-09 15:40:57

On Mon, Aug 09, 2004 at 04:38:13PM +0200, Michael T Kerrisk wrote:
Godday,

On Linux 2.4.26 and 2.6.7, if we connect a datagram socket and 
then use write() to send 0 bytes, a datagram is NOT generated 
(this happens in both the Unix and Internet domains).  
Datagrams are generated in this case for send() and sendto() 
though.
Some postings were made about this some time ago, it appears SUS has an
opinion on zero byte writes:

If nbyte is 0, write() will return 0 and have no other results if the file
is a regular file; otherwise, the results are unspecified.
http://www.opengroup.org/onlinepubs/007908799/xsh/write.html

The send(2) manpage states:

The send() function is identical to sendto() with a null pointer dest_len
argument, and to write() if no flags are used.

Which means that a zero byte send() without flags is unspecified.

Also note that it is hard if impossible to usefully inform userspace of the
reception of a zery byte packet - returning 0 from recvfrom may also mean an
'orderly shutdown'.

Do you actually have a need for zero byte packets?

-- 
http://www.PowerDNS.com      Open source, database driven DNS Software 
http://lartc.org           Linux Advanced Routing & Traffic Control HOWTO

Re: Strangeness when write()-ing zero-length datagrams

From: Michael T Kerrisk <hidden>
Date: 2004-08-09 15:59:00

Bert,
quoted
On Linux 2.4.26 and 2.6.7, if we connect a datagram socket and 
then use write() to send 0 bytes, a datagram is NOT generated 
(this happens in both the Unix and Internet domains).  
Datagrams are generated in this case for send() and sendto() 
though.
Some postings were made about this some time ago, 
I didn't find anything with google or archive seach -- do
you have any more specific reference on this thread?
it appears SUS has an
opinion on zero byte writes:

If nbyte is 0, write() will return 0 and have no other results if the 
file is a regular file; otherwise, the results are unspecified.
http://www.opengroup.org/onlinepubs/007908799/xsh/write.html

The send(2) manpage states:

The send() function is identical to sendto() with a null pointer dest_len
argument, and to write() if no flags are used.

Which means that a zero byte send() without flags is unspecified.
Yes, but on Linux write(fd, buf, 0) != send(fd, buf, 0, 0), which
does seem inconsistent.  And as I noted, all the other implementations
I tested behave differently from Linux.

(Just so I'm sure we have our scenarios clear, I'm referring to 
the following:

HOST-A                     HOST-B

create datagram socket

bind socket to 
INADDR_ANY:port-x

                            create datagram socket

                            connect socket to 
                            HOST-B:port-x

                            Now the following behave 
                            differently:
                                write(fd, buf, 0);
                                send(fd, buf, 0, 0);

)
Also note that it is hard if impossible to usefully inform userspace of
the reception of a zery byte packet - returning 0 from recvfrom may 
also mean an 'orderly shutdown'.
Am I missing something?  There isn't the notion of a true 
connection with datagram sockets, and so no notion of an orderly 
shutdown (I am assuming you are meaning some scenario where the 
peer calls shutdown() or close()).

It is straightforward to detect a zero-length datagram: recvfrom()
returns 0.
Do you actually have a need for zero byte packets?
No, but I discovered this difference during some testing that I 
was doing, and then observed that it seems different from 
most (all?) other implementations.  It seemed worth documenting 
this fact.

Cheers,

Michael

-- 
Michael Kerrisk
mtk-lists@gmx.net

NEU: WLAN-Router f�r 0,- EUR* - auch f�r DSL-Wechsler!
GMX DSL = superg�nstig & kabellos http://www.gmx.net/de/go/dsl
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help