]>
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)
24 struct dangling_entry
{
29 int reason
; /* AT_NETSPLIT or AT_RESTART */
30 struct dangling_entry
*next
;
33 struct dangling_server
{
34 struct dangling_entry
*de
[DANGLING_HASHSIZE
];
37 struct dangling_server
*ds
[MAXSERVERS
];
39 static struct dangling_entry
*get_de() {
40 return nsmalloc(POOL_AUTHTRACKER
, sizeof(struct dangling_entry
));
43 static void free_de(struct dangling_entry
*dep
) {
44 nsfree(POOL_AUTHTRACKER
, dep
);
47 void at_lostnick(unsigned int numeric
, unsigned long userid
, time_t accountts
, time_t losttime
, int reason
) {
48 unsigned int server
=homeserver(numeric
);
50 struct dangling_entry
*dep
;
51 unsigned int thehash
=dangling_hash(numeric
);
53 /* If their server doesn't have an entry, make one. */
55 ds
[server
]=nsmalloc(POOL_AUTHTRACKER
, sizeof(struct dangling_server
));
56 for (i
=0;i
<DANGLING_HASHSIZE
;i
++)
57 ds
[server
]->de
[i
]=NULL
;
60 /* Now make an entry */
64 dep
->authts
=accountts
;
65 dep
->losttime
=losttime
;
67 dep
->next
=ds
[server
]->de
[thehash
];
68 ds
[server
]->de
[thehash
]=dep
;
71 /* Removes a returning user from the "dangling" tables. Return 1 if we found it, 0 otherwise. */
72 int at_foundnick(unsigned int numeric
, unsigned long userid
, time_t accountts
) {
73 unsigned int server
=homeserver(numeric
);
74 struct dangling_entry
*dep
, **deh
;
75 unsigned int thehash
=dangling_hash(numeric
);
77 /* If we've not got an entry for their server we certainly won't for them. */
81 for (deh
=&(ds
[server
]->de
[thehash
]); *deh
; deh
=&((*deh
)->next
)) {
83 if ((dep
->numeric
== numeric
) && (dep
->userid
==userid
) && (dep
->authts
==accountts
)) {
91 /* Dropped through - didn't find it */
95 /* When a server is back (fully linked), any remaining dangling users on that server are definately gone. */
96 void at_serverback(unsigned int server
) {
98 struct dangling_entry
*dep
, *ndep
;
103 for (i
=0;i
<DANGLING_HASHSIZE
;i
++) {
104 for (dep
=ds
[server
]->de
[i
];dep
;dep
=ndep
) {
107 at_logquit(dep
->userid
, dep
->authts
, time(NULL
), (dep
->reason
==AT_NETSPLIT
)? "(netsplit)" : "(restart)");
112 nsfree(POOL_AUTHTRACKER
, ds
[server
]);
116 void at_flushghosts() {
119 for (i
=0;i
<MAXSERVERS
;i
++) {
120 if (serverlist
[i
].linkstate
== LS_LINKED
)
125 int at_dumpdb(void *source
, int argc
, char **argv
) {
127 struct dangling_entry
*dep
;
130 for(i
=0;i
<MAXSERVERS
;i
++) {
133 for(j
=0;j
<DANGLING_HASHSIZE
;j
++) {
134 for (dep
=ds
[i
]->de
[j
];dep
;dep
=dep
->next
) {
138 chanservsendmessage(np
, "Server %d (%s) has %d entries.",i
,longtonumeric(i
,2),k
);
142 chanservstdmessage(np
,QM_ENDOFLIST
);