But not me alone, huh, huh! The first is Balazs nagy and his ucspi-tcp-0.88-periplimit.6.patch; then it is QFTANG and his Frequencylimit's Patch, even just get these together!
PATCH: UCSPI-TCP-0.88-periplimit.6-frequencylimit.1.patch.txt
CVS Diff -u -r1.1 TCPServer.c
INDEX: TCPSERVER.C
============================================================================================================================================================================================================= ==================
RCS file: /Home/cvs/ucspi-tcp/tcpserver.c ,v
Retrieving Revision 1.1
Diff -u -r1.1 tcpserver.c
--- TCPSERVER.C 11 Jul 2004 09:09:21 -0000 1.1
TCPSERVER.C 18 AUG 2004 09:24:52 -0000
@@ -2, 6 2,7 @@
#include
#include
#include "uint16.h"
# include "uint32.h"
#include "str.h"
#include "byte.h"
#include "fmt.h"
@@ -27, 6 28 ,7 @@
#include "rules.h"
#include "sig.h"
#include "dns.h"
# include
INT verbosity = 1;
INT flagkillopts = 1;
@@ -235, 6 237, 7 @@
/ * ---------------------------- Parent * /
#define fatal "TCPSERVER: FATAL:"
# define max_ip_time 4096
Void Usage (Void)
{
@@ -242, 6 245, 8 @@
TCPSERVER: USAGE: TCPSERVER /
[-1uxphhrrooddqv] /
[-c limited] /
[-S Perip Limit] /
[-f Max Connection Per ip in One Minite] /
[-x rules.cdb] /
[-B banner] /
[-g gid] /
@@ -254, 13 259, 165 @@
}
UNSIGNED long limit = 40;
unsigned long periplimit = 0; unsigned long Numchildren = 0;
unsigned long max_freq = 20;
TypedEf struct
{
PID_T PID;
int offset
CONNECTIONS;
TypedEf struct
{
uint32 ipaddr;
unsigned long Num;
ipchildren;
TYPEDEF STRUCT FREEIP_T
{
CHAR IP [4];
uint32 ipaddr;
unsigned long Num;
struct freeip_t * next;
Freeip;
TypedEf struct
{
uint32 ipaddr;
unsigned long time;
} iptime;
Connections * Children;
IPCHILDREN * NUMIPCHILDREN
freeip * freeIPList = null;
iptime iptimebuf [max_ip_time];
INT FLAG1 = 0;
Unsigned long backlog = 20;
UNSIGNED long uid = 0;
Unsigned long gid = 0;
Void InitFreeip (void)
{
freeip * tail = null;
freeip * new = null;
CHAR TEMPIP [4];
uint32 tempaddr;
Char buf [buffs] = {0};
File * fp;
IF (! (freeip *) Malloc (SizeOf (FreeIP))))))))))))
STRERR_DIE2X (111, Fatal, "Out of Memory);
uint32_unpack (localip, & tail-> ipaddr);
TAIL-> NUM = 100;
TAIL-> next = null;
FreeIPList = TAIL;
IF (! (new = (freeip *) Malloc (SIZEOF (FreeIP))))))
STRERR_DIE2X (111, Fatal, "Out of Memory);
IF (IP4_scan ("127.0.0.1", Tempip) {
uint32_unpack (tempip, & new-> ipaddr);
new-> Num = 100;
new-> next = NULL;
TAIL-> Next = New;
TAIL = tail-> next; }
fp = fopen ("/ var / qmail / control / freeip", "r");
IF (! fp) {
STRERR_DIE2X (111, Fatal, "Can Not Read Control File: / VAR / QMAIL / Control / Freeip");
}
While (FGETS (BUF, BUFSIZ, FP)) {
IF (iP4_scan (buf, tempip)) {
uint32_unpack (Tempip, & Tempaddr);
IF (IsFreeiP (Tempaddr))
Continue;
IF (! (new = (freeip *) Malloc (SIZEOF (FreeIP))))))
STRERR_DIE2X (111, Fatal, "Out of Memory);
New-> ipaddr = tempaddr;
new-> Num = 100;
new-> next = NULL;
TAIL-> Next = New;
TAIL = Tail-> Next;
}
}
}
Void Dumpfreeip (void)
{
freeip * Temp = freeIPList;
CHAR TEMPIP [4];
CHAR IPSTR [ip4_fmt];
CHAR BUF [256] = {0};
DO {
UINT32_PACK (Tempip, Temp-> ipaddr);
IPSTR [IP4_FMT (IPSTR, TEMPIP)] = 0;
Sprintf (Buf, "FreeIP:% S, NUM:% D / N", IPSTR, TEMP-> NUM);
Write (2, BUF, Strlen (BUF));
TEMP = TEMP-> NEXT;
While (TEMP);
}
Int isfreeip (uint32 ipaddr)
{
freeip * Temp = freeIPList;
Int isfree = 0;
DO {
IF (TEMP-> ipaddr == ipaddr) {
isFree = 1;
TEMP = NULL;
Break;
}
TEMP = Temp-> Next; } While (TEMP);
Return isfree;
}
Void FreeFreeip (Void)
{
}
Int ISOVERFREQUENCY (UINT32 IPADDR)
{
iptime * EMPTY_IPTIME = NULL;
iptime * piptime = NULL;
TIME_T now = Time (0);
INT J;
INT count = 0;
int EMP_POS = 0;
for (j = 0; j PIPTIME = & iptimebuf [j]; IF (! empty_iptime) { IF (! piptime-> ipaddr || piptime-> time <(now - 60)) { EMPTY_IPTIME = PIPTIME; EMP_POS = J; } } IF (piptime-> ipaddr == ipaddr && piptime-> Time> (now - 60)) { COUNT ; IF (EMPTY_IPTIME & COUNT> = Max_FREQ) Break; } } if (! empty_iptime) EMPTY_IPTIME = & iptimebuf [0]; EMPTY_IPTIME-> ipaddr = ipaddr; EMPTY_IPTIME-> TIME = NOW; RETURN (count> = max_freq)? 1: 0; } Void PrintStatus (void) { IF (Verbosity <2) return; @@ -278, 6 435 ,7 @@ { Int Wstat; int PI; INT I; While ((PID = Wait_nohang (& Wstat))> 0) { IF (verbosity> = 2) { @@ -286, 6 444, 12 @@ STRERR_WARN4 ("TCPSERVER: END", Strnum, "Status", Strnum2,0); } IF (NumChildren) --NumChildren; PrintStatus (); for (i = 0; i IF (Children [i] .pid == PID) { Children [i] .PID = 0; NumipChildren [Children [i] .offset] .num-- Break; } } } @@ -300, 10 464, 12 @@ Int S; Int T; - while ((Opt = getopt (Argc, Argv, "DDVQqHrr1uxx: T: u: g: l: B: B: C: PPO"))! = opteof) while ((OPT = Getopt (Argc, Argv, "DDVQqHrr1uxx: T: u: g: l: B: B: C: S: f: PPO"))! = 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 'F': scan_ulong (Optarg, & Max_Freq); Break; Case 'x': flagallownorules = 1; Break; Case 'x': fnRules = OPTARG; Break; Case 'b': banner = OPTARG; Break; @@ -334, 6 500 ,11 @@ IF (! Verbosit) Buffer_2-> fd = -1; IF (! periplimit) periplimit = limited; IF (Limit STRERR_DIE2X (111, Fatal, "Periplimit Must Be Smaller Tan Or Equal To Connection Limit); Hostname = * Argv ; if (! Hostname) USAGE (); @@ -358, 6 529, 13 @@ SIG_CATCH (SIG_TERM, SIGTERM); SIG_IGNORE (SIG_PIPE); IF (! (ipchildren = (ipchildren *) malloc (ipchildren * limited)))))) STRERR_DIE2X (111, Fatal, "Out of Memory); Byte_zero (NumipChildren, Sizeof (IPCHildren); IF (! (CHILDREN = (Connections *) Malloc (SIZEOF (CONNEOF (Connections) * Limit)))) STRERR_DIE2X (111, Fatal, "Out of Memory); BYTE_ZERO (Children, Sizeof (Connections) * Limit; Byte_zero (iptimebuf, sizeof (iptime) * max_ip_time); IF (! stalloc_copys (& tmp, hostname)) STRERR_DIE2X (111, Fatal, "Out of Memory"; IF (DNS_IP4_QUALIFY (& Addresses, & FQDN, & TMP) == -1) @@ -390, 12 568, 23 @@ Buffer_puts (& B, "/ N"); Buffer_flush (& B); } InitFreeip (); dumpfreeip (); CLOSE (0); Close (1); 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 592, 53 @@ SIG_BLOCK (SIG_CHILD); IF (t == -1) Continue; for (i = 0; i IF (Children [i] .pid == 0) { freeChild = i; Break; } } uint32_unpack (remoteip, & ipaddr); for (i = 0; i ipcount = & numipchildren [i]; IF (! ipcount-> ipaddr ||! ipcount-> num) lastempty = i; Else if (ipcount-> ipaddr == ipaddr) { ipcount-> num; Break; } } IF (i == limited) { 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 (! isfreeip (ipaddr) && (ipcount-> num> periplimit) { RemoteIPSTR [IP4_FMT (Remoteipstr, Remoteip)] = 0; STRERR_WARN3 (DROP, "Per IP Limit Reached For", Remoteipstr, 0); Close (T); - - IPCOUNT-> NUM; Continue; } IF (ISOVERFREQUENCY (IPADDR)) { RemoteIPSTR [IP4_FMT (Remoteipstr, Remoteip)] = 0; STRERR_WARN3 (DROP, "Frequency Limit Reached For", Remoteipstr, 0); Close (T); Continue; } NumChildren; PrintStatus (); - Switch (fork ()) { Switch (pid = for ()) { Case 0: Close (s); DOIT (T); @@ -420, 6 653, 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); } PATCH: MAKEFILE DIFF -U -R1.2 -R1.3 --- Makefile 19 Jul 2004 09:12:09 -0000 1.2 Makefile 9 Aug 2004 08:06:06 -0000 1.3 @@ -757, 7 757 ,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 ipause.h TAIA.H TAI.H uint64.h / -taia.h TAIA.H uint32.h ./compile tcpserver.c Time.a: /