Browse code

- the IP leaf nodes store the state - if blocked or not; this is more efficient and also allows better reporting (log and MI)

- module auto logs the events of initial blocking and of unblocking (no interim logging)

- pike_check_req() return -2 if the IP was detected as flood source for the first time -> help for script reporting of initial blocking.

- new module parameter "pike_log_level" for controlling the logging level of auto messages for blocking/unblocking




git-svn-id: https://openser.svn.sourceforge.net/svnroot/openser/trunk@4029 689a6050-402a-0410-94f2-e92a70836424

Bogdan-Andrei Iancu authored on 17/04/2008 12:23:34
Showing 5 changed files
... ...
@@ -118,7 +118,29 @@ modparam("pike", "remove_latency", 130)
118 118
 </programlisting>
119 119
 		</example>
120 120
 	</section>
121
+	<section>
122
+		<title><varname>pike_log_level</varname> (integer)</title>
123
+		<para>
124
+		Log level to be used by module to auto report the blocking (only first
125
+		time) and unblocking of IPs detected as source of floods.
126
+		</para>
127
+		<para>
128
+		<emphasis>
129
+			Default value is 1 (L_WARN).
130
+		</emphasis>
131
+		</para>
132
+		<example>
133
+		<title>Set <varname>remove_latency</varname> parameter</title>
134
+		<programlisting format="linespecific">
135
+...
136
+modparam("pike", "remove_latency", 130)
137
+...
138
+</programlisting>
139
+		</example>
121 140
 	</section>
141
+	</section>
142
+
143
+
122 144
 	<section>
123 145
 	<title>Exported Functions</title>
124 146
 	<section>
... ...
@@ -130,8 +152,31 @@ modparam("pike", "remove_latency", 130)
130 152
 		the IP was exceeding the blocking limit.
131 153
 		</para>
132 154
 		<para>
133
-		IMPORTANT: in case of internal error, the function returns true to
134
-		avoid reporting the current processed IP as blocked.
155
+		Return codes:
156
+		<itemizedlist>
157
+			<listitem>
158
+			<para>
159
+				<emphasis>1 (true)</emphasis> - IP is not to be blocked or 
160
+				internal error occured.
161
+			</para>
162
+			<warning>
163
+			IMPORTANT: in case of internal error, the function returns true to
164
+			avoid reporting the current processed IP as blocked.
165
+			</warning>
166
+			</listitem>
167
+			<listitem>
168
+			<para>
169
+				<emphasis>-1 (false)</emphasis> - IP is source of
170
+				flooding, being previously detected
171
+			</para>
172
+			</listitem>
173
+			<listitem>
174
+			<para>
175
+				<emphasis>-2 (false)</emphasis> - IP is detected as a new 
176
+				source of flooding - first time detection
177
+			</para>
178
+			</listitem>
179
+		</itemizedlist>
135 180
 		</para>
136 181
 		<para>
137 182
 		This function can be used from REQUEST_ROUTE.
... ...
@@ -163,13 +208,13 @@ if (!pike_check_req()) { exit; };
163 208
  		<para>
164 209
 		MI FIFO Command Format:
165 210
 		</para>
166
-        <programlisting  format="linespecific">
211
+		<programlisting  format="linespecific">
167 212
 		:pike_list:_reply_fifo_file_
168 213
 		_empty_line_
169 214
 		</programlisting>
170
-    </section>
171
-    </section>
215
+	</section>
216
+	</section>
217
+
172 218
 
173
-	
174 219
 </chapter>
175 220
 
... ...
@@ -22,6 +22,8 @@
22 22
  * History:
23 23
  * --------
24 24
  *  2004-11-05: adaptiv init lock (bogdan)
25
+ *  2008-04-17  the leaf nodes memorize (via flags) if they are in RED state
26
+ *               (detected) or not -> better logging and MI (bogdan)
25 27
  */
26 28
 
27 29
 
