67ed9882c517f394f9c47fd7f910400adb0e65d5
[strongswan.git] / src / libcharon / plugins / stroke / stroke_counter.c
1 /*
2 * Copyright (C) 2012 Martin Willi
3 * Copyright (C) 2012 revosec AG
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * for more details.
14 */
15
16 #include "stroke_counter.h"
17
18 #include <threading/spinlock.h>
19
20 ENUM(stroke_counter_type_names,
21 COUNTER_INIT_IKE_SA_REKEY, COUNTER_OUT_INFORMATIONAL_RSP,
22 "ikeInitRekey",
23 "ikeRspRekey",
24 "ikeChildSaRekey",
25 "ikeInInvalid",
26 "ikeInInvalidSpi",
27 "ikeInInitReq",
28 "ikeInInitRsp",
29 "ikeOutInitReq",
30 "ikeOutInitRsp",
31 "ikeInAuthReq",
32 "ikeInAuthRsp",
33 "ikeOutAuthReq",
34 "ikeOutAuthRsp",
35 "ikeInCrChildReq",
36 "ikeInCrChildRsp",
37 "ikeOutCrChildReq",
38 "ikeOutCrChildRsp",
39 "ikeInInfoReq",
40 "ikeInInfoRsp",
41 "ikeOutInfoReq",
42 "ikeOutInfoRsp",
43 );
44
45 typedef struct private_stroke_counter_t private_stroke_counter_t;
46
47 /**
48 * Private data of an stroke_counter_t object.
49 */
50 struct private_stroke_counter_t {
51
52 /**
53 * Public stroke_counter_t interface.
54 */
55 stroke_counter_t public;
56
57 /**
58 * Counter values
59 */
60 u_int64_t counter[COUNTER_MAX];
61
62 /**
63 * Lock for counter values
64 */
65 spinlock_t *lock;
66 };
67
68 METHOD(listener_t, alert, bool,
69 private_stroke_counter_t *this, ike_sa_t *ike_sa,
70 alert_t alert, va_list args)
71 {
72 stroke_counter_type_t type;
73
74 switch (alert)
75 {
76 case ALERT_INVALID_IKE_SPI:
77 type = COUNTER_IN_INVALID_IKE_SPI;
78 break;
79 case ALERT_PARSE_ERROR_HEADER:
80 case ALERT_PARSE_ERROR_BODY:
81 type = COUNTER_IN_INVALID;
82 break;
83 default:
84 return TRUE;
85 }
86
87 this->lock->lock(this->lock);
88 this->counter[type]++;
89 this->lock->unlock(this->lock);
90
91 return TRUE;
92 }
93
94 METHOD(listener_t, ike_rekey, bool,
95 private_stroke_counter_t *this, ike_sa_t *old, ike_sa_t *new)
96 {
97 stroke_counter_type_t type;
98 ike_sa_id_t *id;
99
100 id = new->get_id(new);
101 if (id->is_initiator(id))
102 {
103 type = COUNTER_INIT_IKE_SA_REKEY;
104 }
105 else
106 {
107 type = COUNTER_RESP_IKE_SA_REKEY;
108 }
109
110 this->lock->lock(this->lock);
111 this->counter[type]++;
112 this->lock->unlock(this->lock);
113
114 return TRUE;
115 }
116
117 METHOD(listener_t, child_rekey, bool,
118 private_stroke_counter_t *this, ike_sa_t *ike_sa,
119 child_sa_t *old, child_sa_t *new)
120 {
121 this->lock->lock(this->lock);
122 this->counter[COUNTER_CHILD_SA_REKEY]++;
123 this->lock->unlock(this->lock);
124
125 return TRUE;
126 }
127
128 METHOD(stroke_counter_t, destroy, void,
129 private_stroke_counter_t *this)
130 {
131 this->lock->destroy(this->lock);
132 free(this);
133 }
134
135 /**
136 * See header
137 */
138 stroke_counter_t *stroke_counter_create()
139 {
140 private_stroke_counter_t *this;
141
142 INIT(this,
143 .public = {
144 .listener = {
145 .alert = _alert,
146 .ike_rekey = _ike_rekey,
147 .child_rekey = _child_rekey,
148 },
149 .destroy = _destroy,
150 },
151 .lock = spinlock_create(),
152 );
153
154 return &this->public;
155 }