2
2
3
3
import java .util .Collection ;
4
4
import java .util .Collections ;
5
+ import java .util .HashMap ;
5
6
import java .util .LinkedList ;
6
7
import java .util .List ;
8
+ import java .util .Map ;
7
9
import java .util .concurrent .ArrayBlockingQueue ;
8
10
import java .util .concurrent .BlockingQueue ;
9
- import java .util .concurrent .ConcurrentMap ;
10
- import java .util .concurrent .ConcurrentSkipListMap ;
11
11
import java .util .concurrent .atomic .AtomicInteger ;
12
12
import java .util .concurrent .atomic .AtomicLong ;
13
13
import java .util .concurrent .atomic .AtomicLongArray ;
14
14
15
15
public class WafMetricCollector implements MetricCollector <WafMetricCollector .WafMetric > {
16
16
17
17
public static WafMetricCollector INSTANCE = new WafMetricCollector ();
18
- private static final int ABSTRACT_POWERWAF_EXCEPTION_NUMBER =
19
- 3 ; // only 3 error codes are possible for now in AbstractPowerwafException
20
18
21
19
public static WafMetricCollector get () {
22
20
return WafMetricCollector .INSTANCE ;
@@ -53,18 +51,10 @@ private WafMetricCollector() {
53
51
new AtomicLongArray (RuleType .getNumValues ());
54
52
private static final AtomicLongArray raspTimeoutCounter =
55
53
new AtomicLongArray (RuleType .getNumValues ());
56
- private static final ConcurrentMap <Integer , AtomicLongArray > raspErrorCodeCounter =
57
- new ConcurrentSkipListMap <>();
58
- private static final ConcurrentMap <Integer , AtomicLongArray > wafErrorCodeCounter =
59
- new ConcurrentSkipListMap <>();
60
-
61
- static {
62
- for (int i = -1 * ABSTRACT_POWERWAF_EXCEPTION_NUMBER ; i < 0 ; i ++) {
63
- raspErrorCodeCounter .put (i , new AtomicLongArray (RuleType .getNumValues ()));
64
- wafErrorCodeCounter .put (i , new AtomicLongArray (RuleType .getNumValues ()));
65
- }
66
- }
67
-
54
+ private static final AtomicLongArray raspErrorCodeCounter =
55
+ new AtomicLongArray (WafErrorCode .values ().length * RuleType .getNumValues ());
56
+ private static final AtomicLongArray wafErrorCodeCounter =
57
+ new AtomicLongArray (WafErrorCode .values ().length );
68
58
private static final AtomicLongArray missingUserLoginQueue =
69
59
new AtomicLongArray (LoginFramework .getNumValues () * LoginEvent .getNumValues ());
70
60
private static final AtomicLongArray missingUserIdQueue =
@@ -151,12 +141,23 @@ public void raspTimeout(final RuleType ruleType) {
151
141
raspTimeoutCounter .incrementAndGet (ruleType .ordinal ());
152
142
}
153
143
154
- public void raspErrorCode (final RuleType ruleType , final int ddwafRunErrorCode ) {
155
- raspErrorCodeCounter .get (ddwafRunErrorCode ).incrementAndGet (ruleType .ordinal ());
144
+ public void raspErrorCode (RuleType ruleType , final int errorCode ) {
145
+ WafErrorCode wafErrorCode = WafErrorCode .fromCode (errorCode );
146
+ // Unsupported waf error code
147
+ if (wafErrorCode == null ) {
148
+ return ;
149
+ }
150
+ int index = wafErrorCode .ordinal () * RuleType .getNumValues () + ruleType .ordinal ();
151
+ raspErrorCodeCounter .incrementAndGet (index );
156
152
}
157
153
158
- public void wafErrorCode (final RuleType ruleType , final int ddwafRunErrorCode ) {
159
- wafErrorCodeCounter .get (ddwafRunErrorCode ).incrementAndGet (ruleType .ordinal ());
154
+ public void wafErrorCode (final int errorCode ) {
155
+ WafErrorCode wafErrorCode = WafErrorCode .fromCode (errorCode );
156
+ // Unsupported waf error code
157
+ if (wafErrorCode == null ) {
158
+ return ;
159
+ }
160
+ wafErrorCodeCounter .incrementAndGet (wafErrorCode .ordinal ());
160
161
}
161
162
162
163
public void missingUserLogin (final LoginFramework framework , final LoginEvent eventType ) {
@@ -321,16 +322,13 @@ public void prepareMetrics() {
321
322
}
322
323
323
324
// RASP rule type for each possible error code
324
- for (int i = - 1 * ABSTRACT_POWERWAF_EXCEPTION_NUMBER ; i < 0 ; i ++ ) {
325
+ for (WafErrorCode errorCode : WafErrorCode . values () ) {
325
326
for (RuleType ruleType : RuleType .values ()) {
326
- long counter = raspErrorCodeCounter .get (i ).getAndSet (ruleType .ordinal (), 0 );
327
- if (counter > 0 ) {
328
- if (!rawMetricsQueue .offer (
329
- new RaspError (counter , ruleType , WafMetricCollector .wafVersion , i ))) {
330
- return ;
331
- }
327
+ int index = errorCode .ordinal () * RuleType .getNumValues () + ruleType .ordinal ();
328
+ long count = raspErrorCodeCounter .getAndSet (index , 0 );
329
+ if (count > 0 ) {
332
330
if (!rawMetricsQueue .offer (
333
- new WafError ( counter , ruleType , WafMetricCollector .wafVersion , i ))) {
331
+ new RaspError ( count , ruleType , WafMetricCollector .wafVersion , errorCode . getCode () ))) {
334
332
return ;
335
333
}
336
334
}
@@ -375,6 +373,17 @@ public void prepareMetrics() {
375
373
}
376
374
}
377
375
376
+ // WAF rule type for each possible error code
377
+ for (WafErrorCode errorCode : WafErrorCode .values ()) {
378
+ long count = wafErrorCodeCounter .getAndSet (errorCode .ordinal (), 0 );
379
+ if (count > 0 ) {
380
+ if (!rawMetricsQueue .offer (
381
+ new WafError (count , WafMetricCollector .wafVersion , errorCode .getCode ()))) {
382
+ return ;
383
+ }
384
+ }
385
+ }
386
+
378
387
// RASP rule skipped per rule type for after-request reason
379
388
for (RuleType ruleType : RuleType .values ()) {
380
389
long counter = raspRuleSkippedCounter .getAndSet (ruleType .ordinal (), 0 );
@@ -569,27 +578,13 @@ public RaspError(
569
578
}
570
579
571
580
public static class WafError extends WafMetric {
572
- public WafError (
573
- final long counter ,
574
- final RuleType ruleType ,
575
- final String wafVersion ,
576
- final Integer ddwafRunError ) {
581
+ public WafError (final long counter , final String wafVersion , final Integer ddwafRunError ) {
577
582
super (
578
583
"waf.error" ,
579
584
counter ,
580
- ruleType .variant != null
581
- ? new String [] {
582
- "rule_type:" + ruleType .type ,
583
- "rule_variant:" + ruleType .variant ,
584
- "waf_version:" + wafVersion ,
585
- "event_rules_version:" + rulesVersion ,
586
- "waf_error:" + ddwafRunError
587
- }
588
- : new String [] {
589
- "rule_type:" + ruleType .type ,
590
- "waf_version:" + wafVersion ,
591
- "waf_error:" + ddwafRunError
592
- });
585
+ "waf_version:" + wafVersion ,
586
+ "event_rules_version:" + rulesVersion ,
587
+ "waf_error:" + ddwafRunError );
593
588
}
594
589
}
595
590
@@ -614,4 +609,38 @@ public final void increment() {
614
609
atomicLong .incrementAndGet ();
615
610
}
616
611
}
612
+
613
+ // TODO This enum should be in liddwaf, remove it when available
614
+ public enum WafErrorCode {
615
+ INVALID_ARGUMENT (-1 ),
616
+ INVALID_OBJECT (-2 ),
617
+ INTERNAL_ERROR (-3 ),
618
+ BINDING_ERROR (
619
+ -127 ); // This is a special error code that is not returned by the WAF, is used to signal a
620
+ // binding error
621
+
622
+ private final int code ;
623
+
624
+ private static final Map <Integer , WafErrorCode > CODE_MAP ;
625
+
626
+ static {
627
+ Map <Integer , WafErrorCode > map = new HashMap <>();
628
+ for (WafErrorCode errorCode : values ()) {
629
+ map .put (errorCode .code , errorCode );
630
+ }
631
+ CODE_MAP = Collections .unmodifiableMap (map );
632
+ }
633
+
634
+ WafErrorCode (int code ) {
635
+ this .code = code ;
636
+ }
637
+
638
+ public int getCode () {
639
+ return code ;
640
+ }
641
+
642
+ public static WafErrorCode fromCode (int code ) {
643
+ return CODE_MAP .get (code );
644
+ }
645
+ }
617
646
}
0 commit comments