ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/src/ipcache.c
Revision: 8752
Committed: Tue Jan 1 11:07:01 2019 UTC (6 years, 7 months ago) by michael
Content type: text/x-csrc
File size: 4642 byte(s)
Log Message:
- Update copyright years

File Contents

# Content
1 /*
2 * ircd-hybrid: an advanced, lightweight Internet Relay Chat Daemon (ircd)
3 *
4 * Copyright (c) 1997-2019 ircd-hybrid development team
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
19 * USA
20 */
21
22 /*! \file ipcache.c
23 * \brief Routines to count connections from particular IP addresses.
24 * \version $Id$
25 */
26
27 #include "stdinc.h"
28 #include "list.h"
29 #include "ipcache.h"
30 #include "event.h"
31 #include "memory.h"
32 #include "conf.h"
33 #include "ircd.h"
34 #include "patricia.h"
35
36
37 static dlink_list ipcache_list;
38 static patricia_tree_t *ipcache_trie_v6;
39 static patricia_tree_t *ipcache_trie_v4;
40
41
42 static void *
43 ipcache_get_trie(void *addr)
44 {
45 if (((struct sockaddr *)addr)->sa_family == AF_INET6)
46 return ipcache_trie_v6;
47 else
48 return ipcache_trie_v4;
49 }
50
51 /* ipcache_find_or_add_address()
52 *
53 * inputs - pointer to struct irc_ssaddr
54 * output - pointer to a struct ip_entry
55 * side effects -
56 *
57 * If the ip # was not found, a new struct ip_entry is created, and the ip
58 * count set to 0.
59 */
60 struct ip_entry *
61 ipcache_record_find_or_add(void *addr)
62 {
63 patricia_tree_t *ptrie = ipcache_get_trie(addr);
64 patricia_node_t *pnode = patricia_make_and_lookup_addr(ptrie, addr, 0);
65
66 if (pnode->data) /* Deliberate crash if 'pnode' is NULL */
67 return pnode->data; /* Already added to the trie */
68
69 struct ip_entry *iptr = xcalloc(sizeof(*iptr));
70 iptr->trie_pointer = ptrie;
71 dlinkAdd(pnode, &iptr->node, &ipcache_list);
72
73 PATRICIA_DATA_SET(pnode, iptr);
74
75 return iptr;
76 }
77
78 static void
79 ipcache_record_delete(patricia_node_t *pnode)
80 {
81 struct ip_entry *iptr = PATRICIA_DATA_GET(pnode, struct ip_entry);
82
83 if (iptr->count_local == 0 && iptr->count_remote == 0 &&
84 (CurrentTime - iptr->last_attempt) >= ConfigGeneral.throttle_time)
85 {
86 patricia_remove(iptr->trie_pointer, pnode);
87
88 dlinkDelete(&iptr->node, &ipcache_list);
89 xfree(iptr);
90 }
91 }
92
93 /* ipcache_remove_addres()
94 *
95 * inputs - unsigned long IP address value
96 * output - NONE
97 * side effects - The ip address given, is looked up in ip hash table
98 * and number of ip#'s for that ip decremented.
99 * If ip # count reaches 0 and has expired,
100 * the struct ip_entry is returned to the ip_entry_heap
101 */
102 void
103 ipcache_record_remove(void *addr, int local)
104 {
105 patricia_node_t *pnode = patricia_try_search_exact_addr(ipcache_get_trie(addr), addr, 0);
106
107 if (pnode == NULL)
108 return;
109
110 struct ip_entry *iptr = PATRICIA_DATA_GET(pnode, struct ip_entry);
111 assert(iptr->count_local > 0 || iptr->count_remote > 0);
112
113 if (local)
114 --iptr->count_local;
115 else
116 --iptr->count_remote;
117
118 ipcache_record_delete(pnode);
119 }
120
121 /* ipcache_remove_expired_entries()
122 *
123 * input - NONE
124 * output - NONE
125 * side effects - free up all ip entries with no connections
126 */
127 static void
128 ipcache_remove_expired_records(void *unused)
129 {
130 dlink_node *node, *node_next;
131
132 DLINK_FOREACH_SAFE(node, node_next, ipcache_list.head)
133 ipcache_record_delete(node->data);
134 }
135
136 /* ipcache_get_stats()
137 *
138 * inputs - pointer to counter of number of ips hashed
139 * - pointer to memory used for ip hash
140 * output - returned via pointers input
141 * side effects - NONE
142 *
143 * number of hashed ip #'s is counted up, plus the amount of memory
144 * used in the hash.
145 */
146 void
147 ipcache_get_stats(unsigned int *const number_ips_stored, size_t *const mem_ips_stored)
148 {
149 /* TBD: inaccurate for now as it does only count the amount of memory for struct ip_entry items */
150 (*number_ips_stored) = dlink_list_length(&ipcache_list);
151 (*mem_ips_stored) = dlink_list_length(&ipcache_list) * sizeof(struct ip_entry);
152 }
153
154 void
155 ipcache_init(void)
156 {
157 static struct event event_expire_ipcache =
158 {
159 .name = "ipcache_remove_expired_records",
160 .handler = ipcache_remove_expired_records,
161 .when = 123
162 };
163
164 ipcache_trie_v6 = patricia_new(128);
165 ipcache_trie_v4 = patricia_new( 32);
166
167 event_add(&event_expire_ipcache, NULL);
168 }

Properties

Name Value
svn:eol-style native
svn:keywords Id