Hello,
I'm trying to add another layer of encryption to media stream using simple XOR encryption.
What I've already done is implementing transport adapter and connect it as master of srtp transport.
I did it by adding to my project xor_transport_adapter.cpp fill which share the code with transport_adapter_example.c. I only add few modification listed below:
//Contansts for buffer size
#define MAX_RTP_BUFFER_LEN PJMEDIA_MAX_MTU
#define MAX_RTCP_BUFFER_LEN PJMEDIA_MAX_MTU
// I keep buffers for outgoing messages and hash in adapter instance
/* The transport adapter instance */
struct xor_tp_adapter
{
/* Outgoing message buffer */
char rtp_tx_buffer[MAX_RTP_BUFFER_LEN]; //My buffer to operate on rtp packets
char rtcp_tx_buffer[MAX_RTP_BUFFER_LEN]; // My buffer to operate on rtcp packets
const char* xor_hash; //My hash
pj_size_t xor_hash_size; // hash size
/* ... */
};
//I also develop function to make xor
void xor_protect_rtcp(char *buffer, pj_size_t pkt_size, const char* hash, pj_size_t hash_size) {
for(unsigned i = 0; i<pkt_size; ++i) {
buffer[i] ^= hash[i%hash_size];
}
}
//It is used in 5 places in code:
static pj_status_t transport_send_rtp( pjmedia_transport *tp,
const void *pkt,
pj_size_t size)
{
struct xor_tp_adapter *adapter = (struct xor_tp_adapter*)tp;
if (size > sizeof(adapter->rtp_tx_buffer)) {
return PJ_ETOOBIG;
}
pj_memcpy(adapter->rtp_tx_buffer, pkt, size);
xor_protect_rtcp(adapter->rtp_tx_buffer,
size,
adapter->xor_hash, adapter->xor_hash_size);
return pjmedia_transport_send_rtp(adapter->slave_tp, adapter->rtp_tx_buffer, size);
}
static pj_status_t transport_send_rtcp(pjmedia_transport *tp,
const void *pkt,
pj_size_t size)
{
struct xor_tp_adapter *adapter = (struct xor_tp_adapter*)tp;
pj_memcpy(adapter->rtcp_tx_buffer, pkt, size);
xor_protect_rtcp(adapter->rtcp_tx_buffer, size,
adapter->xor_hash, adapter->xor_hash_size);
return pjmedia_transport_send_rtcp(adapter->slave_tp, adapter->rtcp_tx_buffer, size);
}
static void transport_rtp_cb(void *user_data, void *pkt, pj_ssize_t size)
{
struct xor_tp_adapter *adapter = (struct xor_tp_adapter*)user_data;
pj_assert(adapter->stream_rtp_cb != NULL);
xor_protect_rtcp((char*)pkt, size, adapter->xor_hash, adapter->xor_hash_size);
adapter->stream_rtp_cb(adapter->stream_user_data, pkt, size);
}
static void transport_rtcp_cb(void *user_data, void *pkt, pj_ssize_t size)
{
struct xor_tp_adapter *adapter = (struct xor_tp_adapter*)user_data;
pj_assert(adapter->stream_rtcp_cb != NULL);
xor_unprotect_rtcp((char*)pkt, size, adapter->xor_hash, adapter->xor_hash_size);
adapter->stream_rtcp_cb(adapter->stream_user_data, pkt, size);
}
static pj_status_t transport_send_rtcp2(pjmedia_transport *tp,
const pj_sockaddr_t *addr,
unsigned addr_len,
const void *pkt,
pj_size_t size)
{
struct xor_tp_adapter *adapter = (struct xor_tp_adapter*)tp;
pj_memcpy(adapter->rtcp_tx_buffer, pkt, size);
xor_protect_rtcp(adapter->rtcp_tx_buffer,
size,
adapter->xor_hash, adapter->xor_hash_size);
return pjmedia_transport_send_rtcp2(adapter->slave_tp, addr, addr_len,
adapter->rtcp_tx_buffer, size);
}
Every seems to work nice for the first 2-4 seconds of call. After that time I receive many errors like this:
Error sending RTP: replay check failed (index too old)\n
Could someone point out what I am doing wrong and how should I handle this?
_______________________________________________ Visit our blog: http://blog.pjsip.org pjsip mailing list pjsip@xxxxxxxxxxxxxxx http://lists.pjsip.org/mailman/listinfo/pjsip_lists.pjsip.org