]>
jfr.im git - irc/quakenet/newserv.git/blob - trusts/data.c
23aaaa76a91138b13f013665641954888873eab8
5 #include "../lib/sstring.h"
6 #include "../core/hooks.h"
7 #include "../core/nsmalloc.h"
8 #include "../lib/irc_string.h"
13 void th_dbupdatecounts(trusthost
*);
14 void tg_dbupdatecounts(trustgroup
*);
16 static trusthost
*th_getnextchildbyhost(trusthost
*, trusthost
*);
18 void trusts_freeall(void) {
22 for(tg
=tglist
;tg
;tg
=ntg
) {
24 for(th
=tg
->hosts
;th
;th
=nth
) {
36 trustgroup
*tg_getbyid(unsigned int id
) {
39 for(tg
=tglist
;tg
;tg
=tg
->next
)
46 void th_free(trusthost
*th
) {
47 nsfree(POOL_TRUSTS
, th
);
50 static void th_updatechildren(trusthost
*th
) {
51 trusthost
*nth
= NULL
;
56 nth
= th_getnextchildbyhost(th
, nth
);
60 nth
->nextbychild
= th
->children
;
65 void th_linktree(void) {
70 for(tg
=tglist
;tg
;tg
=tg
->next
)
71 for(th
=tg
->hosts
;th
;th
=th
->next
)
72 th
->parent
= th_getsmallestsupersetbyhost(th
->ip
, th
->mask
);
74 for(tg
=tglist
;tg
;tg
=tg
->next
)
75 for(th
=tg
->hosts
;th
;th
=th
->next
)
77 th_updatechildren(th
->parent
);
80 trusthost
*th_add(trusthost
*ith
) {
83 th
= nsmalloc(POOL_TRUSTS
, sizeof(trusthost
));
87 memcpy(th
, ith
, sizeof(trusthost
));
97 th
->next
= th
->group
->hosts
;
98 th
->group
->hosts
= th
;
103 void tg_free(trustgroup
*tg
) {
104 triggerhook(HOOK_TRUSTS_LOSTGROUP
, tg
);
106 freesstring(tg
->name
);
107 freesstring(tg
->createdby
);
108 freesstring(tg
->contact
);
109 freesstring(tg
->comment
);
110 nsfree(POOL_TRUSTS
, tg
);
113 trustgroup
*tg_add(trustgroup
*itg
) {
114 trustgroup
*tg
= nsmalloc(POOL_TRUSTS
, sizeof(trustgroup
));
118 memcpy(tg
, itg
, sizeof(trustgroup
));
120 tg
->name
= getsstring(tg
->name
->content
, TRUSTNAMELEN
);
121 tg
->createdby
= getsstring(tg
->createdby
->content
, NICKLEN
);
122 tg
->contact
= getsstring(tg
->contact
->content
, CONTACTLEN
);
123 tg
->comment
= getsstring(tg
->comment
->content
, COMMENTLEN
);
124 if(!tg
->name
|| !tg
->createdby
|| !tg
->contact
|| !tg
->comment
) {
133 memset(tg
->exts
, 0, sizeof(tg
->exts
));
138 triggerhook(HOOK_TRUSTS_NEWGROUP
, tg
);
143 trusthost
*th_getbyhost(uint32_t ip
) {
145 trusthost
*th
, *result
= NULL
;
148 for(tg
=tglist
;tg
;tg
=tg
->next
) {
149 for(th
=tg
->hosts
;th
;th
=th
->next
) {
150 if((ip
& th
->mask
) == th
->ip
) {
151 if(!result
|| (th
->mask
> mask
)) {
162 trusthost
*th_getbyhostandmask(uint32_t ip
, uint32_t mask
) {
166 for(tg
=tglist
;tg
;tg
=tg
->next
)
167 for(th
=tg
->hosts
;th
;th
=th
->next
)
168 if((th
->ip
== ip
) && (th
->mask
== mask
))
174 /* returns the ip with the smallest prefix that is still a superset of the given host */
175 trusthost
*th_getsmallestsupersetbyhost(uint32_t ip
, uint32_t mask
) {
177 trusthost
*th
, *result
= NULL
;
180 for(tg
=tglist
;tg
;tg
=tg
->next
) {
181 for(th
=tg
->hosts
;th
;th
=th
->next
) {
182 if(th
->ip
== (ip
& th
->mask
)) {
183 if((th
->mask
< mask
) && (!result
|| (th
->mask
> smask
))) {
194 /* returns the first ip that is a subset it comes across */
195 trusthost
*th_getsubsetbyhost(uint32_t ip
, uint32_t mask
) {
199 for(tg
=tglist
;tg
;tg
=tg
->next
)
200 for(th
=tg
->hosts
;th
;th
=th
->next
)
201 if((th
->ip
& mask
) == ip
)
208 /* NOT reentrant obviously */
209 static trusthost
*th_getnextchildbyhost(trusthost
*orig
, trusthost
*th
) {
214 for(tg
=tglist
;tg
;tg
=tg
->next
) {
220 /* INVARIANT: tg => th */
224 if(th
->parent
== orig
)
234 th
= th
->group
->next
->hosts
;
237 if(th
->parent
== orig
)
242 void th_getsuperandsubsets(uint32_t ip
, uint32_t mask
, trusthost
**superset
, trusthost
**subset
) {
243 *superset
= th_getsmallestsupersetbyhost(ip
, mask
);
244 *subset
= th_getsubsetbyhost(ip
, mask
);
247 void trusts_flush(void (*thflush
)(trusthost
*), void (*tgflush
)(trustgroup
*)) {
250 time_t t
= time(NULL
);
252 for(tg
=tglist
;tg
;tg
=tg
->next
) {
258 for(th
=tg
->hosts
;th
;th
=th
->next
) {
267 trustgroup
*tg_strtotg(char *name
) {
273 id
= strtoul(&name
[1], NULL
, 10);
277 for(tg
=tglist
;tg
;tg
=tg
->next
)
282 for(tg
=tglist
;tg
;tg
=tg
->next
)
283 if(!match(name
, tg
->name
->content
))
286 id
= strtoul(name
, NULL
, 10);
291 for(tg
=tglist
;tg
;tg
=tg
->next
)
298 void th_adjusthosts(trusthost
*th
, trusthost
*superset
, trusthost
*subset
) {
300 * First and foremost, CIDR doesn't allow hosts to cross boundaries, i.e. everything with a smaller prefix
301 * is entirely contained with the prefix that is one smaller.
302 * e.g. 0.0.0.0/23, 0.0.0.128/23, you can't have a single prefix for 0.0.0.64-0.0.0.192, instead
303 * you have two, 0.0.0.64/26 and 0.0.0.128/26.
305 * This makes the code MUCH easier as the entire thing is one huge set/tree.
308 * 1: host isn't covered by any existing hosts.
309 * 2: host is covered by a less specific one only, e.g. adding 0.0.0.1/32, while 0.0.0.0/24 already exists.
310 * 3: host is covered by a more specific one only, e.g. adding 0.0.0.0/24 while 0.0.0.1/32 already exists
311 * (note there might be more than one more specific host, e.g. 0.0.0.1/32 and 0.0.0.2/32).
312 * 4: covered by more and less specific cases, e.g. adding 0.0.0.0/24 to: { 0.0.0.1/32, 0.0.0.2/32, 0.0.0.0/16 }.
317 * !superset && !subset
319 * Scan through the host hash and add any clients which match our host, this is exactly the same as case 3
320 * but without needing to check (though checking doesn't hurt), so we'll just use the code for that.
325 * superset && !subset
327 * We have the less specific host in 'superset', we know it is the only one so pull out clients in it's
328 * ->users list matching our new host.
329 * No need to look for extra hosts in the main nick hash as they're all covered already.
334 * !superset && subset
336 * We have one host in 'subset', but there might be more than one, we don't care though!
337 * We can scan the entire host hash and pull out any hosts that match us and don't have
338 * a trust group already, this ignores any with a more specific prefix.
345 * Here we first fix up the ones less specific then us, so we just perform what we did for case 2,
346 * then we perform what we did for case 3.
355 * if(1 || 3 || 4): DO 3
358 /* we let the compiler do the boolean minimisation for clarity reasons */
360 if((superset
&& !subset
) || (superset
&& subset
)) { /* cases 2 and 4 */
362 for(np
=superset
->users
;np
;np
=nnp
) {
363 nnp
= nextbytrust(np
);
364 if((irc_in_addr_v4_to_int(&np
->p_ipaddr
) & th
->mask
) == th
->ip
) {
365 trusts_lostnick(np
, 1);
366 trusts_newnick(np
, 1);
371 if((!superset
&& !subset
) || (!superset
&& subset
) || (superset
&& subset
)) { /* cases 1, 3 and 4 */
375 for(i
=0;i
<NICKHASHSIZE
;i
++)
376 for(np
=nicktable
[i
];np
;np
=np
->next
)
377 if(!gettrusthost(np
) && ((irc_in_addr_v4_to_int(&np
->p_ipaddr
) & th
->mask
) == th
->ip
))
378 trusts_newnick(np
, 1);
382 unsigned int nexttgmarker(void) {
383 static unsigned int tgmarker
= 0;
388 /* If we wrapped to zero, zap the marker on all groups */
389 for(tg
=tglist
;tg
;tg
=tg
->next
)
398 unsigned int nextthmarker(void) {
399 static unsigned int thmarker
= 0;
405 /* If we wrapped to zero, zap the marker on all hosts */
406 for(tg
=tglist
;tg
;tg
=tg
->next
)
407 for(th
=tg
->hosts
;th
;th
=th
->next
)
416 trustgroup
*tg_inttotg(unsigned int id
) {
419 for(tg
=tglist
;tg
;tg
=tg
->next
)