*BSD News Article 4750


Return to BSD News archive

Xref: sserve comp.unix.ultrix:13608 comp.unix.bsd:4798
Newsgroups: comp.unix.ultrix,comp.unix.bsd
Path: sserve!manuel!munnari.oz.au!spool.mu.edu!wupost!uunet!mcsun!sun4nl!fwi.uva.nl!casper
From: casper@fwi.uva.nl (Casper H.S. Dik)
Subject: Re: A major BSD socket bug?
Message-ID: <1992Sep9.095942.12013@fwi.uva.nl>
Sender: news@fwi.uva.nl
Nntp-Posting-Host: adam.fwi.uva.nl
Organization: FWI, University of Amsterdam
References: <1992Sep9.053147.411@lmpsbbs.comm.mot.com>
Date: Wed, 9 Sep 1992 09:59:42 GMT
Lines: 60

rittle@supra (Loren James Rittle) writes:

>I have reproduced this bug (be it in my code or the BSD OS) under
>both ULTRIX 4.2A and SunOS 4.1.2.  As I don't read any sun groups, I didn't
>know where to crosspost there.  The example below is under 20 lines of code.

This is not a bug, but a possibly unexpect effect of a call to
recvfrom().
First a bit of comment:

>#define ERROR(a) do { perror (a); exit (1); } while (0)
>#define SEND(m) if (sendto (s,m,sizeof m,0,&a,sizeof a)==-1) ERROR ("sendto");
>#define RECV rcv.sin_addr.S_un.S_addr = 0; m[0] = '\0'; \
>		recvfrom (s, m, sizeof m, 0, &rcv, &rcvsize); \
>		printf ("%d %s\n", rcv.sin_addr.S_un.S_addr, m)

Yuck! This may seem to make the code more readable, but only
if you think that less code is more readable code. Don't
do this is production code.

>int main ()
>{
>  if ((s = socket (AF_INET, SOCK_DGRAM, 0)) == -1) ERROR ("socket");

>  if (bind (s, &a, sizeof a) == -1) ERROR ("bind");

>  if (ioctl (s, FIONBIO, (char *) &one) == -1) ERROR ("ioctl");

>  SEND ("hello1"); 
>  RECV; /* AND PRINT NETWORK ADDRESS OF SENDER AND MESSAGE */
>  RECV; /* THIS RECV DOESN'T FIND ANYTHING BUT DOESN'T BLOCK */

This is where thing go wrong. You have initialised the variable
recvsize to the size of the address structure. But, this
parameter is a value/result parameter. On entry, you specify the size
available for the address, on exit the system specifies the real
size of the address. When reading fails, recvfrom doesn't store an
address (or stores 0 bytes). This is indictating by modifying the
recvfrom variable and giving it the value zero. All subsequent
calls to recvfrom will not return an address.

If you add ``rvcsize = sizeof rcv;'' to your  RECV; macro,
recvfrom will return the address, as it will know there is space
available to write the address.

One can argue that recvfrom shouldn't touch rcvsize when an error
code is returned, but there is no valid reason not to reinitialise
the rcvsize variable.

I also see that you do:
57> cc test2.c -ldl
on the Sun.

This probably indicates that someone screwed up when installing a new shared
libc. (I.e., if it doesn't work without the -ldl)

Casper
-- 
						|	Casper H.S. Dik
						|	casper@fwi.uva.nl