brnstnd@kramden.acf.nyu.edu (Dan Bernstein) (06/13/91)
The enclosed program creates a stream socket, fcntl()s it to FNDELAY, attempts to connect() to a nonexistent address, and select()s the socket for writing. On any sane BSD machine, the select returns almost immediately, as does a straight connect(): the network is unreachable. Under Ultrix 4.1, a straight connect() fails almost immediately, but the select() for writing hangs for 75 seconds. That's an awfully long time to figure out that a net doesn't exist. Who dreamed up this asinine behavior? (Probably the same person who thought that if you select() a server socket for reading, accept() will always succeed, even if you're out of file descriptors. In reality, the accept() fails, and this person blithely continues to select()-accept() and fill up people's error logs, as was noted here recently. [sigh]) ---Dan #include <sys/types.h> #include <sys/socket.h> #include <sys/file.h> #include <sys/time.h> #include <netinet/in.h> #include <arpa/inet.h> #include <fcntl.h> #include <errno.h> extern int errno; main() { int s; char *c; struct sockaddr_in sa; int fl; int r; fd_set rfds; fd_set wfds; fd_set efds; int now; s = socket(AF_INET,SOCK_STREAM,0); printf("socket %d\n",s); sa.sin_family = AF_INET; sa.sin_port = ntohs(21); c = (char *) &(sa.sin_addr); c[0] = 1; c[1] = 2; c[2] = 3; c[3] = 4; printf("address %s\n",inet_ntoa(sa.sin_addr)); printf("getfl originally %d\n",fl = fcntl(s,F_GETFL,0)); fcntl(s,F_SETFL,fl | FNDELAY); printf("getfl now %d\n",fl = fcntl(s,F_GETFL,0)); r = connect(s,&sa,sizeof(sa)); if (r == -1) if ((errno == EINPROGRESS) || (errno == EWOULDBLOCK)) { perror("connect failed, known error"); FD_ZERO(&rfds); FD_ZERO(&wfds); FD_ZERO(&efds); FD_SET(s,&wfds); time(&now); printf("select started %s",ctime(&now)); printf("select returned %d\n" ,select(s + 1,&rfds,&wfds,&efds,(struct timeval *) 0)); time(&now); printf("select finished %s",ctime(&now)); printf("socket writable: %d\n",!!FD_ISSET(s,&wfds)); /* if connection failed, will find out on first I/O */ } else perror("connect failed, unrecognized error"); else printf("connect succeeded immediately\n"); exit(0); }
brnstnd@kramden.acf.nyu.edu (Dan Bernstein) (06/18/91)
In article <26530:Jun1218:54:1991@kramden.acf.nyu.edu> brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes: > Under Ultrix 4.1, a straight connect() fails almost immediately, but the > select() for writing hangs for 75 seconds. That's an awfully long time > to figure out that a net doesn't exist. Perhaps I wasn't clear enough the first time. Is DEC going to fix this bug before the end of the millenium? Has it, by any chance, already been fixed in 4.2? (I doubt it, considering DEC's track record. No offense intended---few companies do any better.) ---Dan