MT#57977 support short-packet blocking

Change-Id: I132cfc24262b97a29a7887e717d15e0ac38f439b
(cherry picked from commit 81151b3793)
rfuchs/dataport-mr11.5
Richard Fuchs 2 years ago
parent ec3dfd8a25
commit 8f338b7cfe

@ -2516,6 +2516,9 @@ static void __update_init_subscribers(struct call_monologue *ml, GQueue *streams
recording_setup_monologue(ml);
if (flags && flags->block_short)
ml->block_short = 1;
for (unsigned int j = 0; j < ml->medias->len; j++) {
struct call_media *media = ml->medias->pdata[j];
if (!media)

@ -1151,6 +1151,11 @@ static void call_ng_flags_flags(struct sdp_ng_flags *out, str *s, void *dummy) {
case CSH_LOOKUP("mirror-rtcp"):
out->rtcp_mirror = 1;
break;
case CSH_LOOKUP("block-short"):
case CSH_LOOKUP("block-shorts"):
case CSH_LOOKUP("block-short-packets"):
out->block_short = 1;
break;
default:
// handle values aliases from other dictionaries
if (call_ng_flags_prefix(out, s, "from-tags-", call_ng_flags_esc_str_list,

@ -308,6 +308,7 @@ static void __handler_shutdown(struct codec_handler *handler) {
handler->cn_payload_type = -1;
handler->pcm_dtmf_detect = 0;
handler->passthrough = 0;
handler->payload_len = 0;
codec_handler_free(&handler->dtmf_injector);
@ -1655,6 +1656,15 @@ static int handler_func_passthrough(struct codec_handler *h, struct media_packet
ts = ntohl(mp->rtp->timestamp);
codec_calc_jitter(mp->ssrc_in, ts, h->source_pt.clock_rate, &mp->tv);
codec_calc_lost(mp->ssrc_in, ntohs(mp->rtp->seq_num));
if (mp->media->monologue->block_short && h->source_pt.codec_def
&& h->source_pt.codec_def->fixed_sizes)
{
if (!h->payload_len)
h->payload_len = mp->payload.len;
else if (mp->payload.len < h->payload_len)
return 0;
}
}
mp->media->monologue->dtmf_injection_active = 0;

@ -1561,16 +1561,18 @@ output:
redi->local = reti->local;
redi->output.tos = call->tos;
// media silencing
// PT manipulations
bool silenced = call->silence_media || media->monologue->silence_media
|| sink_handler->attrs.silence_media;
if (silenced) {
bool manipulate_pt = silenced || media->monologue->block_short;
if (manipulate_pt && payload_types) {
int i = 0;
for (GList *l = *payload_types; l; l = l->next) {
struct rtp_stats *rs = l->data;
struct rtpengine_pt_output *rpt = &redi->output.pt_output[i++];
struct codec_handler *ch = codec_handler_get(media, rs->payload_type,
sink->media, sink_handler);
str replace_pattern = STR_NULL;
if (silenced && ch->source_pt.codec_def)
replace_pattern = ch->source_pt.codec_def->silence_pattern;
@ -1581,6 +1583,9 @@ output:
rpt->replace_pattern_len = replace_pattern.len;
memcpy(rpt->replace_pattern, replace_pattern.s, replace_pattern.len);
}
if (media->monologue->block_short && ch->payload_len)
rpt->min_payload_len = ch->payload_len;
}
}

@ -807,6 +807,14 @@ Spaces in each string may be replaced by hyphens.
Corresponds to the *rtpproxy* `a` flag. Advertises an RTP endpoint which uses asymmetric
RTP, which disables learning of endpoint addresses (see below).
* `block short` or `block short packets`
Enables blocking of short RTP packets for the applicable call participant.
Short RTP packets are packets shorter than the expected minimum length,
which is determined empirically based on what is observed on the wire.
Short packets are simply discarded. This is supported only for codecs for
which a fixed packet size is expected (e.g. G.711).
* `debug` or `debugging`
Enabled full debug logging for this call, regardless of global log level settings.

@ -539,6 +539,7 @@ struct call_monologue {
unsigned int detect_dtmf:1;
unsigned int no_recording:1;
unsigned int transcoding:1;
unsigned int block_short:1;
};
struct call_iterator_list {

@ -199,6 +199,7 @@ struct sdp_ng_flags {
drop_traffic_stop:1,
passthrough_on:1,
passthrough_off:1,
block_short:1,
disable_jb:1,
nat_wait:1,
pierce_nat:1;

@ -47,6 +47,8 @@ struct codec_handler {
unsigned int transcoder:1;
unsigned int pcm_dtmf_detect:1;
size_t payload_len; // for short-packet blocking
struct ssrc_hash *ssrc_hash;
struct codec_handler *input_handler; // == main handler for supp codecs
struct codec_handler *output_handler; // == self, or other PT handler

@ -1789,11 +1789,12 @@ static int proc_list_show(struct seq_file *f, void *v) {
seq_printf(f, "\n");
for (j = 0; j < g->target.num_payload_types; j++) {
if (o->output.pt_output[j].replace_pattern_len)
if (o->output.pt_output[j].replace_pattern_len || o->output.pt_output[j].min_payload_len)
seq_printf(f, " RTP payload type %3u: "
"%u bytes replacement payload\n",
"%u bytes replacement payload, min payload len %u\n",
g->target.pt_input[j].pt_num,
o->output.pt_output[j].replace_pattern_len);
o->output.pt_output[j].replace_pattern_len,
o->output.pt_output[j].min_payload_len);
}
proc_list_crypto_print(f, &o->encrypt_rtp, &o->output.encrypt, "encryption");
@ -5134,7 +5135,7 @@ static void proxy_packet_output_rtcp(struct sk_buff *skb, struct rtpengine_outpu
skb_put(skb, rtp->payload_len - pllen);
}
static void proxy_packet_output_rtXp(struct sk_buff *skb, struct rtpengine_output *o,
static bool proxy_packet_output_rtXp(struct sk_buff *skb, struct rtpengine_output *o,
int rtp_pt_idx,
struct rtp_parsed *rtp, int ssrc_idx)
{
@ -5144,20 +5145,26 @@ static void proxy_packet_output_rtXp(struct sk_buff *skb, struct rtpengine_outpu
if (!rtp->ok) {
proxy_packet_output_rtcp(skb, o, rtp, ssrc_idx);
return;
return true;
}
// pattern rewriting
if (rtp_pt_idx >= 0 && o->output.pt_output[rtp_pt_idx].replace_pattern_len) {
if (o->output.pt_output[rtp_pt_idx].replace_pattern_len == 1)
memset(rtp->payload, o->output.pt_output[rtp_pt_idx].replace_pattern[0],
rtp->payload_len);
else {
for (i = 0; i < rtp->payload_len;
i += o->output.pt_output[rtp_pt_idx].replace_pattern_len)
memcpy(&rtp->payload[i],
o->output.pt_output[rtp_pt_idx].replace_pattern,
o->output.pt_output[rtp_pt_idx].replace_pattern_len);
if (rtp_pt_idx >= 0) {
if (o->output.pt_output[rtp_pt_idx].min_payload_len
&& rtp->payload_len < o->output.pt_output[rtp_pt_idx].min_payload_len)
return false;
if (o->output.pt_output[rtp_pt_idx].replace_pattern_len) {
if (o->output.pt_output[rtp_pt_idx].replace_pattern_len == 1)
memset(rtp->payload, o->output.pt_output[rtp_pt_idx].replace_pattern[0],
rtp->payload_len);
else {
for (i = 0; i < rtp->payload_len;
i += o->output.pt_output[rtp_pt_idx].replace_pattern_len)
memcpy(&rtp->payload[i],
o->output.pt_output[rtp_pt_idx].replace_pattern,
o->output.pt_output[rtp_pt_idx].replace_pattern_len);
}
}
}
@ -5175,6 +5182,8 @@ static void proxy_packet_output_rtXp(struct sk_buff *skb, struct rtpengine_outpu
srtp_encrypt(&o->encrypt_rtp, &o->output.encrypt, rtp, pkt_idx);
srtp_authenticate(&o->encrypt_rtp, &o->output.encrypt, rtp, pkt_idx);
skb_put(skb, rtp->payload_len - pllen);
return true;
}
static int send_proxy_packet_output(struct sk_buff *skb, struct rtpengine_target *g,
@ -5182,7 +5191,9 @@ static int send_proxy_packet_output(struct sk_buff *skb, struct rtpengine_target
struct rtpengine_output *o, struct rtp_parsed *rtp, int ssrc_idx,
const struct xt_action_param *par)
{
proxy_packet_output_rtXp(skb, o, rtp_pt_idx, rtp, ssrc_idx);
bool send_or_not = proxy_packet_output_rtXp(skb, o, rtp_pt_idx, rtp, ssrc_idx);
if (!send_or_not)
return 0;
return send_proxy_packet(skb, &o->output.src_addr, &o->output.dst_addr, o->output.tos, par);
}

@ -100,6 +100,7 @@ struct rtpengine_pt_input {
uint32_t clock_rate;
};
struct rtpengine_pt_output {
unsigned int min_payload_len;
char replace_pattern[16];
unsigned char replace_pattern_len;
};

@ -256,6 +256,7 @@ static struct codec_def_s __codec_defs[] = {
[DTX_SILENCE] = &dtx_method_silence,
[DTX_CN] = &dtx_method_cn,
},
.fixed_sizes = 1,
},
{
.rtpname = "PCMU",
@ -272,6 +273,7 @@ static struct codec_def_s __codec_defs[] = {
[DTX_SILENCE] = &dtx_method_silence,
[DTX_CN] = &dtx_method_cn,
},
.fixed_sizes = 1,
},
{
.rtpname = "G723",
@ -288,6 +290,7 @@ static struct codec_def_s __codec_defs[] = {
[DTX_SILENCE] = &dtx_method_silence,
[DTX_CN] = &dtx_method_cn,
},
.fixed_sizes = 1,
},
{
.rtpname = "G722",
@ -305,6 +308,7 @@ static struct codec_def_s __codec_defs[] = {
[DTX_SILENCE] = &dtx_method_silence,
[DTX_CN] = &dtx_method_cn,
},
.fixed_sizes = 1,
},
{
.rtpname = "QCELP",
@ -334,6 +338,7 @@ static struct codec_def_s __codec_defs[] = {
[DTX_SILENCE] = &dtx_method_silence,
[DTX_CN] = &dtx_method_cn,
},
.fixed_sizes = 1,
},
{
.rtpname = "G729a",
@ -349,6 +354,7 @@ static struct codec_def_s __codec_defs[] = {
[DTX_SILENCE] = &dtx_method_silence,
[DTX_CN] = &dtx_method_cn,
},
.fixed_sizes = 1,
},
#else
{
@ -367,6 +373,7 @@ static struct codec_def_s __codec_defs[] = {
[DTX_SILENCE] = &dtx_method_silence,
[DTX_CN] = &dtx_method_cn,
},
.fixed_sizes = 1,
},
{
.rtpname = "G729a",
@ -383,6 +390,7 @@ static struct codec_def_s __codec_defs[] = {
[DTX_SILENCE] = &dtx_method_silence,
[DTX_CN] = &dtx_method_cn,
},
.fixed_sizes = 1,
},
#endif
{

@ -213,6 +213,7 @@ struct codec_def_s {
// flags
unsigned int supplemental:1,
dtmf:1, // special case
fixed_sizes:1, // hint for `block-short` feature
amr:1;
const codec_type_t *codec_type;
@ -465,6 +466,7 @@ INLINE int decoder_event(decoder_t *dec, enum codec_event event, void *ptr) {
struct codec_def_s {
int dtmf;
int supplemental;
int fixed_sizes;
format_cmp_f * const format_cmp;
format_print_f * const format_print;
const str silence_pattern;

@ -50,6 +50,7 @@ my @flags = qw(
no-passthrough
pause
early-media
block-short
);
my @string_opts = qw(

Loading…
Cancel
Save