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
23 * $Id: reject.c 26 2006-09-20 18:02:06Z spb $
37 static patricia_tree_t
*reject_tree
;
38 dlink_list delay_exit
;
39 static dlink_list reject_list
;
49 reject_exit(void *unused
)
51 struct Client
*client_p
;
52 dlink_node
*ptr
, *ptr_next
;
54 DLINK_FOREACH_SAFE(ptr
, ptr_next
, delay_exit
.head
)
60 /* this MUST be here, to prevent the possibility
61 * sendto_one() generates a write error, and then a client
62 * ends up on the dead_list and the abort_list --fl
64 * new disconnect notice stolen from ircu --nenolod
65 * no, this only happens when someone's IP has some
66 * ban on it and rejects them rather longer than the
67 * ircu message suggests --jilles
69 if(!IsIOError(client_p
))
70 sendto_one(client_p
, "ERROR :Closing Link: %s (*** Banned (cache))", client_p
->host
);
72 close_connection(client_p
);
74 dlinkAddAlloc(client_p
, &dead_list
);
77 delay_exit
.head
= delay_exit
.tail
= NULL
;
78 delay_exit
.length
= 0;
82 reject_expires(void *unused
)
84 dlink_node
*ptr
, *next
;
85 patricia_node_t
*pnode
;
86 struct reject_data
*rdata
;
88 DLINK_FOREACH_SAFE(ptr
, next
, reject_list
.head
)
93 if(rdata
->time
+ ConfigFileEntry
.reject_duration
> CurrentTime
)
96 dlinkDelete(ptr
, &reject_list
);
98 patricia_remove(reject_tree
, pnode
);
105 reject_tree
= New_Patricia(PATRICIA_BITS
);
106 eventAdd("reject_exit", reject_exit
, NULL
, DELAYED_EXIT_TIME
);
107 eventAdd("reject_expires", reject_expires
, NULL
, 60);
112 add_reject(struct Client
*client_p
)
114 patricia_node_t
*pnode
;
115 struct reject_data
*rdata
;
117 /* Reject is disabled */
118 if(ConfigFileEntry
.reject_after_count
== 0 || ConfigFileEntry
.reject_ban_time
== 0)
121 if((pnode
= match_ip(reject_tree
, (struct sockaddr
*)&client_p
->localClient
->ip
)) != NULL
)
124 rdata
->time
= CurrentTime
;
131 if(client_p
->localClient
->ip
.ss_family
== AF_INET6
)
134 pnode
= make_and_lookup_ip(reject_tree
, (struct sockaddr
*)&client_p
->localClient
->ip
, bitlen
);
135 pnode
->data
= rdata
= MyMalloc(sizeof(struct reject_data
));
136 dlinkAddTail(pnode
, &rdata
->rnode
, &reject_list
);
137 rdata
->time
= CurrentTime
;
143 check_reject(struct Client
*client_p
)
145 patricia_node_t
*pnode
;
146 struct reject_data
*rdata
;
148 /* Reject is disabled */
149 if(ConfigFileEntry
.reject_after_count
== 0 || ConfigFileEntry
.reject_ban_time
== 0 ||
150 ConfigFileEntry
.reject_duration
== 0)
153 pnode
= match_ip(reject_tree
, (struct sockaddr
*)&client_p
->localClient
->ip
);
158 rdata
->time
= CurrentTime
;
159 if(rdata
->count
> ConfigFileEntry
.reject_after_count
)
161 ServerStats
->is_rej
++;
163 comm_setselect(client_p
->localClient
->fd
, FDLIST_NONE
, COMM_SELECT_WRITE
| COMM_SELECT_READ
, NULL
, NULL
, 0);
164 SetClosing(client_p
);
165 dlinkMoveNode(&client_p
->localClient
->tnode
, &unknown_list
, &delay_exit
);
169 /* Caller does what it wants */
176 dlink_node
*ptr
, *next
;
177 patricia_node_t
*pnode
;
178 struct reject_data
*rdata
;
180 DLINK_FOREACH_SAFE(ptr
, next
, reject_list
.head
)
184 dlinkDelete(ptr
, &reject_list
);
186 patricia_remove(reject_tree
, pnode
);
191 remove_reject(const char *ip
)
193 patricia_node_t
*pnode
;
195 /* Reject is disabled */
196 if(ConfigFileEntry
.reject_after_count
== 0 || ConfigFileEntry
.reject_ban_time
== 0 ||
197 ConfigFileEntry
.reject_duration
== 0)
200 if((pnode
= match_string(reject_tree
, ip
)) != NULL
)
202 struct reject_data
*rdata
= pnode
->data
;
203 dlinkDelete(&rdata
->rnode
, &reject_list
);
205 patricia_remove(reject_tree
, pnode
);