Return to BSD News archive
Xref: sserve comp.unix.ultrix:13601 comp.unix.bsd:4787
Newsgroups: comp.unix.ultrix,comp.unix.bsd
Path: sserve!manuel!munnari.oz.au!uunet!ftpbox!mothost!lmpsbbs!supra!rittle
From: rittle@supra (Loren James Rittle)
Subject: A major BSD socket bug?
Organization: Land Mobile Products Sector, Motorola Inc.
Date: Wed, 9 Sep 1992 05:31:47 GMT
Message-ID: <1992Sep9.053147.411@lmpsbbs.comm.mot.com>
Followup-To: comp.unix.ultrix
Summary: sockets in non-blocking mode appear to have problems
Sender: Loren J. Rittle <rittle@comm.mot.com>
Nntp-Posting-Host: 145.1.80.40
Lines: 82
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.
If you are a BSD hacker, please take a look.
Thanks,
Loren
/* It appears that whenever recvfrom() doesn't block and yet doesn't
return a packet (due to being in non-blocking mode), it hoses the
socket in some way. Any later call to recvfrom() that returns a
valid packet fails to write the sender's network address in the
sockaddr stucture that was passed to recvfrom(). Any number of
correctly matched SEND() - RECV pairs (i.e. SEND() comes before RECV)
can be inserted above the extra RECV with the same results
occurring. I have cut this example to the bone in the hopes that
people will look at it. Thanks to you if you do take the time. */
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/ioctl.h>
struct sockaddr_in a = {AF_INET, 0xf1f1};
struct sockaddr_in rcv = {AF_INET, 0xf1f1};
int s, rcvsize = sizeof rcv, one = 1;
char m[80];
#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)
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 */
SEND ("hello2"); /* QUEUE UP ONE MORE MESSAGE ON OUR SOCKET */
RECV; /* BOGUS NETWORK ADDRESS OF SENDER IS PRINTED! */
return 0;
}
/* Output from a DECstation 5100 running Ultrix 4.2A:
rittle@supra 631> uname -a
ULTRIX supra 4.2 0 RISC
rittle@supra 632> gcc test2.c # c89 and cc output session similar.
rittle@supra 633> a.out
676331921 hello1
0
0 hello2
Output from a Sun running SunOS 4.1.2 looked similar:
56> uname -a
SunOS asun 4.1.2 1 sun4c
57> cc test2.c -ldl
58> a.out
2130706433 hello1
0
0 hello2
It seems to me that the correct output (for my machine) should be:
676331921 hello1 # 676331921 is 145.1.80.40 - my machine's IP address BTW...
0
676331921 hello2
Anyone have a clue as to what is going on? Did I find a bug that afflicts
many versions of BSD UNIX, or is my code or thought process buggy? */
--
"I really doubt it," he said, "it's far more likely he was bumped off by
someone on the net." - The rumors of Mark's death are greatly exaggerated.