Browse Source

TT#31403 decouple RTCP AVPF filtering from crypto stuff

Change-Id: I99b2b5720f1012b59be90e110b6ed7902826a861
changes/98/18898/6
Richard Fuchs 8 years ago
parent
commit
5d67605535
6 changed files with 76 additions and 82 deletions
  1. +9
    -4
      daemon/codec.c
  2. +1
    -2
      daemon/codec.h
  3. +54
    -56
      daemon/media_socket.c
  4. +3
    -0
      daemon/media_socket.h
  5. +4
    -17
      daemon/rtcp.c
  6. +5
    -3
      daemon/rtcp.h

+ 9
- 4
daemon/codec.c View File

@ -320,6 +320,8 @@ next:
// the list, as we must expect to potentially receive media in that codec, which we
// then could not transcode.
if (MEDIA_ISSET(receiver, TRANSCODE)) {
// XXX we also must switch all "passthrough" handlers to a special passthrough
// that substitutes out the SSRC
for (GList *l = receiver->codecs_prefs_recv.head; l; ) {
struct rtp_payload_type *pt = l->data;
@ -366,13 +368,16 @@ void codec_handlers_free(struct call_media *m) {
}
static int handler_func_passthrough(struct codec_handler *h, struct call_media *media,
struct media_packet *mp)
{
void codec_add_raw_packet(struct media_packet *mp, const str *raw) {
struct codec_packet *p = g_slice_alloc(sizeof(*p));
p->s = mp->raw;
p->s = *raw;
p->free_func = NULL;
g_queue_push_tail(&mp->packets_out, p);
}
static int handler_func_passthrough(struct codec_handler *h, struct call_media *media,
struct media_packet *mp)
{
codec_add_raw_packet(mp, &mp->raw);
return 0;
}


+ 1
- 2
daemon/codec.h View File

@ -33,11 +33,10 @@ struct codec_packet {
void codec_handlers_update(struct call_media *receiver, struct call_media *sink);
struct codec_handler *codec_handler_get(struct call_media *, int payload_type);
void codec_handlers_free(struct call_media *);
void codec_add_raw_packet(struct media_packet *mp, const str *);
void codec_packet_free(void *);
void codec_rtp_payload_types(struct call_media *media, struct call_media *other_media,


+ 54
- 56
daemon/media_socket.c View File

@ -42,9 +42,10 @@ typedef int (*rewrite_func)(str *, struct packet_stream *, struct stream_fd *, c
struct streamhandler_io {
rewrite_func rtp;
rewrite_func rtcp;
int (*kernel)(struct rtpengine_srtp *, struct packet_stream *);
rewrite_func rtp_crypt;
rewrite_func rtcp_crypt;
rtcp_filter_func *rtcp_filter;
int (*kernel)(struct rtpengine_srtp *, struct packet_stream *);
};
struct streamhandler {
const struct streamhandler_io *in;
@ -68,6 +69,7 @@ struct packet_handler_ctx {
struct call_media *media; // stream->media
struct packet_stream *sink; // where to send output packets to (forward destination)
rewrite_func decrypt_func, encrypt_func; // handlers for decrypt/encrypt
rtcp_filter_func *rtcp_filter;
struct packet_stream *in_srtp, *out_srtp; // SRTP contexts for decrypt/encrypt (relevant for muxed RTCP)
int payload_type; // -1 if unknown or not RTP
int rtcp; // true if this is an RTCP packet
@ -88,8 +90,6 @@ static int __k_null(struct rtpengine_srtp *s, struct packet_stream *);
static int __k_srtp_encrypt(struct rtpengine_srtp *s, struct packet_stream *);
static int __k_srtp_decrypt(struct rtpengine_srtp *s, struct packet_stream *);
static int call_noop_rtcp(str *s, struct packet_stream *, struct stream_fd *, const endpoint_t *,
const struct timeval *, struct ssrc_ctx *);
static int call_avp2savp_rtp(str *s, struct packet_stream *, struct stream_fd *, const endpoint_t *,
const struct timeval *, struct ssrc_ctx *);
static int call_savp2avp_rtp(str *s, struct packet_stream *, struct stream_fd *, const endpoint_t *,
@ -98,12 +98,6 @@ static int call_avp2savp_rtcp(str *s, struct packet_stream *, struct stream_fd *
const struct timeval *, struct ssrc_ctx *);
static int call_savp2avp_rtcp(str *s, struct packet_stream *, struct stream_fd *, const endpoint_t *,
const struct timeval *, struct ssrc_ctx *);
static int call_avpf2avp_rtcp(str *s, struct packet_stream *, struct stream_fd *, const endpoint_t *,
const struct timeval *, struct ssrc_ctx *);
//static int call_avpf2savp_rtcp(str *s, struct packet_stream *);
static int call_savpf2avp_rtcp(str *s, struct packet_stream *, struct stream_fd *, const endpoint_t *,
const struct timeval *, struct ssrc_ctx *);
//static int call_savpf2savp_rtcp(str *s, struct packet_stream *);
static struct logical_intf *__get_logical_interface(const str *name, sockfamily_t *fam);
@ -117,34 +111,34 @@ static const struct streamhandler_io __shio_noop = { // non-RTP protocols
};
static const struct streamhandler_io __shio_noop_rtp = {
.kernel = __k_null,
.rtcp = call_noop_rtcp,
};
static const struct streamhandler_io __shio_decrypt = {
.kernel = __k_srtp_decrypt,
.rtp = call_savp2avp_rtp,
.rtcp = call_savp2avp_rtcp,
.rtp_crypt = call_savp2avp_rtp,
.rtcp_crypt = call_savp2avp_rtcp,
};
static const struct streamhandler_io __shio_encrypt = {
.kernel = __k_srtp_encrypt,
.rtp = call_avp2savp_rtp,
.rtcp = call_avp2savp_rtcp,
.rtp_crypt = call_avp2savp_rtp,
.rtcp_crypt = call_avp2savp_rtcp,
};
static const struct streamhandler_io __shio_decrypt_rtcp_only = {
.kernel = __k_null,
.rtcp = call_savp2avp_rtcp,
.rtcp_crypt = call_savp2avp_rtcp,
};
static const struct streamhandler_io __shio_encrypt_rtcp_only = {
.kernel = __k_null,
.rtcp = call_avp2savp_rtcp,
.rtcp_crypt = call_avp2savp_rtcp,
};
static const struct streamhandler_io __shio_avpf_strip = {
.kernel = __k_null,
.rtcp = call_avpf2avp_rtcp,
.rtcp_filter = rtcp_avpf2avp_filter,
};
static const struct streamhandler_io __shio_decrypt_avpf_strip = {
.kernel = __k_srtp_decrypt,
.rtp = call_savp2avp_rtp,
.rtcp = call_savpf2avp_rtcp,
.rtp_crypt = call_savp2avp_rtp,
.rtcp_crypt = call_savp2avp_rtcp,
.rtcp_filter = rtcp_avpf2avp_filter,
};
/* ********** */
@ -869,17 +863,6 @@ static int rtcp_demux(const str *s, struct call_media *media) {
return rtcp_demux_is_rtcp(s) ? 2 : 1;
}
static int call_noop_rtcp(str *s, struct packet_stream *stream, struct stream_fd *sfd, const endpoint_t *src,
const struct timeval *tv, struct ssrc_ctx *ssrc_ctx)
{
rtcp_parse(s, sfd, src, tv);
return 0;
}
static int call_avpf2avp_rtcp(str *s, struct packet_stream *stream, struct stream_fd *sfd, const endpoint_t *src,
const struct timeval *tv, struct ssrc_ctx *ssrc_ctx)
{
return rtcp_avpf2avp(s, sfd, src, tv); // also does rtcp_parse
}
static int call_avp2savp_rtp(str *s, struct packet_stream *stream, struct stream_fd *sfd, const endpoint_t *src,
const struct timeval *tv, struct ssrc_ctx *ssrc_ctx)
{
@ -898,20 +881,7 @@ static int call_savp2avp_rtp(str *s, struct packet_stream *stream, struct stream
static int call_savp2avp_rtcp(str *s, struct packet_stream *stream, struct stream_fd *sfd, const endpoint_t *src,
const struct timeval *tv, struct ssrc_ctx *ssrc_ctx)
{
int ret = rtcp_savp2avp(s, &stream->selected_sfd->crypto, ssrc_ctx);
if (ret < 0)
return ret;
rtcp_parse(s, sfd, src, tv);
return ret;
}
static int call_savpf2avp_rtcp(str *s, struct packet_stream *stream, struct stream_fd *sfd, const endpoint_t *src,
const struct timeval *tv, struct ssrc_ctx *ssrc_ctx)
{
int ret;
ret = rtcp_savp2avp(s, &stream->selected_sfd->crypto, ssrc_ctx);
if (ret < 0)
return ret;
return rtcp_avpf2avp(s, sfd, src, tv);
return rtcp_savp2avp(s, &stream->selected_sfd->crypto, ssrc_ctx);
}
@ -1337,12 +1307,13 @@ static int media_packet_decrypt(struct packet_handler_ctx *phc)
// XXX use an array with index instead of if/else
if (G_LIKELY(!phc->rtcp)) {
phc->decrypt_func = phc->in_srtp->handler->in->rtp;
phc->encrypt_func = phc->in_srtp->handler->out->rtp;
phc->decrypt_func = phc->in_srtp->handler->in->rtp_crypt;
phc->encrypt_func = phc->in_srtp->handler->out->rtp_crypt;
}
else {
phc->decrypt_func = phc->in_srtp->handler->in->rtcp;
phc->encrypt_func = phc->in_srtp->handler->out->rtcp;
phc->decrypt_func = phc->in_srtp->handler->in->rtcp_crypt;
phc->encrypt_func = phc->in_srtp->handler->out->rtcp_crypt;
phc->rtcp_filter = phc->in_srtp->handler->in->rtcp_filter;
}
/* return values are: 0 = forward packet, -1 = error/dont forward,
@ -1513,6 +1484,27 @@ static void media_packet_kernel_check(struct packet_handler_ctx *phc) {
}
static int do_rtcp(struct packet_handler_ctx *phc) {
int ret = -1;
// XXX use a handler for RTCP
// XXX rewrite/consume for transcoding
GQueue rtcp_list = G_QUEUE_INIT;
if (rtcp_parse(&rtcp_list, &phc->s, phc->sfd, &phc->fsin, &phc->tv))
goto out;
if (phc->rtcp_filter)
if (phc->rtcp_filter(&phc->s, &rtcp_list))
goto out;
codec_add_raw_packet(&phc->mp, &phc->s);
ret = 0;
out:
rtcp_list_free(&rtcp_list);
return ret;
}
/* called lock-free */
static int stream_packet(struct packet_handler_ctx *phc) {
/**
@ -1596,12 +1588,18 @@ static int stream_packet(struct packet_handler_ctx *phc) {
if (phc->call->recording)
dump_packet(phc->call->recording, phc->stream, &phc->s);
// XXX use a handler for RTCP
struct codec_handler *transcoder = codec_handler_get(phc->media, phc->payload_type);
// this transfers the packet from 's' to 'packets_out'
phc->mp.raw = phc->s;
if (transcoder->func(transcoder, phc->media, &phc->mp))
goto drop;
// RTCP detection is further up, so we could make this determination there
if (phc->mp.rtcp) {
if (do_rtcp(phc))
goto drop;
}
else {
struct codec_handler *transcoder = codec_handler_get(phc->media, phc->payload_type);
// this transfers the packet from 's' to 'packets_out'
phc->mp.raw = phc->s;
if (transcoder->func(transcoder, phc->media, &phc->mp))
goto drop;
}
if (G_LIKELY(handler_ret >= 0))
handler_ret = media_packet_encrypt(phc);


+ 3
- 0
daemon/media_socket.h View File

@ -15,6 +15,9 @@
typedef int rtcp_filter_func(str *, GQueue *);
struct logical_intf {


+ 4
- 17
daemon/rtcp.c View File

@ -616,13 +616,13 @@ next:
static void rtcp_ce_free(void *p) {
g_slice_free1(sizeof(struct rtcp_chain_element), p);
}
static void rtcp_list_free(GQueue *q) {
void rtcp_list_free(GQueue *q) {
g_queue_clear_full(q, rtcp_ce_free);
}
static int __rtcp_parse(GQueue *q, const str *_s, struct stream_fd *sfd, const endpoint_t *src,
int rtcp_parse(GQueue *q, const str *_s, struct stream_fd *sfd, const endpoint_t *src,
const struct timeval *tv)
{
struct rtcp_header *hdr;
@ -704,26 +704,15 @@ error:
return -1;
}
void rtcp_parse(const str *s, struct stream_fd *sfd, const endpoint_t *src, const struct timeval *tv) {
GQueue rtcp_list = G_QUEUE_INIT;
if (__rtcp_parse(&rtcp_list, s, sfd, src, tv))
return;
rtcp_list_free(&rtcp_list);
}
int rtcp_avpf2avp(str *s, struct stream_fd *sfd, const endpoint_t *src, const struct timeval *tv) {
GQueue rtcp_list = G_QUEUE_INIT;
int rtcp_avpf2avp_filter(str *s, GQueue *rtcp_list) {
GList *l;
struct rtcp_chain_element *el;
void *start;
unsigned int removed, left;
if (__rtcp_parse(&rtcp_list, s, sfd, src, tv))
return 0;
left = s->len;
removed = 0;
for (l = rtcp_list.head; l; l = l->next) {
for (l = rtcp_list->head; l; l = l->next) {
el = l->data;
left -= el->len;
@ -740,8 +729,6 @@ int rtcp_avpf2avp(str *s, struct stream_fd *sfd, const endpoint_t *src, const st
}
}
rtcp_list_free(&rtcp_list);
s->len -= removed;
if (!s->len)
return -1;


+ 5
- 3
daemon/rtcp.h View File

@ -3,6 +3,7 @@
#include "str.h"
#include "call.h"
#include "media_socket.h"
#include <glib.h>
@ -12,14 +13,15 @@ struct ssrc_ctx;
int rtcp_avpf2avp(str *, struct stream_fd *sfd, const endpoint_t *, const struct timeval *);
int rtcp_avp2savp(str *, struct crypto_context *, struct ssrc_ctx *);
int rtcp_savp2avp(str *, struct crypto_context *, struct ssrc_ctx *);
int rtcp_payload(struct rtcp_packet **out, str *p, const str *s);
//void parse_and_log_rtcp_report(struct stream_fd *sfd, const str *, const endpoint_t *, const struct timeval *);
void rtcp_parse(const str *, struct stream_fd *sfd, const endpoint_t *, const struct timeval *);
int rtcp_parse(GQueue *q, const str *, struct stream_fd *sfd, const endpoint_t *, const struct timeval *);
void rtcp_list_free(GQueue *q);
rtcp_filter_func rtcp_avpf2avp_filter;
void rtcp_init();


Loading…
Cancel
Save