Taken from ircd-ratbox 3 via shadowircd.
*/
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;
};
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;
};
#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)
#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 *);
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);
}
static void
-conf_set_class_cidr_bitlen(void *data)
+conf_set_class_cidr_ipv4_bitlen(void *data)
{
+ unsigned int maxsize = 32;
+ if(*(unsigned int *) data > maxsize)
+ conf_report_error
+ ("class::cidr_ipv4_bitlen argument exceeds maxsize (%d > %d) - ignoring.",
+ *(unsigned int *) data, maxsize);
+ else
+ 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;
-#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_ipv6_bitlen argument exceeds maxsize (%d > %d) - ignoring.",
*(unsigned int *) data, maxsize);
else
- yy_class->cidr_bitlen = *(unsigned int *) data;
+ yy_class->cidr_ipv6_bitlen = *(unsigned int *) data;
}
+#endif
+
static void
conf_set_class_number_per_cidr(void *data)
{
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 },
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;
}
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);
}