]> jfr.im git - irc/quakenet/newserv.git/blame - chanserv/authtracker/authtracker_db.c
Use nsmalloc/nsfree for authtracker.
[irc/quakenet/newserv.git] / chanserv / authtracker / authtracker_db.c
CommitLineData
84563ebd 1/* Keeps track of current "dangling" auths.
2 *
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.
7 *
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.
11 */
12
13#include "authtracker.h"
2aaa684c 14#include "../chanserv.h"
84563ebd 15#include "../../core/nsmalloc.h"
16#include "../../server/server.h"
17#include "../../irc/irc_config.h"
18
19#include <time.h>
20
21#define DANGLING_HASHSIZE 500
22#define dangling_hash(x) ((x)%DANGLING_HASHSIZE)
23
84563ebd 24struct dangling_entry {
25 unsigned int numeric;
26 unsigned long userid;
27 time_t authts;
28 time_t losttime;
29 int reason; /* AT_NETSPLIT or AT_RESTART */
30 struct dangling_entry *next;
31};
32
33struct dangling_server {
34 struct dangling_entry *de[DANGLING_HASHSIZE];
35};
36
37struct dangling_server *ds[MAXSERVERS];
84563ebd 38
39static struct dangling_entry *get_de() {
9c610068 40 return nsmalloc(POOL_AUTHTRACKER, sizeof(struct dangling_entry));
84563ebd 41}
42
43static void free_de(struct dangling_entry *dep) {
9c610068 44 nsfree(POOL_AUTHTRACKER, dep);
84563ebd 45}
46
47void at_lostnick(unsigned int numeric, unsigned long userid, time_t accountts, time_t losttime, int reason) {
48 unsigned int server=homeserver(numeric);
49 unsigned int i;
50 struct dangling_entry *dep;
51 unsigned int thehash=dangling_hash(numeric);
52
53 /* If their server doesn't have an entry, make one. */
54 if (!ds[server]) {
55 ds[server]=nsmalloc(POOL_AUTHTRACKER, sizeof(struct dangling_server));
56 for (i=0;i<DANGLING_HASHSIZE;i++)
57 ds[server]->de[i]=NULL;
58 }
59
60 /* Now make an entry */
61 dep=get_de();
62 dep->numeric=numeric;
63 dep->userid=userid;
64 dep->authts=accountts;
65 dep->losttime=losttime;
66 dep->reason=reason;
67 dep->next=ds[server]->de[thehash];
68 ds[server]->de[thehash]=dep;
69}
70
71/* Removes a returning user from the "dangling" tables. Return 1 if we found it, 0 otherwise. */
72int 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);
76
77 /* If we've not got an entry for their server we certainly won't for them. */
78 if (!ds[server])
79 return 0;
80
81 for (deh=&(ds[server]->de[thehash]); *deh; deh=&((*deh)->next)) {
82 dep=*deh;
83 if ((dep->numeric == numeric) && (dep->userid==userid) && (dep->authts==accountts)) {
84 /* Got it */
85 *deh=dep->next;
86 free_de(dep);
87 return 1;
88 }
89 }
90
91 /* Dropped through - didn't find it */
92 return 0;
93}
94
95/* When a server is back (fully linked), any remaining dangling users on that server are definately gone. */
96void at_serverback(unsigned int server) {
97 int i;
98 struct dangling_entry *dep, *ndep;
99
100 if (!ds[server])
101 return;
102
103 for (i=0;i<DANGLING_HASHSIZE;i++) {
104 for (dep=ds[server]->de[i];dep;dep=ndep) {
105 ndep=dep->next;
106
107 at_logquit(dep->userid, dep->authts, time(NULL), (dep->reason==AT_NETSPLIT)? "(netsplit)" : "(restart)");
108 free_de(dep);
109 }
110 }
111
112 nsfree(POOL_AUTHTRACKER, ds[server]);
113 ds[server]=NULL;
114}
115
116void at_flushghosts() {
117 int i;
118
119 for (i=0;i<MAXSERVERS;i++) {
120 if (serverlist[i].linkstate == LS_LINKED)
121 at_serverback(i);
122 }
123}
2aaa684c 124
125int at_dumpdb(void *source, int argc, char **argv) {
126 nick *np=source;
127 struct dangling_entry *dep;
128 unsigned int i,j,k;
129
130 for(i=0;i<MAXSERVERS;i++) {
131 if (ds[i]) {
132 k=0;
133 for(j=0;j<DANGLING_HASHSIZE;j++) {
134 for (dep=ds[i]->de[j];dep;dep=dep->next) {
135 k++;
136 }
137 }
138 chanservsendmessage(np, "Server %d (%s) has %d entries.",i,longtonumeric(i,2),k);
139 }
140 }
141
142 chanservstdmessage(np,QM_ENDOFLIST);
143
144 return CMD_OK;
9c610068 145}