From owner-freebsd-hackers Sat Jun 12 23:14:29 1999 Delivered-To: freebsd-hackers@freebsd.org Received: from janus.syracuse.net (janus.syracuse.net [205.232.47.15]) by hub.freebsd.org (Postfix) with ESMTP id CA4AB14D0E for ; Sat, 12 Jun 1999 23:14:24 -0700 (PDT) (envelope-from green@unixhelp.org) Received: from localhost (green@localhost) by janus.syracuse.net (8.9.2/8.8.7) with ESMTP id CAA19251 for ; Sun, 13 Jun 1999 02:14:32 -0400 (EDT) Date: Sun, 13 Jun 1999 02:14:32 -0400 (EDT) From: Brian Feldman X-Sender: green@janus.syracuse.net To: hackers@FreeBSD.ORG Subject: Just connect(2) breakage (Was Re: select(2) breakage) In-Reply-To: Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Sender: owner-freebsd-hackers@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG On Sun, 13 Jun 1999, Brian Feldman wrote: > I'm using the attached program which I wrote today (don't ask why, I think > I just wanted to beat the heck out of FreeBSD!) I have maxusers 200, a > MAXFILES=65536, and the limits set to allow me to use the program > fully (all 30000 ports; I don't want to monopolize EVERY port...) When > run, select doesn't time out after 60 seconds like it should. Disregard this part! User error (not making sure stdio is flushed). > Another problem that came up with this: I originally started at port 1024. > I monopolized 30000 ports (almost all consecutive, of course). When I try to > connect() a TCP socket as non-root, it fails with EAGAIN (I only tracked it > far enough down as in_pcbbind().) It seems that eventually it gives up trying > to find a port... :-/ This problem is quite real. > > Brian Feldman _ __ ___ ____ ___ ___ ___ > green@unixhelp.org _ __ ___ | _ ) __| \ > FreeBSD: The Power to Serve! _ __ | _ \._ \ |) | > http://www.freebsd.org _ |___/___/___/ > " THAT'S WRONG WRONG WRONG!" > > /*- > * Copyright (c) 1999 Brian Fundakowski Feldman > * All rights reserved. > * > * Redistribution and use in source and binary forms, with or without > * modification, are permitted provided that the following conditions > * are met: > * 1. Redistributions of source code must retain the above copyright > * notice, this list of conditions and the following disclaimer. > * 2. Redistributions in binary form must reproduce the above copyright > * notice, this list of conditions and the following disclaimer in the > * documentation and/or other materials provided with the distribution. > * > * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND > * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE > * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE > * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE > * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL > * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS > * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) > * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT > * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY > * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF > * SUCH DAMAGE. > * > * $Id$ > * > */ > > #include > #include > #include > #include > > #include > > #include > #include > #include > #include > #include > #include > > int > anothersocket(u_short port) { > struct sockaddr_in sin; > int fd, serrno; > > if ((fd = socket(PF_INET, SOCK_STREAM, 0)) == -1) > return fd; > > sin.sin_family = AF_INET; > sin.sin_port = htons(port); > sin.sin_addr.s_addr = htonl(INADDR_ANY); > if (bind(fd, (struct sockaddr *)&sin, sizeof(sin)) == -1) { > serrno = errno; > close(fd); > errno = serrno; > return -1; > } > > listen(fd, 1); > > return fd; > } > > int > allocatesockets(int *fdvec, u_short *portvec, int nsockets) { > int fd, ncreated = 0, serrno; > u_short port = 32768; > > while (nsockets) { > if (++port == 65535) > break; > if ((fd = anothersocket(port)) == -1) > if (errno == ENFILE || errno == EMFILE) { > serrno = errno; > close(fdvec[--ncreated]); > errno = serrno; > break; > } else > continue; > portvec[ncreated] = port; > fdvec[ncreated++] = fd; > nsockets--; > } > > return ncreated; > } > > int > main(int argc, char **argv) { > int fdvec[30000]; > u_short portvec[30000]; > int nsockets, tmp, highestsock; > fd_set odescriptors, ndescriptors; > struct timeval timeout; > > nsockets = allocatesockets(fdvec, portvec, > sizeof(fdvec) / sizeof(fdvec[0])); > printf("%s started: %d PF_INET SOCK_STREAM sockets ready\n", > strrchr(argv[0], '/') + 1, nsockets); > highestsock = fdvec[nsockets - 1] + 1; > FD_ZERO(&odescriptors); > for (tmp = 0; tmp < nsockets; tmp++) > FD_SET(fdvec[tmp], &odescriptors); > > for (;;) { > int nfound, curnum, nset; > int *selected; > u_short *selectedports; > const struct timespec sleeper = { 0, 100000000 }; > > timeout.tv_sec = 60; > timeout.tv_usec = 0; > > ndescriptors = odescriptors; > if ((nfound = select(highestsock, &ndescriptors, NULL, NULL, > &timeout)) < 1) { > if (nfound == -1) > perror("select()"); > else > printf("no select() action"); > continue; > } > > selected = malloc(nfound * sizeof(int)); > selectedports = malloc(nfound * sizeof(u_short)); > for (curnum = nset = 0; nset < nfound; curnum++) { > if (!FD_ISSET(fdvec[curnum], &ndescriptors)) > continue; > > selectedports[nset] = portvec[curnum]; > selected[nset++] = accept(fdvec[curnum], NULL, NULL); > } > > printf("Sockets ready:\n\t"); > for (nset = 0; nset < nfound; nset++) > printf("%d,", selectedports[nset]); > putchar('\n'); > > for (nset = 0; nset < nfound; nset++) > close(selected[nset]); > > free(selected); > free(selectedports); > nanosleep(&sleeper, NULL); > } > } > > > > To Unsubscribe: send mail to majordomo@FreeBSD.org > with "unsubscribe freebsd-hackers" in the body of the message > Brian Feldman _ __ ___ ____ ___ ___ ___ green@unixhelp.org _ __ ___ | _ ) __| \ FreeBSD: The Power to Serve! _ __ | _ \._ \ |) | http://www.freebsd.org _ |___/___/___/ " THAT'S WRONG WRONG WRONG!" To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-hackers" in the body of the message