summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am2
-rw-r--r--src/compat.h3
-rw-r--r--src/lrtp.cc134
-rw-r--r--src/lrtp.h102
-rw-r--r--src/rtp_profile.h8
-rw-r--r--src/rtp_profile_amrwb.cc4
-rw-r--r--src/rtp_profile_jpeg.cc2
-rw-r--r--src/rtp_profile_l16.cc2
-rw-r--r--src/rtp_profile_opus.cc2
-rw-r--r--src/rtp_profile_raw.cc2
-rw-r--r--src/srtp.cc95
-rw-r--r--src/srtp.h21
12 files changed, 264 insertions, 113 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 8dfcf71..ef3cfdb 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -6,6 +6,7 @@ liblrtp_la_CXXFLAGS = $(SRTP_CXXFLAGS)
liblrtp_la_SOURCES = \
lrtp.cc \
+ error.cc \
rtp.cc \
srtp.cc \
rtp_profile_amrwb.cc \
@@ -21,6 +22,7 @@ include_HEADERS = \
EXTRA_DIST = \
compat.h \
+ error.h \
rtp_profile.h \
rtp_profile_amrwb.h \
rtp_profile_opus.h \
diff --git a/src/compat.h b/src/compat.h
index 70a6286..f4a7f20 100644
--- a/src/compat.h
+++ b/src/compat.h
@@ -29,9 +29,10 @@
#define __LRTP_COMPAT_H__
#ifdef WIN32
+#define _throw(...)
typedef signed int ssize_t;
#else
-
+#define _throw(fmt...) throw(fmt)
#endif
#endif/*__LRTP_COMPAT_H__*/
diff --git a/src/lrtp.cc b/src/lrtp.cc
index b627c95..71854f0 100644
--- a/src/lrtp.cc
+++ b/src/lrtp.cc
@@ -45,9 +45,21 @@
extern "C" {
#endif
+#define MAGIC 0x726c7074
+
+// Check if 'h' is a valid smtl handle and report/return error if not.
+#define CHECK_HANDLE(h) \
+ do { \
+ if(!h || h->magic != MAGIC) { \
+ return LRTP_MISSING_HANDLE; \
+ } \
+ } while(0)
+
typedef std::map<csrc_t, lrtp_profile_t *> profile_map_t;
struct lrtp_t {
+ unsigned int magic;
+
SRTP *srtp;
csrc_t ssrc;
unsigned short seq;
@@ -55,7 +67,7 @@ struct lrtp_t {
csrc_t next_csrc; // for frame iterator (see get_next_frame)
- std::list<outputframe_t *> framelist;
+ oframelist_t framelist;
};
typedef struct {
@@ -74,35 +86,71 @@ static const profile_class_t registered_profiles[] = {
};
EXPORT
-struct lrtp_t *lrtp_init(const char *key, unsigned int ssrc)
+struct lrtp_t *lrtp_init(enum lrtp_status_t *status,
+ const char *key, unsigned int ssrc)
{
- struct lrtp_t *lrtp = new struct lrtp_t;
+ if(status == NULL) return NULL;
- lrtp->srtp = new SRTP(key, ssrc);
+ struct lrtp_t *lrtp = new (std::nothrow) struct lrtp_t;
+ if(!lrtp) {
+ *status = LRTP_OUT_OF_MEMORY;
+ return NULL;
+ }
+
+ try {
+ lrtp->srtp = new SRTP(key, ssrc);
+ } catch(enum lrtp_status_t s) {
+ *status = s;
+ delete lrtp;
+ return NULL;
+ }
+
lrtp->ssrc = ssrc;
lrtp->seq = 0;
+ lrtp->magic = MAGIC;
+
return lrtp;
}
EXPORT
-void lrtp_close(struct lrtp_t *lrtp)
+enum lrtp_status_t lrtp_close(struct lrtp_t *lrtp)
{
- delete lrtp->srtp;
- delete lrtp;
+ CHECK_HANDLE(lrtp);
+
+ enum lrtp_status_t status = LRTP_OK;
+
+ try {
+ if(lrtp->srtp) delete lrtp->srtp;
+ lrtp->srtp = NULL;
+ } catch(enum lrtp_status_t s) {
+ status = s;
+ }
+
+ lrtp->magic = 0;
+
+ try {
+ delete lrtp;
+ } catch(enum lrtp_status_t s) {
+ status = s;
+ }
+
+ return status;
}
EXPORT
-int lrtp_create_profile(struct lrtp_t *lrtp,
- lrtp_profile_id_t profile_id,
- unsigned int csrc, ...)
+enum lrtp_status_t lrtp_create_profile(struct lrtp_t *lrtp,
+ lrtp_profile_id_t profile_id,
+ unsigned int csrc, ...)
{
+ CHECK_HANDLE(lrtp);
+
struct lrtp_profile_t *profile = NULL;
if(lrtp->profiles.find(csrc) != lrtp->profiles.end()) {
// TODO: CSRC already active
printf("ERROR: CSRC already active\n");
- return 1;
+ return LRTP_CSRC_ALREADY_ACTIVE;
}
va_list ap;
@@ -122,7 +170,7 @@ int lrtp_create_profile(struct lrtp_t *lrtp,
if(!profile) {
printf("ERROR: Could not find profile [%d]\n", profile_id);
- return 1;
+ return LRTP_MISSING_PROFILE;
}
profile->id = profile_id;
@@ -131,32 +179,34 @@ int lrtp_create_profile(struct lrtp_t *lrtp,
lrtp->profiles[csrc] = profile;
- return 0;
+ return LRTP_OK;
}
EXPORT
-void lrtp_destroy_profile(struct lrtp_t *lrtp, unsigned int csrc)
+enum lrtp_status_t lrtp_destroy_profile(struct lrtp_t *lrtp, unsigned int csrc)
{
+ CHECK_HANDLE(lrtp);
+
if(lrtp->profiles.find(csrc) == lrtp->profiles.end()) {
- // TODO: CSRC not found
- printf("ERROR: CSRC not found\n");
- return;
+ return LRTP_MISSING_CSRC;
}
struct lrtp_profile_t *profile = lrtp->profiles[csrc];
profile->destroy(profile);
lrtp->profiles.erase(csrc);
+
+ return LRTP_OK;
}
EXPORT
-int lrtp_enqueue_frame(struct lrtp_t *lrtp, unsigned int csrc,
- char *data, size_t size,
- unsigned long int timestamp)
+enum lrtp_status_t lrtp_enqueue_frame(struct lrtp_t *lrtp, unsigned int csrc,
+ char *data, size_t size,
+ unsigned long int timestamp)
{
+ CHECK_HANDLE(lrtp);
+
if(lrtp->profiles.find(csrc) == lrtp->profiles.end()) {
- // TODO: CSRC not found
- printf("ERROR: CSRC not found\n");
- return 1;
+ return LRTP_MISSING_CSRC;
}
struct lrtp_profile_t *profile = lrtp->profiles[csrc];
@@ -171,7 +221,7 @@ int lrtp_enqueue_frame(struct lrtp_t *lrtp, unsigned int csrc,
profile->framelist.push_back(frame);
- return 0;
+ return LRTP_OK;
}
// Assume we have at least one csrc in the list
@@ -219,6 +269,8 @@ static lrtp_profile_t *get_next_profile(struct lrtp_t *lrtp)
EXPORT
int lrtp_pack(struct lrtp_t *lrtp, char *packet, size_t maxsize)
{
+ CHECK_HANDLE(lrtp);
+
//if(!profile) return PACK_MISSING_PROFILE;
// TODO: Check profile magic word
@@ -271,6 +323,8 @@ int lrtp_dequeue_frame(struct lrtp_t *lrtp,
char *frame, size_t maxsize,
unsigned int *csrc, unsigned int *ts)
{
+ CHECK_HANDLE(lrtp);
+
if(lrtp->framelist.size() == 0) return 0;
outputframe_t *f = lrtp->framelist.front();
@@ -297,11 +351,10 @@ int lrtp_dequeue_frame(struct lrtp_t *lrtp,
}
EXPORT
-int lrtp_unpack(struct lrtp_t *lrtp, const char *packet, size_t size)
+enum lrtp_status_t lrtp_unpack(struct lrtp_t *lrtp,
+ const char *packet, size_t size)
{
- if(!lrtp) return -UNPACK_MISSING_HANDLE;
-
- // TODO: Check lrtp magic word
+ CHECK_HANDLE(lrtp);
char *pkg = (char*)malloc(size);
memcpy(pkg, packet, size);
@@ -309,12 +362,11 @@ int lrtp_unpack(struct lrtp_t *lrtp, const char *packet, size_t size)
int ret = 0;
#ifndef SKIP_SRTP
- ret = lrtp->srtp->decrypt(pkg, size);
-
- if(ret < 0) {
- printf("lrtp_unpack::decrypt error: %d\n", ret);
+ try {
+ ret = lrtp->srtp->decrypt(pkg, size);
+ } catch(enum lrtp_status_t s) {
free(pkg);
- return -1;
+ return s;
}
size = ret;
@@ -325,11 +377,11 @@ int lrtp_unpack(struct lrtp_t *lrtp, const char *packet, size_t size)
std::list<csrc_t> csrcs = rtp.getCSrcs();
if(csrcs.size() == 0) {
free(pkg);
- return -UNPACK_MISSING_CSRC;
+ return LRTP_MISSING_CSRC;
}
if(csrcs.size() > 1) {
free(pkg);
- return -UNPACK_TOO_MANY_CSRCS;
+ return LRTP_TOO_MANY_CSRCS;
}
csrc_t csrc = *csrcs.begin();
@@ -337,22 +389,22 @@ int lrtp_unpack(struct lrtp_t *lrtp, const char *packet, size_t size)
struct lrtp_profile_t *profile = NULL;
if(lrtp->profiles.find(csrc) == lrtp->profiles.end()) {
free(pkg);
- return -UNPACK_MISSING_PROFILE;
+ return LRTP_MISSING_PROFILE;
}
profile = lrtp->profiles[csrc];
- std::list<outputframe_t*> framelist;
+ oframelist_t framelist;
ret = profile->unpack(profile, rtp, framelist);
if(ret < 0) {
printf("lrtp_unpack::Profile unpack failed: %d\n", ret);
free(pkg);
- return -1;
+ return (enum lrtp_status_t)ret;
}
// Make sure all frames in the list have the correct csrc.
- std::list<outputframe_t*>::iterator fi = framelist.begin();
+ oframelist_t::iterator fi = framelist.begin();
while(fi != framelist.end()) {
(*fi)->csrc = csrc;
fi++;
@@ -362,9 +414,11 @@ int lrtp_unpack(struct lrtp_t *lrtp, const char *packet, size_t size)
free(pkg);
- return ret;
+ return LRTP_OK;
}
+// NOTE: lrtp_strerror implemented in error.cc
+
#ifdef __cplusplus
}
#endif
diff --git a/src/lrtp.h b/src/lrtp.h
index b68205a..ec654b9 100644
--- a/src/lrtp.h
+++ b/src/lrtp.h
@@ -48,23 +48,76 @@ extern "C" {
#include "lrtp_profiles.h"
+/**
+ * Status return codes. Note that all of these values (except @ref ERROR_OK)
+ * are negative. The reason for this is that many functions return a size or
+ * a negative integer (one of these values) in case of error.
+ */
+enum lrtp_status_t {
+ LRTP_OK = 0, ///< All went well.
+ LRTP_UNKNOWN = -1, ///< An unknown error occurred.
+ LRTP_MISSING_HANDLE = -2, ///< The handle is corrupted or NULL.
+ LRTP_OUT_OF_MEMORY = -3, ///< Out of memory error.
+
+ // SRTP errors
+ LRTP_SRTP_FAIL = -4, ///< unspecified failure
+ LRTP_SRTP_BAD_PARAM = -5, ///< unsupported parameter
+ LRTP_SRTP_ALLOC_FAIL = -6, ///< couldn't allocate memory
+ LRTP_SRTP_DEALLOC_FAIL = -7, ///< couldn't deallocate properly
+ LRTP_SRTP_INIT_FAIL = -8, ///< couldn't initialize
+ LRTP_SRTP_TERMINUS = -9, ///< can't process as much data as requested
+ LRTP_SRTP_AUTH_FAIL = -10, ///< authentication failure
+ LRTP_SRTP_CIPHER_FAIL = -11, ///< cipher failure
+ LRTP_SRTP_REPLAY_FAIL = -12, ///< replay check failed (bad index)
+ LRTP_SRTP_REPLAY_OLD = -13, ///< replay check failed (index too old)
+ LRTP_SRTP_ALGO_FAIL = -14, ///< algorithm failed test routine
+ LRTP_SRTP_NO_SUCH_OP = -15, ///< unsupported operation
+ LRTP_SRTP_NO_CTX = -16, ///< no appropriate context found
+ LRTP_SRTP_CANT_CHECK = -17, ///< unable to perform desired validation
+ LRTP_SRTP_KEY_EXPIRED = -18, ///< can't use key any more
+ LRTP_SRTP_SOCKET_ERR = -19, ///< error in use of socket
+ LRTP_SRTP_SIGNAL_ERR = -20, ///< error in use POSIX signals
+ LRTP_SRTP_NONCE_BAD = -21, ///< nonce check failed
+ LRTP_SRTP_READ_FAIL = -22, ///< couldn't read data
+ LRTP_SRTP_WRITE_FAIL = -23, ///< couldn't write data
+ LRTP_SRTP_PARSE_ERR = -24, ///< error pasring data
+ LRTP_SRTP_ENCODE_ERR = -25, ///< error encoding data
+ LRTP_SRTP_SEMAPHORE_ERR = -26, ///< error while using semaphores
+ LRTP_SRTP_PFKEY_ERR = -27, ///< error while using pfkey
+
+ LRTP_MISSING_CSRC = -28, ///< Invalid CSrc
+
+ LRTP_TOO_MANY_CSRCS = -29, ///< Exactly one csrc must be present.
+ LRTP_MISSING_PROFILE = -30, ///< CSrc from packet could not be connected with a profile..
+ LRTP_UNPACK_ERROR = -31, ///< Error unpacking RTP pakcet.
+ LRTP_BUFFER_TOO_SMALL = -32, ///< Supplied buffer was not big enough.
+
+ LRTP_CSRC_ALREADY_ACTIVE= -33, ///< CSrc already in session list.
+};
+
struct lrtp_t;
/**
* Initialise lrtp.
+ * @param status A pointer to the function status code. If the function returns
+ * NULL this status code will indicate what went wrong. If status is NULL it
+ * will simply be ignored.
* @param key The key to be use in this session.
* @param ssrc The secure source to be used in the session.
* @return Returns the handle to the newly created session.
*/
EXPORT
-struct lrtp_t *lrtp_init(const char *key, unsigned int ssrc);
+struct lrtp_t *lrtp_init(enum lrtp_status_t *status,
+ const char *key, unsigned int ssrc);
/**
* Close session.
* @param lrtp The lrtp context handle to be closed.
+ * @return LRTP_OK on success, or LRTP_MISSING_HANDLE if handle was broken or
+ * NULL.
*/
EXPORT
-void lrtp_close(struct lrtp_t *lrtp);
+enum lrtp_status_t lrtp_close(struct lrtp_t *lrtp);
/**
* Create a new profile to be used in the lrtp_enqueue_frame and
@@ -75,34 +128,28 @@ void lrtp_close(struct lrtp_t *lrtp);
* @param profile_id See lrtp_profiles.h for possible values.
* @param csrc The csrc to be connected with this profile.
* @param ... Options for the profile. See lrtp_profiles.h for possible values.
- * @return 0 on success, 1 on error.
+ * @return TODO: TBD
*/
EXPORT
-int lrtp_create_profile(struct lrtp_t *lrtp,
- lrtp_profile_id_t profile_id,
- unsigned int csrc, ...);
-
+enum lrtp_status_t lrtp_create_profile(struct lrtp_t *lrtp,
+ lrtp_profile_id_t profile_id,
+ unsigned int csrc, ...);
+
/**
* Free all resources connected with a profile.
* @param lrtp The lrtp context handle.
* @param csrc The csrc of the profile to be freed.
+ * @return TODO: TBD
*/
EXPORT
-void lrtp_destroy_profile(struct lrtp_t *lrtp, unsigned int csrc);
-
-typedef enum {
- // Errors:
- PACK_ERROR = 1000, // Error...
- PACK_BUFFER_TOO_SMALL = 1001, // Packet buffer needs to be bigger.
- PACK_UNKNOWN_PROFILE = 1002, // Illegal profile id
- PACK_MISSING_PROFILE = 1003, // Profile pointer NULL or not valid.
-} lrtp_pack_status_t;
+enum lrtp_status_t lrtp_destroy_profile(struct lrtp_t *lrtp, unsigned int csrc);
/**
* Enqueue a media frame for the packetiser.
* @param profile A pointer to profile needed for processing the frame type.
* @param framedate The frame data that needs encapsulation.
* @param framesize The size in bytes of the frame data.
+ * @return TODO: TBD
* @return 0 on success, or a negative error code on error.
* WARNING: The frame pointer cannot be freed or overwritten until all frame
* data has been handled by lrtp_pack(). Either call lrtp_pack() until it
@@ -111,9 +158,9 @@ typedef enum {
* See lrtp_profiles.h for further details.
*/
EXPORT
-int lrtp_enqueue_frame(struct lrtp_t *lrtp, unsigned int csrc,
- char *framedate, size_t framesize,
- unsigned long int timestamp);
+enum lrtp_status_t lrtp_enqueue_frame(struct lrtp_t *lrtp, unsigned int csrc,
+ char *framedate, size_t framesize,
+ unsigned long int timestamp);
/**
* Handle frame data from the frame queue and create at most a single sRTP
@@ -127,16 +174,6 @@ int lrtp_enqueue_frame(struct lrtp_t *lrtp, unsigned int csrc,
*/
EXPORT int lrtp_pack(struct lrtp_t *lrtp, char *packet, size_t maxsize);
-typedef enum {
- // Errors:
- UNPACK_ERROR = 1000, // Error...
- UNPACK_BUFFER_TOO_SMALL = 1001, // Frame buffer needs to be bigger.
- UNPACK_MISSING_HANDLE = 1002, // Handle pointer NULL or not valid.
- UNPACK_MISSING_CSRC = 1003, // Exactly one csrc must be present.
- UNPACK_TOO_MANY_CSRCS = 1004, // Exactly one csrc must be present.
- UNPACK_MISSING_PROFILE = 1005, // CSrc from packet could not be connected with a profile..
-} lrtp_unpack_status_t;
-
/**
* Dequeue a frame from the frame queue.
* @param lrtp The lrtp context handle.
@@ -144,7 +181,7 @@ typedef enum {
* @param maxsize The size of the char buffer stored in 'frame'.
* @param csrc The csrc of the dequeued frame is returned in this pointer.
* @param ts The timestamp of the dequeued frame is returned in this pointer.
- * @return The size of the returned frame. -1 on error.
+ * @return The size of the returned frame or a negative error code on error.
*/
EXPORT
int lrtp_dequeue_frame(struct lrtp_t *lrtp,
@@ -157,10 +194,11 @@ int lrtp_dequeue_frame(struct lrtp_t *lrtp,
* @param lrtp The lrtp context handle.
* @param packet The packet data.
* @param size The size of the packet.
- * @return 0 on success, error code (negative integer) on error.
+ * @return TODO: TBD
*/
EXPORT
-int lrtp_unpack(struct lrtp_t *lrtp, const char *packet, size_t size);
+enum lrtp_status_t lrtp_unpack(struct lrtp_t *lrtp,
+ const char *packet, size_t size);
#ifdef __cplusplus
}
diff --git a/src/rtp_profile.h b/src/rtp_profile.h
index bfb7572..6865adb 100644
--- a/src/rtp_profile.h
+++ b/src/rtp_profile.h
@@ -42,6 +42,8 @@ typedef struct {
unsigned long int timestamp;
} inputframe_t;
+typedef std::list<inputframe_t *> iframelist_t;
+
typedef struct {
char *data;
size_t size;
@@ -52,13 +54,15 @@ typedef struct {
} outputframe_t;
+typedef std::list<outputframe_t *> oframelist_t;
+
struct lrtp_profile_t {
struct lrtp_t *lrtp;
lrtp_profile_id_t id;
unsigned int csrc;
// Frames ready for packing with this profile:
- std::list<inputframe_t *> framelist;
+ iframelist_t framelist;
// Profile functions:
/**
@@ -78,7 +82,7 @@ struct lrtp_profile_t {
int (*unpack)(struct lrtp_profile_t *profile,
const RTP &rtp,
- std::list<outputframe_t *> &framelist);
+ oframelist_t &framelist);
void (*destroy)(struct lrtp_profile_t *profile);
diff --git a/src/rtp_profile_amrwb.cc b/src/rtp_profile_amrwb.cc
index 94084cf..7b02c11 100644
--- a/src/rtp_profile_amrwb.cc
+++ b/src/rtp_profile_amrwb.cc
@@ -222,7 +222,7 @@ int profile_amrwb_pack(struct lrtp_profile_t *profile,
int profile_amrwb_unpack(struct lrtp_profile_t *profile,
const RTP &rtp,
- std::list<outputframe_t *> &framelist)
+ oframelist_t &framelist)
{
//struct lrtp_profile_amrwb_t *p = (struct lrtp_profile_amrwb_t *)profile;
@@ -244,7 +244,7 @@ int profile_amrwb_unpack(struct lrtp_profile_t *profile,
char CMR = payload[0];
if(CMR != 15) {
printf("CMR not 15\n");
- return UNPACK_ERROR;
+ return LRTP_UNPACK_ERROR;
}
// TODO: What to do if there are 0 frames (and therefore no header to set the
diff --git a/src/rtp_profile_jpeg.cc b/src/rtp_profile_jpeg.cc
index 9ce667f..c597fe6 100644
--- a/src/rtp_profile_jpeg.cc
+++ b/src/rtp_profile_jpeg.cc
@@ -1587,7 +1587,7 @@ int profile_jpeg_pack(struct lrtp_profile_t *profile,
int profile_jpeg_unpack(struct lrtp_profile_t *profile,
const RTP &rtp,
- std::list<outputframe_t *> &framelist)
+ oframelist_t &framelist)
{
struct lrtp_profile_jpeg_t *p = (struct lrtp_profile_jpeg_t *)profile;
diff --git a/src/rtp_profile_l16.cc b/src/rtp_profile_l16.cc
index 379df1c..f57ba4b 100644
--- a/src/rtp_profile_l16.cc
+++ b/src/rtp_profile_l16.cc
@@ -79,7 +79,7 @@ int profile_l16_pack(struct lrtp_profile_t *profile,
int profile_l16_unpack(struct lrtp_profile_t *profile,
const RTP &rtp,
- std::list<outputframe_t *> &framelist)
+ oframelist_t &framelist)
{
struct lrtp_profile_l16_t *p = (struct lrtp_profile_l16_t *)profile;
diff --git a/src/rtp_profile_opus.cc b/src/rtp_profile_opus.cc
index 3fc0de9..af0b2cc 100644
--- a/src/rtp_profile_opus.cc
+++ b/src/rtp_profile_opus.cc
@@ -142,7 +142,7 @@ int profile_opus_pack(struct lrtp_profile_t *profile,
int profile_opus_unpack(struct lrtp_profile_t *profile,
const RTP &rtp,
- std::list<outputframe_t *> &framelist)
+ oframelist_t &framelist)
{
//struct lrtp_profile_opus_t *p = (struct lrtp_profile_opus_t *)profile;
diff --git a/src/rtp_profile_raw.cc b/src/rtp_profile_raw.cc
index 25cc297..0a36c79 100644
--- a/src/rtp_profile_raw.cc
+++ b/src/rtp_profile_raw.cc
@@ -55,7 +55,7 @@ int profile_raw_pack(struct lrtp_profile_t *profile,
int profile_raw_unpack(struct lrtp_profile_t *profile,
const RTP &rtp,
- std::list<outputframe_t *> &framelist)
+ oframelist_t &framelist)
{
//struct lrtp_profile_raw_t *p = (struct lrtp_profile_raw_t *)profile;
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);
+ }
+}
diff --git a/src/srtp.h b/src/srtp.h
index 3d8b697..66197bb 100644
--- a/src/srtp.h
+++ b/src/srtp.h
@@ -30,25 +30,36 @@
#include <string>
+#include "lrtp.h"
#include "rtp.h"
+#include "compat.h"
#define MAX_KEY_LEN 64
#define MASTER_KEY_LEN 30
class SRTP {
public:
- SRTP(std::string key, unsigned int ssrc);
+ SRTP(std::string key, unsigned int ssrc) _throw(enum lrtp_status_t);
~SRTP();
- int encrypt(char *packet, size_t size);
- int decrypt(char *packet, size_t size);
+ int encrypt(char *packet, size_t size) _throw(enum lrtp_status_t);
+ int decrypt(char *packet, size_t size) _throw(enum lrtp_status_t);
private:
+ class SRTPInstance {
+ public:
+ SRTPInstance() _throw(enum lrtp_status_t);
+ ~SRTPInstance() _throw(enum lrtp_status_t);
+ };
+
+ SRTPInstance instance;
+
struct prv;
struct prv *prv;
- void setupKey(const std::string &key);
- void setupPolicy(bool confidentiality, bool authentication);
+ void setupKey(const std::string &key) _throw(enum lrtp_status_t);
+ void setupPolicy(bool confidentiality, bool authentication)
+ _throw(enum lrtp_status_t);
};
#endif/*__LRTP_SRTP_H__*/