]> jfr.im git - irc/quakenet/newserv.git/blob - chanserv/authtracker/authtracker_db.c
127417f557a8bb1a007ef8587e76ae1423c50763
[irc/quakenet/newserv.git] / chanserv / authtracker / authtracker_db.c
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"
14 #include "../../core/nsmalloc.h"
15 #include "../../server/server.h"
16 #include "../../irc/irc_config.h"
17
18 #include <time.h>
19
20 #define DANGLING_HASHSIZE 500
21 #define dangling_hash(x) ((x)%DANGLING_HASHSIZE)
22
23 #define ALLOCUNIT 100
24
25 struct dangling_entry {
26 unsigned int numeric;
27 unsigned long userid;
28 time_t authts;
29 time_t losttime;
30 int reason; /* AT_NETSPLIT or AT_RESTART */
31 struct dangling_entry *next;
32 };
33
34 struct dangling_server {
35 struct dangling_entry *de[DANGLING_HASHSIZE];
36 };
37
38 struct dangling_server *ds[MAXSERVERS];
39 struct dangling_entry *free_des;
40
41 static struct dangling_entry *get_de() {
42 struct dangling_entry *dep;
43 int i;
44
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]);
49 }
50 free_des[ALLOCUNIT-1].next=NULL;
51 }
52
53 dep=free_des;
54 free_des=dep->next;
55
56 return dep;
57 }
58
59 static void free_de(struct dangling_entry *dep) {
60 dep->next=free_des;
61 free_des=dep;
62 }
63
64 void at_lostnick(unsigned int numeric, unsigned long userid, time_t accountts, time_t losttime, int reason) {
65 unsigned int server=homeserver(numeric);
66 unsigned int i;
67 struct dangling_entry *dep;
68 unsigned int thehash=dangling_hash(numeric);
69
70 /* If their server doesn't have an entry, make one. */
71 if (!ds[server]) {
72 ds[server]=nsmalloc(POOL_AUTHTRACKER, sizeof(struct dangling_server));
73 for (i=0;i<DANGLING_HASHSIZE;i++)
74 ds[server]->de[i]=NULL;
75 }
76
77 /* Now make an entry */
78 dep=get_de();
79 dep->numeric=numeric;
80 dep->userid=userid;
81 dep->authts=accountts;
82 dep->losttime=losttime;
83 dep->reason=reason;
84 dep->next=ds[server]->de[thehash];
85 ds[server]->de[thehash]=dep;
86 }
87
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);
93
94 /* If we've not got an entry for their server we certainly won't for them. */
95 if (!ds[server])
96 return 0;
97
98 for (deh=&(ds[server]->de[thehash]); *deh; deh=&((*deh)->next)) {
99 dep=*deh;
100 if ((dep->numeric == numeric) && (dep->userid==userid) && (dep->authts==accountts)) {
101 /* Got it */
102 *deh=dep->next;
103 free_de(dep);
104 return 1;
105 }
106 }
107
108 /* Dropped through - didn't find it */
109 return 0;
110 }
111
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) {
114 int i;
115 struct dangling_entry *dep, *ndep;
116
117 if (!ds[server])
118 return;
119
120 for (i=0;i<DANGLING_HASHSIZE;i++) {
121 for (dep=ds[server]->de[i];dep;dep=ndep) {
122 ndep=dep->next;
123
124 at_logquit(dep->userid, dep->authts, time(NULL), (dep->reason==AT_NETSPLIT)? "(netsplit)" : "(restart)");
125 free_de(dep);
126 }
127 }
128
129 nsfree(POOL_AUTHTRACKER, ds[server]);
130 ds[server]=NULL;
131 }
132
133 void at_flushghosts() {
134 int i;
135
136 for (i=0;i<MAXSERVERS;i++) {
137 if (serverlist[i].linkstate == LS_LINKED)
138 at_serverback(i);
139 }
140 }