分享
 
 
 

[CODE] 通过tcpserver实现对同一IP的最大连接数和连接频率的限制

王朝other·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

1. 同一IP最大连接数的限制

使用Balazs Nagy的 periplimit patch 实现同一IP的最大连接数的限制。

相关地址: http://js.hu/package/ucspi-tcp/

实现: ucspi-tcp-0.88-periplimit.6.patch

diff -ru 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 Fri May 28 06:48:15 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 -ru 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 Thu Jul 1 08:37:03 2004

@@ -2,6 +2,7 @@

#include

#include

#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;ifd = -1;

+

+ if (!periplimit)

+ periplimit = limit;

+ if (limit= limit) sig_pause();

sig_unblock(sig_child);

@@ -403,9 +446,43 @@

sig_block(sig_child);

if (t == -1) continue;

+

+ for (i=0;iipaddr || !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 +497,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);

}

2. 修改 periplimit patch, 实现对特定的IP地址不受限制 (实现: myhan)

上面的patch对所有的IP地址都限制了, 但是我们在使用的时候, 往往有部分IP地址, 如 127.0.0.1 或者本机地址, 不希望受此限制.

通过设置控制文件, 可以实现从控制文件中读取不受限制的IP地址.

控制文件的位置: /var/qmail/control/freeip

控制文件的格式: 每一行一个完整的IP地址

3. 实现对同一IP的连接频率的限制 (实现: qftang)

2和3 的实现: ucspi-tcp-0.88-frequencylimit.1.patch

--- tcpserver.c.1.2 2004-08-13 16:50:41.000000000 +0800

+++ tcpserver.c 2004-08-17 16:11:59.000000000 +0800

@@ -28,6 +28,7 @@

#include "rules.h"

#include "sig.h"

#include "dns.h"

+#include <stdio.h>

int verbosity = 1;

int flagkillopts = 1;

@@ -236,6 +237,7 @@

/* ---------------------------- parent */

#define FATAL "tcpserver: fatal: "

+#define MAX_IP_TIME 4096

void usage(void)

{

@@ -244,6 +246,7 @@

[ -1UXpPhHrRoOdDqQv ] [ -c limit ] [ -s perip limit ] +[ -f max connection per ip in one minite ] [ -x rules.cdb ] [ -B banner ] [ -g gid ] @@ -258,6 +261,7 @@

unsigned long limit = 40;

unsigned long periplimit = 0;

unsigned long numchildren = 0;

+unsigned long max_freq = 20;

typedef struct

{

@@ -271,14 +275,143 @@

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 *head = NULL;

+ freeip *tail = NULL;

+ char tempip[4];

+ char buf[256] = {0};

+ FILE *fp;

+

+ if (!(head = (freeip *)malloc(sizeof(freeip))))

+ strerr_die2x(111,FATAL,"out of memory");

+ if (!(tail = (freeip *)malloc(sizeof(freeip))))

+ strerr_die2x(111,FATAL,"out of memory");

+

+ uint32_unpack(localip, &head-ipaddr);

+ head-num = 100;

+ head-next = NULL;

+

+ if (ip4_scan("127.0.0.1", tempip)) {

+ uint32_unpack(tempip, &tail-ipaddr);

+ tail-num = 100;

+ tail-next = NULL;

+ head-next = tail;

+ }

+

+ fp = fopen("/var/qmail/control/freeip", "r");

+ if( !fp ) {

+ freeiplist = head;

+ return;

+ }

+ while(fgets(buf, 256, fp)) {

+ freeip *new;

+ if (ip4_scan(buf, tempip)) {

+ new = (freeip *)malloc(sizeof(freeip));

+ uint32_unpack(tempip, &new-ipaddr);

+ new-num = 100;

+ new-next = NULL;

+ tail-next = new;

+ tail = tail-next;

+ } else {

+ continue;

+ }

+ }

+

+ freeiplist = head;

+}

+

+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;

+ 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; jipaddr || piptime-time 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 num periplimit) {

+ //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(pid = fork()) {

4. 测试工具 :)

tcpservertester.php

#!/usr/local/bin/php -f

<?php

error_reporting(0);

set_time_limit(6000);

$keepconnect = false;

for ($i=0; $i

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有