From c8d858891539e6d5f56d56a2c9c3bfae9698282b Mon Sep 17 00:00:00 2001 From: Jilles Tjoelker Date: Sun, 30 Nov 2008 13:31:59 +0100 Subject: [PATCH] Split cidr_bitlen into cidr_ipv4_bitlen and cidr_ipv6_bitlen. Taken from ircd-ratbox 3 via shadowircd. --- doc/example.conf | 11 ++++++----- include/class.h | 9 ++++++--- src/class.c | 3 ++- src/newconf.c | 31 +++++++++++++++++++++++-------- src/s_conf.c | 25 ++++++++++++++++--------- 5 files changed, 53 insertions(+), 26 deletions(-) diff --git a/doc/example.conf b/doc/example.conf index 688c2de..932846e 100755 --- a/doc/example.conf +++ b/doc/example.conf @@ -92,11 +92,12 @@ log { */ class "users" { ping_time = 2 minutes; - number_per_ident = 10; - number_per_ip = 10; - number_per_ip_global = 50; - cidr_bitlen = 64; - number_per_cidr = 8; + number_per_ident = 2; + number_per_ip = 3; + number_per_ip_global = 5; + cidr_ipv4_bitlen = 24; + cidr_ipv6_bitlen = 64; + number_per_cidr = 4; max_number = 3000; sendq = 400 kbytes; }; diff --git a/include/class.h b/include/class.h index 058a0d6..c076c18 100644 --- a/include/class.h +++ b/include/class.h @@ -44,7 +44,8 @@ struct Class int ping_freq; int total; rb_patricia_tree_t *ip_limits; - int cidr_bitlen; + int cidr_ipv4_bitlen; + int cidr_ipv6_bitlen; int cidr_amount; }; @@ -62,7 +63,8 @@ extern struct Class *default_class; #define MaxSendq(x) ((x)->max_sendq) #define CurrUsers(x) ((x)->total) #define IpLimits(x) ((x)->ip_limits) -#define CidrBitlen(x) ((x)->cidr_bitlen) +#define CidrIpv4Bitlen(x) ((x)->cidr_ipv4_bitlen) +#define CidrIpv6Bitlen(x) ((x)->cidr_ipv6_bitlen) #define CidrAmount(x) ((x)->cidr_amount) #define ClassPtr(x) ((x)->c_class) @@ -77,7 +79,8 @@ extern struct Class *default_class; #define ConfCurrUsers(x) (ClassPtr(x)->total) #define ConfIpLimits(x) (ClassPtr(x)->ip_limits) #define ConfCidrAmount(x) (ClassPtr(x)->cidr_amount) -#define ConfCidrBitlen(x) (ClassPtr(x)->cidr_bitlen) +#define ConfCidrIpv4Bitlen(x) (ClassPtr(x)->cidr_ipv4_bitlen) +#define ConfCidrIpv6Bitlen(x) (ClassPtr(x)->cidr_ipv6_bitlen) void add_class(struct Class *); diff --git a/src/class.c b/src/class.c index 4b4769e..3b55fff 100644 --- a/src/class.c +++ b/src/class.c @@ -199,7 +199,8 @@ add_class(struct Class *classptr) PingFreq(tmpptr) = PingFreq(classptr); MaxSendq(tmpptr) = MaxSendq(classptr); ConFreq(tmpptr) = ConFreq(classptr); - CidrBitlen(tmpptr) = CidrBitlen(classptr); + CidrIpv4Bitlen(tmpptr) = CidrIpv4Bitlen(classptr); + CidrIpv6Bitlen(tmpptr) = CidrIpv6Bitlen(classptr); CidrAmount(tmpptr) = CidrAmount(classptr); free_class(classptr); diff --git a/src/newconf.c b/src/newconf.c index 6fe62dd..35a18f8 100644 --- a/src/newconf.c +++ b/src/newconf.c @@ -723,21 +723,33 @@ conf_set_class_ping_time(void *data) } static void -conf_set_class_cidr_bitlen(void *data) +conf_set_class_cidr_ipv4_bitlen(void *data) { -#ifdef RB_IPV6 - unsigned int maxsize = 128; -#else unsigned int maxsize = 32; -#endif if(*(unsigned int *) data > maxsize) conf_report_error - ("class::cidr_bitlen argument exceeds maxsize (%d > %d) - ignoring.", + ("class::cidr_ipv4_bitlen argument exceeds maxsize (%d > %d) - ignoring.", *(unsigned int *) data, maxsize); else - yy_class->cidr_bitlen = *(unsigned int *) data; + yy_class->cidr_ipv4_bitlen = *(unsigned int *) data; } + +#ifdef RB_IPV6 +static void +conf_set_class_cidr_ipv6_bitlen(void *data) +{ + unsigned int maxsize = 128; + if(*(unsigned int *) data > maxsize) + conf_report_error + ("class::cidr_ipv6_bitlen argument exceeds maxsize (%d > %d) - ignoring.", + *(unsigned int *) data, maxsize); + else + yy_class->cidr_ipv6_bitlen = *(unsigned int *) data; + +} +#endif + static void conf_set_class_number_per_cidr(void *data) { @@ -2036,7 +2048,10 @@ static struct ConfEntry conf_privset_table[] = static struct ConfEntry conf_class_table[] = { { "ping_time", CF_TIME, conf_set_class_ping_time, 0, NULL }, - { "cidr_bitlen", CF_INT, conf_set_class_cidr_bitlen, 0, NULL }, + { "cidr_ipv4_bitlen", CF_INT, conf_set_class_cidr_ipv4_bitlen, 0, NULL }, +#ifdef RB_IPV6 + { "cidr_ipv6_bitlen", CF_INT, conf_set_class_cidr_ipv6_bitlen, 0, NULL }, +#endif { "number_per_cidr", CF_INT, conf_set_class_number_per_cidr, 0, NULL }, { "number_per_ip", CF_INT, conf_set_class_number_per_ip, 0, NULL }, { "number_per_ip_global", CF_INT,conf_set_class_number_per_ip_global, 0, NULL }, diff --git a/src/s_conf.c b/src/s_conf.c index 11f6f2a..b78fa51 100644 --- a/src/s_conf.c +++ b/src/s_conf.c @@ -397,32 +397,38 @@ static int add_ip_limit(struct Client *client_p, struct ConfItem *aconf) { rb_patricia_node_t *pnode; + int bitlen; /* If the limits are 0 don't do anything.. */ - if(ConfCidrAmount(aconf) == 0 || ConfCidrBitlen(aconf) == 0) + if(ConfCidrAmount(aconf) == 0 + || (ConfCidrIpv4Bitlen(aconf) == 0 && ConfCidrIpv6Bitlen(aconf) == 0)) return -1; pnode = rb_match_ip(ConfIpLimits(aconf), (struct sockaddr *)&client_p->localClient->ip); + if(GET_SS_FAMILY(&client_p->localClient->ip) == AF_INET) + bitlen = ConfCidrIpv4Bitlen(aconf); + else + bitlen = ConfCidrIpv6Bitlen(aconf); + if(pnode == NULL) - pnode = make_and_lookup_ip(ConfIpLimits(aconf), (struct sockaddr *)&client_p->localClient->ip, ConfCidrBitlen(aconf)); + pnode = make_and_lookup_ip(ConfIpLimits(aconf), (struct sockaddr *)&client_p->localClient->ip, bitlen); s_assert(pnode != NULL); if(pnode != NULL) { - if(((long) pnode->data) >= ConfCidrAmount(aconf) - && !IsConfExemptLimits(aconf)) + if(((intptr_t)pnode->data) >= ConfCidrAmount(aconf) && !IsConfExemptLimits(aconf)) { /* This should only happen if the limits are set to 0 */ - if((unsigned long) pnode->data == 0) + if((intptr_t)pnode->data == 0) { rb_patricia_remove(ConfIpLimits(aconf), pnode); } return (0); } - pnode->data++; + pnode->data = (void *)(((intptr_t)pnode->data) + 1); } return 1; } @@ -433,15 +439,16 @@ remove_ip_limit(struct Client *client_p, struct ConfItem *aconf) rb_patricia_node_t *pnode; /* If the limits are 0 don't do anything.. */ - if(ConfCidrAmount(aconf) == 0 || ConfCidrBitlen(aconf) == 0) + if(ConfCidrAmount(aconf) == 0 + || (ConfCidrIpv4Bitlen(aconf) == 0 && ConfCidrIpv6Bitlen(aconf) == 0)) return; pnode = rb_match_ip(ConfIpLimits(aconf), (struct sockaddr *)&client_p->localClient->ip); if(pnode == NULL) return; - pnode->data--; - if(((unsigned long) pnode->data) == 0) + pnode->data = (void *)(((intptr_t)pnode->data) - 1); + if(((intptr_t)pnode->data) == 0) { rb_patricia_remove(ConfIpLimits(aconf), pnode); }