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

Reply via email to