diff -Nru ORIGINAL-3.8.1p1/Makefile.in openssh-3.8.1p1-alptpatch/Makefile.in
--- ORIGINAL-3.8.1p1/Makefile.in	2004-02-18 04:35:11.000000000 +0100
+++ openssh-3.8.1p1-alptpatch/Makefile.in	2004-09-05 19:51:11.000000000 +0200
@@ -77,6 +77,7 @@
 
 SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o auth-rsa.o auth-rh-rsa.o \
 	sshpty.o sshlogin.o servconf.o serverloop.o uidswap.o \
+	inet.o accept.o \
 	auth.o auth1.o auth2.o auth-options.o session.o \
 	auth-chall.o auth2-chall.o groupaccess.o \
 	auth-skey.o auth-bsdauth.o auth2-hostbased.o auth2-kbdint.o \
diff -Nru ORIGINAL-3.8.1p1/accept.c openssh-3.8.1p1-alptpatch/accept.c
--- ORIGINAL-3.8.1p1/accept.c	1970-01-01 01:00:00.000000000 +0100
+++ openssh-3.8.1p1-alptpatch/accept.c	2004-09-07 15:52:03.941042280 +0200
@@ -0,0 +1,231 @@
+/* This file is part of Netsukuku
+ * (c) Copyright 2004 Andrea Lo Pumo aka AlpT <alpt@freaknet.org>
+ *
+ * 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 ``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 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.
+ */
+
+ /* accept.c: This is how it works:
+ * When a new accept is made add_accept is called. It first updates the accept
+ * table and then, if the accept_tbl isn't full add the new accept in the tbl.
+ * If the accept_tbl is full the connection is dropped.
+ * Each accept in the table last for free_accept_time after the close of that
+ * connection, so if an host has fulled the accept_tbl has to wait 
+ * free_accept_time of seconds to be able reconnect again.
+ */
+
+#include <sys/types.h>
+#include <signal.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include "accept.h"
+#include "xmalloc.h"
+#include "log.h"
+
+
+void init_accept_tbl(int startups, int accepts, int time)
+{
+	int i;
+
+	max_connections=startups;
+	max_accepts_per_host=accepts;
+	free_accept_time=time;
+	accept_idx=accept_sidx=0;
+	
+	accept_tbl=(struct accept_table *)xmalloc(sizeof(struct accept_table)*max_connections);
+	memset(accept_tbl, '\0', sizeof(struct accept_table)*max_connections);
+
+	for(i=0; i<max_connections; i++) {
+		accept_tbl[i].pid=(pid_t *)xmalloc(sizeof(pid_t)*max_accepts_per_host);
+		memset(accept_tbl[i].pid, '\0', sizeof(pid_t)*max_accepts_per_host);
+			
+		accept_tbl[i].closed=(unsigned char *)xmalloc(sizeof(unsigned char)*max_accepts_per_host);
+		memset(accept_tbl[i].closed, '\0', sizeof(unsigned char)*max_accepts_per_host);
+			
+		accept_tbl[i].acp_t=(time_t *)xmalloc(sizeof(time_t)*max_accepts_per_host);
+		memset(accept_tbl[i].acp_t, '\0', sizeof(time_t)*max_accepts_per_host);
+	}
+}
+
+void destroy_accept_tbl(void)
+{
+	int i; 
+	if(!accept_tbl)
+		return;
+	for(i=0; i<max_connections; i++) {
+		xfree(accept_tbl[i].pid);
+		xfree(accept_tbl[i].closed);
+		xfree(accept_tbl[i].acp_t);
+	}
+	xfree(accept_tbl);
+	accept_tbl=0;
+}
+
+
+void update_accept_tbl(void)
+{
+	int i,e,k;
+	time_t cur_t;
+	
+	if(update_accept_tbl_mutex)
+		return;
+	else
+		update_accept_tbl_mutex=1;
+	
+	time(&cur_t);
+	
+	for(i=0; i < max_connections; i++) {
+		if(!accept_tbl[i].ip.len)
+			continue;
+		if(accept_tbl[i].accepts) {
+			for(e=0; e<max_accepts_per_host; e++) {
+				if(!accept_tbl[i].acp_t[e])
+					break;
+				k=kill(accept_tbl[i].pid[e], 0);
+				debug("ACPT: Updating tbl: cur_t: %d, accept_tbl[%d].acp_t[%d]:%d+%d, accept_tbl[i].pid[e]: %d, kill=%d (ESRCH=%d)",
+						cur_t, i,e, accept_tbl[i].acp_t[e], free_accept_time, accept_tbl[i].pid[e], k, ESRCH);
+				if((accept_tbl[i].closed[e] || (k==-1 && errno==ESRCH)) && 
+						accept_tbl[i].acp_t[e]+free_accept_time <= cur_t) {
+					debug("ACPT: removing from tbl");
+					accept_tbl[i].accepts--;
+					accept_tbl[i].acp_t[e]=0;
+					accept_tbl[i].closed[e]=0;
+					accept_tbl[i].pid[e]=0;
+					if(!accept_tbl[i].accepts)
+						memset(&accept_tbl[i].ip, '\0', sizeof(inet_prefix));
+				}
+			}
+		}
+	}
+
+	update_accept_tbl_mutex=0;
+}
+
+int find_ip_acpt(inet_prefix ip)
+{
+	int i;
+	
+	for(i=0; i<max_accepts_per_host; i++) {
+		if(!memcmp(&accept_tbl[i].ip, &ip, sizeof(inet_prefix)))
+			return i;
+	}
+
+	return -1;
+}
+
+int find_first_free(void)
+{
+	int i;
+	
+	for(i=0; i<max_connections; i++) {
+		if(!accept_tbl[i].accepts)
+			return i;
+	}
+
+	return -1;
+}
+
+int is_ip_acpt_free(inet_prefix ip, int *index)
+{
+	int idx;
+	
+	update_accept_tbl();
+	
+	if((idx=find_ip_acpt(ip))==-1)
+		if((idx=find_first_free())==-1)
+			return -1;
+	debug("ACPT: accept_tbl[idx].accepts: %d, max_acp: %d", accept_tbl[idx].accepts, max_accepts_per_host);
+	if(accept_tbl[idx].accepts > max_accepts_per_host)
+		return -1;
+
+	*index=idx;
+	return 0;
+}
+
+int find_free_acp_t(int idx)
+{
+	int e;
+	
+	for(e=0; e < max_accepts_per_host; e++) {
+		if(!accept_tbl[idx].acp_t[e])
+			return e;
+	}
+	
+	return -1;	/*This happens if the rq_tbl is full for the "rq" request*/
+}
+
+int add_accept(inet_prefix ip)
+{
+	int err, idx, cl;
+	time_t cur_t;
+	
+	if((err=is_ip_acpt_free(ip, &idx)))
+		return err;
+	
+	time(&cur_t);
+	
+	if((cl=find_free_acp_t(idx))==-1)
+		return -1;
+	accept_tbl[idx].accepts++;
+	accept_tbl[idx].acp_t[cl]=cur_t;
+	accept_tbl[idx].closed[cl]=0;
+	memcpy(&accept_tbl[idx].ip, &ip, sizeof(inet_prefix));
+
+	/*This global var will be given to the thread*/
+	accept_idx=idx;
+	accept_sidx=cl;
+
+	return 0;
+}
+
+void del_accept(int idx)
+{
+	if(!accept_tbl[idx].accepts) 
+		return;
+
+	if(accept_tbl[idx].acp_t[accept_sidx]) {
+		accept_tbl[idx].accepts--;
+		accept_tbl[idx].acp_t[accept_sidx]=0;
+		accept_tbl[idx].closed[accept_sidx]=0;
+		if(!accept_tbl[idx].accepts)
+			memset(&accept_tbl[idx].ip, '\0', sizeof(inet_prefix));
+		accept_sidx--;
+	}
+}
+
+int close_accept(void)
+{
+	if(!accept_tbl[accept_idx].accepts) 
+		return -1;
+	
+	accept_tbl[accept_idx].closed[accept_sidx]=0;
+
+	update_accept_tbl();
+
+	return 0;
+}
+
+void add_accept_pid(pid_t pid)
+{
+	accept_tbl[accept_idx].pid[accept_sidx]=pid;
+	debug("ACPT: Added pig %d in accept_tbl[%d].pid[%d]", accept_tbl[accept_idx].pid[accept_sidx], accept_idx, accept_sidx);
+}
diff -Nru ORIGINAL-3.8.1p1/accept.h openssh-3.8.1p1-alptpatch/accept.h
--- ORIGINAL-3.8.1p1/accept.h	1970-01-01 01:00:00.000000000 +0100
+++ openssh-3.8.1p1-alptpatch/accept.h	2004-09-07 15:52:25.986690832 +0200
@@ -0,0 +1,73 @@
+/* This file is part of Netsukuku
+ * (c) Copyright 2004 Andrea Lo Pumo aka AlpT <alpt@freaknet.org>
+ *
+ * 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 ``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 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.
+ */
+
+#include <time.h>
+#include "inet.h"
+
+#define MAX_CONNECTIONS		500
+#define MAX_ACCEPTS		50
+#define FREE_ACCEPT_TIME	5		/*in seconds*/
+
+/*This struct keep tracks of single connection to the server.
+ * The thread_daemon who handle the connection knows the connection
+ * position in the accept_tbl
+ */
+struct accept_table
+{
+	inet_prefix	   ip;			/*Ip of the node connected*/
+	unsigned char	   accepts;		/*Number of connection from this node*/
+	pid_t              *pid;   	        /*The pid of each child that have accepted the conn*/
+	unsigned char      *closed; 		/*Each element of this array is 1 or 0. It indicates if the connection has
+                                                  been closed*/
+	time_t		   *acp_t;		/*The time when the connection was accepted. The "accepts" counter
+						  will decrement when one of the acp_t+FREE_ACCEPT_TIME will 
+						  be <= current_time AND (the relative pid will be non existent OR
+						  the relative closed element will be == 1)
+						 */
+};
+
+/*This struct keeps all the info regarding each node connected*/
+struct accept_table *accept_tbl;
+
+/*accept_idx it the position of the accept_tbl of a thread.
+ *accept_sidx is the second index, it is used for example in pid[accept_sidx] 
+ *note: this var are used only in the child and the child doesn't need to modify them!
+ */
+int accept_idx, accept_sidx;
+
+int update_accept_tbl_mutex;
+
+int max_connections, max_accepts_per_host, free_accept_time;
+
+void init_accept_tbl(int startups, int accepts, int time);
+void destroy_accept_tbl(void);
+void update_accept_tbl(void);
+int find_ip_acpt(inet_prefix ip);
+int find_first_free(void);
+int is_ip_acpt_free(inet_prefix ip, int *index);
+int find_free_acp_t(int idx);
+int add_accept(inet_prefix ip);
+void del_accept(int idx);
+int close_accept(void);
+void add_accept_pid(pid_t pid);
diff -Nru ORIGINAL-3.8.1p1/inet.c openssh-3.8.1p1-alptpatch/inet.c
--- ORIGINAL-3.8.1p1/inet.c	1970-01-01 01:00:00.000000000 +0100
+++ openssh-3.8.1p1-alptpatch/inet.c	2004-09-07 16:05:00.921923232 +0200
@@ -0,0 +1,100 @@
+/* This file is part of Netsukuku
+ * (c) Copyright 2004 Andrea Lo Pumo aka AlpT <alpt@freaknet.org>
+ *
+ * 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 ``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 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.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+#include "inet.h"
+#include "xmalloc.h"
+
+char *inet_to_str(inet_prefix *ip)
+{
+	char *dst;
+
+	if(ip->family==AF_INET) {
+		struct in_addr src;
+
+		memcpy(&src, ip->data, ip->len);
+		dst=xmalloc(INET_ADDRSTRLEN);
+		inet_ntop(ip->family, &src, dst, INET_ADDRSTRLEN);
+	}
+	else if(ip->family==AF_INET6) {
+		struct in6_addr src;
+
+		memcpy(&src, ip->data, ip->len);
+		dst=xmalloc(INET6_ADDRSTRLEN);
+		inet_ntop(ip->family, &src, dst, INET6_ADDRSTRLEN);
+	}
+
+	return dst;
+}
+
+int inet_to_sockaddr(inet_prefix *ip, u_short port, struct sockaddr *dst, socklen_t *dstlen)
+{
+	memset(dst, '\0',  sizeof(struct sockaddr));
+	
+	dst->sa_family=ip->family;
+	port=htons(port);
+	memcpy(dst->sa_data, &port, sizeof(u_short));
+	
+	if(ip->family==AF_INET)
+		memcpy(dst->sa_data+sizeof(u_short), ip->data, ip->len);
+	else if(ip->family==AF_INET6) 
+		memcpy(dst->sa_data+sizeof(u_short)+sizeof(u_int), ip->data, ip->len);
+	else
+		return -1;
+
+	if(!dstlen)
+		return 0;
+
+	*dstlen=ip->len;
+
+	return 0;
+}
+	
+int sockaddr_to_inet(struct sockaddr *ip, inet_prefix *dst, u_short *port)
+{
+	u_short po;
+	
+	memset(dst, '\0',  sizeof(inet_prefix));
+	
+	dst->family=ip->sa_family;
+	memcpy(&po, &ip->sa_data, sizeof(u_short));
+	if(port)
+		*port=ntohs(po);
+	
+	if(ip->sa_family==AF_INET) {
+		memcpy(dst->data, &ip->sa_data+sizeof(u_short), sizeof(struct in_addr));
+		dst->data[0]=ntohl(dst->data[0]);
+		dst->len=sizeof(struct in_addr);
+	} else if(ip->sa_family==AF_INET6) {
+		memcpy(dst->data, &ip->sa_data+sizeof(u_short)+sizeof(int), sizeof(struct in6_addr));
+		dst->len=sizeof(struct in6_addr);
+	} else
+		return -1;
+
+	return 0;
+}
diff -Nru ORIGINAL-3.8.1p1/inet.h openssh-3.8.1p1-alptpatch/inet.h
--- ORIGINAL-3.8.1p1/inet.h	1970-01-01 01:00:00.000000000 +0100
+++ openssh-3.8.1p1-alptpatch/inet.h	2004-09-07 15:51:40.199651520 +0200
@@ -0,0 +1,37 @@
+/* This file is part of Netsukuku
+ * (c) Copyright 2004 Andrea Lo Pumo aka AlpT <alpt@freaknet.org>
+ *
+ * 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 ``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 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.
+ */
+
+#include <asm/types.h>
+#include <sys/socket.h>
+
+typedef struct
+{
+	__u8 family;
+	__u16 len;
+	__u32 data[4];
+} inet_prefix;
+
+char *inet_to_str(inet_prefix *ip);
+int inet_to_sockaddr(inet_prefix *ip, u_short port, struct sockaddr *dst, socklen_t *dstlen);
+int sockaddr_to_inet(struct sockaddr *ip, inet_prefix *dst, u_short *port);
diff -Nru ORIGINAL-3.8.1p1/log.h openssh-3.8.1p1-alptpatch/log.h
--- ORIGINAL-3.8.1p1/log.h	2003-10-02 08:12:37.000000000 +0200
+++ openssh-3.8.1p1-alptpatch/log.h	2004-09-05 20:58:08.000000000 +0200
@@ -16,7 +16,7 @@
 #define SSH_LOG_H
 
 #include <syslog.h> /* Needed for LOG_AUTHPRIV (if present) */
