]>
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 "../chanserv.h"
15 #include "../../core/nsmalloc.h"
16 #include "../../server/server.h"
17 #include "../../irc/irc_config.h"
21 #define DANGLING_HASHSIZE 500
22 #define dangling_hash(x) ((x)%DANGLING_HASHSIZE)
26 struct dangling_entry
{
31 int reason
; /* AT_NETSPLIT or AT_RESTART */
32 struct dangling_entry
*next
;
35 struct dangling_server
{
36 struct dangling_entry
*de
[DANGLING_HASHSIZE
];
39 struct dangling_server
*ds
[MAXSERVERS
];
40 struct dangling_entry
*free_des
;
42 static struct dangling_entry
*get_de() {
43 struct dangling_entry
*dep
;
46 if (free_des
== NULL
) {
47 free_des
= (struct dangling_entry
*)nsmalloc(POOL_AUTHTRACKER
, ALLOCUNIT
* sizeof(struct dangling_entry
));
48 for (i
=0;i
<(ALLOCUNIT
-1);i
++) {
49 free_des
[i
].next
= &(free_des
[i
+1]);
51 free_des
[ALLOCUNIT
-1].next
=NULL
;
60 static void free_de(struct dangling_entry
*dep
) {
65 void at_lostnick(unsigned int numeric
, unsigned long userid
, time_t accountts
, time_t losttime
, int reason
) {
66 unsigned int server
=homeserver(numeric
);
68 struct dangling_entry
*dep
;
69 unsigned int thehash
=dangling_hash(numeric
);
71 /* If their server doesn't have an entry, make one. */
73 ds
[server
]=nsmalloc(POOL_AUTHTRACKER
, sizeof(struct dangling_server
));
74 for (i
=0;i
<DANGLING_HASHSIZE
;i
++)
75 ds
[server
]->de
[i
]=NULL
;
78 /* Now make an entry */
82 dep
->authts
=accountts
;
83 dep
->losttime
=losttime
;
85 dep
->next
=ds
[server
]->de
[thehash
];
86 ds
[server
]->de
[thehash
]=dep
;
89 /* Removes a returning user from the "dangling" tables. Return 1 if we found it, 0 otherwise. */
90 int at_foundnick(unsigned int numeric
, unsigned long userid
, time_t accountts
) {
91 unsigned int server
=homeserver(numeric
);
92 struct dangling_entry
*dep
, **deh
;
93 unsigned int thehash
=dangling_hash(numeric
);
95 /* If we've not got an entry for their server we certainly won't for them. */
99 for (deh
=&(ds
[server
]->de
[thehash
]); *deh
; deh
=&((*deh
)->next
)) {
101 if ((dep
->numeric
== numeric
) && (dep
->userid
==userid
) && (dep
->authts
==accountts
)) {
109 /* Dropped through - didn't find it */
113 /* When a server is back (fully linked), any remaining dangling users on that server are definately gone. */
114 void at_serverback(unsigned int server
) {
116 struct dangling_entry
*dep
, *ndep
;
121 for (i
=0;i
<DANGLING_HASHSIZE
;i
++) {
122 for (dep
=ds
[server
]->de
[i
];dep
;dep
=ndep
) {
125 at_logquit(dep
->userid
, dep
->authts
, time(NULL
), (dep
->reason
==AT_NETSPLIT
)? "(netsplit)" : "(restart)");
130 nsfree(POOL_AUTHTRACKER
, ds
[server
]);
134 void at_flushghosts() {
137 for (i
=0;i
<MAXSERVERS
;i
++) {
138 if (serverlist
[i
].linkstate
== LS_LINKED
)
143 int at_dumpdb(void *source
, int argc
, char **argv
) {
145 struct dangling_entry
*dep
;
148 for(i
=0;i
<MAXSERVERS
;i
++) {
151 for(j
=0;j
<DANGLING_HASHSIZE
;j
++) {
152 for (dep
=ds
[i
]->de
[j
];dep
;dep
=dep
->next
) {
156 chanservsendmessage(np
, "Server %d (%s) has %d entries.",i
,longtonumeric(i
,2),k
);
160 chanservstdmessage(np
,QM_ENDOFLIST
);