blob: 5c163139e586a89f2655d8f64d4c9df9a051b18a [file] [log] [blame]
Alexandre Lision51140e12013-12-02 10:54:09 -05001/*
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05002 Copyright (C) 2006-2013 Werner Dittmann
Alexandre Lision51140e12013-12-02 10:54:09 -05003
4 This program is free software: you can redistribute it and/or modify
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05005 it under the terms of the GNU Lesser 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 Lision7fd5d3d2013-12-04 13:06:40 -0500164 /**
165 * Hello packet version sent to other partner
166 */
167 int32_t sentVersion;
168
Alexandre Lision51140e12013-12-02 10:54:09 -0500169public:
170 /// Create a ZrtpStateClass
171 ZrtpStateClass(ZRtp *p);
172 ~ZrtpStateClass();
173
174 /// Check if in a specified state
175 bool inState(const int32_t state) { return engine->inState(state); };
176
177 /// Switch to the specified state
178 void nextState(int32_t state) { engine->nextState(state); };
179
180 /// Process an event, the main entry point into the state engine
181 void processEvent(Event_t *ev);
182
183 /**
184 * The state event handling methods.
185 *
186 * Refer to the protocol state diagram for further documentation.
187 */
188 /// Initial event state
189 void evInitial();
190
191 /// Detect state
192 void evDetect();
193
194 /// HelloAck detected state
195 void evAckDetected();
196
197 /// HelloAck sent state
198 void evAckSent();
199
200 /// Wait for Commit message
201 void evWaitCommit();
202
203 /// Commit sent state
204 void evCommitSent();
205
206 /// Wait for DHPart2 message
207 void evWaitDHPart2();
208
209 /// Wait for Confirm2 message
210 void evWaitConfirm1();
211
212 /// Wait for Confirm2 message
213 void evWaitConfirm2();
214
215 /// Wait for ConfAck message
216 void evWaitConfAck();
217
218 /// Wait for ClearAck message (not used)
219 void evWaitClearAck();
220
221 /// Secure reached state
222 void evSecureState();
223
224 /// Wait for ErrorAck message
225 void evWaitErrorAck();
226
227 /**
228 * Initialize and activate a timer.
229 *
230 * @param t
231 * The ZRTP timer structure to use for the timer.
232 * @return
233 * 1 timer was activated
234 * 0 activation failed
235 */
236 int32_t startTimer(zrtpTimer_t *t);
237
238 /**
239 * Compute and set the next timeout value.
240 *
241 * @param t
242 * The ZRTP timer structure to use for the timer.
243 * @return
244 * 1 timer was activated
245 * 0 activation failed
246 * -1 resend counter exceeded
247 */
248 int32_t nextTimer(zrtpTimer_t *t);
249
250 /**
251 * Cancel the active timer.
252 *
253 * @return
254 * 1 timer was canceled
255 * 0 cancelation failed
256 */
257 int32_t cancelTimer() {return parent->cancelTimer(); };
258
259 /**
260 * Prepare and send an Error packet.
261 *
262 * Preparse an Error packet and sends it. It stores the Error
263 * packet in the sentPacket variable to enable resending. The
264 * method switches to protocol state Initial.
265 */
266 void sendErrorPacket(uint32_t errorCode);
267
268 /**
269 * Set status if an error occured while sending a ZRTP packet.
270 *
271 * This functions clears data and set the state to Initial after the engine
272 * detected a problem while sending a ZRTP packet.
273 *
274 * @return
275 * Fail code
276 */
277 void sendFailed();
278
279 /**
280 * Set status if a timer problems occure.
281 *
282 * This functions clears data and set state to Initial after a timer
283 * error occured. Either no timer available or resend counter exceedeed.
284 *
285 * @return
286 * Fail code
287 */
288 void timerFailed(int32_t subCode);
289
290 /**
291 * Set multi-stream mode flag.
292 *
293 * This functions set the multi-stream mode. The protocol
294 * engine will run the multi-stream mode variant of the ZRTP
295 * protocol if this flag is set to true.
296 *
297 * @param multi
298 * Set the multi-stream mode flag to true or false.
299 */
300 void setMultiStream(bool multi);
301
302 /**
303 * Status of multi-stream mode flag.
304 *
305 * This functions returns the value of the multi-stream mode flag.
306 *
307 * @return
308 * Value of the multi-stream mode flag.
309 */
310 bool isMultiStream();
311
312 /**
313 * Send a SAS relay packet.
314 *
315 * the functions stores sends the SAS relay packet and stores the pointer in
316 * the sentPacket variable to enable resending.
317 *
318 * The method switches to secure substate WaitSasRelayAck.
319 *
320 * @param relay
321 * Pointer to the SAS relay packet.
322 */
323 void sendSASRelay(ZrtpPacketSASrelay* relay);
324};
325
326/**
327 * @}
328 */
329#endif // _ZRTPSTATECLASS_H_
330