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.