-
+#include <stdarg.h>
 /* Supported syslog facilities and levels. */
 typedef enum {
 	SYSLOG_FACILITY_DAEMON,
diff -Nru ORIGINAL-3.8.1p1/servconf.c openssh-3.8.1p1-alptpatch/servconf.c
--- ORIGINAL-3.8.1p1/servconf.c	2004-01-23 12:03:10.000000000 +0100
+++ openssh-3.8.1p1-alptpatch/servconf.c	2004-09-07 13:17:36.658883312 +0200
@@ -23,6 +23,7 @@
 #include "cipher.h"
 #include "kex.h"
 #include "mac.h"
+#include "accept.h"
 
 static void add_listen_addr(ServerOptions *, char *, u_short);
 static void add_one_listen_addr(ServerOptions *, char *, u_short);
@@ -92,9 +93,14 @@
 	options->protocol = SSH_PROTO_UNKNOWN;
 	options->gateway_ports = -1;
 	options->num_subsystems = 0;
-	options->max_startups_begin = -1;
-	options->max_startups_rate = -1;
+	/*
+	 *options->max_startups_begin = -1;
+	 *options->max_startups_rate = -1;
+	 */
 	options->max_startups = -1;
+	options->max_connections = -1;
+	options->max_accepts_per_host = -1;
+	options->max_accepts_per_host_time = -1;
 	options->banner = NULL;
 	options->use_dns = -1;
 	options->client_alive_interval = -1;
@@ -206,12 +212,19 @@
 		options->allow_tcp_forwarding = 1;
 	if (options->gateway_ports == -1)
 		options->gateway_ports = 0;
-	if (options->max_startups == -1)
-		options->max_startups = 10;
-	if (options->max_startups_rate == -1)
-		options->max_startups_rate = 100;		/* 100% */
+/*	if (options->max_startups_rate == -1)
+		options->max_startups_rate = 100;		// 100 %
 	if (options->max_startups_begin == -1)
 		options->max_startups_begin = options->max_startups;
+*/
+	if (options->max_connections == -1)
+		options->max_connections = MAX_CONNECTIONS;
+	if (options->max_accepts_per_host == -1)
+		options->max_accepts_per_host = 10;
+	if (options->max_accepts_per_host_time == -1)
+		options->max_accepts_per_host_time = FREE_ACCEPT_TIME;
+	if (options->max_startups == -1)
+		options->max_startups = options->max_connections*options->max_accepts_per_host;
 	if (options->use_dns == -1)
 		options->use_dns = 1;
 	if (options->client_alive_interval == -1)
@@ -262,8 +275,8 @@
 	sPermitUserEnvironment, sUseLogin, sAllowTcpForwarding, sCompression,
 	sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
 	sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
-	sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem, sMaxStartups,
-	sBanner, sUseDNS, sHostbasedAuthentication,
+	sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem, sMaxStartups, 
+	sMaxAcceptsPerHost, sMaxConnections, sBanner, sUseDNS, sHostbasedAuthentication,
 	sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
 	sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
 	sGssAuthentication, sGssCleanupCreds,
@@ -356,7 +369,11 @@
 	{ "protocol", sProtocol },
 	{ "gatewayports", sGatewayPorts },
 	{ "subsystem", sSubsystem },
-	{ "maxstartups", sMaxStartups },
+	/*It's useless now, because max_startups=max_connections*max_accepts_per_host
+	 *{ "maxstartups", sMaxStartups },
+	 */
+	{ "maxconnections", sMaxConnections },
+	{ "maxacceptsperhost", sMaxAcceptsPerHost  },
 	{ "banner", sBanner },
 	{ "usedns", sUseDNS },
 	{ "verifyreversemapping", sDeprecated },
@@ -846,6 +863,7 @@
 		options->num_subsystems++;
 		break;
 
+	/*It's useless now, because max_startups=max_connections*max_accepts_per_host
 	case sMaxStartups:
 		arg = strdelim(&cp);
 		if (!arg || *arg == '\0')
@@ -868,6 +886,36 @@
 			options->max_startups = options->max_startups_begin;
 		break;
 
+		*/
+	case sMaxAcceptsPerHost:
+		arg = strdelim(&cp);
+		if (!arg || *arg == '\0')
+			fatal("%s line %d: Missing MaxAcceptsPerHost spec.",
+					filename, linenum);
+		if ((n = sscanf(arg, "%d:%d", 
+		   &options->max_accepts_per_host, 
+		   &options->max_accepts_per_host_time)) != 2 && n != 1)
+				fatal("%s line %d: Illegal MaxAcceptsPerHost spec.",
+				    filename, linenum);
+		else if(n == 1) {
+			options->max_accepts_per_host_time = FREE_ACCEPT_TIME;
+			debug("Default sMaxAcceptsPerHost time: %d", options->max_accepts_per_host_time);
+		}
+		
+		if(options->max_accepts_per_host > MAX_ACCEPTS)
+			fatal("%s line %d: MaxAcceptsPerHost is > of MAX_ACCEPTS (%d).",
+					filename, linenum, MAX_ACCEPTS);
+		debug("sMaxAcceptsPerHost: %d", options->max_accepts_per_host);
+		if(options->max_accepts_per_host_time < 0)
+			fatal("%s line %d: MaxAcceptsPerHost time is < of 0.",
+					filename, linenum);
+		debug("sMaxAcceptsPerHost time: %d", options->max_accepts_per_host_time);
+		break;
+
+	case sMaxConnections:
+		intptr = &options->max_connections;
+		goto parse_int;
+
 	case sBanner:
 		charptr = &options->banner;
 		goto parse_filename;
diff -Nru ORIGINAL-3.8.1p1/servconf.h openssh-3.8.1p1-alptpatch/servconf.h
--- ORIGINAL-3.8.1p1/servconf.h	2003-12-31 01:37:34.000000000 +0100
+++ openssh-3.8.1p1-alptpatch/servconf.h	2004-09-07 13:23:40.303600912 +0200
@@ -107,9 +107,10 @@
 	char   *subsystem_name[MAX_SUBSYSTEMS];
 	char   *subsystem_command[MAX_SUBSYSTEMS];
 
-	int	max_startups_begin;
-	int	max_startups_rate;
 	int	max_startups;
+	int	max_connections;
+	int	max_accepts_per_host;
+	int	max_accepts_per_host_time;
 	char   *banner;			/* SSH-2 banner message */
 	int	use_dns;
 	int	client_alive_interval;	/*
diff -Nru ORIGINAL-3.8.1p1/session.c openssh-3.8.1p1-alptpatch/session.c
--- ORIGINAL-3.8.1p1/session.c	2004-04-16 14:47:55.000000000 +0200
+++ openssh-3.8.1p1-alptpatch/session.c	2004-09-06 22:10:35.000000000 +0200
@@ -57,6 +57,7 @@
 #include "canohost.h"
 #include "session.h"
 #include "monitor_wrap.h"
+#include "accept.h"
 
 #if defined(KRB5) && defined(USE_AFS)
 #include <kafs.h>
@@ -2257,4 +2258,7 @@
 	 */
 	if (!use_privsep || mm_is_monitor())
 		session_destroy_all(session_pty_cleanup2);
+
+	debug("ACPT: do_cleanup: Destroying the accept_tbl");
+	destroy_accept_tbl();
 }
