blob: c1887c9a6793c4a092ce94c2cb548e1f2d5d292b [file] [log] [blame]
Alexandre Lision51140e12013-12-02 10:54:09 -05001/*
Alexandre Lisionddd731e2014-01-31 11:50:08 -05002 Copyright (C) 2006-2010 Werner Dittmann
Alexandre Lision51140e12013-12-02 10:54:09 -05003
4 This program is free software: you can redistribute it and/or modify
Alexandre Lisionddd731e2014-01-31 11:50:08 -05005 it under the terms of the GNU General Public License as published by
Alexandre Lision51140e12013-12-02 10:54:09 -05006 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/
17
18#ifndef _ZRTPSTATECLASS_H_
19#define _ZRTPSTATECLASS_H_
20
21/**
22 * @file ZrtpStateClass.h
23 * @brief The ZRTP state handling class
24 *
25 * @ingroup GNU_ZRTP
26 * @{
27 */
28
29#include <libzrtpcpp/ZrtpStates.h>
30#include <libzrtpcpp/ZrtpPacketBase.h>
31
32/**
33 * The ZRTP states
34 *
35 * Depending on the role of this state engine and the actual protocl flow
36 * not all states are processed during a ZRTP handshake.
37 */
38enum zrtpStates {
39 Initial, ///< Initial state after starting the state engine
40 Detect, ///< State sending Hello, try to detect answer message
41 AckDetected, ///< HelloAck received
42 AckSent, ///< HelloAck sent after Hello received
43 WaitCommit, ///< Wait for a Commit message
44 CommitSent, ///< Commit message sent
45 WaitDHPart2, ///< Wait for a DHPart2 message
46 WaitConfirm1, ///< Wait for a Confirm1 message
47 WaitConfirm2, ///< Wait for a confirm2 message
48 WaitConfAck, ///< Wait for Conf2Ack
49 WaitClearAck, ///< Wait for clearAck - not used
50 SecureState, ///< This is the secure state - SRTP active
51 WaitErrorAck, ///< Wait for ErrorAck message
52 numberOfStates ///< Gives total number of protocol states
53};
54
55enum EventReturnCodes {
56 Fail = 0, ///< ZRTP event processing failed.
57 Done = 1 ///< Event processing ok.
58};
59
60enum EventDataType {
61 ZrtpInitial = 1, ///< Initial event, enter Initial state
62 ZrtpClose, ///< Close event, shut down state engine
63 ZrtpPacket, ///< Normal ZRTP message event, process according to state
64 Timer, ///< Timer event
65 ErrorPkt ///< Error packet event
66};
67
68enum SecureSubStates {
69 Normal,
70 WaitSasRelayAck,
71 numberofSecureSubStates
72};
73
74/// A ZRTP state event
75typedef struct Event {
76 EventDataType type; ///< Type of event
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -050077 size_t length; ///< length of the message data
Alexandre Lision51140e12013-12-02 10:54:09 -050078 uint8_t* packet; ///< Event data if availabe, usually a ZRTP message
79} Event_t;
80
81
82/**
83 * The ZRTP timer structure.
84 *
85 * This structure holds all necessary data to compute the timer for
86 * the protocol timers. The state engine allocate one structure for
87 * each timer. ZRTP uses two timers, T1 and T2, to monitor protocol
88 * timeouts. As a slight misuse but to make overall handling a bit
89 * simpler this structure also contains the resend counter. This is
90 * possible in ZRTP because it uses a simple timeout strategy.
91 */
92typedef struct zrtpTimer {
93 int32_t time, ///< Current timeout value
94 start, ///< Start value for timeout
95 increment, ///< increment timeout after each timeout event (not used anymore)
96 capping, ///< Maximum timeout value
97 counter, ///< Current number of timeouts
98 maxResend; ///< Maximum number of timeout resends
99} zrtpTimer_t;
100
101
102class ZRtp;
103
104/**
105 * This class is the ZRTP protocol state engine.
106 *
107 * This class is responsible to handle the ZRTP protocol. It does not
108 * handle the ZRTP HMAC, DH, and other data management. This is done in
109 * class ZRtp, which is the parent of this class.
110 *
111 * The methods of this class implement the ZRTP state actions.
112 *
113 */
114
115
116class __EXPORT ZrtpStateClass {
117
118private:
119 ZRtp* parent; ///< The ZRTP implmentation
120 ZrtpStates* engine; ///< The state switching engine
121 Event_t* event; ///< Current event to process
122
123 /**
124 * The last packet that was sent.
125 *
126 * If we are <code>Initiator</code> then resend this packet in case of
127 * timeout.
128 */
129 ZrtpPacketBase* sentPacket;
130
131 /**
132 * Points to prepared Commit packet after receiving a Hello packet
133 */
134 ZrtpPacketCommit* commitPkt;
135
136 zrtpTimer_t T1; ///< The Hello message timeout timer
137 zrtpTimer_t T2; ///< Timeout timer for other messages
138
139 /*
140 * If this is set to true the protocol engine handle the multi-stream
141 * variant of ZRTP. Refer to chapter 5.4.2 in the ZRTP specification.
142 */
143 bool multiStream;
144
145 // Secure substate to handle SAS relay packets
146 SecureSubStates secSubstate;
147
148 /**
149 * Secure Sub state WaitSasRelayAck.
150 *
151 * This state belongs to the secure substates and handles
152 * SAS Relay Ack.
153 *
154 * When entering this transition function
155 * - sentPacket contains Error packet, Error timer active
156 *
157 * Possible events in this state are:
158 * - timeout for sent SAS Relay packet: causes a resend check and repeat sending
159 * of packet
160 * - SASRelayAck: Stop timer and switch to secure substate Normal.
161 */
162 bool subEvWaitRelayAck();
163
Alexandre Lision51140e12013-12-02 10:54:09 -0500164public:
165 /// Create a ZrtpStateClass
166 ZrtpStateClass(ZRtp *p);
167 ~ZrtpStateClass();
168
169 /// Check if in a specified state
170 bool inState(const int32_t state) { return engine->inState(state); };
171
172 /// Switch to the specified state
173 void nextState(int32_t state) { engine->nextState(state); };
174
175 /// Process an event, the main entry point into the state engine
176 void processEvent(Event_t *ev);
177
178 /**
179 * The state event handling methods.
180 *
181 * Refer to the protocol state diagram for further documentation.
182 */
183 /// Initial event state
184 void evInitial();
185
186 /// Detect state
187 void evDetect();
188
189 /// HelloAck detected state
190 void evAckDetected();
191
192 /// HelloAck sent state
193 void evAckSent();
194
195 /// Wait for Commit message
196 void evWaitCommit();
197
198 /// Commit sent state
199 void evCommitSent();
200
201 /// Wait for DHPart2 message
202 void evWaitDHPart2();
203
204 /// Wait for Confirm2 message
205 void evWaitConfirm1();
206
207 /// Wait for Confirm2 message
208 void evWaitConfirm2();
209
210 /// Wait for ConfAck message
211 void evWaitConfAck();
212
213 /// Wait for ClearAck message (not used)
214 void evWaitClearAck();
215
216 /// Secure reached state
217 void evSecureState();
218
219 /// Wait for ErrorAck message
220 void evWaitErrorAck();
221
222 /**
223 * Initialize and activate a timer.
224 *
225 * @param t
226 * The ZRTP timer structure to use for the timer.
227 * @return
228 * 1 timer was activated
229 * 0 activation failed
230 */
231 int32_t startTimer(zrtpTimer_t *t);
232
233 /**
234 * Compute and set the next timeout value.
235 *
236 * @param t
237 * The ZRTP timer structure to use for the timer.
238 * @return
239 * 1 timer was activated
240 * 0 activation failed
241 * -1 resend counter exceeded
242 */
243 int32_t nextTimer(zrtpTimer_t *t);
244
245 /**
246 * Cancel the active timer.
247 *
248 * @return
249 * 1 timer was canceled
250 * 0 cancelation failed
251 */
252 int32_t cancelTimer() {return parent->cancelTimer(); };
253
254 /**
255 * Prepare and send an Error packet.
256 *
257 * Preparse an Error packet and sends it. It stores the Error
258 * packet in the sentPacket variable to enable resending. The
259 * method switches to protocol state Initial.
260 */
261 void sendErrorPacket(uint32_t errorCode);
262
263 /**
264 * Set status if an error occured while sending a ZRTP packet.
265 *
266 * This functions clears data and set the state to Initial after the engine
267 * detected a problem while sending a ZRTP packet.
268 *
269 * @return
270 * Fail code
271 */
272 void sendFailed();
273
274 /**
275 * Set status if a timer problems occure.
276 *
277 * This functions clears data and set state to Initial after a timer
278 * error occured. Either no timer available or resend counter exceedeed.
279 *
280 * @return
281 * Fail code
282 */
283 void timerFailed(int32_t subCode);
284
285 /**
286 * Set multi-stream mode flag.
287 *
288 * This functions set the multi-stream mode. The protocol
289 * engine will run the multi-stream mode variant of the ZRTP
290 * protocol if this flag is set to true.
291 *
292 * @param multi
293 * Set the multi-stream mode flag to true or false.
294 */
295 void setMultiStream(bool multi);
296
297 /**
298 * Status of multi-stream mode flag.
299 *
300 * This functions returns the value of the multi-stream mode flag.
301 *
302 * @return
303 * Value of the multi-stream mode flag.
304 */
305 bool isMultiStream();
306
307 /**
308 * Send a SAS relay packet.
309 *
310 * the functions stores sends the SAS relay packet and stores the pointer in
311 * the sentPacket variable to enable resending.
312 *
313 * The method switches to secure substate WaitSasRelayAck.
314 *
315 * @param relay
316 * Pointer to the SAS relay packet.
317 */
318 void sendSASRelay(ZrtpPacketSASrelay* relay);
319};
320
321/**
322 * @}
323 */
324#endif // _ZRTPSTATECLASS_H_
325