2 * ircd-ratbox: A slightly useful ircd
3 * reject.c: reject users with prejudice
5 * Copyright (C) 2003 Aaron Sethman <androsyn@ratbox.org>
6 * Copyright (C) 2003-2005 ircd-ratbox development team
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
35 static patricia_tree_t
*reject_tree
;
36 dlink_list delay_exit
;
37 static dlink_list reject_list
;
47 reject_exit(void *unused
)
49 struct Client
*client_p
;
50 dlink_node
*ptr
, *ptr_next
;
52 DLINK_FOREACH_SAFE(ptr
, ptr_next
, delay_exit
.head
)
58 /* this MUST be here, to prevent the possibility
59 * sendto_one() generates a write error, and then a client
60 * ends up on the dead_list and the abort_list --fl
62 * new disconnect notice stolen from ircu --nenolod
63 * no, this only happens when someone's IP has some
64 * ban on it and rejects them rather longer than the
65 * ircu message suggests --jilles
67 if(!IsIOError(client_p
))
68 sendto_one(client_p
, "ERROR :Closing Link: %s (*** Banned (cache))", client_p
->host
);
70 close_connection(client_p
);
72 dlinkAddAlloc(client_p
, &dead_list
);
75 delay_exit
.head
= delay_exit
.tail
= NULL
;
76 delay_exit
.length
= 0;
80 reject_expires(void *unused
)
82 dlink_node
*ptr
, *next
;
83 patricia_node_t
*pnode
;
84 struct reject_data
*rdata
;
86 DLINK_FOREACH_SAFE(ptr
, next
, reject_list
.head
)
91 if(rdata
->time
+ ConfigFileEntry
.reject_duration
> CurrentTime
)
94 dlinkDelete(ptr
, &reject_list
);
96 patricia_remove(reject_tree
, pnode
);
103 reject_tree
= New_Patricia(PATRICIA_BITS
);
104 eventAdd("reject_exit", reject_exit
, NULL
, DELAYED_EXIT_TIME
);
105 eventAdd("reject_expires", reject_expires
, NULL
, 60);
110 add_reject(struct Client
*client_p
)
112 patricia_node_t
*pnode
;
113 struct reject_data
*rdata
;
115 /* Reject is disabled */
116 if(ConfigFileEntry
.reject_after_count
== 0 || ConfigFileEntry
.reject_ban_time
== 0)
119 if((pnode
= match_ip(reject_tree
, (struct sockaddr
*)&client_p
->localClient
->ip
)) != NULL
)
122 rdata
->time
= CurrentTime
;
129 if(client_p
->localClient
->ip
.ss_family
== AF_INET6
)
132 pnode
= make_and_lookup_ip(reject_tree
, (struct sockaddr
*)&client_p
->localClient
->ip
, bitlen
);
133 pnode
->data
= rdata
= MyMalloc(sizeof(struct reject_data
));
134 dlinkAddTail(pnode
, &rdata
->rnode
, &reject_list
);
135 rdata
->time
= CurrentTime
;
141 check_reject(struct Client
*client_p
)
143 patricia_node_t
*pnode
;
144 struct reject_data
*rdata
;
146 /* Reject is disabled */
147 if(ConfigFileEntry
.reject_after_count
== 0 || ConfigFileEntry
.reject_ban_time
== 0 ||
148 ConfigFileEntry
.reject_duration
== 0)
151 pnode
= match_ip(reject_tree
, (struct sockaddr
*)&client_p
->localClient
->ip
);
156 rdata
->time
= CurrentTime
;
157 if(rdata
->count
> ConfigFileEntry
.reject_after_count
)
159 ServerStats
->is_rej
++;
161 comm_setselect(client_p
->localClient
->fd
, FDLIST_NONE
, COMM_SELECT_WRITE
| COMM_SELECT_READ
, NULL
, NULL
, 0);
162 SetClosing(client_p
);
163 dlinkMoveNode(&client_p
->localClient
->tnode
, &unknown_list
, &delay_exit
);
167 /* Caller does what it wants */
174 dlink_node
*ptr
, *next
;
175 patricia_node_t
*pnode
;
176 struct reject_data
*rdata
;
178 DLINK_FOREACH_SAFE(ptr
, next
, reject_list
.head
)
182 dlinkDelete(ptr
, &reject_list
);
184 patricia_remove(reject_tree
, pnode
);
189 remove_reject(const char *ip
)
191 patricia_node_t
*pnode
;
193 /* Reject is disabled */
194 if(ConfigFileEntry
.reject_after_count
== 0 || ConfigFileEntry
.reject_ban_time
== 0 ||
195 ConfigFileEntry
.reject_duration
== 0)
198 if((pnode
= match_string(reject_tree
, ip
)) != NULL
)
200 struct reject_data
*rdata
= pnode
->data
;
201 dlinkDelete(&rdata
->rnode
, &reject_list
);
203 patricia_remove(reject_tree
, pnode
);