|
|
|
@ -321,7 +321,6 @@ struct rtpengine_target {
|
|
|
|
|
unsigned int last_pt; // index into pt_input[] and pt_output[]
|
|
|
|
|
|
|
|
|
|
spinlock_t ssrc_stats_lock;
|
|
|
|
|
struct ssrc_stats ssrc_stats[RTPE_NUM_SSRC_TRACKING];
|
|
|
|
|
|
|
|
|
|
struct re_crypto_context decrypt_rtp;
|
|
|
|
|
struct re_crypto_context decrypt_rtcp;
|
|
|
|
@ -1860,15 +1859,6 @@ static void target_retrieve_stats(struct rtpengine_target *g, struct rtpengine_s
|
|
|
|
|
|
|
|
|
|
spin_lock_irqsave(&g->ssrc_stats_lock, flags);
|
|
|
|
|
|
|
|
|
|
for (u = 0; u < RTPE_NUM_SSRC_TRACKING; u++) {
|
|
|
|
|
i->ssrc[u] = g->target.ssrc[u];
|
|
|
|
|
i->ssrc_stats[u] = g->ssrc_stats[u];
|
|
|
|
|
|
|
|
|
|
atomic64_set(&g->ssrc_stats[u].packets, 0);
|
|
|
|
|
atomic64_set(&g->ssrc_stats[u].bytes, 0);
|
|
|
|
|
atomic_set(&g->ssrc_stats[u].total_lost, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (u = 0; u < g->target.num_destinations; u++) {
|
|
|
|
|
for (v = 0; v < RTPE_NUM_SSRC_TRACKING; v++)
|
|
|
|
|
i->last_rtcp_index[u][v] = g->outputs[u].output.encrypt.last_rtcp_index[v];
|
|
|
|
@ -2472,10 +2462,8 @@ static int table_new_target(struct rtpengine_table *t, struct rtpengine_target_i
|
|
|
|
|
crypto_context_init(&g->decrypt_rtp, &g->target.decrypt);
|
|
|
|
|
crypto_context_init(&g->decrypt_rtcp, &g->target.decrypt);
|
|
|
|
|
spin_lock_init(&g->ssrc_stats_lock);
|
|
|
|
|
for (u = 0; u < RTPE_NUM_SSRC_TRACKING; u++) {
|
|
|
|
|
g->ssrc_stats[u].lost_bits = -1;
|
|
|
|
|
for (u = 0; u < RTPE_NUM_SSRC_TRACKING; u++)
|
|
|
|
|
g->target.ssrc_stats[u] = ssrc_stats[u];
|
|
|
|
|
}
|
|
|
|
|
rwlock_init(&g->outputs_lock);
|
|
|
|
|
g->target.iface_stats = iface_stats;
|
|
|
|
|
g->target.stats = stats;
|
|
|
|
@ -2601,6 +2589,8 @@ static int table_add_destination(struct rtpengine_table *t, struct rtpengine_des
|
|
|
|
|
struct rtpengine_target *g;
|
|
|
|
|
struct interface_stats_block *iface_stats;
|
|
|
|
|
struct stream_stats *stats;
|
|
|
|
|
struct ssrc_stats *ssrc_stats[RTPE_NUM_SSRC_TRACKING];
|
|
|
|
|
unsigned int u;
|
|
|
|
|
|
|
|
|
|
// validate input
|
|
|
|
|
|
|
|
|
@ -2619,6 +2609,15 @@ static int table_add_destination(struct rtpengine_table *t, struct rtpengine_des
|
|
|
|
|
stats = shm_map_resolve(i->output.stats, sizeof(*stats));
|
|
|
|
|
if (!stats)
|
|
|
|
|
return -EFAULT;
|
|
|
|
|
for (u = 0; u < RTPE_NUM_SSRC_TRACKING; u++) {
|
|
|
|
|
// XXX order expected to be the same as input target
|
|
|
|
|
// XXX validate if target->ssrc[u] is set?
|
|
|
|
|
if (!i->output.ssrc_stats[u])
|
|
|
|
|
break;
|
|
|
|
|
ssrc_stats[u] = shm_map_resolve(i->output.ssrc_stats[u], sizeof(*ssrc_stats[u]));
|
|
|
|
|
if (!ssrc_stats[u])
|
|
|
|
|
return -EFAULT;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
g = get_target(t, &i->local);
|
|
|
|
@ -2646,6 +2645,8 @@ static int table_add_destination(struct rtpengine_table *t, struct rtpengine_des
|
|
|
|
|
g->outputs[i->num].output = i->output;
|
|
|
|
|
g->outputs[i->num].output.iface_stats = iface_stats;
|
|
|
|
|
g->outputs[i->num].output.stats = stats;
|
|
|
|
|
for (u = 0; u < RTPE_NUM_SSRC_TRACKING; u++)
|
|
|
|
|
g->outputs[i->num].output.ssrc_stats[u] = ssrc_stats[u];
|
|
|
|
|
|
|
|
|
|
// init crypto stuff lock free: the "output" is already filled so we
|
|
|
|
|
// know it's there, but outputs_unfilled hasn't been decreased yet, so
|
|
|
|
@ -5200,6 +5201,13 @@ static bool proxy_packet_output_rtXp(struct sk_buff *skb, struct rtpengine_outpu
|
|
|
|
|
srtp_authenticate(&o->encrypt_rtp, &o->output.encrypt, rtp, pkt_idx);
|
|
|
|
|
skb_put(skb, rtp->payload_len - pllen);
|
|
|
|
|
|
|
|
|
|
if (ssrc_idx >= 0 && o->output.ssrc_stats[ssrc_idx]) {
|
|
|
|
|
atomic64_inc(&o->output.ssrc_stats[ssrc_idx]->packets);
|
|
|
|
|
atomic64_add(rtp->payload_len, &o->output.ssrc_stats[ssrc_idx]->bytes);
|
|
|
|
|
atomic_set(&o->output.ssrc_stats[ssrc_idx]->ext_seq, pkt_idx);
|
|
|
|
|
atomic_set(&o->output.ssrc_stats[ssrc_idx]->timestamp, ntohl(rtp->rtp_header->timestamp));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -5221,10 +5229,10 @@ static int send_proxy_packet_output(struct sk_buff *skb, struct rtpengine_target
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void rtp_stats(struct rtpengine_target *g, struct rtp_parsed *rtp, s64 arrival_time, int pt_idx,
|
|
|
|
|
int ssrc_idx)
|
|
|
|
|
int ssrc_idx, struct global_stats_counter *rtpe_stats)
|
|
|
|
|
{
|
|
|
|
|
unsigned long flags;
|
|
|
|
|
struct ssrc_stats *s = &g->ssrc_stats[ssrc_idx];
|
|
|
|
|
struct ssrc_stats *s = g->target.ssrc_stats[ssrc_idx];
|
|
|
|
|
uint16_t old_seq_trunc;
|
|
|
|
|
uint32_t last_seq;
|
|
|
|
|
uint16_t seq_diff;
|
|
|
|
@ -5273,13 +5281,18 @@ static void rtp_stats(struct rtpengine_target *g, struct rtp_parsed *rtp, s64 ar
|
|
|
|
|
if (seq_diff >= (sizeof(s->lost_bits) * 8)) {
|
|
|
|
|
// complete loss
|
|
|
|
|
atomic_add(sizeof(s->lost_bits) * 8, &s->total_lost);
|
|
|
|
|
atomic64_add(sizeof(s->lost_bits) * 8, &g->target.iface_stats->s.packets_lost);
|
|
|
|
|
atomic64_add(sizeof(s->lost_bits) * 8, &rtpe_stats->packets_lost);
|
|
|
|
|
s->lost_bits = -1;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
while (seq_diff) {
|
|
|
|
|
// shift out one bit and see if we lost it
|
|
|
|
|
if ((s->lost_bits & 0x80000000) == 0)
|
|
|
|
|
if ((s->lost_bits & 0x80000000) == 0) {
|
|
|
|
|
atomic_inc(&s->total_lost);
|
|
|
|
|
atomic64_inc(&g->target.iface_stats->s.packets_lost);
|
|
|
|
|
atomic64_inc(&rtpe_stats->packets_lost);
|
|
|
|
|
}
|
|
|
|
|
s->lost_bits <<= 1;
|
|
|
|
|
seq_diff--;
|
|
|
|
|
}
|
|
|
|
@ -5458,7 +5471,7 @@ static unsigned int rtpengine46(struct sk_buff *skb, struct sk_buff *oskb,
|
|
|
|
|
skb_trim(skb, rtp.header_len + rtp.payload_len);
|
|
|
|
|
|
|
|
|
|
if (g->target.rtp_stats && ssrc_idx != -1 && rtp_pt_idx >= 0)
|
|
|
|
|
rtp_stats(g, &rtp, ktime_to_us(skb->tstamp), rtp_pt_idx, ssrc_idx);
|
|
|
|
|
rtp_stats(g, &rtp, ktime_to_us(skb->tstamp), rtp_pt_idx, ssrc_idx, t->rtpe_stats);
|
|
|
|
|
|
|
|
|
|
DBG("packet payload decrypted as %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x...\n",
|
|
|
|
|
rtp.payload[0], rtp.payload[1], rtp.payload[2], rtp.payload[3],
|
|
|
|
|