... ...
@@ -256,6 +258,12 @@ struct ip_node *split_node(struct ip_node* dad, unsigned char byte)
256 258
 	(( (1<<(8*sizeof(_x)-1))-1 )|( (1<<(8*sizeof(_x)-1)) ))
257 259
 
258 260
 
261
+int is_node_hot_leaf(struct ip_node *node)
262
+{
263
+	return is_hot_leaf(node);
264
+}
265
+
266
+
259 267
 /* mark with one more hit the given IP address - */
260 268
 struct ip_node* mark_node(unsigned char *ip,int ip_len,
261 269
 							struct ip_node **father,unsigned char *flag)
... ...
@@ -292,8 +300,15 @@ struct ip_node* mark_node(unsigned char *ip,int ip_len,
292 300
 		/* increment it, but be careful not to overflow the value */
293 301
 		if(node->leaf_hits[CURR_POS]<MAX_TYPE_VAL(node->leaf_hits[CURR_POS])-1)
294 302
 			node->leaf_hits[CURR_POS]++;
295
-		if ( is_hot_leaf(node) )
303
+		/* becoming red node? */
304
+		if ( (node->flags&NODE_ISRED_FLAG)==0 ) {
305
+			if (is_hot_leaf(node) ) {
306
+				*flag |= RED_NODE|NEWRED_NODE;
307
+				node->flags |= NODE_ISRED_FLAG;
308
+			}
309
+		} else {
296 310
 			*flag |= RED_NODE;
311
+		}
297 312
 	} else if (byte_pos==0) {
298 313
 		/* we hit an empty branch in the IP tree */
299 314
 		assert(node==0);
... ...
@@ -25,6 +25,8 @@
25 25
  *              on darwin (andrei)
26 26
  *  2004-11-05  adaptiv init lock (bogdan)
27 27
  *  2005-06-02  flags added to ip_node structure (bogdan)
28
+ *  2008-04-17  the leaf nodes memorize (via flags) if they are in RED state
29
+ *               (detected) or not -> better logging and MI (bogdan)
28 30
  */
29 31
 
30 32
 #ifndef _IP_TREE_H
... ...
@@ -36,9 +38,10 @@
36 38
 #include "timer.h"
37 39
 
38 40
 
39
-#define NEW_NODE   (1<<0)
40
-#define RED_NODE   (1<<1)
41
-#define NO_UPDATE  (1<<2)
41
+#define NEW_NODE    (1<<0)
42
+#define RED_NODE    (1<<1)
43
+#define NEWRED_NODE (1<<2)
44
+#define NO_UPDATE   (1<<3)
42 45
 
43 46
 #define MAX_IP_BRANCHES 256
44 47
 
... ...
@@ -49,6 +52,7 @@
49 52
 #define NODE_EXPIRED_FLAG  (1<<0)
50 53
 #define NODE_INTIMER_FLAG  (1<<1)
51 54
 #define NODE_IPLEAF_FLAG   (1<<2)
55
+#define NODE_ISRED_FLAG    (1<<3)
52 56
 
53 57
 struct ip_node
54 58
 {
... ...
@@ -91,6 +95,7 @@ int    is_red_leaf(struct ip_node *node);
91 95
 void lock_tree_branch(unsigned char b);
92 96
 void unlock_tree_branch(unsigned char b);
93 97
 struct ip_node* get_tree_branch(unsigned char b);
98
+int is_node_hot_leaf(struct ip_node *node);
94 99
 
95 100
 
96 101
 
... ...
@@ -27,6 +27,8 @@
27 27
  *  2003-03-11  converted to the new locking interface: locking.h --
28 28
  *               major changes (andrei)
29 29
  *  2003-03-16  flags export parameter added (janakj)
30
+ *  2008-04-17  new parameter to control the module's log regarding the
31
+ *               blocking/unblocking of IPs (bogdan)
30 32
  */
31 33
 
32 34
 
... ...
@@ -61,6 +63,7 @@ static int pike_exit(void);
61 63
 static int time_unit = 2;
62 64
 static int max_reqs  = 30;
63 65
 int timeout   = 120;
66
+int pike_log_level = L_WARN;
64 67
 
65 68
 /* global variables */
66 69
 gen_lock_t*             timer_lock=0;
... ...
@@ -68,7 +71,7 @@ struct list_link*       timer = 0;
68 71
 
69 72
 
70 73
 static cmd_export_t cmds[]={
71
-	{"pike_check_req",  (cmd_function)pike_check_req,  0,  0, 0, REQUEST_ROUTE},
74
+	{"pike_check_req", (cmd_function)pike_check_req,  0,  0, 0, REQUEST_ROUTE},
72 75
 	{0,0,0,0,0,0}
73 76
 };
74 77
 
... ...
@@ -76,6 +79,7 @@ static param_export_t params[]={
76 79
 	{"sampling_time_unit",    INT_PARAM,  &time_unit},
77 80
 	{"reqs_density_per_unit", INT_PARAM,  &max_reqs},
78 81
 	{"remove_latency",        INT_PARAM,  &timeout},
82
+	{"pike_log_level",        INT_PARAM, &pike_log_level},
79 83
 	{0,0,0}
80 84
 };
81 85
 
... ...
@@ -25,6 +25,10 @@
25 25
  *               major changes (andrei)
26 26
  *  2005-05-02  flags field added to node stucture -better sync between timer
27 27
  *              and worker processes; some races eliminated (bogdan)
28
+ *  2008-04-17  new parameter to control the module's log regarding the
29
+ *               blocking/unblocking of IPs (bogdan)
30
+ *  2008-04-17  the leaf nodes memorize (via flags) if they are in RED state
31
+ *               (detected) or not -> better logging and MI (bogdan)
28 32
  */
29 33
 
30 34
 
... ...
@@ -49,6 +53,7 @@
49 53
 extern gen_lock_t*       timer_lock;
50 54
 extern struct list_link* timer;
51 55
 extern int               timeout;
56
+extern int               pike_log_level;
52 57
 
53 58
 
54 59
 
... ...
@@ -146,7 +151,11 @@ int pike_check_req(struct sip_msg *msg, char *foo, char *bar)
146 151
 	/*print_tree( 0 );*/ /* debug */
147 152
 
148 153
 	if (flags&RED_NODE) {
149
-		LM_WARN("too many hits on %s !!\n", ip_addr2a( ip ) );
154
+		if (flags&NEWRED_NODE) {
155
+			LM_GEN1( pike_log_level,
156
+				"PIKE - BLOCKing ip %s, node=%p\n",ip_addr2a(ip),node);
157
+			return -2;
158
+		}
150 159
 		return -1;
151 160
 	}
152 161
 	return 1;
... ...
@@ -256,13 +265,17 @@ void clean_routine(unsigned int ticks , void *param)
256 265
 
257 266
 
258 267
 
259
-void refresh_node( struct ip_node *node)
268
+static inline void refresh_node( struct ip_node *node)
260 269
 {
261 270
 	for( ; node ; node=node->next ) {
262 271
 		node->hits[PREV_POS] = node->hits[CURR_POS];
263 272
 		node->hits[CURR_POS] = 0;
264 273
 		node->leaf_hits[PREV_POS] = node->leaf_hits[CURR_POS];
265 274
 		node->leaf_hits[CURR_POS] = 0;
275
+		if ( node->flags&NODE_ISRED_FLAG && !is_node_hot_leaf(node) ) {
276
+			node->flags &= ~(NODE_ISRED_FLAG);
277
+			LM_GEN1( pike_log_level,"PIKE - UNBLOCKing node %p\n",node);
278
+		}
266 279
 		if (node->kids)
267 280
 			refresh_node( node->kids );
268 281
 	}