$OpenBSD: patch-tcp_listen_c,v 1.2 2016/09/10 13:03:42 ajacoutot Exp $
--- tcp_listen.c.orig	Sun May  4 10:26:14 2003
+++ tcp_listen.c	Sat Sep 10 11:45:32 2016
@@ -6,10 +6,16 @@
 #include <netdb.h>
 #include <string.h>
 #include <syslog.h>
+#include <sys/select.h> /* fd_set */
 #include <stdio.h>
 #include <unistd.h>
 #include <errno.h>
 
+#define MAX_SOCKETS 10
+int socket_array[MAX_SOCKETS], maxs;
+int *socks=socket_array;
+fd_set deffds;
+ 
 static void Setsockopt(int fd, int level, int optname, const void * optval, socklen_t optlen) {
   if (setsockopt(fd,level,optname,optval,optlen) < 0) {
     syslog(LOG_WARNING,"%s: %s","setsockopt failed",strerror(errno));
@@ -29,8 +35,8 @@ static void Listen(int fd, int backlog) {
   }
 }
 
-static int tcp_listen(const char * host, const char * serv, socklen_t * addrlenp) {
-  int listenfd, n;
+static int* tcp_listen(const char * host, const char * serv) {
+  int n, *s;
   const int on = 1;
   struct addrinfo hints, * res, * ressave;
   struct linger sl = { 1, 5 };
@@ -39,37 +45,37 @@ static int tcp_listen(const char * host, const char * 
   hints.ai_flags = AI_PASSIVE;
   hints.ai_family = AF_UNSPEC;
   hints.ai_socktype = SOCK_STREAM;
+  FD_ZERO(&deffds);
 
-  if ((n = getaddrinfo(host,serv,&hints,&res)) != 0) {
+  if ((n = getaddrinfo(host,serv,&hints,&ressave)) != 0) {
     syslog(LOG_ERR,"%s: %s, %s: %s","getaddrinfo failed",host?host:"(any)",serv,strerror(errno));
     perror("getaddrinfo");
     exit(EXIT_FAILURE);
   }
-  ressave = res;
 
-  do {
-    listenfd = socket(res->ai_family,res->ai_socktype,res->ai_protocol);
-    if (listenfd < 0)
+  for (s=socks, res=ressave, maxs=0; res; res = res->ai_next) {
+    *s = socket(res->ai_family, res->ai_socktype,res->ai_protocol);
+    if (*s < 0)
       continue;
-    Setsockopt(listenfd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on));
-    Setsockopt(listenfd,SOL_SOCKET,SO_LINGER,&sl,sizeof(sl));
-    if (bind(listenfd,res->ai_addr,res->ai_addrlen) == 0)
-      break;
-    close(listenfd);
-  } while ((res = res->ai_next) != NULL);
-  if (res == NULL) {
-    syslog(LOG_ERR,"%s: %s, %s: %s","failed to bind socket",host?host:"(any)",serv,strerror(errno));
-    perror("tcp_listen");
-    exit(EXIT_FAILURE);
+    if (maxs==MAX_SOCKETS) {
+      syslog(LOG_ERR,"limiting socket number to %d",MAX_SOCKETS);
+      continue;
+    }
+    Setsockopt(*s,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on));
+    Setsockopt(*s,SOL_SOCKET,SO_LINGER,&sl,sizeof(sl));
+    if (bind(*s,res->ai_addr,res->ai_addrlen) != 0) {
+      close(*s);
+      continue;
+    }
+    Listen(*s,LISTENQ);
+    FD_SET(*s, &deffds);
+    s++; maxs++;
   }
-  Listen(listenfd,LISTENQ);
-  if (addrlenp) 
-    *addrlenp = res->ai_addrlen;
 
   freeaddrinfo(ressave);
-  return listenfd;
+  return socks;
 }
 
-int Tcp_listen(const char * host, const char * serv, socklen_t * addrlenp) {
-  return tcp_listen(host,serv,addrlenp);
+int* Tcp_listen(const char * host, const char * serv) {
+  return tcp_listen(host,serv);
 }
