]> jfr.im git - irc/quakenet/newserv.git/blob - proxyscan/proxyscanqueue.c
sanity check input to scan, ref/deref nodes during scanning
[irc/quakenet/newserv.git] / proxyscan / proxyscanqueue.c
1
2 /*
3 * Handle the scan queues
4 */
5
6 #include "proxyscan.h"
7 #include "../irc/irc.h"
8 #include "../core/error.h"
9 #include <assert.h>
10
11 pendingscan *ps_normalqueue=NULL;
12 pendingscan *ps_prioqueue=NULL;
13 pendingscan *ps_normalqueueend=NULL;
14
15 unsigned int normalqueuedscans=0;
16 unsigned int prioqueuedscans=0;
17
18 unsigned long countpendingscan=0;
19
20 void queuescan(patricia_node_t *node, short scantype, unsigned short port, char class, time_t when) {
21 pendingscan *psp, *psp2;
22
23 /* we can just blindly queue the scans as node extension cleanhost cache blocks duplicate scans normally.
24 * Scans may come from:
25 * a) scan <node> (from an oper)
26 * b) newnick handler - which ignores clean hosts, only scans new hosts or dirty hosts
27 * c) adding a new scan type (rare)
28 */
29
30 /* we should never have an internal node */
31 assert(node->prefix);
32 /* reference the node - we either start a or queue a single scan */
33 patricia_ref_prefix(node->prefix);
34
35 /* If there are scans spare, just start it immediately..
36 * provided we're not supposed to wait */
37 if (activescans < maxscans && when<=time(NULL) && ps_ready) {
38 startscan(node, scantype, port, class);
39 return;
40 }
41
42 /* We have to queue it */
43 if (!(psp=getpendingscan()))
44 Error("proxyscan",ERR_STOP,"Unable to allocate memory");
45
46 countpendingscan++;
47
48 psp->node=node;
49 psp->type=scantype;
50 psp->port=port;
51 psp->class=class;
52 psp->when=when;
53 psp->next=NULL;
54
55 if (!when) {
56 /* normal queue */
57 normalqueuedscans++;
58 if (ps_normalqueueend) {
59 ps_normalqueueend->next=psp;
60 ps_normalqueueend=psp;
61 } else {
62 ps_normalqueueend=ps_normalqueue=psp;
63 }
64 } else {
65 prioqueuedscans++;
66 if (!ps_prioqueue || ps_prioqueue->when > when) {
67 psp->next=ps_prioqueue;
68 ps_prioqueue=psp;
69 } else {
70 for (psp2=ps_prioqueue; ;psp2=psp2->next) {
71 if (!psp2->next || psp2->next->when > when) {
72 psp->next = psp2->next;
73 psp2->next = psp;
74 break;
75 }
76 }
77 }
78 }
79 }
80
81 void startqueuedscans() {
82 pendingscan *psp=NULL;
83
84 while (activescans < maxscans) {
85 if (ps_prioqueue && (ps_prioqueue->when <= time(NULL))) {
86 psp=ps_prioqueue;
87 ps_prioqueue=psp->next;
88 prioqueuedscans--;
89 } else if (ps_normalqueue) {
90 psp=ps_normalqueue;
91 ps_normalqueue=psp->next;
92 if (!ps_normalqueue)
93 ps_normalqueueend=NULL;
94 normalqueuedscans--;
95 }
96
97 if (psp) {
98 startscan(psp->node, psp->type, psp->port, psp->class);
99 freependingscan(psp);
100 countpendingscan--;
101 psp=NULL;
102 } else {
103 break;
104 }
105 }
106 }
107
108