From ab3113bff7c5a70bdd768dea6f9f08d78d737b95 Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Mon, 24 Feb 2025 12:07:13 -0400 Subject: [PATCH] MT#61625 support "blackhole" codec handler Special codec handler to support not forwarding (nor any processing whatsoever) of particular payload types at all. Support this in the kernel module as well. Change-Id: If10227affa54307e1e9b448eadd0bf2bfc5774ba --- daemon/codec.c | 18 +++++++++++++++++- daemon/media_socket.c | 4 ++++ include/call.h | 1 + include/codec.h | 1 + kernel-module/xt_RTPENGINE.c | 9 ++++++++- kernel-module/xt_RTPENGINE.h | 1 + 6 files changed, 32 insertions(+), 2 deletions(-) diff --git a/daemon/codec.c b/daemon/codec.c index 4b95614e6..2d86ad4a3 100644 --- a/daemon/codec.c +++ b/daemon/codec.c @@ -297,6 +297,7 @@ static codec_handler_func handler_func_playback; static codec_handler_func handler_func_inject_dtmf; static codec_handler_func handler_func_dtmf; static codec_handler_func handler_func_t38; +static codec_handler_func handler_func_blackhole; static struct ssrc_entry *__ssrc_handler_transcode_new(void *p); static struct ssrc_entry *__ssrc_handler_decode_new(void *p); @@ -347,6 +348,14 @@ static struct codec_handler codec_handler_stub_ssrc = { .kernelize = true, .passthrough = true, }; +static struct codec_handler codec_handler_stub_blackhole = { + .source_pt.payload_type = -1, + .dest_pt.payload_type = -1, + .handler_func = handler_func_blackhole, + .blackhole = true, + .kernelize = true, + .passthrough = false, +}; @@ -369,6 +378,7 @@ static void __handler_shutdown(struct codec_handler *handler) { handler->pcm_dtmf_detect = false; handler->passthrough = false; handler->payload_len = 0; + handler->blackhole = false; codec_handler_free(&handler->dtmf_injector); @@ -485,6 +495,10 @@ static void __handler_stats_entry(struct codec_handler *handler) { __atomic_fetch_add(&stats_entry->num_transcoders, 1, __ATOMIC_RELAXED); } +static int handler_func_blackhole(struct codec_handler *h, struct media_packet *mp) { + return 0; +} + static void __reset_sequencer(void *p, void *dummy) { struct ssrc_entry_call *s = p; if (s->sequencers) @@ -506,7 +520,7 @@ static bool __make_transcoder_full(struct codec_handler *handler, rtp_payload_ty goto reset; if (!rtp_payload_type_eq_exact(dest, &handler->dest_pt)) goto reset; - if (handler->handler_func != handler_func_transcode) + if (handler->handler_func != handler_func_transcode && handler->handler_func != handler_func_blackhole) goto reset; if (handler->packet_decoded != packet_decoded) goto reset; @@ -1780,6 +1794,8 @@ struct codec_handler *codec_handler_get(struct call_media *m, int payload_type, out: if (ret) return ret; + if (MEDIA_ISSET(sink, SELECT_PT)) + return &codec_handler_stub_blackhole; if (sh && sh->attrs.transcoding) return &codec_handler_stub_ssrc; #endif diff --git a/daemon/media_socket.c b/daemon/media_socket.c index 86d4061f1..0f362bec5 100644 --- a/daemon/media_socket.c +++ b/daemon/media_socket.c @@ -1657,6 +1657,8 @@ static const char *kernelize_target(kernelize_state *s, struct packet_stream *st struct codec_handler *ch = codec_handler_get(media, rs->payload_type, ksink->media, ksh); + if (ch->blackhole) + s->manipulate_pt = true; if (ch->kernelize) continue; @@ -1744,6 +1746,8 @@ static const char *kernelize_one(kernelize_state *s, if (ML_ISSET(media->monologue, BLOCK_SHORT) && ch->payload_len) rpt->min_payload_len = ch->payload_len; + + rpt->blackhole = ch->blackhole; } } diff --git a/include/call.h b/include/call.h index 83539dea2..a010e37e9 100644 --- a/include/call.h +++ b/include/call.h @@ -218,6 +218,7 @@ enum { * if not set, then inactive. */ #define MEDIA_FLAG_REAL_SENDONLY (1LL << 35) +#define MEDIA_FLAG_SELECT_PT (1LL << 36) /* struct call_monologue */ #define ML_FLAG_REC_FORWARDING (1LL << 16) diff --git a/include/codec.h b/include/codec.h index 28e212c20..c33b7a18c 100644 --- a/include/codec.h +++ b/include/codec.h @@ -58,6 +58,7 @@ struct codec_handler { bool kernelize:1; bool transcoder:1; bool pcm_dtmf_detect:1; + bool blackhole:1; size_t payload_len; // for short-packet blocking diff --git a/kernel-module/xt_RTPENGINE.c b/kernel-module/xt_RTPENGINE.c index e5b6a574c..da749e79e 100644 --- a/kernel-module/xt_RTPENGINE.c +++ b/kernel-module/xt_RTPENGINE.c @@ -1796,6 +1796,9 @@ static int proc_list_show(struct seq_file *f, void *v) { g->target.pt_stats[j]->payload_type, o->output.pt_output[j].replace_pattern_len, o->output.pt_output[j].min_payload_len); + if (o->output.pt_output[j].blackhole) + seq_printf(f, " RTP payload type %3u: blackhole\n", + g->target.pt_stats[j]->payload_type); } proc_list_crypto_print(f, &o->encrypt_rtp, &o->output.encrypt, "encryption"); @@ -6023,8 +6026,12 @@ static bool proxy_packet_output_rtXp(struct sk_buff *skb, struct rtpengine_outpu return true; } - // pattern rewriting if (rtp_pt_idx >= 0) { + // blackhole? + if (o->output.pt_output[rtp_pt_idx].blackhole) + return false; + + // pattern rewriting 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; diff --git a/kernel-module/xt_RTPENGINE.h b/kernel-module/xt_RTPENGINE.h index bb6264e20..738ee426c 100644 --- a/kernel-module/xt_RTPENGINE.h +++ b/kernel-module/xt_RTPENGINE.h @@ -78,6 +78,7 @@ struct rtpengine_pt_output { unsigned int min_payload_len; char replace_pattern[16]; unsigned char replace_pattern_len; + unsigned int blackhole:1; }; struct rtpengine_target_info {