diff -Nru ORIGINAL-3.8.1p1/sshd.c openssh-3.8.1p1-alptpatch/sshd.c
--- ORIGINAL-3.8.1p1/sshd.c	2004-03-21 23:36:01.000000000 +0100
+++ openssh-3.8.1p1-alptpatch/sshd.c	2004-09-07 16:05:43.680422952 +0200
@@ -85,6 +85,7 @@
 #include "monitor_wrap.h"
 #include "monitor_fdpass.h"
 
+#include "accept.h"
 #ifdef LIBWRAP
 #include <tcpd.h>
 #include <syslog.h>
@@ -737,6 +738,7 @@
  * of (max_startups_rate/100). the probability increases linearly until
  * all connections are dropped for startups > max_startups
  */
+/* Now it's useless, accept.c does the dirty job
 static int
 drop_connection(int startups)
 {
@@ -759,6 +761,7 @@
 	debug("drop_connection: p %g, r %g", p, r);
 	return (r < p) ? 1 : 0;
 }
+*/
 
 static void
 usage(void)
@@ -785,6 +788,7 @@
 	socklen_t fromlen;
 	fd_set *fdset;
 	struct sockaddr_storage from;
+	struct sockaddr from_tmp;
 	const char *remote_ip;
 	int remote_port;
 	FILE *f;
