Search
j0ke.net Open Build Service
>
Projects
>
server:mail
>
ucspi-tcp
> ucspi-tcp-0.88-periplimit.7.patch
Sign Up
|
Log In
Username
Password
Cancel
Overview
Repositories
Revisions
Requests
Users
Advanced
Attributes
Meta
File ucspi-tcp-0.88-periplimit.7.patch of Package ucspi-tcp
diff -ruN ucspi-tcp-0.88-orig/Makefile ucspi-tcp-0.88/Makefile --- ucspi-tcp-0.88-orig/Makefile Sat Mar 18 16:18:42 2000 +++ ucspi-tcp-0.88/Makefile Sat Aug 21 20:53:03 2004 @@ -753,7 +753,7 @@ alloc.h buffer.h error.h strerr.h sgetopt.h subgetopt.h pathexec.h \ socket.h uint16.h ndelay.h remoteinfo.h stralloc.h uint16.h rules.h \ stralloc.h sig.h dns.h stralloc.h iopause.h taia.h tai.h uint64.h \ -taia.h +taia.h uint32.h ./compile tcpserver.c time.a: \ diff -ruN ucspi-tcp-0.88-orig/tcpserver.c ucspi-tcp-0.88/tcpserver.c --- ucspi-tcp-0.88-orig/tcpserver.c Sat Mar 18 16:18:42 2000 +++ ucspi-tcp-0.88/tcpserver.c Sat Aug 21 20:56:32 2004 @@ -2,6 +2,7 @@ #include <sys/param.h> #include <netdb.h> #include "uint16.h" +#include "uint32.h" #include "str.h" #include "byte.h" #include "fmt.h" @@ -242,6 +243,7 @@ tcpserver: usage: tcpserver \ [ -1UXpPhHrRoOdDqQv ] \ [ -c limit ] \ +[ -s perip limit ] \ [ -x rules.cdb ] \ [ -B banner ] \ [ -g gid ] \ @@ -254,8 +256,24 @@ } unsigned long limit = 40; +unsigned long periplimit = 0; unsigned long numchildren = 0; +typedef struct +{ + pid_t pid; + int offset; +} connections; + +typedef struct +{ + uint32 ipaddr; + unsigned long num; +} ipchildren; + +connections *children; +ipchildren *numipchildren; + int flag1 = 0; unsigned long backlog = 20; unsigned long uid = 0; @@ -278,6 +296,7 @@ { int wstat; int pid; + int i; while ((pid = wait_nohang(&wstat)) > 0) { if (verbosity >= 2) { @@ -286,6 +305,12 @@ strerr_warn4("tcpserver: end ",strnum," status ",strnum2,0); } if (numchildren) --numchildren; printstatus(); + for (i=0;i<limit;++i) + if (children[i].pid == pid) { + children[i].pid=0; + numipchildren[children[i].offset].num--; + break; + } } } @@ -300,10 +325,11 @@ int s; int t; - while ((opt = getopt(argc,argv,"dDvqQhHrR1UXx:t:u:g:l:b:B:c:pPoO")) != opteof) + while ((opt = getopt(argc,argv,"dDvqQhHrR1UXx:t:u:g:l:b:B:c:s:pPoO")) != opteof) switch(opt) { case 'b': scan_ulong(optarg,&backlog); break; case 'c': scan_ulong(optarg,&limit); break; + case 's': scan_ulong(optarg,&periplimit); break; case 'X': flagallownorules = 1; break; case 'x': fnrules = optarg; break; case 'B': banner = optarg; break; @@ -334,6 +360,11 @@ if (!verbosity) buffer_2->fd = -1; + + if (!periplimit) + periplimit = limit; + if (limit<periplimit) + strerr_die2x(111,FATAL,"periplimit must be smaller than or equal to connection limit"); hostname = *argv++; if (!hostname) usage(); @@ -358,6 +389,12 @@ sig_catch(sig_term,sigterm); sig_ignore(sig_pipe); + if (!(numipchildren = (ipchildren*)malloc(sizeof(ipchildren)*limit))) + strerr_die2x(111,FATAL,"out of memory"); + byte_zero(numipchildren,sizeof(ipchildren)*limit); + if (!(children = (connections*)malloc(sizeof(connections)*limit))) + strerr_die2x(111,FATAL,"out of memory"); + byte_zero(children,sizeof(connections)*limit); if (!stralloc_copys(&tmp,hostname)) strerr_die2x(111,FATAL,"out of memory"); if (dns_ip4_qualify(&addresses,&fqdn,&tmp) == -1) @@ -396,6 +433,13 @@ printstatus(); for (;;) { + uint32 ipaddr; + pid_t pid; + int i; + int lastempty = 0; + int freechild = 0; + ipchildren *ipcount; + while (numchildren >= limit) sig_pause(); sig_unblock(sig_child); @@ -403,9 +447,43 @@ sig_block(sig_child); if (t == -1) continue; + + for (i=0;i<limit;++i) { + if (children[i].pid == 0) { + freechild = i; + break; + } + } + uint32_unpack(remoteip,&ipaddr); + for (i=0;i<limit;++i) { + ipcount = &numipchildren[i]; + if (!ipcount->ipaddr || !ipcount->num) + lastempty = i; + else if (ipcount->ipaddr == ipaddr) { + ++ipcount->num; + break; + } + } + if (i == limit) { + if (lastempty) { + i = lastempty; + ipcount = &numipchildren[i]; + ipcount->ipaddr = ipaddr; + ipcount->num = 1; + } else + /* never reached */ + strerr_die2x(111,DROP,"internal problem"); + } + if (ipcount->num > periplimit) { + remoteipstr[ip4_fmt(remoteipstr,remoteip)] = 0; + strerr_warn3(DROP, "per ip limit reached for ", remoteipstr, 0); + close(t); + --ipcount->num; + continue; + } ++numchildren; printstatus(); - switch(fork()) { + switch(pid = fork()) { case 0: close(s); doit(t); @@ -420,6 +498,10 @@ case -1: strerr_warn2(DROP,"unable to fork: ",&strerr_sys); --numchildren; printstatus(); + break; + default: + children[freechild].pid = pid; + children[freechild].offset = i; } close(t); }