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. 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... :-/
Brian Feldman _ __ ___ ____ ___ ___ ___ gr...@unixhelp.org _ __ ___ | _ ) __| \ FreeBSD: The Power to Serve! _ __ | _ \._ \ |) | http://www.freebsd.org _ |___/___/___/ "<green_> 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 <sys/types.h> #include <sys/socket.h> #include <sys/ioctl.h> #include <sys/time.h> #include <netinet/in.h> #include <errno.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #include <unistd.h> 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 majord...@freebsd.org with "unsubscribe freebsd-hackers" in the body of the message