summaryrefslogtreecommitdiff
path: root/src/srtp.cc
diff options
context:
space:
mode:
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);
+ }
+}