summaryrefslogtreecommitdiff
path: root/src/srtp.cc
diff options
context:
space:
mode:
authorBent Bisballe Nyeng <deva@aasimon.org>2014-05-29 14:20:50 +0200
committerBent Bisballe Nyeng <deva@aasimon.org>2014-05-29 14:20:50 +0200
commit7b6e7703cdeeecae28552f589f249a6ab7f6c4d2 (patch)
tree2443c4b3f2e1cd0cb6cf5350b745b60e11eaf87f /src/srtp.cc
parent1caa03670f91309e4237a37368c4df696d56a47d (diff)
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.
Diffstat (limited to 'src/srtp.cc')
-rw-r--r--src/srtp.cc95
1 files changed, 68 insertions, 27 deletions
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);
+ }
+}