Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 13 Jun 1999 02:14:32 -0400 (EDT)
From:      Brian Feldman <green@unixhelp.org>
To:        hackers@FreeBSD.ORG
Subject:   Just connect(2) breakage (Was Re: select(2) breakage)
Message-ID:  <Pine.BSF.4.10.9906130213090.19234-100000@janus.syracuse.net>
In-Reply-To: <Pine.BSF.4.10.9906130033380.17648-100000@janus.syracuse.net>

next in thread | previous in thread | raw e-mail | index | archive | help
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           _ |___/___/___/ 
>  "<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 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           _ |___/___/___/ 
 "<green_> THAT'S WRONG WRONG WRONG!"



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




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.BSF.4.10.9906130213090.19234-100000>