From 7b6e7703cdeeecae28552f589f249a6ab7f6c4d2 Mon Sep 17 00:00:00 2001 From: Bent Bisballe Nyeng Date: Thu, 29 May 2014 14:20:50 +0200 Subject: Make typedef for framelists. Add some error handling in SRTP class. Make new instance protection mechanism for SRTP. Make some error handling in lrtp public API. --- src/srtp.cc | 95 +++++++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 68 insertions(+), 27 deletions(-) (limited to 'src/srtp.cc') diff --git a/src/srtp.cc b/src/srtp.cc index 596949d..36f3148 100644 --- a/src/srtp.cc +++ b/src/srtp.cc @@ -35,6 +35,38 @@ #include "asc2bin.h" +// This macro translates srtp status codes into exceptions: +#define SRTP_THROW(s) \ + do { \ + switch(s) { \ + case err_status_fail: throw LRTP_SRTP_FAIL; \ + case err_status_bad_param: throw LRTP_SRTP_BAD_PARAM; \ + case err_status_alloc_fail: throw LRTP_SRTP_ALLOC_FAIL; \ + case err_status_dealloc_fail: throw LRTP_SRTP_DEALLOC_FAIL; \ + case err_status_init_fail: throw LRTP_SRTP_INIT_FAIL; \ + case err_status_terminus: throw LRTP_SRTP_TERMINUS; \ + case err_status_auth_fail: throw LRTP_SRTP_AUTH_FAIL; \ + case err_status_cipher_fail: throw LRTP_SRTP_CIPHER_FAIL; \ + case err_status_replay_fail: throw LRTP_SRTP_REPLAY_FAIL; \ + case err_status_replay_old: throw LRTP_SRTP_REPLAY_OLD; \ + case err_status_algo_fail: throw LRTP_SRTP_ALGO_FAIL; \ + case err_status_no_such_op: throw LRTP_SRTP_NO_SUCH_OP; \ + case err_status_no_ctx: throw LRTP_SRTP_NO_CTX; \ + case err_status_cant_check: throw LRTP_SRTP_CANT_CHECK; \ + case err_status_key_expired: throw LRTP_SRTP_KEY_EXPIRED; \ + case err_status_socket_err: throw LRTP_SRTP_SOCKET_ERR; \ + case err_status_signal_err: throw LRTP_SRTP_SIGNAL_ERR; \ + case err_status_nonce_bad: throw LRTP_SRTP_NONCE_BAD; \ + case err_status_read_fail: throw LRTP_SRTP_READ_FAIL; \ + case err_status_write_fail: throw LRTP_SRTP_WRITE_FAIL; \ + case err_status_parse_err: throw LRTP_SRTP_PARSE_ERR; \ + case err_status_encode_err: throw LRTP_SRTP_ENCODE_ERR; \ + case err_status_semaphore_err: throw LRTP_SRTP_SEMAPHORE_ERR; \ + case err_status_pfkey_err: throw LRTP_SRTP_PFKEY_ERR; \ + default: throw LRTP_SRTP_FAIL; \ + } \ + } while(0) + struct SRTP::prv { char *key; size_t key_len; @@ -45,24 +77,15 @@ struct SRTP::prv { srtp_policy_t policy; }; -static bool is_initialised = false; - SRTP::SRTP(std::string key, unsigned int ssrc) + _throw(enum lrtp_status_t) { prv = NULL; err_status_t status; - if(!is_initialised) { - status = srtp_init(); - if(status != err_status_ok) { - // TODO: Error handling - printf("srtp_init failed %d\n", status); - } - is_initialised = true; - } - prv = new struct prv; + if(!prv) throw LRTP_OUT_OF_MEMORY; prv->ssrc = ssrc; @@ -70,16 +93,10 @@ SRTP::SRTP(std::string key, unsigned int ssrc) setupPolicy(true, true); status = srtp_create(&prv->session, &prv->policy); - if(status != err_status_ok) { - // TODO: Error handling - printf("srtp_create %d\n", status); - } + if(status != err_status_ok) SRTP_THROW(status); status = srtp_add_stream(prv->session, &prv->policy); - if(status != err_status_ok) { - // TODO: Error handling - printf("srtp_add_stream %d\n", status); - } + if(status != err_status_ok) SRTP_THROW(status); } SRTP::~SRTP() @@ -96,14 +113,6 @@ SRTP::~SRTP() printf("srtp_dealloc failed %d\n", status); } - status = srtp_shutdown(); - if(status != err_status_ok) { - // TODO: Error handling - printf("srtp_shutdown failed %d\n", status); - } - - is_initialised = false; - if(prv) { free(prv->key); delete prv; @@ -111,6 +120,7 @@ SRTP::~SRTP() } void SRTP::setupKey(const std::string &key) + _throw(enum lrtp_status_t) { prv->key = (char *)calloc(MASTER_KEY_LEN, 1); prv->key_len = MASTER_KEY_LEN; @@ -128,6 +138,7 @@ void SRTP::setupKey(const std::string &key) } void SRTP::setupPolicy(bool confidentiality, bool authentication) + _throw(enum lrtp_status_t) { #ifndef USE_CRYPTO confidentiality = authentication = false; @@ -176,6 +187,7 @@ void SRTP::setupPolicy(bool confidentiality, bool authentication) } int SRTP::encrypt(char *packet, size_t size) + _throw(enum lrtp_status_t) { int sz = size; err_status_t status = srtp_protect(prv->session, packet, &sz); @@ -188,6 +200,7 @@ int SRTP::encrypt(char *packet, size_t size) } int SRTP::decrypt(char *packet, size_t size) + _throw(enum lrtp_status_t) { int sz = size; err_status_t status = srtp_unprotect(prv->session, packet, &sz); @@ -228,3 +241,31 @@ int SRTP::decrypt(char *packet, size_t size) return sz; } + +// Global SRTP instance reference counter +static int active_srtp_instances = 0; + +SRTP::SRTPInstance::SRTPInstance() + _throw(enum lrtp_status_t) +{ + err_status_t status; + + if(active_srtp_instances == 0) { + status = srtp_init(); + active_srtp_instances++; + if(status != err_status_ok) SRTP_THROW(status); + } +} + +SRTP::SRTPInstance::~SRTPInstance() + _throw(enum lrtp_status_t) +{ + err_status_t status; + + active_srtp_instances--; + + if(active_srtp_instances == 0) { + status = srtp_shutdown(); + if(status != err_status_ok) SRTP_THROW(status); + } +} -- cgit v1.2.3