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                _ __ ___ ____  ___ ___ ___  
>  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
> 

 Brian Feldman                _ __ ___ ____  ___ ___ ___  
 gr...@unixhelp.org                _ __ ___ | _ ) __|   \ 
     FreeBSD: The Power to Serve!      _ __ | _ \._ \ |) |
         http://www.freebsd.org           _ |___/___/___/ 
 "<green_> THAT'S WRONG WRONG WRONG!"



To Unsubscribe: send mail to majord...@freebsd.org
with "unsubscribe freebsd-hackers" in the body of the message

Reply via email to