]>
jfr.im git - irc/quakenet/newserv.git/blob - trusts/data.c
6 #include "../lib/sstring.h"
7 #include "../core/hooks.h"
8 #include "../core/nsmalloc.h"
9 #include "../lib/irc_string.h"
10 #include "../irc/irc.h"
15 void th_dbupdatecounts(trusthost
*);
16 void tg_dbupdatecounts(trustgroup
*);
18 static trusthost
*th_getnextchildbyhost(trusthost
*, trusthost
*);
20 void trusts_freeall(void) {
24 for(tg
=tglist
;tg
;tg
=ntg
) {
26 for(th
=tg
->hosts
;th
;th
=nth
) {
38 trustgroup
*tg_getbyid(unsigned int id
) {
41 for(tg
=tglist
;tg
;tg
=tg
->next
)
48 void th_free(trusthost
*th
) {
49 triggerhook(HOOK_TRUSTS_LOSTHOST
, th
);
51 nsfree(POOL_TRUSTS
, th
);
54 static void th_updatechildren(trusthost
*th
) {
55 trusthost
*nth
= NULL
;
60 nth
= th_getnextchildbyhost(th
, nth
);
64 nth
->nextbychild
= th
->children
;
69 void th_linktree(void) {
74 for(tg
=tglist
;tg
;tg
=tg
->next
)
75 for(th
=tg
->hosts
;th
;th
=th
->next
)
76 th
->parent
= th_getsmallestsupersetbyhost(&th
->ip
, th
->bits
);
78 for(tg
=tglist
;tg
;tg
=tg
->next
)
79 for(th
=tg
->hosts
;th
;th
=th
->next
)
81 th_updatechildren(th
->parent
);
84 trusthost
*th_add(trusthost
*ith
) {
87 th
= nsmalloc(POOL_TRUSTS
, sizeof(trusthost
));
91 memcpy(th
, ith
, sizeof(trusthost
));
101 th
->next
= th
->group
->hosts
;
102 th
->group
->hosts
= th
;
107 void tg_free(trustgroup
*tg
, int created
) {
109 triggerhook(HOOK_TRUSTS_LOSTGROUP
, tg
);
111 freesstring(tg
->name
);
112 freesstring(tg
->createdby
);
113 freesstring(tg
->contact
);
114 freesstring(tg
->comment
);
115 nsfree(POOL_TRUSTS
, tg
);
118 trustgroup
*tg_add(trustgroup
*itg
) {
119 trustgroup
*tg
= nsmalloc(POOL_TRUSTS
, sizeof(trustgroup
));
123 memcpy(tg
, itg
, sizeof(trustgroup
));
125 tg
->name
= getsstring(tg
->name
->content
, TRUSTNAMELEN
);
126 tg
->createdby
= getsstring(tg
->createdby
->content
, CREATEDBYLEN
);
127 tg
->contact
= getsstring(tg
->contact
->content
, CONTACTLEN
);
128 tg
->comment
= getsstring(tg
->comment
->content
, COMMENTLEN
);
129 if(!tg
->name
|| !tg
->createdby
|| !tg
->contact
|| !tg
->comment
) {
138 memset(tg
->exts
, 0, sizeof(tg
->exts
));
143 triggerhook(HOOK_TRUSTS_NEWGROUP
, tg
);
148 trusthost
*th_getbyhost(struct irc_in_addr
*ip
) {
150 trusthost
*th
, *result
= NULL
;
153 for(tg
=tglist
;tg
;tg
=tg
->next
) {
154 for(th
=tg
->hosts
;th
;th
=th
->next
) {
155 if(ipmask_check(ip
, &th
->ip
, th
->bits
)) {
156 if(!result
|| (th
->bits
> bits
)) {
167 trusthost
*th_getbyhostandmask(struct irc_in_addr
*ip
, uint32_t bits
) {
171 for(tg
=tglist
;tg
;tg
=tg
->next
)
172 for(th
=tg
->hosts
;th
;th
=th
->next
)
173 if(ipmask_check(ip
, &th
->ip
, 128) && th
->bits
== bits
)
179 /* returns the ip with the smallest prefix that is still a superset of the given host */
180 trusthost
*th_getsmallestsupersetbyhost(struct irc_in_addr
*ip
, uint32_t bits
) {
182 trusthost
*th
, *result
= NULL
;
185 for(tg
=tglist
;tg
;tg
=tg
->next
) {
186 for(th
=tg
->hosts
;th
;th
=th
->next
) {
187 if(ipmask_check(ip
, &th
->ip
, th
->bits
)) {
188 if((th
->bits
< bits
) && (!result
|| (th
->bits
> sbits
))) {
199 /* returns the first ip that is a subset it comes across */
200 trusthost
*th_getsubsetbyhost(struct irc_in_addr
*ip
, uint32_t bits
) {
204 for(tg
=tglist
;tg
;tg
=tg
->next
)
205 for(th
=tg
->hosts
;th
;th
=th
->next
)
206 if(ipmask_check(ip
, &th
->ip
, th
->bits
))
213 /* NOT reentrant obviously */
214 static trusthost
*th_getnextchildbyhost(trusthost
*orig
, trusthost
*th
) {
218 for(tg
=tglist
;tg
;tg
=tg
->next
) {
224 /* INVARIANT: tg => th */
228 if(th
->parent
== orig
)
236 trustgroup
*tg
= th
->group
;
240 } while (tg
&& !tg
->hosts
);
248 if(th
->parent
== orig
)
253 void th_getsuperandsubsets(struct irc_in_addr
*ip
, uint32_t bits
, trusthost
**superset
, trusthost
**subset
) {
254 *superset
= th_getsmallestsupersetbyhost(ip
, bits
);
255 *subset
= th_getsubsetbyhost(ip
, bits
);
258 void trusts_flush(void (*thflush
)(trusthost
*), void (*tgflush
)(trustgroup
*)) {
261 time_t t
= getnettime();
263 for(tg
=tglist
;tg
;tg
=tg
->next
) {
269 for(th
=tg
->hosts
;th
;th
=th
->next
) {
278 trustgroup
*tg_strtotg(char *name
) {
285 id
= strtoul(&name
[1], &endp
, 10);
289 return tg_getbyid(id
);
292 for(tg
=tglist
;tg
;tg
=tg
->next
)
293 if(!strcasecmp(name
, tg
->name
->content
))
299 void th_adjusthosts(trusthost
*th
, trusthost
*superset
, trusthost
*subset
) {
301 * First and foremost, CIDR doesn't allow hosts to cross boundaries, i.e. everything with a smaller prefix
302 * is entirely contained with the prefix that is one smaller.
303 * 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
304 * you have two, 0.0.0.64/26 and 0.0.0.128/26.
306 * This makes the code MUCH easier as the entire thing is one huge set/tree.
309 * 1: host isn't covered by any existing hosts.
310 * 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.
311 * 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
312 * (note there might be more than one more specific host, e.g. 0.0.0.1/32 and 0.0.0.2/32).
313 * 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 }.
318 * !superset && !subset
320 * Scan through the host hash and add any clients which match our host, this is exactly the same as case 3
321 * but without needing to check (though checking doesn't hurt), so we'll just use the code for that.
326 * superset && !subset
328 * We have the less specific host in 'superset', we know it is the only one so pull out clients in it's
329 * ->users list matching our new host.
330 * No need to look for extra hosts in the main nick hash as they're all covered already.
335 * !superset && subset
337 * We have one host in 'subset', but there might be more than one, we don't care though!
338 * We can scan the entire host hash and pull out any hosts that match us and don't have
339 * a trust group already, this ignores any with a more specific prefix.
346 * Here we first fix up the ones less specific then us, so we just perform what we did for case 2,
347 * then we perform what we did for case 3.
356 * if(1 || 3 || 4): DO 3
359 /* we let the compiler do the boolean minimisation for clarity reasons */
361 if((superset
&& !subset
) || (superset
&& subset
)) { /* cases 2 and 4 */
363 for(np
=superset
->users
;np
;np
=nnp
) {
364 nnp
= nextbytrust(np
);
365 if(ipmask_check(&np
->p_nodeaddr
, &th
->ip
, th
->bits
)) {
366 trusts_lostnick(np
, 1);
367 trusts_newnick(np
, 1);
372 if((!superset
&& !subset
) || (!superset
&& subset
) || (superset
&& subset
)) { /* cases 1, 3 and 4 */
376 for(i
=0;i
<NICKHASHSIZE
;i
++)
377 for(np
=nicktable
[i
];np
;np
=np
->next
)
378 if(!gettrusthost(np
) && ipmask_check(&np
->p_nodeaddr
, &th
->ip
, th
->bits
))
379 trusts_newnick(np
, 1);
383 unsigned int nexttgmarker(void) {
384 static unsigned int tgmarker
= 0;
389 /* If we wrapped to zero, zap the marker on all groups */
390 for(tg
=tglist
;tg
;tg
=tg
->next
)
399 unsigned int nextthmarker(void) {
400 static unsigned int thmarker
= 0;
406 /* If we wrapped to zero, zap the marker on all hosts */
407 for(tg
=tglist
;tg
;tg
=tg
->next
)
408 for(th
=tg
->hosts
;th
;th
=th
->next
)
417 trusthost
*th_getbyid(unsigned int id
) {
421 for(tg
=tglist
;tg
;tg
=tg
->next
)
422 for(th
=tg
->hosts
;th
;th
=th
->next
)
429 int tg_modify(trustgroup
*oldtg
, trustgroup
*newtg
) {
432 memcpy(&vnewtg
, oldtg
, sizeof(trustgroup
));
434 /* unfortunately we can't just memcpy the new one over */
436 vnewtg
.name
= getsstring(newtg
->name
->content
, TRUSTNAMELEN
);
437 vnewtg
.createdby
= getsstring(newtg
->createdby
->content
, CREATEDBYLEN
);
438 vnewtg
.contact
= getsstring(newtg
->contact
->content
, CONTACTLEN
);
439 vnewtg
.comment
= getsstring(newtg
->comment
->content
, COMMENTLEN
);
440 if(!vnewtg
.name
|| !vnewtg
.createdby
|| !vnewtg
.contact
|| !vnewtg
.comment
) {
441 freesstring(vnewtg
.name
);
442 freesstring(vnewtg
.createdby
);
443 freesstring(vnewtg
.contact
);
444 freesstring(vnewtg
.comment
);
448 /* id remains the same, count/hosts/marker/next/exts are ignored */
449 vnewtg
.trustedfor
= newtg
->trustedfor
;
450 vnewtg
.flags
= newtg
->flags
;
451 vnewtg
.maxperident
= newtg
->maxperident
;
452 vnewtg
.maxusage
= newtg
->maxusage
;
453 vnewtg
.expires
= newtg
->expires
;
454 vnewtg
.lastseen
= newtg
->lastseen
;
455 vnewtg
.lastmaxusereset
= newtg
->lastmaxusereset
;
457 memcpy(oldtg
, &vnewtg
, sizeof(trustgroup
));
462 int th_modify(trusthost
*oldth
, trusthost
*newth
) {
463 oldth
->maxpernode
= newth
->maxpernode
;
464 oldth
->nodebits
= newth
->nodebits
;