|
|
|
|
@ -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);
|
|
|
|
|
|