]>
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
) {
219 for(tg
=tglist
;tg
;tg
=tg
->next
) {
225 /* INVARIANT: tg => th */
229 if(th
->parent
== orig
)
237 trustgroup
*tg
= th
->group
;
241 } while (tg
&& !tg
->hosts
);
249 if(th
->parent
== orig
)
254 void th_getsuperandsubsets(struct irc_in_addr
*ip
, uint32_t bits
, trusthost
**superset
, trusthost
**subset
) {
255 *superset
= th_getsmallestsupersetbyhost(ip
, bits
);
256 *subset
= th_getsubsetbyhost(ip
, bits
);
259 void trusts_flush(void (*thflush
)(trusthost
*), void (*tgflush
)(trustgroup
*)) {
262 time_t t
= getnettime();
264 for(tg
=tglist
;tg
;tg
=tg
->next
) {
270 for(th
=tg
->hosts
;th
;th
=th
->next
) {
279 trustgroup
*tg_strtotg(char *name
) {
286 id
= strtoul(&name
[1], &endp
, 10);
290 return tg_getbyid(id
);
293 for(tg
=tglist
;tg
;tg
=tg
->next
)
294 if(!strcasecmp(name
, tg
->name
->content
))
300 void th_adjusthosts(trusthost
*th
, trusthost
*superset
, trusthost
*subset
) {
302 * First and foremost, CIDR doesn't allow hosts to cross boundaries, i.e. everything with a smaller prefix
303 * is entirely contained with the prefix that is one smaller.
304 * 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
305 * you have two, 0.0.0.64/26 and 0.0.0.128/26.
307 * This makes the code MUCH easier as the entire thing is one huge set/tree.
310 * 1: host isn't covered by any existing hosts.
311 * 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.
312 * 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
313 * (note there might be more than one more specific host, e.g. 0.0.0.1/32 and 0.0.0.2/32).
314 * 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 }.
319 * !superset && !subset
321 * Scan through the host hash and add any clients which match our host, this is exactly the same as case 3
322 * but without needing to check (though checking doesn't hurt), so we'll just use the code for that.
327 * superset && !subset
329 * We have the less specific host in 'superset', we know it is the only one so pull out clients in it's
330 * ->users list matching our new host.
331 * No need to look for extra hosts in the main nick hash as they're all covered already.
336 * !superset && subset
338 * We have one host in 'subset', but there might be more than one, we don't care though!
339 * We can scan the entire host hash and pull out any hosts that match us and don't have
340 * a trust group already, this ignores any with a more specific prefix.
347 * Here we first fix up the ones less specific then us, so we just perform what we did for case 2,
348 * then we perform what we did for case 3.
357 * if(1 || 3 || 4): DO 3
360 /* we let the compiler do the boolean minimisation for clarity reasons */
362 if((superset
&& !subset
) || (superset
&& subset
)) { /* cases 2 and 4 */
364 for(np
=superset
->users
;np
;np
=nnp
) {
365 nnp
= nextbytrust(np
);
366 if(ipmask_check(&np
->p_nodeaddr
, &th
->ip
, th
->bits
)) {
367 trusts_lostnick(np
, 1);
368 trusts_newnick(np
, 1);
373 if((!superset
&& !subset
) || (!superset
&& subset
) || (superset
&& subset
)) { /* cases 1, 3 and 4 */
377 for(i
=0;i
<NICKHASHSIZE
;i
++)
378 for(np
=nicktable
[i
];np
;np
=np
->next
)
379 if(!gettrusthost(np
) && ipmask_check(&np
->p_nodeaddr
, &th
->ip
, th
->bits
))
380 trusts_newnick(np
, 1);
384 unsigned int nexttgmarker(void) {
385 static unsigned int tgmarker
= 0;
390 /* If we wrapped to zero, zap the marker on all groups */
391 for(tg
=tglist
;tg
;tg
=tg
->next
)
400 unsigned int nextthmarker(void) {
401 static unsigned int thmarker
= 0;
407 /* If we wrapped to zero, zap the marker on all hosts */
408 for(tg
=tglist
;tg
;tg
=tg
->next
)
409 for(th
=tg
->hosts
;th
;th
=th
->next
)
418 trusthost
*th_getbyid(unsigned int id
) {
422 for(tg
=tglist
;tg
;tg
=tg
->next
)
423 for(th
=tg
->hosts
;th
;th
=th
->next
)
430 int tg_modify(trustgroup
*oldtg
, trustgroup
*newtg
) {
433 memcpy(&vnewtg
, oldtg
, sizeof(trustgroup
));
435 /* unfortunately we can't just memcpy the new one over */
437 vnewtg
.name
= getsstring(newtg
->name
->content
, TRUSTNAMELEN
);
438 vnewtg
.createdby
= getsstring(newtg
->createdby
->content
, CREATEDBYLEN
);
439 vnewtg
.contact
= getsstring(newtg
->contact
->content
, CONTACTLEN
);
440 vnewtg
.comment
= getsstring(newtg
->comment
->content
, COMMENTLEN
);
441 if(!vnewtg
.name
|| !vnewtg
.createdby
|| !vnewtg
.contact
|| !vnewtg
.comment
) {
442 freesstring(vnewtg
.name
);
443 freesstring(vnewtg
.createdby
);
444 freesstring(vnewtg
.contact
);
445 freesstring(vnewtg
.comment
);
449 /* id remains the same, count/hosts/marker/next/exts are ignored */
450 vnewtg
.trustedfor
= newtg
->trustedfor
;
451 vnewtg
.flags
= newtg
->flags
;
452 vnewtg
.maxperident
= newtg
->maxperident
;
453 vnewtg
.maxusage
= newtg
->maxusage
;
454 vnewtg
.expires
= newtg
->expires
;
455 vnewtg
.lastseen
= newtg
->lastseen
;
456 vnewtg
.lastmaxusereset
= newtg
->lastmaxusereset
;
458 memcpy(oldtg
, &vnewtg
, sizeof(trustgroup
));
463 int th_modify(trusthost
*oldth
, trusthost
*newth
) {
464 oldth
->maxpernode
= newth
->maxpernode
;
465 oldth
->nodebits
= newth
->nodebits
;