blob: fba061d68ce6489e3ff5fdaae1c82224e641d842 [file] [log] [blame]
/*
Copyright (C) 2006-2010 Werner Dittmann
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _ZRTPSTATECLASS_H_
#define _ZRTPSTATECLASS_H_
/**
* @file ZrtpStateClass.h
* @brief The ZRTP state handling class
*
* @ingroup GNU_ZRTP
* @{
*/
#include <libzrtpcpp/ZrtpStates.h>
#include <libzrtpcpp/ZrtpPacketBase.h>
/**
* The ZRTP states
*
* Depending on the role of this state engine and the actual protocl flow
* not all states are processed during a ZRTP handshake.
*/
enum zrtpStates {
Initial, ///< Initial state after starting the state engine
Detect, ///< State sending Hello, try to detect answer message
AckDetected, ///< HelloAck received
AckSent, ///< HelloAck sent after Hello received
WaitCommit, ///< Wait for a Commit message
CommitSent, ///< Commit message sent
WaitDHPart2, ///< Wait for a DHPart2 message
WaitConfirm1, ///< Wait for a Confirm1 message
WaitConfirm2, ///< Wait for a confirm2 message
WaitConfAck, ///< Wait for Conf2Ack
WaitClearAck, ///< Wait for clearAck - not used
SecureState, ///< This is the secure state - SRTP active
WaitErrorAck, ///< Wait for ErrorAck message
numberOfStates ///< Gives total number of protocol states
};
enum EventReturnCodes {
Fail = 0, ///< ZRTP event processing failed.
Done = 1 ///< Event processing ok.
};
enum EventDataType {
ZrtpInitial = 1, ///< Initial event, enter Initial state
ZrtpClose, ///< Close event, shut down state engine
ZrtpPacket, ///< Normal ZRTP message event, process according to state
Timer, ///< Timer event
ErrorPkt ///< Error packet event
};
enum SecureSubStates {
Normal,
WaitSasRelayAck,
numberofSecureSubStates
};
/// A ZRTP state event
typedef struct Event {
EventDataType type; ///< Type of event
uint8_t* packet; ///< Event data if availabe, usually a ZRTP message
} Event_t;
/**
* The ZRTP timer structure.
*
* This structure holds all necessary data to compute the timer for
* the protocol timers. The state engine allocate one structure for
* each timer. ZRTP uses two timers, T1 and T2, to monitor protocol
* timeouts. As a slight misuse but to make overall handling a bit
* simpler this structure also contains the resend counter. This is
* possible in ZRTP because it uses a simple timeout strategy.
*/
typedef struct zrtpTimer {
int32_t time, ///< Current timeout value
start, ///< Start value for timeout
increment, ///< increment timeout after each timeout event (not used anymore)
capping, ///< Maximum timeout value
counter, ///< Current number of timeouts
maxResend; ///< Maximum number of timeout resends
} zrtpTimer_t;
class ZRtp;
/**
* This class is the ZRTP protocol state engine.
*
* This class is responsible to handle the ZRTP protocol. It does not
* handle the ZRTP HMAC, DH, and other data management. This is done in
* class ZRtp, which is the parent of this class.
*
* The methods of this class implement the ZRTP state actions.
*
*/
class __EXPORT ZrtpStateClass {
private:
ZRtp* parent; ///< The ZRTP implmentation
ZrtpStates* engine; ///< The state switching engine
Event_t* event; ///< Current event to process
/**
* The last packet that was sent.
*
* If we are <code>Initiator</code> then resend this packet in case of
* timeout.
*/
ZrtpPacketBase* sentPacket;
/**
* Points to prepared Commit packet after receiving a Hello packet
*/
ZrtpPacketCommit* commitPkt;
zrtpTimer_t T1; ///< The Hello message timeout timer
zrtpTimer_t T2; ///< Timeout timer for other messages
/*
* If this is set to true the protocol engine handle the multi-stream
* variant of ZRTP. Refer to chapter 5.4.2 in the ZRTP specification.
*/
bool multiStream;
// Secure substate to handle SAS relay packets
SecureSubStates secSubstate;
/**
* Secure Sub state WaitSasRelayAck.
*
* This state belongs to the secure substates and handles
* SAS Relay Ack.
*
* When entering this transition function
* - sentPacket contains Error packet, Error timer active
*
* Possible events in this state are:
* - timeout for sent SAS Relay packet: causes a resend check and repeat sending
* of packet
* - SASRelayAck: Stop timer and switch to secure substate Normal.
*/
bool subEvWaitRelayAck();
public:
/// Create a ZrtpStateClass
ZrtpStateClass(ZRtp *p);
~ZrtpStateClass();
/// Check if in a specified state
bool inState(const int32_t state) { return engine->inState(state); };
/// Switch to the specified state
void nextState(int32_t state) { engine->nextState(state); };
/// Process an event, the main entry point into the state engine
void processEvent(Event_t *ev);
/**
* The state event handling methods.
*
* Refer to the protocol state diagram for further documentation.
*/
/// Initial event state
void evInitial();
/// Detect state
void evDetect();
/// HelloAck detected state
void evAckDetected();
/// HelloAck sent state
void evAckSent();
/// Wait for Commit message
void evWaitCommit();
/// Commit sent state
void evCommitSent();
/// Wait for DHPart2 message
void evWaitDHPart2();
/// Wait for Confirm2 message
void evWaitConfirm1();
/// Wait for Confirm2 message
void evWaitConfirm2();
/// Wait for ConfAck message
void evWaitConfAck();
/// Wait for ClearAck message (not used)
void evWaitClearAck();
/// Secure reached state
void evSecureState();
/// Wait for ErrorAck message
void evWaitErrorAck();
/**
* Initialize and activate a timer.
*
* @param t
* The ZRTP timer structure to use for the timer.
* @return
* 1 timer was activated
* 0 activation failed
*/
int32_t startTimer(zrtpTimer_t *t);
/**
* Compute and set the next timeout value.
*
* @param t
* The ZRTP timer structure to use for the timer.
* @return
* 1 timer was activated
* 0 activation failed
* -1 resend counter exceeded
*/
int32_t nextTimer(zrtpTimer_t *t);
/**
* Cancel the active timer.
*
* @return
* 1 timer was canceled
* 0 cancelation failed
*/
int32_t cancelTimer() {return parent->cancelTimer(); };
/**
* Prepare and send an Error packet.
*
* Preparse an Error packet and sends it. It stores the Error
* packet in the sentPacket variable to enable resending. The
* method switches to protocol state Initial.
*/
void sendErrorPacket(uint32_t errorCode);
/**
* Set status if an error occured while sending a ZRTP packet.
*
* This functions clears data and set the state to Initial after the engine
* detected a problem while sending a ZRTP packet.
*
* @return
* Fail code
*/
void sendFailed();
/**
* Set status if a timer problems occure.
*
* This functions clears data and set state to Initial after a timer
* error occured. Either no timer available or resend counter exceedeed.
*
* @return
* Fail code
*/
void timerFailed(int32_t subCode);
/**
* Set multi-stream mode flag.
*
* This functions set the multi-stream mode. The protocol
* engine will run the multi-stream mode variant of the ZRTP
* protocol if this flag is set to true.
*
* @param multi
* Set the multi-stream mode flag to true or false.
*/
void setMultiStream(bool multi);
/**
* Status of multi-stream mode flag.
*
* This functions returns the value of the multi-stream mode flag.
*
* @return
* Value of the multi-stream mode flag.
*/
bool isMultiStream();
/**
* Send a SAS relay packet.
*
* the functions stores sends the SAS relay packet and stores the pointer in
* the sentPacket variable to enable resending.
*
* The method switches to secure substate WaitSasRelayAck.
*
* @param relay
* Pointer to the SAS relay packet.
*/
void sendSASRelay(ZrtpPacketSASrelay* relay);
};
/**
* @}
*/
#endif // _ZRTPSTATECLASS_H_