]>
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 void trusts_freeall(void) {
20 for(tg
=tglist
;tg
;tg
=ntg
) {
22 for(th
=tg
->hosts
;th
;th
=nth
) {
34 trustgroup
*tg_getbyid(unsigned int id
) {
37 for(tg
=tglist
;tg
;tg
=tg
->next
)
44 void th_free(trusthost
*th
) {
45 triggerhook(HOOK_TRUSTS_LOSTHOST
, th
);
47 nsfree(POOL_TRUSTS
, th
);
50 trusthost
*th_add(trusthost
*ith
) {
53 th
= nsmalloc(POOL_TRUSTS
, sizeof(trusthost
));
57 memcpy(th
, ith
, sizeof(trusthost
));
62 th
->next
= th
->group
->hosts
;
63 th
->group
->hosts
= th
;
68 void tg_free(trustgroup
*tg
, int created
) {
70 triggerhook(HOOK_TRUSTS_LOSTGROUP
, tg
);
72 freesstring(tg
->name
);
73 freesstring(tg
->createdby
);
74 freesstring(tg
->contact
);
75 freesstring(tg
->comment
);
76 nsfree(POOL_TRUSTS
, tg
);
79 trustgroup
*tg_add(trustgroup
*itg
) {
80 trustgroup
*tg
= nsmalloc(POOL_TRUSTS
, sizeof(trustgroup
));
84 memcpy(tg
, itg
, sizeof(trustgroup
));
86 tg
->name
= getsstring(tg
->name
->content
, TRUSTNAMELEN
);
87 tg
->createdby
= getsstring(tg
->createdby
->content
, CREATEDBYLEN
);
88 tg
->contact
= getsstring(tg
->contact
->content
, CONTACTLEN
);
89 tg
->comment
= getsstring(tg
->comment
->content
, COMMENTLEN
);
90 if(!tg
->name
|| !tg
->createdby
|| !tg
->contact
|| !tg
->comment
) {
98 memset(tg
->exts
, 0, sizeof(tg
->exts
));
103 triggerhook(HOOK_TRUSTS_NEWGROUP
, tg
);
108 trusthost
*th_getbyhost(uint32_t ip
) {
110 trusthost
*th
, *result
= NULL
;
113 for(tg
=tglist
;tg
;tg
=tg
->next
) {
114 for(th
=tg
->hosts
;th
;th
=th
->next
) {
115 if((ip
& th
->mask
) == th
->ip
) {
116 if(!result
|| (th
->mask
> mask
)) {
127 trusthost
*th_getbyhostandmask(uint32_t ip
, uint32_t mask
) {
131 for(tg
=tglist
;tg
;tg
=tg
->next
)
132 for(th
=tg
->hosts
;th
;th
=th
->next
)
133 if((th
->ip
== ip
) && (th
->mask
== mask
))
139 /* returns the ip with the smallest prefix that is still a superset of the given host */
140 trusthost
*th_getsmallestsupersetbyhost(uint32_t ip
, uint32_t mask
) {
142 trusthost
*th
, *result
= NULL
;
145 for(tg
=tglist
;tg
;tg
=tg
->next
) {
146 for(th
=tg
->hosts
;th
;th
=th
->next
) {
147 if(th
->ip
== (ip
& th
->mask
)) {
148 if((th
->mask
< mask
) && (!result
|| (th
->mask
> smask
))) {
159 /* returns the first ip that is a subset it comes across */
160 trusthost
*th_getsubsetbyhost(uint32_t ip
, uint32_t mask
) {
164 for(tg
=tglist
;tg
;tg
=tg
->next
)
165 for(th
=tg
->hosts
;th
;th
=th
->next
)
166 if((th
->ip
& mask
) == ip
)
173 void th_getsuperandsubsets(uint32_t ip
, uint32_t mask
, trusthost
**superset
, trusthost
**subset
) {
174 *superset
= th_getsmallestsupersetbyhost(ip
, mask
);
175 *subset
= th_getsubsetbyhost(ip
, mask
);
178 void trusts_flush(void (*thflush
)(trusthost
*), void (*tgflush
)(trustgroup
*)) {
181 time_t t
= time(NULL
);
183 for(tg
=tglist
;tg
;tg
=tg
->next
) {
189 for(th
=tg
->hosts
;th
;th
=th
->next
) {
198 trustgroup
*tg_strtotg(char *name
) {
205 id
= strtoul(&name
[1], &endp
, 10);
209 return tg_getbyid(id
);
212 for(tg
=tglist
;tg
;tg
=tg
->next
)
213 if(!strcmp(name
, tg
->name
->content
))
219 void th_adjusthosts(trusthost
*th
, trusthost
*superset
, trusthost
*subset
) {
221 * First and foremost, CIDR doesn't allow hosts to cross boundaries, i.e. everything with a smaller prefix
222 * is entirely contained with the prefix that is one smaller.
223 * 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
224 * you have two, 0.0.0.64/26 and 0.0.0.128/26.
226 * This makes the code MUCH easier as the entire thing is one huge set/tree.
229 * 1: host isn't covered by any existing hosts.
230 * 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.
231 * 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
232 * (note there might be more than one more specific host, e.g. 0.0.0.1/32 and 0.0.0.2/32).
233 * 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 }.
238 * !superset && !subset
240 * Scan through the host hash and add any clients which match our host, this is exactly the same as case 3
241 * but without needing to check (though checking doesn't hurt), so we'll just use the code for that.
246 * superset && !subset
248 * We have the less specific host in 'superset', we know it is the only one so pull out clients in it's
249 * ->users list matching our new host.
250 * No need to look for extra hosts in the main nick hash as they're all covered already.
255 * !superset && subset
257 * We have one host in 'subset', but there might be more than one, we don't care though!
258 * We can scan the entire host hash and pull out any hosts that match us and don't have
259 * a trust group already, this ignores any with a more specific prefix.
266 * Here we first fix up the ones less specific then us, so we just perform what we did for case 2,
267 * then we perform what we did for case 3.
276 * if(1 || 3 || 4): DO 3
279 /* we let the compiler do the boolean minimisation for clarity reasons */
281 if((superset
&& !subset
) || (superset
&& subset
)) { /* cases 2 and 4 */
283 for(np
=superset
->users
;np
;np
=nnp
) {
284 nnp
= nextbytrust(np
);
285 if((irc_in_addr_v4_to_int(&np
->p_ipaddr
) & th
->mask
) == th
->ip
) {
286 trusts_lostnick(np
, 1);
287 trusts_newnick(np
, 1);
292 if((!superset
&& !subset
) || (!superset
&& subset
) || (superset
&& subset
)) { /* cases 1, 3 and 4 */
296 for(i
=0;i
<NICKHASHSIZE
;i
++)
297 for(np
=nicktable
[i
];np
;np
=np
->next
)
298 if(!gettrusthost(np
) && ((irc_in_addr_v4_to_int(&np
->p_ipaddr
) & th
->mask
) == th
->ip
))
299 trusts_newnick(np
, 1);
303 trusthost
*th_getbyid(unsigned int id
) {
307 for(tg
=tglist
;tg
;tg
=tg
->next
)
308 for(th
=tg
->hosts
;th
;th
=th
->next
)
315 int tg_modify(trustgroup
*oldtg
, trustgroup
*newtg
) {
318 memcpy(&vnewtg
, oldtg
, sizeof(trustgroup
));
320 /* unfortunately we can't just memcpy the new one over */
322 vnewtg
.name
= getsstring(newtg
->name
->content
, TRUSTNAMELEN
);
323 vnewtg
.createdby
= getsstring(newtg
->createdby
->content
, CREATEDBYLEN
);
324 vnewtg
.contact
= getsstring(newtg
->contact
->content
, CONTACTLEN
);
325 vnewtg
.comment
= getsstring(newtg
->comment
->content
, COMMENTLEN
);
326 if(!vnewtg
.name
|| !vnewtg
.createdby
|| !vnewtg
.contact
|| !vnewtg
.comment
) {
327 freesstring(vnewtg
.name
);
328 freesstring(vnewtg
.createdby
);
329 freesstring(vnewtg
.contact
);
330 freesstring(vnewtg
.comment
);
334 /* id remains the same, count/hosts/marker/next/exts are ignored */
335 vnewtg
.trustedfor
= newtg
->trustedfor
;
336 vnewtg
.mode
= newtg
->mode
;
337 vnewtg
.maxperident
= newtg
->maxperident
;
338 vnewtg
.maxusage
= newtg
->maxusage
;
339 vnewtg
.expires
= newtg
->expires
;
340 vnewtg
.lastseen
= newtg
->lastseen
;
341 vnewtg
.lastmaxusereset
= newtg
->lastmaxusereset
;
343 memcpy(oldtg
, &vnewtg
, sizeof(trustgroup
));