home *** CD-ROM | disk | FTP | other *** search
- Xref: sparky comp.unix.ultrix:6778 comp.unix.bsd:5363
- Newsgroups: comp.unix.ultrix,comp.unix.bsd
- Path: sparky!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.
-