Search
j0ke.net Open Build Service
>
Projects
>
server:mail
>
ucspi-tcp
> ucspi-tcp-0.88-periplimit.7_ssl.patch
Sign Up
|
Log In
Username
Password
Cancel
Overview
Repositories
Revisions
Requests
Users
Advanced
Attributes
Meta
File ucspi-tcp-0.88-periplimit.7_ssl.patch of Package ucspi-tcp
--- ucspi-tcp-0.88/tcpserver.c.orig 2009-06-01 19:36:13.000000000 +0200 +++ ucspi-tcp-0.88/tcpserver.c 2013-09-25 11:09:07.551224853 +0200 @@ -3,6 +3,7 @@ #include <netdb.h> #include <openssl/ssl.h> #include "uint16.h" +#include "uint32.h" #include "str.h" #include "byte.h" #include "fmt.h" @@ -290,6 +291,7 @@ tcpserver: usage: tcpserver \ [ -461UXpPhHrRoOdDqQv ] \ [ -c limit ] \ +[ -m perip limit ] \ [ -x rules.cdb ] \ [ -B banner ] \ [ -g gid ] \ @@ -321,8 +323,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; @@ -345,6 +363,7 @@ { int wstat; int pid; + int i; while ((pid = wait_nohang(&wstat)) > 0) { if (verbosity >= 2) { @@ -353,6 +372,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; + } } } @@ -366,6 +391,7 @@ unsigned long u; int s; int t; + int fakev4=0; #ifdef WITH_SSL BIO *sbio; @@ -379,13 +405,14 @@ strerr_die2x(111,FATAL,"out of memory"); if (!stralloc_copys(&jaildir, JAILDIR) || !stralloc_0(&jaildir) ) strerr_die2x(111,FATAL,"out of memory"); - while ((opt = getopt(argc,argv,"dDvqQhHrRsS1UXx:t:u:g:l:b:B:c:n:a:j:J:pPoO")) != opteof) + while ((opt = getopt(argc,argv,"dDvqQhHrRsS1UXx:t:u:g:l:b:B:c:n:a:j:J:m:pPoO")) != opteof) #else - while ((opt = getopt(argc,argv,"46dDvqQhHrR1UXx:t:u:g:l:b:B:c:I:pPoO")) != opteof) + while ((opt = getopt(argc,argv,"46dDvqQhHrR1UXx:t:u:g:l:b:B:c:I:m:pPoO")) != opteof) #endif switch(opt) { case 'b': scan_ulong(optarg,&backlog); break; case 'c': scan_ulong(optarg,&limit); break; + case 'm': scan_ulong(optarg,&periplimit); break; case 'X': flagallownorules = 1; break; case 'x': fnrules = optarg; break; case 'B': banner = optarg; break; @@ -436,6 +463,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(); @@ -458,6 +490,13 @@ sig_catch(sig_child,sigchld); 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 (str_equal(hostname,"0")) { byte_zero(localip,sizeof localip); @@ -527,6 +566,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); @@ -534,9 +580,49 @@ 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) { + if (!forcev6 && ip6_isv4mapped(remoteip)) + fakev4=1; + if (fakev4) + remoteipstr[ip4_fmt(remoteipstr,remoteip+12)] = 0; + else + remoteipstr[ip6_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); @@ -600,6 +686,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); }