mirror of
https://github.com/signalwire/freeswitch.git
synced 2025-02-05 18:44:54 +00:00
d2edcad66e
Thanks to Phil Zimmermann for the code and for the license exception we needed to include it. There remains some build system integration work to be done before this code will build properly in the FreeSWITCH tree.
153 lines
4.7 KiB
C
153 lines
4.7 KiB
C
/*
|
|
* libZRTP SDK library, implements the ZRTP secure VoIP protocol.
|
|
* Copyright (c) 2006-2009 Philip R. Zimmermann. All rights reserved.
|
|
* Contact: http://philzimmermann.com
|
|
* For licensing and other legal details, see the file zrtp_legal.c.
|
|
*
|
|
* Viktor Krykun <v.krikun at zfoneproject.com>
|
|
*/
|
|
|
|
#include "zrtp.h"
|
|
|
|
#define _ZTU_ "zrtp dengine"
|
|
|
|
|
|
#if (defined(ZRTP_BUILD_FOR_CSD) && (ZRTP_BUILD_FOR_CSD == 1))
|
|
|
|
extern zrtp_status_t _zrtp_machine_process_hello(zrtp_stream_t* stream, zrtp_rtp_info_t* packet);
|
|
extern zrtp_status_t start_send_and_resend_hello(zrtp_stream_t* stream);
|
|
extern zrtp_status_t start_initiating_secure(zrtp_stream_t *stream);
|
|
extern zrtp_status_t _zrtp_machine_start_send_and_resend_hello(zrtp_stream_t* stream);
|
|
|
|
|
|
/*----------------------------------------------------------------------------*/
|
|
void zrtp_driven_stream_start(zrtp_stream_t* stream, zrtp_statemachine_type_t role)
|
|
{
|
|
|
|
ZRTP_LOG(3,(_ZTU_,"START Driven %s Stream ID=%u mode=%s state=%s.",
|
|
(ZRTP_STATEMACHINE_INITIATOR == role)?"INITIATOR":"RESPONDER",
|
|
stream->id, zrtp_log_mode2str(stream->mode), zrtp_log_state2str(stream->state)));
|
|
|
|
/* This function can be called in parallel to the main processing loop protect internal stream data. */
|
|
zrtp_mutex_lock(stream->stream_protector);
|
|
|
|
if ( (ZRTP_STATE_ACTIVE != stream->state) &&
|
|
(ZRTP_STATE_ERROR != stream->state) &&
|
|
(ZRTP_STATE_NO_ZRTP != stream->state))
|
|
{
|
|
ZRTP_LOG(1,(_ZTU_,"ERROR! can't start stream ID=%u from state %d.", stream->id, stream->state));
|
|
}
|
|
else
|
|
{
|
|
if (ZRTP_STATEMACHINE_INITIATOR == role) {
|
|
_zrtp_change_state(stream, ZRTP_STATE_DRIVEN_INITIATOR);
|
|
_zrtp_machine_start_send_and_resend_hello(stream);
|
|
} else if (ZRTP_STATEMACHINE_RESPONDER == role) {
|
|
_zrtp_change_state(stream, ZRTP_STATE_DRIVEN_RESPONDER);
|
|
}
|
|
}
|
|
|
|
zrtp_mutex_unlock(stream->stream_protector);
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
zrtp_status_t _zrtp_machine_process_while_in_driven_initiator( zrtp_stream_t* stream,
|
|
zrtp_rtp_info_t* packet)
|
|
{
|
|
zrtp_status_t s = zrtp_status_ok;
|
|
|
|
switch (packet->type)
|
|
{
|
|
case ZRTP_HELLO: {
|
|
s = _zrtp_machine_process_hello(stream, packet);
|
|
if (zrtp_status_ok != s) {
|
|
ZRTP_LOG(1,(_ZTU_,"ERROR! _zrtp_machine_process_hello()4 failed with status=%d. ID=%u",s, stream->id));
|
|
break; /* Just stay in DRIVEN_INITIATOR state. */
|
|
}
|
|
|
|
/* Now we have ZIDs for both sides and can upload secrets from the cache */
|
|
s = _zrtp_prepare_secrets(stream->session);
|
|
if (zrtp_status_ok != s) {
|
|
ZRTP_LOG(1,(_ZTU_,"ERROR! _zrtp_prepare_secrets()3 failed with status=%d. ID=%u",s, stream->id));
|
|
break; /* Just stay in START state. */
|
|
}
|
|
|
|
// TODO: handle autosecure and licensing modes there
|
|
_zrtp_cancel_send_packet_later(stream, ZRTP_HELLO);
|
|
stream->mode = _zrtp_define_stream_mode(stream);
|
|
s = _zrtp_machine_enter_initiatingsecure(stream);
|
|
} break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return s;
|
|
}
|
|
|
|
zrtp_status_t _zrtp_machine_process_while_in_driven_responder( zrtp_stream_t* stream,
|
|
zrtp_rtp_info_t* packet)
|
|
{
|
|
zrtp_status_t s = zrtp_status_ok;
|
|
|
|
switch (packet->type)
|
|
{
|
|
case ZRTP_HELLO: {
|
|
s = _zrtp_machine_process_hello(stream, packet);
|
|
if (zrtp_status_ok != s) {
|
|
ZRTP_LOG(1,(_ZTU_,"ERROR! _zrtp_machine_process_hello()5 failed with status=%d. ID=%u", s, stream->id));
|
|
break; /* Just stay in DRIVEN_INITIATOR state. */
|
|
}
|
|
|
|
/* Now we have ZIDs for both sides and can upload secrets from the cache */
|
|
s = _zrtp_prepare_secrets(stream->session);
|
|
if (zrtp_status_ok != s) {
|
|
ZRTP_LOG(1,(_ZTU_,"ERROR! _zrtp_prepare_secrets()4 failed with status=%d. ID=%u", s, stream->id));
|
|
break; /* Just stay in START state. */
|
|
}
|
|
|
|
// TODO: handle autosecure and licensing modes there
|
|
s = _zrtp_packet_send_message(stream, ZRTP_HELLO, &stream->messages.hello);
|
|
if (zrtp_status_ok == s) {
|
|
_zrtp_change_state(stream, ZRTP_STATE_DRIVEN_PENDING);
|
|
}
|
|
} break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return s;
|
|
}
|
|
|
|
zrtp_status_t _zrtp_machine_process_while_in_driven_pending( zrtp_stream_t* stream,
|
|
zrtp_rtp_info_t* packet)
|
|
{
|
|
zrtp_status_t s = zrtp_status_ok;
|
|
|
|
switch (packet->type)
|
|
{
|
|
case ZRTP_HELLO: {
|
|
s = _zrtp_packet_send_message(stream, ZRTP_HELLO, &stream->messages.hello);
|
|
} break;
|
|
|
|
case ZRTP_COMMIT: {
|
|
zrtp_statemachine_type_t role = _zrtp_machine_preparse_commit(stream, packet);
|
|
if (ZRTP_STATEMACHINE_RESPONDER == role) {
|
|
s = _zrtp_machine_enter_pendingsecure(stream, packet);
|
|
} else if (ZRTP_STATEMACHINE_INITIATOR == role) {
|
|
s = _zrtp_machine_start_initiating_secure(stream);
|
|
} else {
|
|
s = zrtp_status_fail;
|
|
}
|
|
} break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return s;
|
|
}
|
|
|
|
#endif /* ZRTP_BUILD_FOR_CSD */
|