mirror of
https://github.com/signalwire/freeswitch.git
synced 2026-11-10 11:50:53 +00:00
Merge Phil Zimmermann's libzrtp as a FreeSWITCH library
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.
This commit is contained in:
commit
d2edcad66e
261 files changed
+86866
No files matched your search
@@ -0,0 +1,866 @@
|
||||
/*
|
||||
* 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"
|
||||
|
||||
#include "zrtp_test_core.h"
|
||||
#include "zrtp_test_queue.h"
|
||||
|
||||
#if (ZRTP_PLATFORM == ZP_WIN32) || (ZRTP_PLATFORM == ZP_WINCE)
|
||||
#include <windows.h>
|
||||
#elif (ZRTP_PLATFORM == ZP_DARWIN) || (ZRTP_PLATFORM == ZP_LINUX)
|
||||
#include <pthread.h>
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
#define _ZTU_ "TEST"
|
||||
#define ZRTP_TEST_PACKET_MAX_SIZE 256
|
||||
#define ZRTP_TEST_STREAMS_COUNT 1
|
||||
|
||||
#define ZRTP_ENABLE_TEST 0
|
||||
|
||||
extern uint8_t hash_word_list_odd[256][12];
|
||||
extern uint8_t hash_word_list_even[256][10];
|
||||
|
||||
/*! Global data storage */
|
||||
typedef struct zrtp_test_global
|
||||
{
|
||||
mlist_t channels_head; /*! List of test channels*/
|
||||
zrtp_mutex_t* channels_protector; /*! Protector from list modifications */
|
||||
unsigned char is_log_enabled; /*! Allows debug messages logging */
|
||||
unsigned packets_rate; /*! Delay in miliseconds between RTP injection */
|
||||
unsigned channels_count; /*! Active channels count */
|
||||
unsigned secure_count; /*! Active channels count */
|
||||
zrtp_queue_t* queue; /*! Queue which emulate communication channel between ZRTP endpoints */
|
||||
unsigned char is_running; /*! Main test loop work while this is not 0 */
|
||||
} zrtp_test_global_t;
|
||||
|
||||
zrtp_test_global_t test_global; /*! zrtp test global data */
|
||||
zrtp_global_t* zrtp_global; /*! libzrtp global data */
|
||||
|
||||
|
||||
typedef struct zrtp_test_session zrtp_test_session_t;
|
||||
typedef struct zrtp_test_stream zrtp_test_stream_t;
|
||||
typedef struct zrtp_test_channel zrtp_test_channel_t;
|
||||
|
||||
#define ZRTP_TEST_PACKET_HEADER_LENGTH 16
|
||||
|
||||
|
||||
typedef struct zrtp_test_packet
|
||||
{
|
||||
uint32_t is_rtp; /*! Defines is packet RTP or RTCP */
|
||||
uint32_t length; /*! Packet Length in bytes */
|
||||
char body[1024]; /*! Packet body */
|
||||
} zrtp_test_packet_t;
|
||||
|
||||
struct zrtp_test_stream
|
||||
{
|
||||
zrtp_stream_t* zrtp_stream; /*! ZRTP stream associated test stream */
|
||||
zrtp_test_session_t* session; /*! Pointer to the parent test session */
|
||||
uint16_t seq; /*! RTP sequence number for media packets construction */
|
||||
uint32_t ssrc; /*! RTP local SSRC for media packets exchanging */
|
||||
uint32_t peer_ssrc; /*! RTP remote SSRC for media packets exchanging */
|
||||
};
|
||||
|
||||
struct zrtp_test_session
|
||||
{
|
||||
zrtp_test_stream_t streams[ZRTP_MAX_STREAMS_PER_SESSION]; /*! Streams array */
|
||||
unsigned streams_count; /*! Active streams counter */
|
||||
zrtp_session_t* zrtp_session; /*! ZRTP session associated test session */
|
||||
zrtp_test_channel_t *channel;
|
||||
mlist_t _list;
|
||||
};
|
||||
|
||||
struct zrtp_test_channel
|
||||
{
|
||||
zrtp_test_channel_id_t id; /*! Channel ID*/
|
||||
zrtp_test_session_t ses_left; /*! Left test session */
|
||||
zrtp_test_session_t ses_right; /*! Right test session */
|
||||
mlist_t _mlist;
|
||||
};
|
||||
|
||||
|
||||
zrtp_test_channel_t* find_channel_by_index(zrtp_test_channel_id_t chan_id);
|
||||
zrtp_test_channel_t* find_channel_with_closest_index(zrtp_test_channel_id_t chan_id);
|
||||
zrtp_test_stream_t* find_peer_stream_by_ssrc(uint32_t ssrc);
|
||||
|
||||
|
||||
/*============================================================================*/
|
||||
/* ZRTP Interfaces */
|
||||
/*============================================================================*/
|
||||
|
||||
static void on_zrtp_protocol_event(zrtp_stream_t *ctx, zrtp_protocol_event_t event)
|
||||
{
|
||||
}
|
||||
|
||||
static void on_zrtp_security_event(zrtp_stream_t *ctx, zrtp_security_event_t event)
|
||||
{
|
||||
}
|
||||
|
||||
static void on_zrtp_secure(zrtp_stream_t *ctx)
|
||||
{
|
||||
zrtp_test_stream_t *stream = (zrtp_test_stream_t*) zrtp_stream_get_userdata(ctx);
|
||||
zrtp_test_channel_t *channel = stream->session->channel;
|
||||
unsigned i = 0;
|
||||
unsigned char not_secure = 0;
|
||||
|
||||
ZRTP_LOG(1, (_ZTU_,"Stream is SECURE ssrc=%u ctx=%d\n", ctx->media_ctx.ssrc, ctx));
|
||||
|
||||
for (i=0; i<channel->ses_left.streams_count; i++) {
|
||||
if (ZRTP_STATE_SECURE != channel->ses_left.streams[i].zrtp_stream->state) {
|
||||
not_secure = 1;
|
||||
}
|
||||
}
|
||||
if (0 == not_secure) {
|
||||
for (i=0; i<channel->ses_right.streams_count; i++) {
|
||||
if (ZRTP_STATE_SECURE != channel->ses_right.streams[i].zrtp_stream->state) {
|
||||
not_secure = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (0 == not_secure) {
|
||||
zrtp_session_info_t session_info;
|
||||
zrtp_stream_info_t a_stream_info;
|
||||
|
||||
test_global.secure_count++;
|
||||
|
||||
ZRTP_LOG(1, (_ZTU_,"===================================================\n"));
|
||||
ZRTP_LOG(1, (_ZTU_,"Entire Channel is SECURE. Total Secure count=%d\n", test_global.secure_count));
|
||||
ZRTP_LOG(1, (_ZTU_,"===================================================\n"));
|
||||
|
||||
zrtp_session_get(channel->ses_left.zrtp_session, &session_info);
|
||||
zrtp_stream_get(channel->ses_left.streams[0].zrtp_stream , &a_stream_info);
|
||||
|
||||
zrtp_log_print_sessioninfo(&session_info);
|
||||
zrtp_log_print_streaminfo(&a_stream_info);
|
||||
}
|
||||
}
|
||||
|
||||
static int on_send_packet(const zrtp_stream_t* ctx, char* message, unsigned int length)
|
||||
{
|
||||
zrtp_queue_elem_t* elem = zrtp_sys_alloc(sizeof(zrtp_queue_elem_t));
|
||||
if (elem) {
|
||||
zrtp_test_packet_t* packet = (zrtp_test_packet_t*) elem->data;
|
||||
elem->size = length;
|
||||
|
||||
packet->is_rtp = 1;
|
||||
packet->length = length;
|
||||
zrtp_memcpy(packet->body, message, length);
|
||||
|
||||
ZRTP_LOG(1, (_ZTU_,"\tSend message to ssrc=%u length=%d\n", ctx->media_ctx.ssrc, length));
|
||||
zrtp_test_queue_push(test_global.queue, elem);
|
||||
return zrtp_status_ok;
|
||||
} else {
|
||||
return zrtp_status_alloc_fail;
|
||||
}
|
||||
}
|
||||
|
||||
void zrtp_def_get_cache_path(char *path, uint32_t length)
|
||||
{
|
||||
#if (ZRTP_PLATFORM == ZP_WIN32) || (ZRTP_PLATFORM == ZP_WINCE)
|
||||
strncpy_s(path, length, "./zrtp_test_cache.dat", length);
|
||||
#else
|
||||
strncpy(path, "./zrtp_test_cache.dat", length);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*============================================================================*/
|
||||
/* Sessions Life-Cycle Logic */
|
||||
/*============================================================================*/
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
#if (ZRTP_PLATFORM == ZP_WIN32) || (ZRTP_PLATFORM == ZP_WINCE)
|
||||
DWORD WINAPI process_incoming(void *param)
|
||||
#else
|
||||
void *process_incoming(void *param)
|
||||
#endif
|
||||
{
|
||||
ZRTP_LOG(1, (_ZTU_,"======> STARTING Incoming processor\n"));
|
||||
while (test_global.is_running)
|
||||
{
|
||||
zrtp_test_packet_t* packet = NULL;
|
||||
zrtp_queue_elem_t* elem = NULL;
|
||||
zrtp_status_t s = zrtp_status_fail;
|
||||
zrtp_test_stream_t *stream = NULL;
|
||||
int is_protocol = 0;
|
||||
|
||||
/* Get packet from the "Network" and find aapropriate stream to process it */
|
||||
elem = zrtp_test_queue_pop(test_global.queue);
|
||||
packet = (zrtp_test_packet_t*) elem->data;
|
||||
|
||||
/* We have ssrc in the packet, which indetifies stream that had send it to us.
|
||||
* so now we have to find appropriate stream which has to process that packet.
|
||||
*/
|
||||
if (packet->is_rtp) {
|
||||
ZRTP_UNALIGNED(zrtp_rtp_hdr_t) *hdr = (zrtp_rtp_hdr_t*) (packet->body);
|
||||
if (ZRTP_PACKETS_MAGIC == zrtp_ntoh32(hdr->ts)) {
|
||||
is_protocol = 1;
|
||||
ZRTP_LOG(1, (_ZTU_,"\n"));
|
||||
}
|
||||
stream = find_peer_stream_by_ssrc(hdr->ssrc);
|
||||
} else {
|
||||
ZRTP_UNALIGNED(zrtp_rtcp_hdr_t) *hdr = (zrtp_rtcp_hdr_t*) (packet->body);
|
||||
stream = find_peer_stream_by_ssrc(hdr->ssrc);
|
||||
}
|
||||
|
||||
if (!stream) {
|
||||
zrtp_sys_free(elem);
|
||||
ZRTP_LOG(1, (_ZTU_,"process_incoming(): ERROR! can't found peer stream!\n"));
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Process incoming packet by libzrtp. Is this a RTP media packet - copy it to the buffer
|
||||
* to print out later.
|
||||
*/
|
||||
if (packet->is_rtp) {
|
||||
s = zrtp_process_srtp(stream->zrtp_stream, packet->body, &packet->length);
|
||||
} else {
|
||||
s = zrtp_process_srtcp(stream->zrtp_stream, packet->body, &packet->length);
|
||||
}
|
||||
|
||||
|
||||
if (!is_protocol)
|
||||
{
|
||||
char *body;
|
||||
if (packet->is_rtp) {
|
||||
body = packet->body + sizeof(zrtp_rtp_hdr_t);
|
||||
body[packet->length - sizeof(zrtp_rtp_hdr_t)] = 0;
|
||||
} else {
|
||||
body = packet->body + sizeof(zrtp_rtcp_hdr_t);
|
||||
body[packet->length - sizeof(zrtp_rtcp_hdr_t)] = 0;
|
||||
}
|
||||
|
||||
switch (s)
|
||||
{
|
||||
case zrtp_status_ok: {
|
||||
ZRTP_LOG(1, (_ZTU_,"Incoming: (%s) [%p:ssrc=%u] INPUT. <%s> decrypted %d bytes.\n",
|
||||
zrtp_log_state2str(stream->zrtp_stream->state), stream->zrtp_stream, stream->ssrc, body, packet->length));
|
||||
} break;
|
||||
|
||||
case zrtp_status_drop: {
|
||||
ZRTP_LOG(1, (_ZTU_,"Incoming: (%s) [%p:ssrc=%u] INPUT DROPPED. <%s>\n",
|
||||
zrtp_log_state2str(stream->zrtp_stream->state), stream->zrtp_stream, stream->ssrc, body));
|
||||
} break;
|
||||
|
||||
case zrtp_status_fail: {
|
||||
ZRTP_LOG(1, (_ZTU_,"Incoming: (%s) [%p:ssrc=%u] DECRYPT FAILED. <%s>\n",
|
||||
zrtp_log_state2str(stream->zrtp_stream->state), stream->zrtp_stream, stream->ssrc, body));
|
||||
} break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
zrtp_sys_free(elem);
|
||||
|
||||
/*
|
||||
* When zrtp_stream is in the pending clear state and other side wants to send plain
|
||||
* traffic. We have to call zrtp_clear_stream().
|
||||
*/
|
||||
if (stream->zrtp_stream->state == ZRTP_STATE_PENDINGCLEAR) {
|
||||
zrtp_stream_clear(stream->zrtp_stream);
|
||||
}
|
||||
} /* while is running */
|
||||
|
||||
#if (ZRTP_PLATFORM == ZP_WIN32) || (ZRTP_PLATFORM == ZP_WINCE)
|
||||
return 0;
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
#if (ZRTP_PLATFORM == ZP_WIN32) || (ZRTP_PLATFORM == ZP_WINCE)
|
||||
DWORD WINAPI process_outgoing(void *param)
|
||||
#else
|
||||
void *process_outgoing(void *param)
|
||||
#endif
|
||||
{
|
||||
unsigned packets_counter = 0;
|
||||
|
||||
ZRTP_LOG(1, (_ZTU_,"======> STARTING Outgoing processor\n"));
|
||||
while (test_global.is_running)
|
||||
{
|
||||
zrtp_test_channel_id_t channel_id = 0;
|
||||
zrtp_test_channel_t* channel = NULL;
|
||||
zrtp_test_session_t* session = NULL;
|
||||
unsigned i;
|
||||
|
||||
zrtp_sleep(test_global.packets_rate);
|
||||
|
||||
if ((0 == test_global.channels_count) || (0 == test_global.secure_count)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Get random channel to operate with and select random peer */
|
||||
zrtp_randstr(zrtp_global, (unsigned char*)&channel_id, sizeof(zrtp_test_channel_id_t));
|
||||
channel = find_channel_with_closest_index(channel_id);
|
||||
if (!channel) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ZRTP_LOG(1, (_ZTU_,"\n"));
|
||||
ZRTP_LOG(1, (_ZTU_,"Out. Generate packet by channel N=%u and %s session.\n",
|
||||
channel->id, ((channel_id % 100) > 50) ? "RIGHT": "LEFT"));
|
||||
|
||||
session = ((channel_id % 100) > 50) ? &channel->ses_right : &channel->ses_left;
|
||||
|
||||
/* Generate RTP or RTCP packet for every stream within the session */
|
||||
for (i=0; i<session->streams_count; i++)
|
||||
{
|
||||
zrtp_status_t s = zrtp_status_fail;
|
||||
zrtp_test_packet_t* packet;
|
||||
zrtp_queue_elem_t* elem;
|
||||
zrtp_test_stream_t* stream = &session->streams[i];
|
||||
char* word = NULL;
|
||||
|
||||
elem = zrtp_sys_alloc(sizeof(zrtp_queue_elem_t));
|
||||
if (!elem) {
|
||||
break;
|
||||
}
|
||||
packet = (zrtp_test_packet_t*) elem->data;
|
||||
packet->is_rtp = (packets_counter++ % 20); /* Every 20-th packet is RTCP */
|
||||
|
||||
/*
|
||||
* Construct RTP/RTCP Packet
|
||||
*/
|
||||
if (packet->is_rtp)
|
||||
{
|
||||
ZRTP_UNALIGNED(zrtp_rtp_hdr_t) *rtp_hdr = (zrtp_rtp_hdr_t*)packet->body;
|
||||
|
||||
/* Fill RTP Header according to the specification */
|
||||
zrtp_memset(rtp_hdr, 0, sizeof(zrtp_rtp_hdr_t));
|
||||
rtp_hdr->version = 2; /* Current RTP version 2 */
|
||||
rtp_hdr->pt = 0; /* PCMU padding type */
|
||||
rtp_hdr->ssrc = stream->ssrc; /* Use ssrc for addressing like in real RTP */
|
||||
if (stream->seq >= 0xFFFF) {
|
||||
stream->seq = 0;
|
||||
}
|
||||
rtp_hdr->seq = zrtp_hton16(stream->seq++);
|
||||
rtp_hdr->ts = zrtp_hton32((uint32_t)(zrtp_time_now()/1000));
|
||||
|
||||
/* Get RTP body from PGP words lists */
|
||||
word = (char*)(i ? hash_word_list_odd[packets_counter % 256] : hash_word_list_even[packets_counter % 256]);
|
||||
|
||||
zrtp_memcpy(packet->body + sizeof(zrtp_rtp_hdr_t), word, (uint32_t)strlen(word));
|
||||
packet->length = sizeof(zrtp_rtp_hdr_t) + (uint32_t)strlen(word);
|
||||
|
||||
/* Process RTP media with libzrtp */
|
||||
s = zrtp_process_rtp(stream->zrtp_stream, packet->body, &packet->length);
|
||||
}
|
||||
else
|
||||
{
|
||||
ZRTP_UNALIGNED(zrtp_rtcp_hdr_t) *rtcp_hdr = (zrtp_rtcp_hdr_t*)packet->body;
|
||||
|
||||
/* Fill RTCP Header according to the specification */
|
||||
rtcp_hdr->rc = 0;
|
||||
rtcp_hdr->version = 2;
|
||||
rtcp_hdr->ssrc = stream->ssrc;
|
||||
|
||||
/* Get RTP body from PGP words lists. Put RTCP marker at the beginning */
|
||||
zrtp_memcpy(packet->body + sizeof(zrtp_rtcp_hdr_t), "RTCP", 4);
|
||||
word = (char*)( i ? hash_word_list_odd[packets_counter % 256] : hash_word_list_even[packets_counter % 256]);
|
||||
|
||||
zrtp_memcpy(packet->body + sizeof(zrtp_rtcp_hdr_t) + 4, word, (uint32_t)strlen(word));
|
||||
packet->length = sizeof(zrtp_rtcp_hdr_t) + (uint32_t)strlen(word) + 4;
|
||||
/* RTCP packets sould be 32 byes aligned */
|
||||
packet->length += (packet->length % 4) ? (4 - packet->length % 4) : 0;
|
||||
|
||||
/* Process RTCP control with libzrtp */
|
||||
s = zrtp_process_rtcp(stream->zrtp_stream, packet->body, &packet->length);
|
||||
}
|
||||
|
||||
/* Handle zrtp_process_xxx() instructions */
|
||||
switch (s)
|
||||
{
|
||||
/* Put the packet to the queue ==> send packet to the other side pear */
|
||||
case zrtp_status_ok: {
|
||||
ZRTP_LOG(3, (_ZTU_,"Outgoing: (%s) [%p:ssrc=%u] OUTPUT. <%s%s> encrypted %d bytes.\n",
|
||||
zrtp_log_state2str(stream->zrtp_stream->state), stream->zrtp_stream, stream->ssrc, packet->is_rtp ? "" : "RTCP", word, packet->length));
|
||||
zrtp_test_queue_push(test_global.queue, elem);
|
||||
} break;
|
||||
|
||||
case zrtp_status_drop: {
|
||||
ZRTP_LOG(1, (_ZTU_,"Outgoing: (%s) [%p:ssrc=%u] OUTPUT DROPPED.\n",
|
||||
zrtp_log_state2str(stream->zrtp_stream->state), stream->zrtp_stream, stream->ssrc));
|
||||
} break;
|
||||
|
||||
case zrtp_status_fail: {
|
||||
ZRTP_LOG(1, (_ZTU_,"Outgoing: (%s) [%p:ssrc=%u] ENCRYPT FAILED.\n",
|
||||
zrtp_log_state2str(stream->zrtp_stream->state), stream->zrtp_stream, stream->ssrc));
|
||||
} break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (zrtp_status_ok != s) {
|
||||
zrtp_sys_free(packet);
|
||||
}
|
||||
|
||||
} /* for (every stream within the session) */
|
||||
} /* while is running */
|
||||
|
||||
#if (ZRTP_PLATFORM == ZP_WIN32) || (ZRTP_PLATFORM == ZP_WINCE)
|
||||
return 0;
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static zrtp_status_t init_test_session( zrtp_test_session_t *session,
|
||||
zrtp_profile_t *zrtp_profile,
|
||||
unsigned nstreams)
|
||||
{
|
||||
unsigned i = 0;
|
||||
g_zrtp_cfg zid;
|
||||
zrtp_status_t s = zrtp_status_fail;
|
||||
|
||||
session->streams_count = nstreams;
|
||||
|
||||
/* Allocate ZRTP session */
|
||||
zrtp_randstr(zrtp_global, (unsigned char*)&zid, sizeof(g_zrtp_cfg));
|
||||
|
||||
ZRTP_LOG(3, (_ZTU_,"INITIALIZE NEW SESSION ctx=%p:\n", session));
|
||||
ZRTP_LOG(3, (_ZTU_,"---------------------------------------------------\n"));
|
||||
|
||||
s = zrtp_session_init(zrtp_global, zrtp_profile, zid, 1, &session->zrtp_session);
|
||||
if (zrtp_status_ok != s) {
|
||||
ZRTP_LOG(3, (_ZTU_,"ERROR! can't initalize ZRTP session d=%d.\n", s));
|
||||
return s;
|
||||
}
|
||||
|
||||
zrtp_session_set_userdata(session->zrtp_session, session);
|
||||
|
||||
ZRTP_LOG(3, (_ZTU_,"Attach %d ZRTP streams.\n", session->streams_count));
|
||||
/* ZRTP session is ready for use. Now it's time to attach streams to it */
|
||||
for (i=0; i<session->streams_count; i++)
|
||||
{
|
||||
zrtp_test_stream_t *stream = &session->streams[i];
|
||||
|
||||
/* Create random sequence number and ssrc for packets generation */
|
||||
zrtp_randstr(zrtp_global, (unsigned char*)&stream->seq, sizeof(stream->seq));
|
||||
zrtp_randstr(zrtp_global, (unsigned char*)&stream->ssrc, sizeof(stream->ssrc));
|
||||
|
||||
ZRTP_LOG(3, (_ZTU_,"Created stream N%d ssrc=%u seq=%d ctx=%p\n", i, stream->ssrc, stream->seq, stream));
|
||||
|
||||
/* Attach zrtp_stream to zrtp_session */
|
||||
s = zrtp_stream_attach(session->zrtp_session, &stream->zrtp_stream);
|
||||
if (zrtp_status_ok != s) {
|
||||
ZRTP_LOG(3, (_ZTU_,"ERROR! can't attach ZRTP stream.\n"));
|
||||
break;
|
||||
}
|
||||
zrtp_stream_set_userdata(stream->zrtp_stream, stream);
|
||||
stream->session = session;
|
||||
}
|
||||
|
||||
if (i != session->streams_count) {
|
||||
zrtp_session_down(session->zrtp_session);
|
||||
return zrtp_status_fail;
|
||||
}
|
||||
|
||||
return zrtp_status_ok;
|
||||
};
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
int zrtp_test_channel_create( const zrtp_test_channel_config_t* config,
|
||||
zrtp_test_channel_id_t* chan_id)
|
||||
{
|
||||
zrtp_status_t s = zrtp_status_fail;
|
||||
zrtp_test_channel_t* channel = NULL;
|
||||
unsigned streams_number = 1;
|
||||
|
||||
|
||||
/*
|
||||
* Create two connection for each side of the call.
|
||||
* They will have the same id in order to simplify calls managing.
|
||||
*/
|
||||
channel = zrtp_sys_alloc(sizeof(zrtp_test_channel_t));
|
||||
if (!channel) {
|
||||
return -1;
|
||||
}
|
||||
zrtp_memset(channel, 0, sizeof(zrtp_test_channel_t));
|
||||
|
||||
/* Generate new unique ID for the channel */
|
||||
zrtp_randstr(zrtp_global, (unsigned char*)chan_id, sizeof(zrtp_test_channel_id_t));
|
||||
|
||||
ZRTP_LOG(1, (_ZTU_,"=====> CREATE NEW CHANNEL ID=%u ctx=%p.\n", chan_id, channel));
|
||||
|
||||
/*
|
||||
* Alloacte and initalize ZRTP crypto stuffs
|
||||
*/
|
||||
do {
|
||||
zrtp_profile_t zrtp_profile;
|
||||
unsigned i = 0;
|
||||
|
||||
/*
|
||||
* Use default ZRTP configuration with slitely changes:
|
||||
* - enable "allowclear" to be able to test more scenarios
|
||||
*/
|
||||
zrtp_profile_defaults(&zrtp_profile, zrtp_global);
|
||||
zrtp_profile.allowclear = 1;
|
||||
zrtp_profile.autosecure = 1;
|
||||
|
||||
channel->ses_left.streams_count = streams_number;
|
||||
#if (ZRTP_ENABLE_TEST == 1)
|
||||
zrtp_profile.pk_schemes[0] = ZRTP_PKTYPE_EC384P;
|
||||
zrtp_profile.pk_schemes[1] = ZRTP_PKTYPE_DH3072;
|
||||
zrtp_profile.pk_schemes[2] = ZRTP_PKTYPE_MULT;
|
||||
zrtp_profile.pk_schemes[3] = 0;
|
||||
#endif
|
||||
s = init_test_session(&channel->ses_left, &zrtp_profile, 1);
|
||||
if (zrtp_status_ok != s) {
|
||||
break;
|
||||
}
|
||||
channel->ses_left.channel = channel;
|
||||
|
||||
channel->ses_right.streams_count = streams_number;
|
||||
#if (ZRTP_ENABLE_TEST == 1)
|
||||
zrtp_profile.autosecure = 1;
|
||||
zrtp_profile.pk_schemes[0] = ZRTP_PKTYPE_EC384P;
|
||||
zrtp_profile.pk_schemes[1] = ZRTP_PKTYPE_DH2048;
|
||||
zrtp_profile.pk_schemes[2] = ZRTP_PKTYPE_DH3072;
|
||||
zrtp_profile.pk_schemes[3] = ZRTP_PKTYPE_MULT;
|
||||
zrtp_profile.pk_schemes[4] = 0;
|
||||
#endif
|
||||
s = init_test_session(&channel->ses_right, &zrtp_profile, 1);
|
||||
if (zrtp_status_ok != s) {
|
||||
break;
|
||||
}
|
||||
channel->ses_right.channel = channel;
|
||||
|
||||
/* Make cross-references to allow left stream to communicate with the right one. */
|
||||
for (i=0; i<streams_number; i++) {
|
||||
channel->ses_left.streams[i].peer_ssrc = channel->ses_right.streams[i].ssrc;
|
||||
channel->ses_right.streams[i].peer_ssrc = channel->ses_left.streams[i].ssrc;
|
||||
}
|
||||
} while (0);
|
||||
|
||||
if (zrtp_status_ok != s) {
|
||||
zrtp_sys_free(channel);
|
||||
} else {
|
||||
channel->id = *chan_id;
|
||||
zrtp_mutex_lock(test_global.channels_protector);
|
||||
mlist_add(&test_global.channels_head, &channel->_mlist);
|
||||
zrtp_mutex_unlock(test_global.channels_protector);
|
||||
}
|
||||
|
||||
test_global.channels_count++;
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static void down_test_session(zrtp_test_session_t *session)
|
||||
{
|
||||
zrtp_session_down(session->zrtp_session);
|
||||
};
|
||||
|
||||
int zrtp_test_channel_delete(zrtp_test_channel_id_t chan_id)
|
||||
{
|
||||
zrtp_test_channel_t* channel = find_channel_by_index(chan_id);
|
||||
if (channel)
|
||||
{
|
||||
test_global.channels_count--;
|
||||
|
||||
zrtp_mutex_lock(test_global.channels_protector);
|
||||
mlist_del(&channel->_mlist);
|
||||
zrtp_mutex_unlock(test_global.channels_protector);
|
||||
|
||||
down_test_session(&channel->ses_left);
|
||||
down_test_session(&channel->ses_right);
|
||||
|
||||
zrtp_sys_free(channel);
|
||||
return 0;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
typedef enum
|
||||
{
|
||||
TEST_ACTION_START = 0,
|
||||
TEST_ACTION_SECURE,
|
||||
TEST_ACTION_CLEAR,
|
||||
TEST_ACTION_STOP
|
||||
} zrtp_test_session_action_t;
|
||||
|
||||
static void test_session_do_action(zrtp_test_session_t *session, zrtp_test_session_action_t action)
|
||||
{
|
||||
unsigned i = 0;
|
||||
if (session->zrtp_session)
|
||||
{
|
||||
for (i=0; i<session->streams_count; i++) {
|
||||
switch (action) {
|
||||
case TEST_ACTION_START:
|
||||
{
|
||||
char buff[65];
|
||||
ZRTP_LOG(1, (_ZTU_,"=====> START TEST SESSION ID=%u ctx=%p.\n", session->channel->id, session->channel));
|
||||
zrtp_stream_start(session->streams[i].zrtp_stream, zrtp_ntoh32(session->streams[i].ssrc));
|
||||
zrtp_signaling_hash_get(session->streams[i].zrtp_stream, buff, sizeof(buff));
|
||||
break;
|
||||
}
|
||||
case TEST_ACTION_STOP:
|
||||
ZRTP_LOG(1, (_ZTU_,"=====> STOP TEST SESSION ID=%u ctx=%p.\n", session->channel->id, session->channel));
|
||||
zrtp_stream_stop(session->streams[i].zrtp_stream);
|
||||
break;
|
||||
case TEST_ACTION_SECURE:
|
||||
ZRTP_LOG(1, (_ZTU_,"=====> SECURE TEST SESSION ID=%u ctx=%p.\n", session->channel->id, session->channel));
|
||||
zrtp_stream_secure(session->streams[i].zrtp_stream);
|
||||
break;
|
||||
case TEST_ACTION_CLEAR:
|
||||
ZRTP_LOG(1, (_ZTU_,"=====> CLEAR TEST SESSION ID=%u ctx=%p.\n", session->channel->id, session->channel));
|
||||
zrtp_stream_clear(session->streams[i].zrtp_stream);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static int test_channel_do_action(zrtp_test_channel_id_t chan_id, zrtp_test_session_action_t action)
|
||||
{
|
||||
zrtp_test_channel_t* channel = find_channel_by_index(chan_id);
|
||||
if (channel) {
|
||||
test_session_do_action(&channel->ses_left, action);
|
||||
test_session_do_action(&channel->ses_right, action);
|
||||
return 0;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int zrtp_test_channel_start(zrtp_test_channel_id_t chan_id) {
|
||||
return test_channel_do_action(chan_id, TEST_ACTION_START);
|
||||
}
|
||||
|
||||
int zrtp_test_channel_secure(zrtp_test_channel_id_t chan_id) {
|
||||
return test_channel_do_action(chan_id, TEST_ACTION_SECURE);
|
||||
}
|
||||
|
||||
int zrtp_test_channel_clear(zrtp_test_channel_id_t chan_id) {
|
||||
return test_channel_do_action(chan_id, TEST_ACTION_CLEAR);
|
||||
}
|
||||
|
||||
int zrtp_test_channel_stop(zrtp_test_channel_id_t chan_id) {
|
||||
return test_channel_do_action(chan_id, TEST_ACTION_STOP);
|
||||
}
|
||||
|
||||
|
||||
/*============================================================================*/
|
||||
/* Test Routine */
|
||||
/*============================================================================*/
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int start_processors(int count)
|
||||
{
|
||||
int32_t i;
|
||||
for (i = 0; i<count; i++)
|
||||
{
|
||||
if (0 != zrtp_thread_create(process_incoming, NULL)) {
|
||||
return -1;
|
||||
}
|
||||
if (0 != zrtp_thread_create(process_outgoing, NULL)) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int zrtp_test_zrtp_init()
|
||||
{
|
||||
int result = -1;
|
||||
zrtp_status_t s = zrtp_status_ok;
|
||||
zrtp_config_t zrtp_config;
|
||||
|
||||
ZRTP_LOG(1, (_ZTU_,"=====>Start ZRTP Test-Unite Core initalization.\n"));
|
||||
|
||||
zrtp_memset(&test_global, 0, sizeof(test_global));
|
||||
|
||||
ZRTP_LOG(1, (_ZTU_,"Create internal components...\n"));
|
||||
do {
|
||||
/* Create global objects: channels list and communication queue */
|
||||
init_mlist(&test_global.channels_head);
|
||||
|
||||
s = zrtp_mutex_init(&test_global.channels_protector);
|
||||
if (zrtp_status_ok != s) {
|
||||
ZRTP_LOG(1, (_ZTU_,"ERROR! Can't create channels protector %d\n", s));
|
||||
break;
|
||||
}
|
||||
|
||||
s = zrtp_test_queue_create(&test_global.queue);
|
||||
if (zrtp_status_ok != s) {
|
||||
ZRTP_LOG(1, (_ZTU_,"ERROR! Can't create global queue: %s\n", s));
|
||||
break;
|
||||
}
|
||||
|
||||
/* Start several threads to process test zrtp channels */
|
||||
test_global.is_running = 1;
|
||||
result = start_processors(ZRTP_TEST_STREAMS_COUNT);
|
||||
if (0 != result) {
|
||||
break;
|
||||
}
|
||||
|
||||
ZRTP_LOG(1, (_ZTU_,"Configuring and Initalizing ZRTP engine...\n"));
|
||||
/* Reset global values to defaults */
|
||||
test_global.is_log_enabled = 1;
|
||||
test_global.packets_rate = 500;
|
||||
test_global.channels_count = 0;
|
||||
|
||||
/* Initalize ZRTP Engine */
|
||||
zrtp_config_defaults(&zrtp_config);
|
||||
zrtp_config.lic_mode = ZRTP_LICENSE_MODE_ACTIVE;
|
||||
zrtp_memcpy(zrtp_config.client_id, "ZRTP Test Unite!", 16);
|
||||
|
||||
zrtp_config.cb.event_cb.on_zrtp_secure = on_zrtp_secure;
|
||||
zrtp_config.cb.event_cb.on_zrtp_security_event = on_zrtp_security_event;
|
||||
zrtp_config.cb.event_cb.on_zrtp_protocol_event = on_zrtp_protocol_event;
|
||||
zrtp_config.cb.misc_cb.on_send_packet = on_send_packet;
|
||||
|
||||
s = zrtp_init(&zrtp_config, &zrtp_global);
|
||||
if (zrtp_status_ok != s) {
|
||||
ZRTP_LOG(1, (_ZTU_,"ERROR! zrtp_init() failed with status=%d.\n", s));
|
||||
break;
|
||||
}
|
||||
|
||||
result = 0;
|
||||
} while (0);
|
||||
|
||||
if (0 != result) {
|
||||
if (!test_global.channels_protector) {
|
||||
zrtp_mutex_destroy(test_global.channels_protector);
|
||||
}
|
||||
if (!test_global.queue) {
|
||||
zrtp_test_queue_destroy(test_global.queue);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
int zrtp_test_zrtp_down()
|
||||
{
|
||||
mlist_t* node = NULL,* tmp = NULL;
|
||||
|
||||
ZRTP_LOG(1, (_ZTU_,"=====> Destroying ZRTP Test Application:\n"));
|
||||
ZRTP_LOG(1, (_ZTU_,"Stop all running threads.\n"));
|
||||
|
||||
/* Stop Main Processing Loop */
|
||||
test_global.is_running = 0;
|
||||
|
||||
ZRTP_LOG(1, (_ZTU_,"Destroy all active connections.\n"));
|
||||
/* Stop and destroy all active sessions */
|
||||
zrtp_mutex_lock(test_global.channels_protector);
|
||||
mlist_for_each_safe(node, tmp, &test_global.channels_head) {
|
||||
zrtp_test_channel_t* result = (zrtp_test_channel_t*) mlist_get_struct(zrtp_test_channel_t, _mlist, node);
|
||||
zrtp_test_channel_delete(result->id);
|
||||
}
|
||||
zrtp_mutex_unlock(test_global.channels_protector);
|
||||
|
||||
ZRTP_LOG(1, (_ZTU_,"Destroy ZRTP Engine.\n"));
|
||||
/* Destroy libzrtp and all utility components */
|
||||
zrtp_down(zrtp_global);
|
||||
|
||||
if (!test_global.channels_protector) {
|
||||
zrtp_mutex_destroy(test_global.channels_protector);
|
||||
}
|
||||
if (!test_global.queue) {
|
||||
zrtp_test_queue_destroy(test_global.queue);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
zrtp_test_channel_t* find_channel_by_index(zrtp_test_channel_id_t chan_id)
|
||||
{
|
||||
unsigned char is_found = 0;
|
||||
mlist_t* node = NULL,* tmp = NULL;
|
||||
zrtp_test_channel_t* result = NULL;
|
||||
|
||||
zrtp_mutex_lock(test_global.channels_protector);
|
||||
mlist_for_each_safe(node, tmp, &test_global.channels_head) {
|
||||
result = (zrtp_test_channel_t*) mlist_get_struct(zrtp_test_channel_t, _mlist, node);
|
||||
if (result->id == chan_id) {
|
||||
is_found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
zrtp_mutex_unlock(test_global.channels_protector);
|
||||
|
||||
return (is_found) ? result : NULL;
|
||||
}
|
||||
|
||||
zrtp_test_channel_t* find_channel_with_closest_index(zrtp_test_channel_id_t chan_id)
|
||||
{
|
||||
unsigned char is_found = 0;
|
||||
mlist_t* node = NULL,* tmp = NULL;
|
||||
zrtp_test_channel_t* result = NULL;
|
||||
zrtp_test_channel_t* left = NULL;
|
||||
|
||||
zrtp_mutex_lock(test_global.channels_protector);
|
||||
mlist_for_each_safe(node, tmp, &test_global.channels_head) {
|
||||
result = (zrtp_test_channel_t*) mlist_get_struct(zrtp_test_channel_t, _mlist, node);
|
||||
if (result->id > chan_id) {
|
||||
is_found = 1;
|
||||
break;
|
||||
} else {
|
||||
left = result;
|
||||
}
|
||||
}
|
||||
zrtp_mutex_unlock(test_global.channels_protector);
|
||||
|
||||
return (is_found) ? result : left;
|
||||
}
|
||||
|
||||
zrtp_test_stream_t* find_peer_stream_by_ssrc(uint32_t ssrc)
|
||||
{
|
||||
unsigned char is_found = 0;
|
||||
mlist_t *node = NULL, *tmp = NULL;
|
||||
zrtp_test_stream_t *result = NULL;
|
||||
|
||||
zrtp_mutex_lock(test_global.channels_protector);
|
||||
mlist_for_each_safe(node, tmp, &test_global.channels_head)
|
||||
{
|
||||
zrtp_test_channel_t *channel = (zrtp_test_channel_t*) mlist_get_struct(zrtp_test_channel_t, _mlist, node);
|
||||
unsigned i = 0;
|
||||
|
||||
for (i=0; i<channel->ses_left.streams_count; i++) {
|
||||
zrtp_test_stream_t *stream = &channel->ses_left.streams[i];
|
||||
if (stream->ssrc == ssrc) {
|
||||
is_found = 1;
|
||||
result = &channel->ses_right.streams[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (i=0; i<channel->ses_right.streams_count; i++) {
|
||||
zrtp_test_stream_t *stream = &channel->ses_right.streams[i];
|
||||
if (stream->ssrc == ssrc) {
|
||||
is_found = 1;
|
||||
result = &channel->ses_left.streams[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (is_found) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
zrtp_mutex_unlock(test_global.channels_protector);
|
||||
|
||||
return (is_found) ? result : NULL;
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* 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>
|
||||
*/
|
||||
|
||||
#ifndef __ZRTP_TEST_CORE_H__
|
||||
#define __ZRTP_TEST_CORE_H__
|
||||
|
||||
#include "zrtp.h"
|
||||
|
||||
extern zrtp_global_t* zrtp_global;
|
||||
|
||||
typedef uint32_t zrtp_test_channel_id_t;
|
||||
|
||||
typedef struct zrtp_test_channel_config
|
||||
{
|
||||
unsigned streams_count;
|
||||
unsigned char is_autosecure;
|
||||
unsigned char is_preshared;
|
||||
} zrtp_test_channel_config_t;
|
||||
|
||||
void zrtp_test_crypto(zrtp_global_t* zrtp);
|
||||
|
||||
int zrtp_test_zrtp_init();
|
||||
int zrtp_test_zrtp_down();
|
||||
|
||||
int zrtp_test_channel_create( const zrtp_test_channel_config_t* config,
|
||||
zrtp_test_channel_id_t* chan_id);
|
||||
int zrtp_test_channel_delete(zrtp_test_channel_id_t chan_id);
|
||||
int zrtp_test_channel_start(zrtp_test_channel_id_t chan_id);
|
||||
int zrtp_test_channel_secure(zrtp_test_channel_id_t chan_id);
|
||||
int zrtp_test_channel_clear(zrtp_test_channel_id_t chan_id);
|
||||
|
||||
#endif /*__ZRTP_TEST_CORE_H__*/
|
||||
@@ -0,0 +1,447 @@
|
||||
/*
|
||||
* 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_ "libzrtp_test"
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void cipher_test(zrtp_global_t *zrtp)
|
||||
{
|
||||
zrtp_cipher_t *cipher = zrtp_comp_find(ZRTP_CC_CIPHER, ZRTP_CIPHER_AES128, zrtp);
|
||||
if (NULL == cipher) {
|
||||
ZRTP_LOG(1, (_ZTU_,"ERROR! can't find ZRTP_CIPHER_AES128 cipher component\n"));
|
||||
} else {
|
||||
cipher->self_test(cipher, ZRTP_CIPHER_MODE_CFB);
|
||||
cipher->self_test(cipher, ZRTP_CIPHER_MODE_CTR);
|
||||
}
|
||||
|
||||
cipher = zrtp_comp_find(ZRTP_CC_CIPHER, ZRTP_CIPHER_AES256, zrtp);
|
||||
if (NULL == cipher) {
|
||||
ZRTP_LOG(1, (_ZTU_,"ERROR! can't find ZRTP_CIPHER_AES256 cipher component\n"));
|
||||
} else {
|
||||
cipher->self_test(cipher, ZRTP_CIPHER_MODE_CFB);
|
||||
cipher->self_test(cipher, ZRTP_CIPHER_MODE_CTR);
|
||||
}
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static zrtp_status_t hash_test(zrtp_global_t *zrtp)
|
||||
{
|
||||
zrtp_hash_t *hash = zrtp_comp_find(ZRTP_CC_HASH, ZRTP_SRTP_HASH_HMAC_SHA1, zrtp);
|
||||
if (NULL == hash) {
|
||||
ZRTP_LOG(1, (_ZTU_,"ERROR! can't find ZRTP_SRTP_HASH_HMAC_SHA1 component\n"));
|
||||
} else {
|
||||
hash->hash_self_test(hash);
|
||||
hash->hmac_self_test(hash);
|
||||
}
|
||||
|
||||
hash = zrtp_comp_find(ZRTP_CC_HASH, ZRTP_HASH_SHA256, zrtp);
|
||||
if (NULL == hash) {
|
||||
ZRTP_LOG(1, (_ZTU_,"ERROR! can't find ZRTP_HASH_SHA256 component\n"));
|
||||
} else {
|
||||
hash->hash_self_test(hash);
|
||||
hash->hmac_self_test(hash);
|
||||
}
|
||||
|
||||
hash = zrtp_comp_find(ZRTP_CC_HASH, ZRTP_HASH_SHA384, zrtp);
|
||||
if (NULL == hash) {
|
||||
ZRTP_LOG(1, (_ZTU_,"ERROR! can't find ZRTP_HASH_SHA384 component\n"));
|
||||
} else {
|
||||
hash->hash_self_test(hash);
|
||||
hash->hmac_self_test(hash);
|
||||
}
|
||||
|
||||
return zrtp_status_ok;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static zrtp_status_t dh_test(zrtp_global_t *zrtp)
|
||||
{
|
||||
zrtp_pk_scheme_t *pks = zrtp_comp_find(ZRTP_CC_PKT, ZRTP_PKTYPE_DH2048, zrtp);
|
||||
if (!pks) {
|
||||
ZRTP_LOG(1, (_ZTU_,"ERROR! can't find ZRTP_PKTYPE_DH2048 component\n"));
|
||||
} else {
|
||||
pks->self_test(pks);
|
||||
}
|
||||
|
||||
pks = zrtp_comp_find(ZRTP_CC_PKT, ZRTP_PKTYPE_DH3072, zrtp);
|
||||
if (!pks) {
|
||||
ZRTP_LOG(1, (_ZTU_,"ERROR! can't find ZRTP_PKTYPE_DH3072 component\n"));
|
||||
} else {
|
||||
pks->self_test(pks);
|
||||
}
|
||||
|
||||
return zrtp_status_ok;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static zrtp_status_t ecdh_test(zrtp_global_t *zrtp)
|
||||
{
|
||||
zrtp_pk_scheme_t *pks = zrtp_comp_find(ZRTP_CC_PKT, ZRTP_PKTYPE_EC256P, zrtp);
|
||||
if (!pks) {
|
||||
ZRTP_LOG(1, (_ZTU_,"ERROR! can't find ZRTP_PKTYPE_EC256P component\n"));
|
||||
} else {
|
||||
pks->self_test(pks);
|
||||
}
|
||||
|
||||
pks = zrtp_comp_find(ZRTP_CC_PKT, ZRTP_PKTYPE_EC384P, zrtp);
|
||||
if (!pks) {
|
||||
ZRTP_LOG(1, (_ZTU_,"ERROR! can't find ZRTP_PKTYPE_EC384P component\n"));
|
||||
} else {
|
||||
pks->self_test(pks);
|
||||
}
|
||||
|
||||
pks = zrtp_comp_find(ZRTP_CC_PKT, ZRTP_PKTYPE_EC521P, zrtp);
|
||||
if (!pks) {
|
||||
ZRTP_LOG(1, (_ZTU_,"ERROR! can't find ZRTP_PKTYPE_EC521P component\n"));
|
||||
} else {
|
||||
pks->self_test(pks);
|
||||
}
|
||||
|
||||
return zrtp_status_ok;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#if (defined(ZRTP_USE_EXTERN_SRTP) && (ZRTP_USE_EXTERN_SRTP == 1))
|
||||
#else
|
||||
|
||||
static uint8_t dk_master_key[16] = {
|
||||
0xE1, 0xF9, 0x7A, 0x0D, 0x3E, 0x01, 0x8B, 0xE0,
|
||||
0xD6, 0x4F, 0xA3, 0x2C, 0x06, 0xDE, 0x41, 0x39
|
||||
};
|
||||
|
||||
static uint8_t dk_master_salt[14] = {
|
||||
0x0E, 0xC6, 0x75, 0xAD, 0x49, 0x8A, 0xFE, 0xEB,
|
||||
0xB6, 0x96, 0x0B, 0x3A, 0xAB, 0xE6
|
||||
};
|
||||
|
||||
|
||||
static uint8_t dk_cipher_key[16] = {
|
||||
0xC6, 0x1E, 0x7A, 0x93, 0x74, 0x4F, 0x39, 0xEE,
|
||||
0x10, 0x73, 0x4A, 0xFE, 0x3F, 0xF7, 0xA0, 0x87
|
||||
};
|
||||
|
||||
static uint8_t dk_cipher_salt[14] = {
|
||||
0x30, 0xCB, 0xBC, 0x08, 0x86, 0x3D, 0x8C, 0x85,
|
||||
0xD4, 0x9D, 0xB3, 0x4A, 0x9A, 0xE1
|
||||
};
|
||||
|
||||
static uint8_t dk_auth_key[94] = {
|
||||
0xCE, 0xBE, 0x32, 0x1F, 0x6F, 0xF7, 0x71, 0x6B,
|
||||
0x6F, 0xD4, 0xAB, 0x49, 0xAF, 0x25, 0x6A, 0x15,
|
||||
0x6D, 0x38, 0xBA, 0xA4, 0x8F, 0x0A, 0x0A, 0xCF,
|
||||
0x3C, 0x34, 0xE2, 0x35, 0x9E, 0x6C, 0xDB, 0xCE,
|
||||
0xE0, 0x49, 0x64, 0x6C, 0x43, 0xD9, 0x32, 0x7A,
|
||||
0xD1, 0x75, 0x57, 0x8E, 0xF7, 0x22, 0x70, 0x98,
|
||||
0x63, 0x71, 0xC1, 0x0C, 0x9A, 0x36, 0x9A, 0xC2,
|
||||
0xF9, 0x4A, 0x8C, 0x5F, 0xBC, 0xDD, 0xDC, 0x25,
|
||||
0x6D, 0x6E, 0x91, 0x9A, 0x48, 0xB6, 0x10, 0xEF,
|
||||
0x17, 0xC2, 0x04, 0x1E, 0x47, 0x40, 0x35, 0x76,
|
||||
0x6B, 0x68, 0x64, 0x2C, 0x59, 0xBB, 0xFC, 0x2F,
|
||||
0x34, 0xDB, 0x60, 0xDB, 0xDF, 0xB2
|
||||
};
|
||||
|
||||
extern zrtp_dk_ctx *zrtp_dk_init(zrtp_cipher_t *cipher, zrtp_stringn_t *key, zrtp_stringn_t *salt);
|
||||
extern zrtp_status_t zrtp_derive_key(zrtp_dk_ctx *ctx, zrtp_srtp_prf_label label, zrtp_stringn_t *result_key);
|
||||
extern void zrtp_dk_deinit(zrtp_dk_ctx *ctx);
|
||||
|
||||
zrtp_status_t hex_cmp(uint8_t *a, uint8_t *b, uint32_t len)
|
||||
{
|
||||
uint32_t i;
|
||||
zrtp_status_t res = zrtp_status_ok;
|
||||
for (i = 0; i<len; i++) {
|
||||
if (a[i] != b[i]) {
|
||||
res = zrtp_status_fail;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
zrtp_status_t dk_test(zrtp_global_t *zrtp)
|
||||
{
|
||||
zrtp_status_t res;
|
||||
zrtp_string16_t master_key, master_salt, cipher_key, cipher_salt;
|
||||
zrtp_string128_t auth_key;
|
||||
zrtp_dk_ctx *ctx;
|
||||
|
||||
zrtp_cipher_t *cipher = zrtp_comp_find(ZRTP_CC_CIPHER, ZRTP_CIPHER_AES128, zrtp);
|
||||
|
||||
if(NULL == cipher){
|
||||
return zrtp_status_fail;
|
||||
}
|
||||
|
||||
master_key.length = master_key.max_length = 16;
|
||||
zrtp_memcpy(master_key.buffer, dk_master_key, 16);
|
||||
|
||||
master_salt.length = 14;
|
||||
master_salt.max_length = 16;
|
||||
zrtp_memcpy(master_salt.buffer, dk_master_salt, 14);
|
||||
|
||||
|
||||
ctx = zrtp_dk_init(cipher, (zrtp_stringn_t*)&master_key, (zrtp_stringn_t*)&master_salt);
|
||||
if(NULL == ctx){
|
||||
return zrtp_status_fail;
|
||||
}
|
||||
|
||||
cipher_key.length = 16;
|
||||
cipher_key.max_length = 16;
|
||||
|
||||
zrtp_derive_key(ctx, label_rtp_encryption, (zrtp_stringn_t*)&cipher_key);
|
||||
res = hex_cmp((uint8_t*)cipher_key.buffer, dk_cipher_key, cipher_key.length);
|
||||
ZRTP_LOG(3, (_ZTU_,"cipher key check...%s\n", zrtp_status_ok==res?"OK":"FAIL"));
|
||||
|
||||
|
||||
cipher_salt.length = 14;
|
||||
cipher_salt.max_length = 16;
|
||||
|
||||
zrtp_derive_key(ctx, label_rtp_salt, (zrtp_stringn_t*)&cipher_salt);
|
||||
res = hex_cmp((uint8_t*)cipher_salt.buffer, dk_cipher_salt, cipher_salt.length);
|
||||
ZRTP_LOG(3, (_ZTU_,"cipher salt check...%s\n", zrtp_status_ok==res?"OK":"FAIL"));
|
||||
|
||||
|
||||
auth_key.length = 94;
|
||||
auth_key.max_length = 128;
|
||||
|
||||
zrtp_derive_key(ctx, label_rtp_msg_auth, (zrtp_stringn_t*)&auth_key);
|
||||
res = hex_cmp((uint8_t*)auth_key.buffer, dk_auth_key, auth_key.length);
|
||||
ZRTP_LOG(3, (_ZTU_,"auth key check...%s\n", zrtp_status_ok==res?"OK":"FAIL"));
|
||||
|
||||
zrtp_dk_deinit(ctx);
|
||||
|
||||
return zrtp_status_ok;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#define TEST_MAP_WIDTH 64
|
||||
#if TEST_MAP_WIDTH%8
|
||||
# define TEST_MAP_WIDTH_BYTES TEST_MAP_WIDTH/8+1
|
||||
#else
|
||||
# define TEST_MAP_WIDTH_BYTES TEST_MAP_WIDTH/8
|
||||
#endif
|
||||
|
||||
#define FIRST_TEST_MAP_INIT_WIDTH 24
|
||||
|
||||
extern zrtp_rp_node_t *get_rp_node_non_lock(zrtp_rp_ctx_t *ctx, uint8_t direction, uint32_t ssrc);
|
||||
extern zrtp_rp_node_t *add_rp_node(zrtp_srtp_ctx_t *srtp_ctx, zrtp_rp_ctx_t *ctx, uint8_t direction, uint32_t ssrc);
|
||||
extern zrtp_status_t zrtp_srtp_rp_check(zrtp_srtp_rp_t *srtp_rp, zrtp_rtp_info_t *packet);
|
||||
extern zrtp_status_t zrtp_srtp_rp_add(zrtp_srtp_rp_t *srtp_rp, zrtp_rtp_info_t *packet);
|
||||
|
||||
void print_map(uint8_t *map, int width_bytes)
|
||||
{
|
||||
int i;
|
||||
for(i=width_bytes-1; i >= 0; i--) {
|
||||
ZRTP_LOGC(3, ("%i%i%i%i%i%i%i%i",
|
||||
zrtp_bitmap_get_bit(map, 8*i+7),
|
||||
zrtp_bitmap_get_bit(map, 8*i+6),
|
||||
zrtp_bitmap_get_bit(map, 8*i+5),
|
||||
zrtp_bitmap_get_bit(map, 8*i+4),
|
||||
zrtp_bitmap_get_bit(map, 8*i+3),
|
||||
zrtp_bitmap_get_bit(map, 8*i+2),
|
||||
zrtp_bitmap_get_bit(map, 8*i+1),
|
||||
zrtp_bitmap_get_bit(map, 8*i+0)));
|
||||
}
|
||||
ZRTP_LOG(3, (_ZTU_, "\n"));
|
||||
}
|
||||
|
||||
void init_random_map(uint8_t *map, int width, zrtp_global_t *zrtp)
|
||||
{
|
||||
int i;
|
||||
for(i=0; i<width; i++) {
|
||||
uint32_t rnd = 0;
|
||||
zrtp_randstr(zrtp, (uint8_t*)&rnd, sizeof(rnd));
|
||||
if(rnd%10 < 5) {
|
||||
zrtp_bitmap_set_bit(map, i);
|
||||
} else {
|
||||
zrtp_bitmap_clear_bit(map, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void inject_from_map( zrtp_srtp_global_t *srtp_global,
|
||||
uint32_t ssrc,
|
||||
uint8_t *src_map, uint8_t *dst_map, int width)
|
||||
{
|
||||
zrtp_rp_node_t *rp_node;
|
||||
int i;
|
||||
zrtp_rtp_info_t pkt;
|
||||
|
||||
rp_node = get_rp_node_non_lock(srtp_global->rp_ctx, RP_INCOMING_DIRECTION, ssrc);
|
||||
if (NULL == rp_node) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (i=0; i< width; i++) {
|
||||
if (1 == zrtp_bitmap_get_bit(src_map, i)) {
|
||||
pkt.seq = i;
|
||||
if (zrtp_status_ok == zrtp_srtp_rp_check(&rp_node->rtp_rp, &pkt)) {
|
||||
zrtp_bitmap_set_bit(dst_map, i);
|
||||
zrtp_srtp_rp_add(&rp_node->rtp_rp, &pkt);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int srtp_replay_protection_test(zrtp_global_t *zrtp)
|
||||
{
|
||||
int res = 0;
|
||||
uint32_t ssrc = 1;
|
||||
int i = 0;
|
||||
uint8_t test_map[TEST_MAP_WIDTH_BYTES];
|
||||
uint8_t result_map[TEST_MAP_WIDTH_BYTES];
|
||||
uint8_t tmp_window[ZRTP_SRTP_WINDOW_WIDTH_BYTES];
|
||||
uint32_t tmp_seq;
|
||||
int delta, shift;
|
||||
|
||||
zrtp_rp_node_t *rp_node;
|
||||
zrtp_srtp_global_t *srtp = zrtp->srtp_global;
|
||||
|
||||
rp_node = add_rp_node(NULL, srtp->rp_ctx, RP_INCOMING_DIRECTION, ssrc);
|
||||
if (NULL == rp_node) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i=0; i< TEST_MAP_WIDTH_BYTES; i++) {
|
||||
test_map[i] = 0;
|
||||
result_map[i] = 0;
|
||||
}
|
||||
/*
|
||||
* 1st test
|
||||
* ----------------------------------------------------------------------
|
||||
*/
|
||||
init_random_map(test_map, FIRST_TEST_MAP_INIT_WIDTH, zrtp);
|
||||
inject_from_map(srtp, ssrc, test_map, result_map, TEST_MAP_WIDTH);
|
||||
|
||||
ZRTP_LOG(3, (_ZTU_,"1st test. Wnd[%i]...\n", ZRTP_SRTP_WINDOW_WIDTH));
|
||||
|
||||
tmp_seq = rp_node->rtp_rp.seq;
|
||||
for (i=0; i<ZRTP_SRTP_WINDOW_WIDTH_BYTES; i++) {
|
||||
tmp_window[i] = rp_node->rtp_rp.window[i];
|
||||
}
|
||||
|
||||
delta = tmp_seq-ZRTP_SRTP_WINDOW_WIDTH + 1;
|
||||
if (delta > 0) {
|
||||
ZRTP_LOG(3, (_ZTU_,"after wnd: (%i;0]\n", delta));
|
||||
ZRTP_LOG(3, (_ZTU_,"inside wnd: [%i;%i]\n", tmp_seq, delta));
|
||||
} else {
|
||||
ZRTP_LOG(3, (_ZTU_,"after wnd: (0;0)\n"));
|
||||
ZRTP_LOG(3, (_ZTU_,"inside wnd: [%i;0]\n", tmp_seq));
|
||||
}
|
||||
|
||||
ZRTP_LOG(3, (_ZTU_,"before wnd: [%i;%i)\n", TEST_MAP_WIDTH-1, tmp_seq));
|
||||
|
||||
ZRTP_LOG(3, (_ZTU_,"Test map: "));
|
||||
print_map(test_map, TEST_MAP_WIDTH_BYTES);
|
||||
|
||||
ZRTP_LOG(3, (_ZTU_,"Res map: "));
|
||||
print_map(result_map, TEST_MAP_WIDTH_BYTES);
|
||||
|
||||
shift = TEST_MAP_WIDTH;
|
||||
shift -= rp_node->rtp_rp.seq + 1;
|
||||
|
||||
ZRTP_LOG(3, (_ZTU_,"Window : "));
|
||||
for(i=shift; i > 0; i--){
|
||||
ZRTP_LOGC(3, (" "));
|
||||
}
|
||||
print_map(rp_node->rtp_rp.window, ZRTP_SRTP_WINDOW_WIDTH_BYTES);
|
||||
|
||||
/*
|
||||
* 2nd test
|
||||
* ----------------------------------------------------------------------
|
||||
*/
|
||||
for(i=0; i< TEST_MAP_WIDTH_BYTES; i++){
|
||||
test_map[i] = 0;
|
||||
result_map[i] = 0;
|
||||
}
|
||||
|
||||
init_random_map(test_map, TEST_MAP_WIDTH, zrtp);
|
||||
inject_from_map(srtp, ssrc, test_map, result_map, TEST_MAP_WIDTH);
|
||||
|
||||
ZRTP_LOG(3, (_ZTU_,"2nd test. Wnd[%i]...\n", ZRTP_SRTP_WINDOW_WIDTH));
|
||||
ZRTP_LOG(3, (_ZTU_,"Test map: "));
|
||||
print_map(test_map, TEST_MAP_WIDTH_BYTES);
|
||||
|
||||
ZRTP_LOG(3, (_ZTU_,"Res map: "));
|
||||
print_map(result_map, TEST_MAP_WIDTH_BYTES);
|
||||
|
||||
shift = TEST_MAP_WIDTH;
|
||||
shift -= rp_node->rtp_rp.seq + 1;
|
||||
|
||||
ZRTP_LOG(3, (_ZTU_,"Window : "));
|
||||
for (i=shift; i > 0; i--) {
|
||||
//zrtp_print_log(ZRTP_LOG_DEBUG, " ");
|
||||
}
|
||||
print_map(rp_node->rtp_rp.window, ZRTP_SRTP_WINDOW_WIDTH_BYTES);
|
||||
|
||||
|
||||
/*
|
||||
in result map:
|
||||
- after window we should to have all zeroes
|
||||
- into the window we should have ones only if window have zero at appropriate position
|
||||
- before window we should have equal values of test map and result map bits
|
||||
*/
|
||||
for (i=0; i < TEST_MAP_WIDTH; i++) {
|
||||
if (delta > 0 && i < delta) {
|
||||
/* After window */
|
||||
if (0 != zrtp_bitmap_get_bit(result_map, i)) {
|
||||
ZRTP_LOG(3, (_ZTU_,"After window. %i bit should be 0\n", i));
|
||||
res = -1;
|
||||
}
|
||||
} else if (i <= (int)tmp_seq && i >= delta) {
|
||||
/* inside window */
|
||||
|
||||
/* check window filtering */
|
||||
if(1 == zrtp_bitmap_get_bit(result_map, i)) {
|
||||
if (1 == zrtp_bitmap_get_bit(tmp_window, i - (tmp_seq-ZRTP_SRTP_WINDOW_WIDTH) - 1)) {
|
||||
ZRTP_LOG(3, (_ZTU_,"Inside window. Window filtering fail. %i bit should be 0\n", i));
|
||||
res = -1;
|
||||
}
|
||||
}
|
||||
/* check test vs result maps */
|
||||
if ( zrtp_bitmap_get_bit(result_map, i) != zrtp_bitmap_get_bit(test_map, i) &&
|
||||
!zrtp_bitmap_get_bit(tmp_window, i - (tmp_seq-ZRTP_SRTP_WINDOW_WIDTH) - 1)) {
|
||||
ZRTP_LOG(3, (_ZTU_, "Inside window. Test map isn't equal to result at bit %i\n", i));
|
||||
res = -1;
|
||||
}
|
||||
|
||||
} else {
|
||||
/* after window */
|
||||
if (zrtp_bitmap_get_bit(result_map, i) != zrtp_bitmap_get_bit(test_map, i)) {
|
||||
ZRTP_LOG(3, (_ZTU_,"Before window. Test map isn't equal to result at bit %i\n", i));
|
||||
res = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (0 == res) {
|
||||
ZRTP_LOG(3, (_ZTU_,"Test passed successfully\n"));
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void zrtp_test_crypto(zrtp_global_t* zrtp)
|
||||
{
|
||||
ZRTP_LOG(3, (_ZTU_,"====================CIPHERS TESTS====================\n"));
|
||||
cipher_test(zrtp);
|
||||
ZRTP_LOG(3, (_ZTU_,"=====================HASHES TESTS====================\n"));
|
||||
hash_test(zrtp);
|
||||
ZRTP_LOG(3, (_ZTU_,"================PUBLIC KEY SCHEMES TESTS==============\n"));
|
||||
dh_test(zrtp);
|
||||
ecdh_test(zrtp);
|
||||
ZRTP_LOG(3, (_ZTU_,"===============SRTP Key derivation TESTS==============\n"));
|
||||
dk_test(zrtp);
|
||||
ZRTP_LOG(3, (_ZTU_,"==============SRTP Replay protection TESTS============\n")) ;
|
||||
srtp_replay_protection_test(zrtp);
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
* 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"
|
||||
#include "zrtp_test_queue.h"
|
||||
|
||||
struct zrtp_queue
|
||||
{
|
||||
zrtp_sem_t* size_sem;
|
||||
zrtp_sem_t* main_sem;
|
||||
zrtp_mutex_t* mutex;
|
||||
mlist_t head;
|
||||
uint32_t size;
|
||||
};
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
zrtp_status_t zrtp_test_queue_create(zrtp_queue_t** queue)
|
||||
{
|
||||
zrtp_status_t s = zrtp_status_fail;
|
||||
zrtp_queue_t* new_queue = (zrtp_queue_t*) zrtp_sys_alloc(sizeof(zrtp_queue_t));
|
||||
if (! new_queue) {
|
||||
return zrtp_status_fail;
|
||||
}
|
||||
zrtp_memset(new_queue, 0, sizeof(zrtp_queue_t));
|
||||
|
||||
do {
|
||||
s = zrtp_sem_init(&new_queue->size_sem, ZRTP_QUEUE_SIZE, ZRTP_QUEUE_SIZE);
|
||||
if (zrtp_status_ok != s) {
|
||||
break;
|
||||
}
|
||||
s = zrtp_sem_init(&new_queue->main_sem, 0, ZRTP_QUEUE_SIZE);
|
||||
if (zrtp_status_ok != s) {
|
||||
break;
|
||||
}
|
||||
|
||||
s = zrtp_mutex_init(&new_queue->mutex);
|
||||
if (zrtp_status_ok != s) {
|
||||
break;
|
||||
}
|
||||
|
||||
init_mlist(&new_queue->head);
|
||||
new_queue->size = 0;
|
||||
|
||||
s = zrtp_status_ok;
|
||||
} while (0);
|
||||
|
||||
if (zrtp_status_ok != s) {
|
||||
if (new_queue->size_sem) {
|
||||
zrtp_sem_destroy(new_queue->size_sem);
|
||||
}
|
||||
if (new_queue->main_sem) {
|
||||
zrtp_sem_destroy(new_queue->main_sem);
|
||||
}
|
||||
if (new_queue->mutex) {
|
||||
zrtp_mutex_destroy(new_queue->mutex);
|
||||
}
|
||||
}
|
||||
|
||||
*queue = new_queue;
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
void zrtp_test_queue_destroy(zrtp_queue_t* queue)
|
||||
{
|
||||
if (queue->size_sem) {
|
||||
zrtp_sem_destroy(queue->size_sem);
|
||||
}
|
||||
if (queue->main_sem) {
|
||||
zrtp_sem_destroy(queue->main_sem);
|
||||
}
|
||||
if (queue->mutex) {
|
||||
zrtp_mutex_destroy(queue->mutex);
|
||||
}
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void zrtp_test_queue_push(zrtp_queue_t* queue, zrtp_queue_elem_t* elem)
|
||||
{
|
||||
zrtp_sem_wait(queue->size_sem);
|
||||
|
||||
zrtp_mutex_lock(queue->mutex);
|
||||
mlist_add_tail(&queue->head, &elem->_mlist);
|
||||
queue->size++;
|
||||
zrtp_mutex_unlock(queue->mutex);
|
||||
|
||||
zrtp_sem_post(queue->main_sem);
|
||||
}
|
||||
|
||||
zrtp_queue_elem_t* zrtp_test_queue_pop(zrtp_queue_t* queue)
|
||||
{
|
||||
zrtp_queue_elem_t* res = NULL;
|
||||
zrtp_sem_wait(queue->main_sem);
|
||||
|
||||
zrtp_mutex_lock(queue->mutex);
|
||||
if (queue->size) {
|
||||
zrtp_queue_elem_t* elem_cover = mlist_get_struct(zrtp_queue_elem_t, _mlist, queue->head.next);
|
||||
res = elem_cover;
|
||||
mlist_del(queue->head.next);
|
||||
|
||||
queue->size--;
|
||||
zrtp_sem_post(queue->size_sem);
|
||||
} else {
|
||||
zrtp_sem_post(queue->main_sem);
|
||||
}
|
||||
zrtp_mutex_unlock(queue->mutex);
|
||||
|
||||
return res;
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* 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>
|
||||
*/
|
||||
|
||||
#ifndef __ZRTP_TEST_QUEUE_H__
|
||||
#define __ZRTP_TEST_QUEUE_H__
|
||||
|
||||
#include "zrtp.h"
|
||||
|
||||
#define ZRTP_QUEUE_SIZE 2000
|
||||
|
||||
typedef struct zrtp_queue_elem
|
||||
{
|
||||
char data[1500];
|
||||
uint32_t size;
|
||||
mlist_t _mlist;
|
||||
} zrtp_queue_elem_t;
|
||||
typedef struct zrtp_queue zrtp_queue_t;
|
||||
|
||||
zrtp_status_t zrtp_test_queue_create(zrtp_queue_t** queue);
|
||||
void zrtp_test_queue_destroy(zrtp_queue_t* queue);
|
||||
void zrtp_test_queue_push(zrtp_queue_t* queue, zrtp_queue_elem_t* elem);
|
||||
zrtp_queue_elem_t* zrtp_test_queue_pop(zrtp_queue_t* queue);
|
||||
|
||||
#endif /* __ZRTP_TEST_QUEUE_H__ */
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* 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_test_core.h"
|
||||
|
||||
#ifndef ZRTP_TEST_ENABLE_CRYPTO_SELFTESTS
|
||||
#define ZRTP_TEST_ENABLE_CRYPTO_SELFTESTS 0
|
||||
#endif
|
||||
|
||||
static zrtp_test_channel_id_t tmp_id;
|
||||
|
||||
void do_create()
|
||||
{
|
||||
zrtp_test_channel_config_t config;
|
||||
int status = 0;
|
||||
|
||||
config.is_autosecure = 1;
|
||||
config.is_preshared = 0;
|
||||
config.streams_count = 1;
|
||||
|
||||
status = zrtp_test_channel_create(&config, &tmp_id);
|
||||
}
|
||||
|
||||
void do_delete()
|
||||
{
|
||||
zrtp_test_channel_delete(tmp_id);
|
||||
}
|
||||
|
||||
void do_quit()
|
||||
{
|
||||
zrtp_test_zrtp_down();
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int status;
|
||||
|
||||
status = zrtp_test_zrtp_init();
|
||||
if (0 != status) {
|
||||
return status;
|
||||
}
|
||||
#if (ZRTP_TEST_ENABLE_CRYPTO_SELFTESTS == 1)
|
||||
zrtp_test_crypto(zrtp_global);
|
||||
#endif
|
||||
|
||||
{
|
||||
zrtp_test_channel_id_t id;
|
||||
zrtp_test_channel_config_t sconfig;
|
||||
|
||||
sconfig.is_autosecure = 0;
|
||||
sconfig.is_preshared = 0;
|
||||
sconfig.streams_count = 1;
|
||||
|
||||
status = zrtp_test_channel_create(&sconfig, &id);
|
||||
|
||||
if (0 == status) {
|
||||
zrtp_test_channel_start(id);
|
||||
}
|
||||
}
|
||||
|
||||
while (1) {
|
||||
zrtp_sleep(1000);
|
||||
}
|
||||
|
||||
|
||||
do_quit();
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in new issue
Block a user