]>
jfr.im git - irc/quakenet/newserv.git/blob - chanserv/authtracker/authtracker_db.c
1 /* Keeps track of current "dangling" auths.
3 * Every entry here corresponds to a user who has an open session in the
4 * session table, but we cannot be sure that the user has actually gone.
5 * This means either (a) their server has split off or (b) we restarted and
6 * found a dangling entry in the session table.
8 * Entries leave when either (a) the user comes back (the entry is dropped),
9 * or (b) the server the user was on relinks without them, in which case we
10 * close off their session.
13 #include "authtracker.h"
14 #include "../../core/nsmalloc.h"
15 #include "../../server/server.h"
16 #include "../../irc/irc_config.h"
20 #define DANGLING_HASHSIZE 500
21 #define dangling_hash(x) ((x)%DANGLING_HASHSIZE)
25 struct dangling_entry
{
30 int reason
; /* AT_NETSPLIT or AT_RESTART */
31 struct dangling_entry
*next
;
34 struct dangling_server
{
35 struct dangling_entry
*de
[DANGLING_HASHSIZE
];
38 struct dangling_server
*ds
[MAXSERVERS
];
39 struct dangling_entry
*free_des
;
41 static struct dangling_entry
*get_de() {
42 struct dangling_entry
*dep
;
45 if (free_des
== NULL
) {
46 free_des
= (struct dangling_entry
*)nsmalloc(POOL_AUTHTRACKER
, ALLOCUNIT
* sizeof(struct dangling_entry
));
47 for (i
=0;i
<(ALLOCUNIT
-1);i
++) {
48 free_des
[i
].next
= &(free_des
[i
+1]);
50 free_des
[ALLOCUNIT
-1].next
=NULL
;
59 static void free_de(struct dangling_entry
*dep
) {
64 void at_lostnick(unsigned int numeric
, unsigned long userid
, time_t accountts
, time_t losttime
, int reason
) {
65 unsigned int server
=homeserver(numeric
);
67 struct dangling_entry
*dep
;
68 unsigned int thehash
=dangling_hash(numeric
);
70 /* If their server doesn't have an entry, make one. */
72 ds
[server
]=nsmalloc(POOL_AUTHTRACKER
, sizeof(struct dangling_server
));
73 for (i
=0;i
<DANGLING_HASHSIZE
;i
++)
74 ds
[server
]->de
[i
]=NULL
;
77 /* Now make an entry */
81 dep
->authts
=accountts
;
82 dep
->losttime
=losttime
;
84 dep
->next
=ds
[server
]->de
[thehash
];
85 ds
[server
]->de
[thehash
]=dep
;
88 /* Removes a returning user from the "dangling" tables. Return 1 if we found it, 0 otherwise. */
89 int at_foundnick(unsigned int numeric
, unsigned long userid
, time_t accountts
) {
90 unsigned int server
=homeserver(numeric
);
91 struct dangling_entry
*dep
, **deh
;
92 unsigned int thehash
=dangling_hash(numeric
);
94 /* If we've not got an entry for their server we certainly won't for them. */
98 for (deh
=&(ds
[server
]->de
[thehash
]); *deh
; deh
=&((*deh
)->next
)) {
100 if ((dep
->numeric
== numeric
) && (dep
->userid
==userid
) && (dep
->authts
==accountts
)) {
108 /* Dropped through - didn't find it */
112 /* When a server is back (fully linked), any remaining dangling users on that server are definately gone. */
113 void at_serverback(unsigned int server
) {
115 struct dangling_entry
*dep
, *ndep
;
120 for (i
=0;i
<DANGLING_HASHSIZE
;i
++) {
121 for (dep
=ds
[server
]->de
[i
];dep
;dep
=ndep
) {
124 at_logquit(dep
->userid
, dep
->authts
, time(NULL
), (dep
->reason
==AT_NETSPLIT
)? "(netsplit)" : "(restart)");
129 nsfree(POOL_AUTHTRACKER
, ds
[server
]);
133 void at_flushghosts() {
136 for (i
=0;i
<MAXSERVERS
;i
++) {
137 if (serverlist
[i
].linkstate
== LS_LINKED
)