TT#146201 support forwarding all RTCP

Change-Id: I305fbf9ec6189da98badbf3b5828f29e1b2c9ddc
pull/1682/head
Richard Fuchs 4 years ago
parent 3a57face11
commit 7bf1595fe5

@ -70,6 +70,7 @@ struct intf_rr {
struct packet_handler_ctx {
// inputs:
str s; // raw input packet
bool kernel_handled; // parse and read contents but do not forward
GQueue *sinks; // where to send output packets to (forward destination)
rewrite_func decrypt_func, encrypt_func; // handlers for decrypt/encrypt
@ -1487,6 +1488,7 @@ static const char *kernelize_one(struct rtpengine_target_info *reti, GQueue *out
if (proto_is_rtp(media->protocol)) {
reti->rtp = 1;
if (!media->monologue->transcoding) {
reti->rtcp_fw = 1;
if (media->protocol->avpf)
reti->rtcp_fb_fw = 1;
}
@ -1679,7 +1681,7 @@ void kernelize(struct packet_stream *stream) {
struct packet_stream *sink = sh->sink;
if (PS_ISSET(sink, NAT_WAIT) && !PS_ISSET(sink, RECEIVED))
continue;
const char *err = kernelize_one(&reti, &outputs, stream, sh, NULL, NULL);
const char *err = kernelize_one(&reti, &outputs, stream, sh, &stream->rtp_sinks, NULL);
if (err)
ilog(LOG_WARNING, "No support for kernel packet forwarding available (%s)", err);
}
@ -2564,6 +2566,8 @@ static int do_rtcp_parse(struct packet_handler_ctx *phc) {
static int do_rtcp_output(struct packet_handler_ctx *phc) {
if (phc->rtcp_discard)
return 0;
if (phc->kernel_handled)
return 0;
if (phc->rtcp_filter)
if (phc->rtcp_filter(&phc->mp, &phc->rtcp_list))
@ -3127,6 +3131,18 @@ restart:
if (ret >= MAX_RTP_PACKET_SIZE)
ilog(LOG_WARNING | LOG_FLAG_LIMIT, "UDP packet possibly truncated");
if (phc.mp.tv.tv_sec < 0) {
// kernel-handled RTCP
phc.kernel_handled = true;
// restore original actual timestamp
if (G_UNLIKELY(phc.mp.tv.tv_usec == 0))
phc.mp.tv.tv_sec = -phc.mp.tv.tv_sec;
else {
phc.mp.tv.tv_sec = -phc.mp.tv.tv_sec - 1;
phc.mp.tv.tv_usec = 1000000 - phc.mp.tv.tv_usec;
}
}
str_init_len(&phc.s, buf + RTP_BUFFER_HEAD_ROOM, ret);
if (sfd->stream && sfd->stream->jb) {

@ -1758,6 +1758,8 @@ static int proc_list_show(struct seq_file *f, void *v) {
seq_printf(f, " SSRC-tracking");
if (g->target.do_intercept)
seq_printf(f, " intercept");
if (g->target.rtcp_fw)
seq_printf(f, " forward-RTCP");
if (g->target.rtcp_fb_fw)
seq_printf(f, " forward-RTCP-FB");
seq_printf(f, "\n");
@ -5271,7 +5273,8 @@ static void rtp_stats(struct rtpengine_target *g, struct rtp_parsed *rtp, s64 ar
}
static unsigned int rtpengine46(struct sk_buff *skb, struct rtpengine_table *t, struct re_address *src,
static unsigned int rtpengine46(struct sk_buff *skb, struct sk_buff *oskb,
struct rtpengine_table *t, struct re_address *src,
struct re_address *dst, uint8_t in_tos, const struct xt_action_param *par)
{
struct udphdr *uh;
@ -5279,6 +5282,7 @@ static unsigned int rtpengine46(struct sk_buff *skb, struct rtpengine_table *t,
struct sk_buff *skb2;
int err;
int error_nf_action = XT_CONTINUE;
int nf_action = NF_DROP;
int rtp_pt_idx = -2;
int ssrc_idx = -1;
unsigned int datalen, datalen_out;
@ -5291,7 +5295,7 @@ static unsigned int rtpengine46(struct sk_buff *skb, struct rtpengine_table *t,
unsigned long flags;
unsigned int i;
unsigned int start_idx, end_idx;
int is_rtcp;
enum {NOT_RTCP = 0, RTCP, RTCP_FORWARD} is_rtcp;
#if (RE_HAS_MEASUREDELAY)
uint64_t starttime, endtime, delay;
@ -5357,18 +5361,18 @@ static unsigned int rtpengine46(struct sk_buff *skb, struct rtpengine_table *t,
// RTP processing
rtp.ok = 0;
rtp.rtcp = 0;
is_rtcp = 0;
is_rtcp = NOT_RTCP;
if (g->target.rtp) {
if (g->target.rtcp) {
if (g->target.rtcp_mux) {
if (is_muxed_rtcp(skb))
is_rtcp = 1;
is_rtcp = RTCP;
}
else
is_rtcp = 1;
is_rtcp = RTCP;
}
if (!is_rtcp) {
if (is_rtcp == NOT_RTCP) {
parse_rtp(&rtp, skb);
if (!rtp.ok && g->target.rtp_only)
goto out; // pass to userspace
@ -5376,6 +5380,8 @@ static unsigned int rtpengine46(struct sk_buff *skb, struct rtpengine_table *t,
else {
if (g->target.rtcp_fb_fw && is_rtcp_fb_packet(skb))
; // forward and then drop
else if (g->target.rtcp_fw)
is_rtcp = RTCP_FORWARD; // forward, mark, and pass to userspace
else
goto out; // just pass to userspace
@ -5423,7 +5429,7 @@ static unsigned int rtpengine46(struct sk_buff *skb, struct rtpengine_table *t,
rtp.payload[12], rtp.payload[13], rtp.payload[14], rtp.payload[15],
rtp.payload[16], rtp.payload[17], rtp.payload[18], rtp.payload[19]);
}
else if (is_rtcp && rtp.rtcp) {
else if (is_rtcp != NOT_RTCP && rtp.rtcp) {
pkt_idx = 0;
err = srtcp_auth_validate(&g->decrypt_rtcp, &g->target.decrypt, &rtp, &pkt_idx);
errstr = "SRTCP authentication tag mismatch";
@ -5436,6 +5442,11 @@ static unsigned int rtpengine46(struct sk_buff *skb, struct rtpengine_table *t,
goto out_error;
}
skb_trim(skb, rtp.header_len + rtp.payload_len);
if (is_rtcp == RTCP_FORWARD) {
// mark packet as "handled" with negative timestamp
oskb->tstamp = -oskb->tstamp;
nf_action = XT_CONTINUE;
}
}
if (g->target.do_intercept) {
@ -5455,8 +5466,8 @@ static unsigned int rtpengine46(struct sk_buff *skb, struct rtpengine_table *t,
}
// output
start_idx = 0;
end_idx = g->num_rtp_destinations;
start_idx = (is_rtcp != NOT_RTCP) ? g->num_rtp_destinations : 0;
end_idx = (is_rtcp != NOT_RTCP) ? g->target.num_destinations : g->num_rtp_destinations;
if (start_idx == end_idx)
goto out; // pass to userspace
@ -5545,7 +5556,7 @@ do_stats:
if (skb)
kfree_skb(skb);
return NF_DROP;
return nf_action;
out_error:
log_err("x_tables action failed: %s", errstr);
@ -5591,7 +5602,7 @@ static unsigned int rtpengine4(struct sk_buff *oskb, const struct xt_action_para
dst.family = AF_INET;
dst.u.ipv4 = ih->daddr;
return rtpengine46(skb, t, &src, &dst, (uint8_t)ih->tos, par);
return rtpengine46(skb, oskb, t, &src, &dst, (uint8_t)ih->tos, par);
skip2:
kfree_skb(skb);
@ -5633,7 +5644,7 @@ static unsigned int rtpengine6(struct sk_buff *oskb, const struct xt_action_para
dst.family = AF_INET6;
memcpy(&dst.u.ipv6, &ih->daddr, sizeof(dst.u.ipv6));
return rtpengine46(skb, t, &src, &dst, ipv6_get_dsfield(ih), par);
return rtpengine46(skb, oskb, t, &src, &dst, ipv6_get_dsfield(ih), par);
skip2:
kfree_skb(skb);

@ -125,6 +125,7 @@ struct rtpengine_target_info {
rtp_only:1,
track_ssrc:1,
rtcp:1,
rtcp_fw:1,
rtcp_fb_fw:1,
do_intercept:1,
pt_filter:1,

Loading…
Cancel
Save