Browse Source

MT#57977 support short-packet blocking

Change-Id: I132cfc24262b97a29a7887e717d15e0ac38f439b
(cherry picked from commit 81151b3793)
rfuchs/dataport-mr11.5
Richard Fuchs 2 years ago
parent
commit
8f338b7cfe
13 changed files with 76 additions and 18 deletions
  1. +3
    -0
      daemon/call.c
  2. +5
    -0
      daemon/call_interfaces.c
  3. +10
    -0
      daemon/codec.c
  4. +7
    -2
      daemon/media_socket.c
  5. +8
    -0
      docs/ng_control_protocol.md
  6. +1
    -0
      include/call.h
  7. +1
    -0
      include/call_interfaces.h
  8. +2
    -0
      include/codec.h
  9. +27
    -16
      kernel-module/xt_RTPENGINE.c
  10. +1
    -0
      kernel-module/xt_RTPENGINE.h
  11. +8
    -0
      lib/codeclib.c
  12. +2
    -0
      lib/codeclib.h
  13. +1
    -0
      utils/rtpengine-ng-client

+ 3
- 0
daemon/call.c View File

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


+ 5
- 0
daemon/call_interfaces.c View File

@ -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,


+ 10
- 0
daemon/codec.c View File

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


+ 7
- 2
daemon/media_socket.c View File

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


+ 8
- 0
docs/ng_control_protocol.md View File

@ -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.


+ 1
- 0
include/call.h View File

@ -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 {


+ 1
- 0
include/call_interfaces.h View File

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


+ 2
- 0
include/codec.h View File

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


+ 27
- 16
kernel-module/xt_RTPENGINE.c View File

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


+ 1
- 0
kernel-module/xt_RTPENGINE.h View File

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


+ 8
- 0
lib/codeclib.c View File

@ -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
{


+ 2
- 0
lib/codeclib.h View File

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


+ 1
- 0
utils/rtpengine-ng-client View File

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


Loading…
Cancel
Save