]>
jfr.im git - irc/quakenet/newserv.git/blob - trusts/data.c
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 triggerhook(HOOK_TRUSTS_LOSTHOST
, th
);
49 nsfree(POOL_TRUSTS
, th
);
52 static void th_updatechildren(trusthost
*th
) {
53 trusthost
*nth
= NULL
;
58 nth
= th_getnextchildbyhost(th
, nth
);
62 nth
->nextbychild
= th
->children
;
67 void th_linktree(void) {
72 for(tg
=tglist
;tg
;tg
=tg
->next
)
73 for(th
=tg
->hosts
;th
;th
=th
->next
)
74 th
->parent
= th_getsmallestsupersetbyhost(th
->ip
, th
->mask
);
76 for(tg
=tglist
;tg
;tg
=tg
->next
)
77 for(th
=tg
->hosts
;th
;th
=th
->next
)
79 th_updatechildren(th
->parent
);
82 trusthost
*th_add(trusthost
*ith
) {
85 th
= nsmalloc(POOL_TRUSTS
, sizeof(trusthost
));
89 memcpy(th
, ith
, sizeof(trusthost
));
99 th
->next
= th
->group
->hosts
;
100 th
->group
->hosts
= th
;
105 void tg_free(trustgroup
*tg
, int created
) {
107 triggerhook(HOOK_TRUSTS_LOSTGROUP
, tg
);
109 freesstring(tg
->name
);
110 freesstring(tg
->createdby
);
111 freesstring(tg
->contact
);
112 freesstring(tg
->comment
);
113 nsfree(POOL_TRUSTS
, tg
);
116 trustgroup
*tg_add(trustgroup
*itg
) {
117 trustgroup
*tg
= nsmalloc(POOL_TRUSTS
, sizeof(trustgroup
));
121 memcpy(tg
, itg
, sizeof(trustgroup
));
123 tg
->name
= getsstring(tg
->name
->content
, TRUSTNAMELEN
);
124 tg
->createdby
= getsstring(tg
->createdby
->content
, CREATEDBYLEN
);
125 tg
->contact
= getsstring(tg
->contact
->content
, CONTACTLEN
);
126 tg
->comment
= getsstring(tg
->comment
->content
, COMMENTLEN
);
127 if(!tg
->name
|| !tg
->createdby
|| !tg
->contact
|| !tg
->comment
) {
136 memset(tg
->exts
, 0, sizeof(tg
->exts
));
141 triggerhook(HOOK_TRUSTS_NEWGROUP
, tg
);
146 trusthost
*th_getbyhost(uint32_t ip
) {
148 trusthost
*th
, *result
= NULL
;
151 for(tg
=tglist
;tg
;tg
=tg
->next
) {
152 for(th
=tg
->hosts
;th
;th
=th
->next
) {
153 if((ip
& th
->mask
) == th
->ip
) {
154 if(!result
|| (th
->mask
> mask
)) {
165 trusthost
*th_getbyhostandmask(uint32_t ip
, uint32_t mask
) {
169 for(tg
=tglist
;tg
;tg
=tg
->next
)
170 for(th
=tg
->hosts
;th
;th
=th
->next
)
171 if((th
->ip
== ip
) && (th
->mask
== mask
))
177 /* returns the ip with the smallest prefix that is still a superset of the given host */
178 trusthost
*th_getsmallestsupersetbyhost(uint32_t ip
, uint32_t mask
) {
180 trusthost
*th
, *result
= NULL
;
183 for(tg
=tglist
;tg
;tg
=tg
->next
) {
184 for(th
=tg
->hosts
;th
;th
=th
->next
) {
185 if(th
->ip
== (ip
& th
->mask
)) {
186 if((th
->mask
< mask
) && (!result
|| (th
->mask
> smask
))) {
197 /* returns the first ip that is a subset it comes across */
198 trusthost
*th_getsubsetbyhost(uint32_t ip
, uint32_t mask
) {
202 for(tg
=tglist
;tg
;tg
=tg
->next
)
203 for(th
=tg
->hosts
;th
;th
=th
->next
)
204 if((th
->ip
& mask
) == ip
)
211 /* NOT reentrant obviously */
212 static trusthost
*th_getnextchildbyhost(trusthost
*orig
, trusthost
*th
) {
217 for(tg
=tglist
;tg
;tg
=tg
->next
) {
223 /* INVARIANT: tg => th */
227 if(th
->parent
== orig
)
237 th
= th
->group
->next
->hosts
;
240 if(th
->parent
== orig
)
245 void th_getsuperandsubsets(uint32_t ip
, uint32_t mask
, trusthost
**superset
, trusthost
**subset
) {
246 *superset
= th_getsmallestsupersetbyhost(ip
, mask
);
247 *subset
= th_getsubsetbyhost(ip
, mask
);
250 void trusts_flush(void (*thflush
)(trusthost
*), void (*tgflush
)(trustgroup
*)) {
253 time_t t
= time(NULL
);
255 for(tg
=tglist
;tg
;tg
=tg
->next
) {
261 for(th
=tg
->hosts
;th
;th
=th
->next
) {
270 trustgroup
*tg_strtotg(char *name
) {
277 id
= strtoul(&name
[1], &endp
, 10);
281 return tg_getbyid(id
);
284 for(tg
=tglist
;tg
;tg
=tg
->next
)
285 if(!strcmp(name
, tg
->name
->content
))
291 void th_adjusthosts(trusthost
*th
, trusthost
*superset
, trusthost
*subset
) {
293 * First and foremost, CIDR doesn't allow hosts to cross boundaries, i.e. everything with a smaller prefix
294 * is entirely contained with the prefix that is one smaller.
295 * 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
296 * you have two, 0.0.0.64/26 and 0.0.0.128/26.
298 * This makes the code MUCH easier as the entire thing is one huge set/tree.
301 * 1: host isn't covered by any existing hosts.
302 * 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.
303 * 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
304 * (note there might be more than one more specific host, e.g. 0.0.0.1/32 and 0.0.0.2/32).
305 * 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 }.
310 * !superset && !subset
312 * Scan through the host hash and add any clients which match our host, this is exactly the same as case 3
313 * but without needing to check (though checking doesn't hurt), so we'll just use the code for that.
318 * superset && !subset
320 * We have the less specific host in 'superset', we know it is the only one so pull out clients in it's
321 * ->users list matching our new host.
322 * No need to look for extra hosts in the main nick hash as they're all covered already.
327 * !superset && subset
329 * We have one host in 'subset', but there might be more than one, we don't care though!
330 * We can scan the entire host hash and pull out any hosts that match us and don't have
331 * a trust group already, this ignores any with a more specific prefix.
338 * Here we first fix up the ones less specific then us, so we just perform what we did for case 2,
339 * then we perform what we did for case 3.
348 * if(1 || 3 || 4): DO 3
351 /* we let the compiler do the boolean minimisation for clarity reasons */
353 if((superset
&& !subset
) || (superset
&& subset
)) { /* cases 2 and 4 */
355 for(np
=superset
->users
;np
;np
=nnp
) {
356 nnp
= nextbytrust(np
);
357 if((irc_in_addr_v4_to_int(&np
->p_ipaddr
) & th
->mask
) == th
->ip
) {
358 trusts_lostnick(np
, 1);
359 trusts_newnick(np
, 1);
364 if((!superset
&& !subset
) || (!superset
&& subset
) || (superset
&& subset
)) { /* cases 1, 3 and 4 */
368 for(i
=0;i
<NICKHASHSIZE
;i
++)
369 for(np
=nicktable
[i
];np
;np
=np
->next
)
370 if(!gettrusthost(np
) && ((irc_in_addr_v4_to_int(&np
->p_ipaddr
) & th
->mask
) == th
->ip
))
371 trusts_newnick(np
, 1);
375 unsigned int nexttgmarker(void) {
376 static unsigned int tgmarker
= 0;
381 /* If we wrapped to zero, zap the marker on all groups */
382 for(tg
=tglist
;tg
;tg
=tg
->next
)
391 unsigned int nextthmarker(void) {
392 static unsigned int thmarker
= 0;
398 /* If we wrapped to zero, zap the marker on all hosts */
399 for(tg
=tglist
;tg
;tg
=tg
->next
)
400 for(th
=tg
->hosts
;th
;th
=th
->next
)
409 trusthost
*th_getbyid(unsigned int id
) {
413 for(tg
=tglist
;tg
;tg
=tg
->next
)
414 for(th
=tg
->hosts
;th
;th
=th
->next
)
421 int tg_modify(trustgroup
*oldtg
, trustgroup
*newtg
) {
424 memcpy(&vnewtg
, oldtg
, sizeof(trustgroup
));
426 /* unfortunately we can't just memcpy the new one over */
428 vnewtg
.name
= getsstring(newtg
->name
->content
, TRUSTNAMELEN
);
429 vnewtg
.createdby
= getsstring(newtg
->createdby
->content
, CREATEDBYLEN
);
430 vnewtg
.contact
= getsstring(newtg
->contact
->content
, CONTACTLEN
);
431 vnewtg
.comment
= getsstring(newtg
->comment
->content
, COMMENTLEN
);
432 if(!vnewtg
.name
|| !vnewtg
.createdby
|| !vnewtg
.contact
|| !vnewtg
.comment
) {
433 freesstring(vnewtg
.name
);
434 freesstring(vnewtg
.createdby
);
435 freesstring(vnewtg
.contact
);
436 freesstring(vnewtg
.comment
);
440 /* id remains the same, count/hosts/marker/next/exts are ignored */
441 vnewtg
.trustedfor
= newtg
->trustedfor
;
442 vnewtg
.mode
= newtg
->mode
;
443 vnewtg
.maxperident
= newtg
->maxperident
;
444 vnewtg
.maxusage
= newtg
->maxusage
;
445 vnewtg
.expires
= newtg
->expires
;
446 vnewtg
.lastseen
= newtg
->lastseen
;
447 vnewtg
.lastmaxusereset
= newtg
->lastmaxusereset
;
449 memcpy(oldtg
, &vnewtg
, sizeof(trustgroup
));