@@ -792,6 +796,7 @@
 	char ntop[NI_MAXHOST], strport[NI_MAXSERV];
 	char *line;
 	int listen_sock, maxfd;
+	inet_prefix ip;
 	int startup_p[2];
 	int startups = 0;
 	Key *key;
@@ -950,6 +955,12 @@
 	/* Fill in default values for those options not explicitly set. */
 	fill_default_server_options(&options);
 
+	debug("ACPT: Initializing the accept_tbl: max_startups: %d, max_connections: %d, "
+			"max_accepts_per_host: %d, max_accept_per_host_time: %d", 
+			options.max_startups, options.max_connections, options.max_accepts_per_host, 
+			options.max_accepts_per_host_time);
+	init_accept_tbl(options.max_connections, options.max_accepts_per_host, options.max_accepts_per_host_time);
+	
 	/* Check that there are no remaining arguments. */
 	if (optind < ac) {
 		fprintf(stderr, "Extra argument %s.\n", av[optind]);
@@ -1278,7 +1289,7 @@
 				if (!FD_ISSET(listen_socks[i], fdset))
 					continue;
 				fromlen = sizeof(from);
-				newsock = accept(listen_socks[i], (struct sockaddr *)&from,
+				newsock = accept(listen_socks[i], (struct sockaddr *)&from_tmp,
 				    &fromlen);
 				if (newsock < 0) {
 					if (errno != EINTR && errno != EWOULDBLOCK)
@@ -1290,15 +1301,33 @@
 					close(newsock);
 					continue;
 				}
+				/*Drop connection now is useless
 				if (drop_connection(startups) == 1) {
 					debug("drop connection #%d", startups);
 					close(newsock);
 					continue;
 				}
+				*/	
 				if (pipe(startup_p) == -1) {
 					close(newsock);
 					continue;
 				}
+				
+				sockaddr_to_inet(&from_tmp, &ip, 0);
+				if(add_accept(ip)) {
+					char *ntop;
+			    		ntop=get_peer_ipaddr(newsock);
+					debug("ACPT: drop connection with %s: Accept table full.", ntop);
+					xfree(ntop);
+					close(newsock);
+					continue;
+				} else {
+					char *ntop;
+			    		ntop=get_peer_ipaddr(newsock);
+					debug("ACPT: Accept_tbl ok! accept_idx: %d from %s", accept_idx, ntop);
+					xfree(ntop);
+				}
+
 
 				for (j = 0; j < options.max_startups; j++)
 					if (startup_pipes[j] == -1) {
@@ -1309,6 +1338,7 @@
 						break;
 					}
 
+
 				/*
 				 * Got connection.  Fork a child to handle it, unless
 				 * we are in debugging mode.
@@ -1327,6 +1357,7 @@
 					pid = getpid();
 					break;
 				} else {
+				
 					/*
 					 * Normal production daemon.  Fork, and have
 					 * the child process the connection. The
@@ -1351,10 +1382,13 @@
 				}
 
 				/* Parent.  Stay in the loop. */
-				if (pid < 0)
+				if (pid < 0) {
 					error("fork: %.100s", strerror(errno));
-				else
+					del_accept(accept_idx);
+				} else {
 					debug("Forked child %ld.", (long)pid);
+					add_accept_pid(pid);
+				}
 
 				close(startup_p[1]);
 
@@ -1489,6 +1523,8 @@
 	 */
 	if (use_privsep) {
 		mm_send_keystate(pmonitor);
+		debug("ACPT: privsep: Destroying the accept_tbl");
+		destroy_accept_tbl();
 		exit(0);
 	}
 
@@ -1520,6 +1556,8 @@
 	if (use_privsep)
 		mm_terminate();
 
+	debug("ACPT: child exit: Destroying the accept_tbl");
+	destroy_accept_tbl();
 	exit(0);
 }
 
diff -Nru ORIGINAL-3.8.1p1/sshd_config openssh-3.8.1p1-alptpatch/sshd_config
--- ORIGINAL-3.8.1p1/sshd_config	2003-12-31 01:38:32.000000000 +0100
+++ openssh-3.8.1p1-alptpatch/sshd_config	2004-09-07 13:24:49.433091632 +0200
@@ -88,7 +88,8 @@
 #ClientAliveCountMax 3
 #UseDNS yes
 #PidFile /var/run/sshd.pid
-#MaxStartups 10
+#MaxConnections	500
+#MaxAcceptsPerHost 10
 
 # no default banner path
 #Banner /some/path
diff -Nru ORIGINAL-3.8.1p1/sshd_config.0 openssh-3.8.1p1-alptpatch/sshd_config.0
--- ORIGINAL-3.8.1p1/sshd_config.0	2004-04-18 14:52:00.000000000 +0200
+++ openssh-3.8.1p1-alptpatch/sshd_config.0	2004-09-07 13:24:03.425085912 +0200
@@ -224,20 +224,27 @@
              ed.  The default is ``hmac-md5,hmac-sha1,hmac-ripemd160,hmac-
              sha1-96,hmac-md5-96''.
 
-     MaxStartups
-             Specifies the maximum number of concurrent unauthenticated con-
-             nections to the sshd daemon.  Additional connections will be
-             dropped until authentication succeeds or the LoginGraceTime ex-
-             pires for a connection.  The default is 10.
-
-             Alternatively, random early drop can be enabled by specifying the
-             three colon separated values ``start:rate:full'' (e.g.,
-             "10:30:60").  sshd will refuse connection attempts with a proba-
-             bility of ``rate/100'' (30%) if there are currently ``start''
-             (10) unauthenticated connections.  The probability increases lin-
-             early and all connection attempts are refused if the number of
-             unauthenticated connections reaches ``full'' (60).
-
+     MaxConnections
+     	     Specifies the maximum number of concurrent connections of authen-
+	     ticated/unauthenticated hosts wich the server will accept.
+	     The default is 500.
+	     The number of total connections is MaxConnections*MaxAcceptsPerHost.
+	     For MaxAcceptsPerHost see below.
+	     
+     MaxAcceptsPerHost
+             Specifies the maximum number of concurrent authenticated/unauthenticated
+	     connections from the same host to the sshd daemon.  Additional con-
+	     nections will be dropped until the host close one or more client.
+	     The default is 10.
+	     
+	     Each accept is kept for free_accept_time (default is 5)seconds
+	     after the close of the relative connection, thus if the accepts 
+	     have reached MaxAcceptPerHost then the host has to wait 
+	     free_accept_time seconds to reconnect again.
+	     The free_accept_time can be modified by speficying the two colon
+	     separeted values ``max_accepts_per_host:free_accept_time'' (e.g.,
+	     "25:3").
+	     
      PasswordAuthentication
              Specifies whether password authentication is allowed.  The de-
              fault is ``yes''.
diff -Nru ORIGINAL-3.8.1p1/sshd_config.5 openssh-3.8.1p1-alptpatch/sshd_config.5
--- ORIGINAL-3.8.1p1/sshd_config.5	2004-04-14 05:04:36.000000000 +0200
+++ openssh-3.8.1p1-alptpatch/sshd_config.5	2004-09-07 13:24:20.684462088 +0200
@@ -386,31 +386,30 @@
 Multiple algorithms must be comma-separated.
 The default is
 .Dq hmac-md5,hmac-sha1,hmac-ripemd160,hmac-sha1-96,hmac-md5-96 .
-.It Cm MaxStartups
-Specifies the maximum number of concurrent unauthenticated connections to the
-.Nm sshd
-daemon.
-Additional connections will be dropped until authentication succeeds or the
-.Cm LoginGraceTime
-expires for a connection.
+.It Cm MaxConnections
+Specifies the maximum number of concurrent connections of 
+authenticated/unauthenticated hosts wich the server will accept. 
+The default is 500.
+The number of total connections is 
+.Dq MaxConnections*MaxAcceptsPerHost
+For MaxAcceptsPerHost see below.
+.It Cm MaxAcceptPerHost
+Specifies the maximum number of concurrent authenticated/unauthenticated
+connections from the same hsot to the sshd daemon. Additional connections
+will be dropped until the host close one or more client.
 The default is 10.
 .Pp
-Alternatively, random early drop can be enabled by specifying
-the three colon separated values
-.Dq start:rate:full
-(e.g., "10:30:60").
-.Nm sshd
-will refuse connection attempts with a probability of
-.Dq rate/100
-(30%)
-if there are currently
-.Dq start
-(10)
-unauthenticated connections.
-The probability increases linearly and all connection attempts
-are refused if the number of unauthenticated connections reaches
-.Dq full
-(60).
+Each accept is kept for 
+.Dq free_accept_time
+(default is 5)seconds
+after the close of the relative connection, thus if the accepts
+have reached 
+.Dq MaxAcceptPerHost
+then the host has to wait free_accept_time seconds to reconnect again.
+The free_accept_time can be modified by speficying the two colon
+separeted values 
+.Dq max_accept_per_host:free_accept_time
+(e.g., "25:3").
 .It Cm PasswordAuthentication
 Specifies whether password authentication is allowed.
 The default is
